File Coverage

blib/lib/Ewindows1257.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 Ewindows1257;
2 206     206   1243 use strict;
  206         347  
  206         8197  
3 206 50   206   3630 BEGIN { $INC{'warnings.pm'} = '' if $] < 5.006 } use warnings;
  206     206   976  
  206         346  
  206         6615  
4             ######################################################################
5             #
6             # Ewindows1257 - Run-time routines for Windows1257.pm
7             #
8             # http://search.cpan.org/dist/Char-Windows1257/
9             #
10             # Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2019 INABA Hitoshi
11             ######################################################################
12              
13 206     206   3228 use 5.00503; # Galapagos Consensus 1998 for primetools
  206         707  
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   1111 use vars qw($VERSION);
  206         516  
  206         26343  
29             $VERSION = '1.23';
30             $VERSION = $VERSION;
31              
32             BEGIN {
33 206 50   206   1302 if ($^X =~ / jperl /oxmsi) {
34 0         0 die __FILE__, ": needs perl(not jperl) 5.00503 or later. (\$^X==$^X)\n";
35             }
36 206         381 if (CORE::ord('A') == 193) {
37             die __FILE__, ": is not US-ASCII script (may be EBCDIC or EBCDIK script).\n";
38             }
39 206         26369 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   13812 CORE::eval q{
  206     206   1389  
  206     64   450  
  206         22517  
  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       78032 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 (Ewindows1257::index($name,'::') >= 0) {
84 0         0 return $name;
85             }
86             elsif (Ewindows1257::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   1486 no strict qw(refs);
  206         389  
  206         13556  
119 0         0 return \*{ qualify $_[0], $_[1] };
  0         0  
120             }
121             else {
122 206     206   1263 no strict qw(refs);
  206     0   456  
  206         35032  
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   1407 use vars qw($qq_char); $qq_char = qr/\\c[\x40-\x5F]|\\?(?:$your_char)/oxms;
  206         441  
  206         11842  
155 206     206   1243 use vars qw($q_char); $q_char = qr/$your_char/oxms;
  206         506  
  206         330883  
156              
157             #
158             # Windows-1257 character range per length
159             #
160             my %range_tr = ();
161              
162             #
163             # Windows-1257 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 Ewindows1257 \z/oxms) {
179             %range_tr = (
180             1 => [ [0x00..0xFF],
181             ],
182             );
183              
184             %lc = (%lc,
185             "\xA8" => "\xB8", # LATIN LETTER O WITH STROKE
186             "\xAA" => "\xBA", # LATIN LETTER R WITH CEDILLA
187             "\xAF" => "\xBF", # LATIN LETTER AE
188             "\xC0" => "\xE0", # LATIN LETTER A WITH OGONEK
189             "\xC1" => "\xE1", # LATIN LETTER I WITH OGONEK
190             "\xC2" => "\xE2", # LATIN LETTER A WITH MACRON
191             "\xC3" => "\xE3", # LATIN LETTER C WITH ACUTE
192             "\xC4" => "\xE4", # LATIN LETTER A WITH DIAERESIS
193             "\xC5" => "\xE5", # LATIN LETTER A WITH RING ABOVE
194             "\xC6" => "\xE6", # LATIN LETTER E WITH OGONEK
195             "\xC7" => "\xE7", # LATIN LETTER E WITH MACRON
196             "\xC8" => "\xE8", # LATIN LETTER C WITH CARON
197             "\xC9" => "\xE9", # LATIN LETTER E WITH ACUTE
198             "\xCA" => "\xEA", # LATIN LETTER Z WITH ACUTE
199             "\xCB" => "\xEB", # LATIN LETTER E WITH DOT ABOVE
200             "\xCC" => "\xEC", # LATIN LETTER G WITH CEDILLA
201             "\xCD" => "\xED", # LATIN LETTER K WITH CEDILLA
202             "\xCE" => "\xEE", # LATIN LETTER I WITH MACRON
203             "\xCF" => "\xEF", # LATIN LETTER L WITH CEDILLA
204             "\xD0" => "\xF0", # LATIN LETTER S WITH CARON
205             "\xD1" => "\xF1", # LATIN LETTER N WITH ACUTE
206             "\xD2" => "\xF2", # LATIN LETTER N WITH CEDILLA
207             "\xD3" => "\xF3", # LATIN LETTER O WITH ACUTE
208             "\xD4" => "\xF4", # LATIN LETTER O WITH MACRON
209             "\xD5" => "\xF5", # LATIN LETTER O WITH TILDE
210             "\xD6" => "\xF6", # LATIN LETTER O WITH DIAERESIS
211             "\xD8" => "\xF8", # LATIN LETTER U WITH OGONEK
212             "\xD9" => "\xF9", # LATIN LETTER L WITH STROKE
213             "\xDA" => "\xFA", # LATIN LETTER S WITH ACUTE
214             "\xDB" => "\xFB", # LATIN LETTER U WITH MACRON
215             "\xDC" => "\xFC", # LATIN LETTER U WITH DIAERESIS
216             "\xDD" => "\xFD", # LATIN LETTER Z WITH DOT ABOVE
217             "\xDE" => "\xFE", # LATIN LETTER Z WITH CARON
218             );
219              
220             %uc = (%uc,
221             "\xB8" => "\xA8", # LATIN LETTER O WITH STROKE
222             "\xBA" => "\xAA", # LATIN LETTER R WITH CEDILLA
223             "\xBF" => "\xAF", # LATIN LETTER AE
224             "\xE0" => "\xC0", # LATIN LETTER A WITH OGONEK
225             "\xE1" => "\xC1", # LATIN LETTER I WITH OGONEK
226             "\xE2" => "\xC2", # LATIN LETTER A WITH MACRON
227             "\xE3" => "\xC3", # LATIN LETTER C WITH ACUTE
228             "\xE4" => "\xC4", # LATIN LETTER A WITH DIAERESIS
229             "\xE5" => "\xC5", # LATIN LETTER A WITH RING ABOVE
230             "\xE6" => "\xC6", # LATIN LETTER E WITH OGONEK
231             "\xE7" => "\xC7", # LATIN LETTER E WITH MACRON
232             "\xE8" => "\xC8", # LATIN LETTER C WITH CARON
233             "\xE9" => "\xC9", # LATIN LETTER E WITH ACUTE
234             "\xEA" => "\xCA", # LATIN LETTER Z WITH ACUTE
235             "\xEB" => "\xCB", # LATIN LETTER E WITH DOT ABOVE
236             "\xEC" => "\xCC", # LATIN LETTER G WITH CEDILLA
237             "\xED" => "\xCD", # LATIN LETTER K WITH CEDILLA
238             "\xEE" => "\xCE", # LATIN LETTER I WITH MACRON
239             "\xEF" => "\xCF", # LATIN LETTER L WITH CEDILLA
240             "\xF0" => "\xD0", # LATIN LETTER S WITH CARON
241             "\xF1" => "\xD1", # LATIN LETTER N WITH ACUTE
242             "\xF2" => "\xD2", # LATIN LETTER N WITH CEDILLA
243             "\xF3" => "\xD3", # LATIN LETTER O WITH ACUTE
244             "\xF4" => "\xD4", # LATIN LETTER O WITH MACRON
245             "\xF5" => "\xD5", # LATIN LETTER O WITH TILDE
246             "\xF6" => "\xD6", # LATIN LETTER O WITH DIAERESIS
247             "\xF8" => "\xD8", # LATIN LETTER U WITH OGONEK
248             "\xF9" => "\xD9", # LATIN LETTER L WITH STROKE
249             "\xFA" => "\xDA", # LATIN LETTER S WITH ACUTE
250             "\xFB" => "\xDB", # LATIN LETTER U WITH MACRON
251             "\xFC" => "\xDC", # LATIN LETTER U WITH DIAERESIS
252             "\xFD" => "\xDD", # LATIN LETTER Z WITH DOT ABOVE
253             "\xFE" => "\xDE", # LATIN LETTER Z WITH CARON
254             );
255              
256             %fc = (%fc,
257             "\xA8" => "\xB8", # LATIN CAPITAL LETTER O WITH STROKE --> LATIN SMALL LETTER O WITH STROKE
258             "\xAA" => "\xBA", # LATIN CAPITAL LETTER R WITH CEDILLA --> LATIN SMALL LETTER R WITH CEDILLA
259             "\xAF" => "\xBF", # LATIN CAPITAL LETTER AE --> LATIN SMALL LETTER AE
260             "\xC0" => "\xE0", # LATIN CAPITAL LETTER A WITH OGONEK --> LATIN SMALL LETTER A WITH OGONEK
261             "\xC1" => "\xE1", # LATIN CAPITAL LETTER I WITH OGONEK --> LATIN SMALL LETTER I WITH OGONEK
262             "\xC2" => "\xE2", # LATIN CAPITAL LETTER A WITH MACRON --> LATIN SMALL LETTER A WITH MACRON
263             "\xC3" => "\xE3", # LATIN CAPITAL LETTER C WITH ACUTE --> LATIN SMALL LETTER C WITH ACUTE
264             "\xC4" => "\xE4", # LATIN CAPITAL LETTER A WITH DIAERESIS --> LATIN SMALL LETTER A WITH DIAERESIS
265             "\xC5" => "\xE5", # LATIN CAPITAL LETTER A WITH RING ABOVE --> LATIN SMALL LETTER A WITH RING ABOVE
266             "\xC6" => "\xE6", # LATIN CAPITAL LETTER E WITH OGONEK --> LATIN SMALL LETTER E WITH OGONEK
267             "\xC7" => "\xE7", # LATIN CAPITAL LETTER E WITH MACRON --> LATIN SMALL LETTER E WITH MACRON
268             "\xC8" => "\xE8", # LATIN CAPITAL LETTER C WITH CARON --> LATIN SMALL LETTER C WITH CARON
269             "\xC9" => "\xE9", # LATIN CAPITAL LETTER E WITH ACUTE --> LATIN SMALL LETTER E WITH ACUTE
270             "\xCA" => "\xEA", # LATIN CAPITAL LETTER Z WITH ACUTE --> LATIN SMALL LETTER Z WITH ACUTE
271             "\xCB" => "\xEB", # LATIN CAPITAL LETTER E WITH DOT ABOVE --> LATIN SMALL LETTER E WITH DOT ABOVE
272             "\xCC" => "\xEC", # LATIN CAPITAL LETTER G WITH CEDILLA --> LATIN SMALL LETTER G WITH CEDILLA
273             "\xCD" => "\xED", # LATIN CAPITAL LETTER K WITH CEDILLA --> LATIN SMALL LETTER K WITH CEDILLA
274             "\xCE" => "\xEE", # LATIN CAPITAL LETTER I WITH MACRON --> LATIN SMALL LETTER I WITH MACRON
275             "\xCF" => "\xEF", # LATIN CAPITAL LETTER L WITH CEDILLA --> LATIN SMALL LETTER L WITH CEDILLA
276             "\xD0" => "\xF0", # LATIN CAPITAL LETTER S WITH CARON --> LATIN SMALL LETTER S WITH CARON
277             "\xD1" => "\xF1", # LATIN CAPITAL LETTER N WITH ACUTE --> LATIN SMALL LETTER N WITH ACUTE
278             "\xD2" => "\xF2", # LATIN CAPITAL LETTER N WITH CEDILLA --> LATIN SMALL LETTER N WITH CEDILLA
279             "\xD3" => "\xF3", # LATIN CAPITAL LETTER O WITH ACUTE --> LATIN SMALL LETTER O WITH ACUTE
280             "\xD4" => "\xF4", # LATIN CAPITAL LETTER O WITH MACRON --> LATIN SMALL LETTER O WITH MACRON
281             "\xD5" => "\xF5", # LATIN CAPITAL LETTER O WITH TILDE --> LATIN SMALL LETTER O WITH TILDE
282             "\xD6" => "\xF6", # LATIN CAPITAL LETTER O WITH DIAERESIS --> LATIN SMALL LETTER O WITH DIAERESIS
283             "\xD8" => "\xF8", # LATIN CAPITAL LETTER U WITH OGONEK --> LATIN SMALL LETTER U WITH OGONEK
284             "\xD9" => "\xF9", # LATIN CAPITAL LETTER L WITH STROKE --> LATIN SMALL LETTER L WITH STROKE
285             "\xDA" => "\xFA", # LATIN CAPITAL LETTER S WITH ACUTE --> LATIN SMALL LETTER S WITH ACUTE
286             "\xDB" => "\xFB", # LATIN CAPITAL LETTER U WITH MACRON --> LATIN SMALL LETTER U WITH MACRON
287             "\xDC" => "\xFC", # LATIN CAPITAL LETTER U WITH DIAERESIS --> LATIN SMALL LETTER U WITH DIAERESIS
288             "\xDD" => "\xFD", # LATIN CAPITAL LETTER Z WITH DOT ABOVE --> LATIN SMALL LETTER Z WITH DOT ABOVE
289             "\xDE" => "\xFE", # LATIN CAPITAL LETTER Z WITH CARON --> LATIN SMALL LETTER Z WITH CARON
290             "\xDF" => "\x73\x73", # LATIN SMALL LETTER SHARP S --> LATIN SMALL LETTER S, LATIN SMALL LETTER S
291             );
292             }
293              
294             else {
295             croak "Don't know my package name '@{[__PACKAGE__]}'";
296             }
297              
298             #
299             # @ARGV wildcard globbing
300             #
301             sub import {
302              
303 0 0   0   0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
304 0         0 my @argv = ();
305 0         0 for (@ARGV) {
306              
307             # has space
308 0 0       0 if (/\A (?:$q_char)*? [ ] /oxms) {
    0          
309 0 0       0 if (my @glob = Ewindows1257::glob(qq{"$_"})) {
310 0         0 push @argv, @glob;
311             }
312             else {
313 0         0 push @argv, $_;
314             }
315             }
316              
317             # has wildcard metachar
318             elsif (/\A (?:$q_char)*? [*?] /oxms) {
319 0 0       0 if (my @glob = Ewindows1257::glob($_)) {
320 0         0 push @argv, @glob;
321             }
322             else {
323 0         0 push @argv, $_;
324             }
325             }
326              
327             # no wildcard globbing
328             else {
329 0         0 push @argv, $_;
330             }
331             }
332 0         0 @ARGV = @argv;
333             }
334              
335 0         0 *Char::ord = \&Windows1257::ord;
336 0         0 *Char::ord_ = \&Windows1257::ord_;
337 0         0 *Char::reverse = \&Windows1257::reverse;
338 0         0 *Char::getc = \&Windows1257::getc;
339 0         0 *Char::length = \&Windows1257::length;
340 0         0 *Char::substr = \&Windows1257::substr;
341 0         0 *Char::index = \&Windows1257::index;
342 0         0 *Char::rindex = \&Windows1257::rindex;
343 0         0 *Char::eval = \&Windows1257::eval;
344 0         0 *Char::escape = \&Windows1257::escape;
345 0         0 *Char::escape_token = \&Windows1257::escape_token;
346 0         0 *Char::escape_script = \&Windows1257::escape_script;
347             }
348              
349             # P.230 Care with Prototypes
350             # in Chapter 6: Subroutines
351             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
352             #
353             # If you aren't careful, you can get yourself into trouble with prototypes.
354             # But if you are careful, you can do a lot of neat things with them. This is
355             # all very powerful, of course, and should only be used in moderation to make
356             # the world a better place.
357              
358             # P.332 Care with Prototypes
359             # in Chapter 7: Subroutines
360             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
361             #
362             # If you aren't careful, you can get yourself into trouble with prototypes.
363             # But if you are careful, you can do a lot of neat things with them. This is
364             # all very powerful, of course, and should only be used in moderation to make
365             # the world a better place.
366              
367             #
368             # Prototypes of subroutines
369             #
370       0     sub unimport {}
371             sub Ewindows1257::split(;$$$);
372             sub Ewindows1257::tr($$$$;$);
373             sub Ewindows1257::chop(@);
374             sub Ewindows1257::index($$;$);
375             sub Ewindows1257::rindex($$;$);
376             sub Ewindows1257::lcfirst(@);
377             sub Ewindows1257::lcfirst_();
378             sub Ewindows1257::lc(@);
379             sub Ewindows1257::lc_();
380             sub Ewindows1257::ucfirst(@);
381             sub Ewindows1257::ucfirst_();
382             sub Ewindows1257::uc(@);
383             sub Ewindows1257::uc_();
384             sub Ewindows1257::fc(@);
385             sub Ewindows1257::fc_();
386             sub Ewindows1257::ignorecase;
387             sub Ewindows1257::classic_character_class;
388             sub Ewindows1257::capture;
389             sub Ewindows1257::chr(;$);
390             sub Ewindows1257::chr_();
391             sub Ewindows1257::glob($);
392             sub Ewindows1257::glob_();
393              
394             sub Windows1257::ord(;$);
395             sub Windows1257::ord_();
396             sub Windows1257::reverse(@);
397             sub Windows1257::getc(;*@);
398             sub Windows1257::length(;$);
399             sub Windows1257::substr($$;$$);
400             sub Windows1257::index($$;$);
401             sub Windows1257::rindex($$;$);
402             sub Windows1257::escape(;$);
403              
404             #
405             # Regexp work
406             #
407 206         16784 use vars qw(
408             $re_a
409             $re_t
410             $re_n
411             $re_r
412 206     206   1687 );
  206         486  
413              
414             #
415             # Character class
416             #
417 206         1845081 use vars qw(
418             $dot
419             $dot_s
420             $eD
421             $eS
422             $eW
423             $eH
424             $eV
425             $eR
426             $eN
427             $not_alnum
428             $not_alpha
429             $not_ascii
430             $not_blank
431             $not_cntrl
432             $not_digit
433             $not_graph
434             $not_lower
435             $not_lower_i
436             $not_print
437             $not_punct
438             $not_space
439             $not_upper
440             $not_upper_i
441             $not_word
442             $not_xdigit
443             $eb
444             $eB
445 206     206   1405 );
  206         405  
446              
447             ${Ewindows1257::dot} = qr{(?>[^\x0A])};
448             ${Ewindows1257::dot_s} = qr{(?>[\x00-\xFF])};
449             ${Ewindows1257::eD} = qr{(?>[^0-9])};
450              
451             # Vertical tabs are now whitespace
452             # \s in a regex now matches a vertical tab in all circumstances.
453             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
454             # ${Ewindows1257::eS} = qr{(?>[^\x09\x0A \x0C\x0D\x20])};
455             # ${Ewindows1257::eS} = qr{(?>[^\x09\x0A\x0B\x0C\x0D\x20])};
456             ${Ewindows1257::eS} = qr{(?>[^\s])};
457              
458             ${Ewindows1257::eW} = qr{(?>[^0-9A-Z_a-z])};
459             ${Ewindows1257::eH} = qr{(?>[^\x09\x20])};
460             ${Ewindows1257::eV} = qr{(?>[^\x0A\x0B\x0C\x0D])};
461             ${Ewindows1257::eR} = qr{(?>\x0D\x0A|[\x0A\x0D])};
462             ${Ewindows1257::eN} = qr{(?>[^\x0A])};
463             ${Ewindows1257::not_alnum} = qr{(?>[^\x30-\x39\x41-\x5A\x61-\x7A])};
464             ${Ewindows1257::not_alpha} = qr{(?>[^\x41-\x5A\x61-\x7A])};
465             ${Ewindows1257::not_ascii} = qr{(?>[^\x00-\x7F])};
466             ${Ewindows1257::not_blank} = qr{(?>[^\x09\x20])};
467             ${Ewindows1257::not_cntrl} = qr{(?>[^\x00-\x1F\x7F])};
468             ${Ewindows1257::not_digit} = qr{(?>[^\x30-\x39])};
469             ${Ewindows1257::not_graph} = qr{(?>[^\x21-\x7F])};
470             ${Ewindows1257::not_lower} = qr{(?>[^\x61-\x7A])};
471             ${Ewindows1257::not_lower_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
472             # ${Ewindows1257::not_lower_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
473             ${Ewindows1257::not_print} = qr{(?>[^\x20-\x7F])};
474             ${Ewindows1257::not_punct} = qr{(?>[^\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E])};
475             ${Ewindows1257::not_space} = qr{(?>[^\s\x0B])};
476             ${Ewindows1257::not_upper} = qr{(?>[^\x41-\x5A])};
477             ${Ewindows1257::not_upper_i} = qr{(?>[^\x41-\x5A\x61-\x7A])}; # Perl 5.16 compatible
478             # ${Ewindows1257::not_upper_i} = qr{(?>[\x00-\xFF])}; # older Perl compatible
479             ${Ewindows1257::not_word} = qr{(?>[^\x30-\x39\x41-\x5A\x5F\x61-\x7A])};
480             ${Ewindows1257::not_xdigit} = qr{(?>[^\x30-\x39\x41-\x46\x61-\x66])};
481             ${Ewindows1257::eb} = qr{(?:\A(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[0-9A-Z_a-z])|(?<=[0-9A-Z_a-z])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]|\z))};
482             ${Ewindows1257::eB} = qr{(?:(?<=[0-9A-Z_a-z])(?=[0-9A-Z_a-z])|(?<=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF])(?=[\x00-\x2F\x40\x5B-\x5E\x60\x7B-\xFF]))};
483              
484             # avoid: Name "Ewindows1257::foo" used only once: possible typo at here.
485             ${Ewindows1257::dot} = ${Ewindows1257::dot};
486             ${Ewindows1257::dot_s} = ${Ewindows1257::dot_s};
487             ${Ewindows1257::eD} = ${Ewindows1257::eD};
488             ${Ewindows1257::eS} = ${Ewindows1257::eS};
489             ${Ewindows1257::eW} = ${Ewindows1257::eW};
490             ${Ewindows1257::eH} = ${Ewindows1257::eH};
491             ${Ewindows1257::eV} = ${Ewindows1257::eV};
492             ${Ewindows1257::eR} = ${Ewindows1257::eR};
493             ${Ewindows1257::eN} = ${Ewindows1257::eN};
494             ${Ewindows1257::not_alnum} = ${Ewindows1257::not_alnum};
495             ${Ewindows1257::not_alpha} = ${Ewindows1257::not_alpha};
496             ${Ewindows1257::not_ascii} = ${Ewindows1257::not_ascii};
497             ${Ewindows1257::not_blank} = ${Ewindows1257::not_blank};
498             ${Ewindows1257::not_cntrl} = ${Ewindows1257::not_cntrl};
499             ${Ewindows1257::not_digit} = ${Ewindows1257::not_digit};
500             ${Ewindows1257::not_graph} = ${Ewindows1257::not_graph};
501             ${Ewindows1257::not_lower} = ${Ewindows1257::not_lower};
502             ${Ewindows1257::not_lower_i} = ${Ewindows1257::not_lower_i};
503             ${Ewindows1257::not_print} = ${Ewindows1257::not_print};
504             ${Ewindows1257::not_punct} = ${Ewindows1257::not_punct};
505             ${Ewindows1257::not_space} = ${Ewindows1257::not_space};
506             ${Ewindows1257::not_upper} = ${Ewindows1257::not_upper};
507             ${Ewindows1257::not_upper_i} = ${Ewindows1257::not_upper_i};
508             ${Ewindows1257::not_word} = ${Ewindows1257::not_word};
509             ${Ewindows1257::not_xdigit} = ${Ewindows1257::not_xdigit};
510             ${Ewindows1257::eb} = ${Ewindows1257::eb};
511             ${Ewindows1257::eB} = ${Ewindows1257::eB};
512              
513             #
514             # Windows-1257 split
515             #
516             sub Ewindows1257::split(;$$$) {
517              
518             # P.794 29.2.161. split
519             # in Chapter 29: Functions
520             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
521              
522             # P.951 split
523             # in Chapter 27: Functions
524             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
525              
526 0     0 0 0 my $pattern = $_[0];
527 0         0 my $string = $_[1];
528 0         0 my $limit = $_[2];
529              
530             # if $pattern is also omitted or is the literal space, " "
531 0 0       0 if (not defined $pattern) {
532 0         0 $pattern = ' ';
533             }
534              
535             # if $string is omitted, the function splits the $_ string
536 0 0       0 if (not defined $string) {
537 0 0       0 if (defined $_) {
538 0         0 $string = $_;
539             }
540             else {
541 0         0 $string = '';
542             }
543             }
544              
545 0         0 my @split = ();
546              
547             # when string is empty
548 0 0       0 if ($string eq '') {
    0          
549              
550             # resulting list value in list context
551 0 0       0 if (wantarray) {
552 0         0 return @split;
553             }
554              
555             # count of substrings in scalar context
556             else {
557 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
558 0         0 @_ = @split;
559 0         0 return scalar @_;
560             }
561             }
562              
563             # split's first argument is more consistently interpreted
564             #
565             # After some changes earlier in v5.17, split's behavior has been simplified:
566             # if the PATTERN argument evaluates to a string containing one space, it is
567             # treated the way that a literal string containing one space once was.
568             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#split's_first_argument_is_more_consistently_interpreted
569              
570             # if $pattern is also omitted or is the literal space, " ", the function splits
571             # on whitespace, /\s+/, after skipping any leading whitespace
572             # (and so on)
573              
574             elsif ($pattern eq ' ') {
575 0 0       0 if (not defined $limit) {
576 0         0 return CORE::split(' ', $string);
577             }
578             else {
579 0         0 return CORE::split(' ', $string, $limit);
580             }
581             }
582              
583             # if $limit is negative, it is treated as if an arbitrarily large $limit has been specified
584 0 0 0     0 if ((not defined $limit) or ($limit <= 0)) {
    0          
585              
586             # a pattern capable of matching either the null string or something longer than the
587             # null string will split the value of $string into separate characters wherever it
588             # matches the null string between characters
589             # (and so on)
590              
591 0 0       0 if ('' =~ / \A $pattern \z /xms) {
592 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
593 0         0 my $limit = scalar(() = $string =~ /($pattern)/oxmsg);
594              
595             # P.1024 Appendix W.10 Multibyte Processing
596             # of ISBN 1-56592-224-7 CJKV Information Processing
597             # (and so on)
598              
599             # the //m modifier is assumed when you split on the pattern /^/
600             # (and so on)
601              
602 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
603             # V
604 0   0     0 while ((--$limit > 0) and ($string =~ s/\A((?:$q_char)+?)$pattern//m)) {
605              
606             # if the $pattern contains parentheses, then the substring matched by each pair of parentheses
607             # is included in the resulting list, interspersed with the fields that are ordinarily returned
608             # (and so on)
609              
610 0         0 local $@;
611 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
612 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
613 0         0 push @split, CORE::eval('$' . $digit);
614             }
615             }
616             }
617              
618             else {
619 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
620              
621 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
622             # V
623 0         0 while ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
624 0         0 local $@;
625 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
626 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
627 0         0 push @split, CORE::eval('$' . $digit);
628             }
629             }
630             }
631             }
632              
633             elsif ($limit > 0) {
634 0 0       0 if ('' =~ / \A $pattern \z /xms) {
635 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
636 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
637              
638 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
639             # V
640 0 0       0 if ($string =~ s/\A((?:$q_char)+?)$pattern//m) {
641 0         0 local $@;
642 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
643 0         0 push @split, CORE::eval('$' . $digit);
644             }
645             }
646             }
647             }
648             else {
649 0         0 my $last_subexpression_offsets = _last_subexpression_offsets($pattern);
650 0   0     0 while ((--$limit > 0) and (CORE::length($string) > 0)) {
651              
652 0         0 eval q{ no warnings }; # avoid: Complex regular subexpression recursion limit (32766) exceeded at ...
653             # V
654 0 0       0 if ($string =~ s/\A((?:$q_char)*?)$pattern//m) {
655 0         0 local $@;
656 0         0 for (my $digit=1; $digit <= ($last_subexpression_offsets + 1); $digit++) {
657 0         0 push @split, CORE::eval('$' . $digit);
658             }
659             }
660             }
661             }
662             }
663              
664 0 0       0 if (CORE::length($string) > 0) {
665 0         0 push @split, $string;
666             }
667              
668             # if $_[2] (NOT "$limit") is omitted or zero, trailing null fields are stripped from the result
669 0 0 0     0 if ((not defined $_[2]) or ($_[2] == 0)) {
670 0   0     0 while ((scalar(@split) >= 1) and ($split[-1] eq '')) {
671 0         0 pop @split;
672             }
673             }
674              
675             # resulting list value in list context
676 0 0       0 if (wantarray) {
677 0         0 return @split;
678             }
679              
680             # count of substrings in scalar context
681             else {
682 0 0       0 carp "Use of implicit split to \@_ is deprecated" if $^W;
683 0         0 @_ = @split;
684 0         0 return scalar @_;
685             }
686             }
687              
688             #
689             # get last subexpression offsets
690             #
691             sub _last_subexpression_offsets {
692 0     0   0 my $pattern = $_[0];
693              
694             # remove comment
695 0         0 $pattern =~ s/\(\?\# .*? \)//oxmsg;
696              
697 0         0 my $modifier = '';
698 0 0       0 if ($pattern =~ /\(\?\^? ([\-A-Za-z]+) :/oxms) {
699 0         0 $modifier = $1;
700 0         0 $modifier =~ s/-[A-Za-z]*//;
701             }
702              
703             # with /x modifier
704 0         0 my @char = ();
705 0 0       0 if ($modifier =~ /x/oxms) {
706 0         0 @char = $pattern =~ /\G((?>
707             [^\\\#\[\(] |
708             \\ $q_char |
709             \# (?>[^\n]*) $ |
710             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
711             \(\? |
712             $q_char
713             ))/oxmsg;
714             }
715              
716             # without /x modifier
717             else {
718 0         0 @char = $pattern =~ /\G((?>
719             [^\\\[\(] |
720             \\ $q_char |
721             \[ (?>(?:[^\\\]]|\\\\|\\\]|$q_char)+) \] |
722             \(\? |
723             $q_char
724             ))/oxmsg;
725             }
726              
727 0         0 return scalar grep { $_ eq '(' } @char;
  0         0  
728             }
729              
730             #
731             # Windows-1257 transliteration (tr///)
732             #
733             sub Ewindows1257::tr($$$$;$) {
734              
735 0     0 0 0 my $bind_operator = $_[1];
736 0         0 my $searchlist = $_[2];
737 0         0 my $replacementlist = $_[3];
738 0   0     0 my $modifier = $_[4] || '';
739              
740 0 0       0 if ($modifier =~ /r/oxms) {
741 0 0       0 if ($bind_operator =~ / !~ /oxms) {
742 0         0 croak "Using !~ with tr///r doesn't make sense";
743             }
744             }
745              
746 0         0 my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
747 0         0 my @searchlist = _charlist_tr($searchlist);
748 0         0 my @replacementlist = _charlist_tr($replacementlist);
749              
750 0         0 my %tr = ();
751 0         0 for (my $i=0; $i <= $#searchlist; $i++) {
752 0 0       0 if (not exists $tr{$searchlist[$i]}) {
753 0 0 0     0 if (defined $replacementlist[$i] and ($replacementlist[$i] ne '')) {
    0 0        
    0          
754 0         0 $tr{$searchlist[$i]} = $replacementlist[$i];
755             }
756             elsif ($modifier =~ /d/oxms) {
757 0         0 $tr{$searchlist[$i]} = '';
758             }
759             elsif (defined $replacementlist[-1] and ($replacementlist[-1] ne '')) {
760 0         0 $tr{$searchlist[$i]} = $replacementlist[-1];
761             }
762             else {
763 0         0 $tr{$searchlist[$i]} = $searchlist[$i];
764             }
765             }
766             }
767              
768 0         0 my $tr = 0;
769 0         0 my $replaced = '';
770 0 0       0 if ($modifier =~ /c/oxms) {
771 0         0 while (defined(my $char = shift @char)) {
772 0 0       0 if (not exists $tr{$char}) {
773 0 0       0 if (defined $replacementlist[-1]) {
774 0         0 $replaced .= $replacementlist[-1];
775             }
776 0         0 $tr++;
777 0 0       0 if ($modifier =~ /s/oxms) {
778 0   0     0 while (@char and (not exists $tr{$char[0]})) {
779 0         0 shift @char;
780 0         0 $tr++;
781             }
782             }
783             }
784             else {
785 0         0 $replaced .= $char;
786             }
787             }
788             }
789             else {
790 0         0 while (defined(my $char = shift @char)) {
791 0 0       0 if (exists $tr{$char}) {
792 0         0 $replaced .= $tr{$char};
793 0         0 $tr++;
794 0 0       0 if ($modifier =~ /s/oxms) {
795 0   0     0 while (@char and (exists $tr{$char[0]}) and ($tr{$char[0]} eq $tr{$char})) {
      0        
796 0         0 shift @char;
797 0         0 $tr++;
798             }
799             }
800             }
801             else {
802 0         0 $replaced .= $char;
803             }
804             }
805             }
806              
807 0 0       0 if ($modifier =~ /r/oxms) {
808 0         0 return $replaced;
809             }
810             else {
811 0         0 $_[0] = $replaced;
812 0 0       0 if ($bind_operator =~ / !~ /oxms) {
813 0         0 return not $tr;
814             }
815             else {
816 0         0 return $tr;
817             }
818             }
819             }
820              
821             #
822             # Windows-1257 chop
823             #
824             sub Ewindows1257::chop(@) {
825              
826 0     0 0 0 my $chop;
827 0 0       0 if (@_ == 0) {
828 0         0 my @char = /\G (?>$q_char) /oxmsg;
829 0         0 $chop = pop @char;
830 0         0 $_ = join '', @char;
831             }
832             else {
833 0         0 for (@_) {
834 0         0 my @char = /\G (?>$q_char) /oxmsg;
835 0         0 $chop = pop @char;
836 0         0 $_ = join '', @char;
837             }
838             }
839 0         0 return $chop;
840             }
841              
842             #
843             # Windows-1257 index by octet
844             #
845             sub Ewindows1257::index($$;$) {
846              
847 0     0 1 0 my($str,$substr,$position) = @_;
848 0   0     0 $position ||= 0;
849 0         0 my $pos = 0;
850              
851 0         0 while ($pos < CORE::length($str)) {
852 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
853 0 0       0 if ($pos >= $position) {
854 0         0 return $pos;
855             }
856             }
857 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
858 0         0 $pos += CORE::length($1);
859             }
860             else {
861 0         0 $pos += 1;
862             }
863             }
864 0         0 return -1;
865             }
866              
867             #
868             # Windows-1257 reverse index
869             #
870             sub Ewindows1257::rindex($$;$) {
871              
872 0     0 0 0 my($str,$substr,$position) = @_;
873 0   0     0 $position ||= CORE::length($str) - 1;
874 0         0 my $pos = 0;
875 0         0 my $rindex = -1;
876              
877 0   0     0 while (($pos < CORE::length($str)) and ($pos <= $position)) {
878 0 0       0 if (CORE::substr($str,$pos,CORE::length($substr)) eq $substr) {
879 0         0 $rindex = $pos;
880             }
881 0 0       0 if (CORE::substr($str,$pos) =~ /\A ($q_char) /oxms) {
882 0         0 $pos += CORE::length($1);
883             }
884             else {
885 0         0 $pos += 1;
886             }
887             }
888 0         0 return $rindex;
889             }
890              
891             #
892             # Windows-1257 lower case first with parameter
893             #
894             sub Ewindows1257::lcfirst(@) {
895 0 0   0 0 0 if (@_) {
896 0         0 my $s = shift @_;
897 0 0 0     0 if (@_ and wantarray) {
898 0         0 return Ewindows1257::lc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
899             }
900             else {
901 0         0 return Ewindows1257::lc(CORE::substr($s,0,1)) . CORE::substr($s,1);
902             }
903             }
904             else {
905 0         0 return Ewindows1257::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
906             }
907             }
908              
909             #
910             # Windows-1257 lower case first without parameter
911             #
912             sub Ewindows1257::lcfirst_() {
913 0     0 0 0 return Ewindows1257::lc(CORE::substr($_,0,1)) . CORE::substr($_,1);
914             }
915              
916             #
917             # Windows-1257 lower case with parameter
918             #
919             sub Ewindows1257::lc(@) {
920 0 0   0 0 0 if (@_) {
921 0         0 my $s = shift @_;
922 0 0 0     0 if (@_ and wantarray) {
923 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
924             }
925             else {
926 0 0       0 return join('', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  0         0  
927             }
928             }
929             else {
930 0         0 return Ewindows1257::lc_();
931             }
932             }
933              
934             #
935             # Windows-1257 lower case without parameter
936             #
937             sub Ewindows1257::lc_() {
938 0     0 0 0 my $s = $_;
939 0 0       0 return join '', map {defined($lc{$_}) ? $lc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
940             }
941              
942             #
943             # Windows-1257 upper case first with parameter
944             #
945             sub Ewindows1257::ucfirst(@) {
946 0 0   0 0 0 if (@_) {
947 0         0 my $s = shift @_;
948 0 0 0     0 if (@_ and wantarray) {
949 0         0 return Ewindows1257::uc(CORE::substr($s,0,1)) . CORE::substr($s,1), @_;
950             }
951             else {
952 0         0 return Ewindows1257::uc(CORE::substr($s,0,1)) . CORE::substr($s,1);
953             }
954             }
955             else {
956 0         0 return Ewindows1257::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
957             }
958             }
959              
960             #
961             # Windows-1257 upper case first without parameter
962             #
963             sub Ewindows1257::ucfirst_() {
964 0     0 0 0 return Ewindows1257::uc(CORE::substr($_,0,1)) . CORE::substr($_,1);
965             }
966              
967             #
968             # Windows-1257 upper case with parameter
969             #
970             sub Ewindows1257::uc(@) {
971 0 50   174 0 0 if (@_) {
972 174         279 my $s = shift @_;
973 174 50 33     266 if (@_ and wantarray) {
974 174 0       362 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
975             }
976             else {
977 0 100       0 return join('', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  174         556  
978             }
979             }
980             else {
981 174         666 return Ewindows1257::uc_();
982             }
983             }
984              
985             #
986             # Windows-1257 upper case without parameter
987             #
988             sub Ewindows1257::uc_() {
989 0     0 0 0 my $s = $_;
990 0 0       0 return join '', map {defined($uc{$_}) ? $uc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
991             }
992              
993             #
994             # Windows-1257 fold case with parameter
995             #
996             sub Ewindows1257::fc(@) {
997 0 50   197 0 0 if (@_) {
998 197         306 my $s = shift @_;
999 197 50 33     233 if (@_ and wantarray) {
1000 197 0       368 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg)), @_;
  0         0  
1001             }
1002             else {
1003 0 100       0 return join('', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg));
  197         501  
1004             }
1005             }
1006             else {
1007 197         1114 return Ewindows1257::fc_();
1008             }
1009             }
1010              
1011             #
1012             # Windows-1257 fold case without parameter
1013             #
1014             sub Ewindows1257::fc_() {
1015 0     0 0 0 my $s = $_;
1016 0 0       0 return join '', map {defined($fc{$_}) ? $fc{$_} : $_} ($s =~ /\G ($q_char) /oxmsg);
  0         0  
1017             }
1018              
1019             #
1020             # Windows-1257 regexp capture
1021             #
1022             {
1023             sub Ewindows1257::capture {
1024 0     0 1 0 return $_[0];
1025             }
1026             }
1027              
1028             #
1029             # Windows-1257 regexp ignore case modifier
1030             #
1031             sub Ewindows1257::ignorecase {
1032              
1033 0     0 0 0 my @string = @_;
1034 0         0 my $metachar = qr/[\@\\|[\]{]/oxms;
1035              
1036             # ignore case of $scalar or @array
1037 0         0 for my $string (@string) {
1038              
1039             # split regexp
1040 0         0 my @char = $string =~ /\G (?>\[\^|\\$q_char|$q_char) /oxmsg;
1041              
1042             # unescape character
1043 0         0 for (my $i=0; $i <= $#char; $i++) {
1044 0 0       0 next if not defined $char[$i];
1045              
1046             # open character class [...]
1047 0 0       0 if ($char[$i] eq '[') {
    0          
    0          
    0          
1048 0         0 my $left = $i;
1049              
1050             # [] make die "unmatched [] in regexp ...\n"
1051              
1052 0 0       0 if ($char[$i+1] eq ']') {
1053 0         0 $i++;
1054             }
1055              
1056 0         0 while (1) {
1057 0 0       0 if (++$i > $#char) {
1058 0         0 croak "Unmatched [] in regexp";
1059             }
1060 0 0       0 if ($char[$i] eq ']') {
1061 0         0 my $right = $i;
1062 0         0 my @charlist = charlist_qr(@char[$left+1..$right-1], 'i');
1063              
1064             # escape character
1065 0         0 for my $char (@charlist) {
1066 0 0       0 if (0) {
1067             }
1068              
1069 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1070 0         0 $char = '\\' . $char;
1071             }
1072             }
1073              
1074             # [...]
1075 0         0 splice @char, $left, $right-$left+1, '(?:' . join('|', @charlist) . ')';
1076              
1077 0         0 $i = $left;
1078 0         0 last;
1079             }
1080             }
1081             }
1082              
1083             # open character class [^...]
1084             elsif ($char[$i] eq '[^') {
1085 0         0 my $left = $i;
1086              
1087             # [^] make die "unmatched [] in regexp ...\n"
1088              
1089 0 0       0 if ($char[$i+1] eq ']') {
1090 0         0 $i++;
1091             }
1092              
1093 0         0 while (1) {
1094 0 0       0 if (++$i > $#char) {
1095 0         0 croak "Unmatched [] in regexp";
1096             }
1097 0 0       0 if ($char[$i] eq ']') {
1098 0         0 my $right = $i;
1099 0         0 my @charlist = charlist_not_qr(@char[$left+1..$right-1], 'i');
1100              
1101             # escape character
1102 0         0 for my $char (@charlist) {
1103 0 0       0 if (0) {
1104             }
1105              
1106 0         0 elsif ($char =~ /\A [.|)] \z/oxms) {
1107 0         0 $char = '\\' . $char;
1108             }
1109             }
1110              
1111             # [^...]
1112 0         0 splice @char, $left, $right-$left+1, '(?!' . join('|', @charlist) . ")(?:$your_char)";
1113              
1114 0         0 $i = $left;
1115 0         0 last;
1116             }
1117             }
1118             }
1119              
1120             # rewrite classic character class or escape character
1121             elsif (my $char = classic_character_class($char[$i])) {
1122 0         0 $char[$i] = $char;
1123             }
1124              
1125             # with /i modifier
1126             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1127 0         0 my $uc = Ewindows1257::uc($char[$i]);
1128 0         0 my $fc = Ewindows1257::fc($char[$i]);
1129 0 0       0 if ($uc ne $fc) {
1130 0 0       0 if (CORE::length($fc) == 1) {
1131 0         0 $char[$i] = '[' . $uc . $fc . ']';
1132             }
1133             else {
1134 0         0 $char[$i] = '(?:' . $uc . '|' . $fc . ')';
1135             }
1136             }
1137             }
1138             }
1139              
1140             # characterize
1141 0         0 for (my $i=0; $i <= $#char; $i++) {
1142 0 0       0 next if not defined $char[$i];
1143              
1144 0 0       0 if (0) {
1145             }
1146              
1147             # quote character before ? + * {
1148 0 0       0 elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
1149 0 0       0 if ($char[$i-1] !~ /\A [\x00-\xFF] \z/oxms) {
1150 0         0 $char[$i-1] = '(?:' . $char[$i-1] . ')';
1151             }
1152             }
1153             }
1154              
1155 0         0 $string = join '', @char;
1156             }
1157              
1158             # make regexp string
1159 0         0 return @string;
1160             }
1161              
1162             #
1163             # classic character class ( \D \S \W \d \s \w \C \X \H \V \h \v \R \N \b \B )
1164             #
1165             sub Ewindows1257::classic_character_class {
1166 0     1867 0 0 my($char) = @_;
1167              
1168             return {
1169             '\D' => '${Ewindows1257::eD}',
1170             '\S' => '${Ewindows1257::eS}',
1171             '\W' => '${Ewindows1257::eW}',
1172             '\d' => '[0-9]',
1173              
1174             # Before Perl 5.6, \s only matched the five whitespace characters
1175             # tab, newline, form-feed, carriage return, and the space character
1176             # itself, which, taken together, is the character class [\t\n\f\r ].
1177              
1178             # Vertical tabs are now whitespace
1179             # \s in a regex now matches a vertical tab in all circumstances.
1180             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1181             # \t \n \v \f \r space
1182             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1183             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1184             '\s' => '\s',
1185              
1186             '\w' => '[0-9A-Z_a-z]',
1187             '\C' => '[\x00-\xFF]',
1188             '\X' => 'X',
1189              
1190             # \h \v \H \V
1191              
1192             # P.114 Character Class Shortcuts
1193             # in Chapter 7: In the World of Regular Expressions
1194             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
1195              
1196             # P.357 13.2.3 Whitespace
1197             # in Chapter 13: perlrecharclass: Perl Regular Expression Character Classes
1198             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1199             #
1200             # 0x00009 CHARACTER TABULATION h s
1201             # 0x0000a LINE FEED (LF) vs
1202             # 0x0000b LINE TABULATION v
1203             # 0x0000c FORM FEED (FF) vs
1204             # 0x0000d CARRIAGE RETURN (CR) vs
1205             # 0x00020 SPACE h s
1206              
1207             # P.196 Table 5-9. Alphanumeric regex metasymbols
1208             # in Chapter 5. Pattern Matching
1209             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1210              
1211             # (and so on)
1212              
1213             '\H' => '${Ewindows1257::eH}',
1214             '\V' => '${Ewindows1257::eV}',
1215             '\h' => '[\x09\x20]',
1216             '\v' => '[\x0A\x0B\x0C\x0D]',
1217             '\R' => '${Ewindows1257::eR}',
1218              
1219             # \N
1220             #
1221             # http://perldoc.perl.org/perlre.html
1222             # Character Classes and other Special Escapes
1223             # Any character but \n (experimental). Not affected by /s modifier
1224              
1225             '\N' => '${Ewindows1257::eN}',
1226              
1227             # \b \B
1228              
1229             # P.180 Boundaries: The \b and \B Assertions
1230             # in Chapter 5: Pattern Matching
1231             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1232              
1233             # P.219 Boundaries: The \b and \B Assertions
1234             # in Chapter 5: Pattern Matching
1235             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1236              
1237             # \b really means (?:(?<=\w)(?!\w)|(?
1238             # or (?:(?<=\A|\W)(?=\w)|(?<=\w)(?=\W|\z))
1239             '\b' => '${Ewindows1257::eb}',
1240              
1241             # \B really means (?:(?<=\w)(?=\w)|(?
1242             # or (?:(?<=\w)(?=\w)|(?<=\W)(?=\W))
1243             '\B' => '${Ewindows1257::eB}',
1244              
1245 1867   100     2737 }->{$char} || '';
1246             }
1247              
1248             #
1249             # prepare Windows-1257 characters per length
1250             #
1251              
1252             # 1 octet characters
1253             my @chars1 = ();
1254             sub chars1 {
1255 1867 0   0 0 67666 if (@chars1) {
1256 0         0 return @chars1;
1257             }
1258 0 0       0 if (exists $range_tr{1}) {
1259 0         0 my @ranges = @{ $range_tr{1} };
  0         0  
1260 0         0 while (my @range = splice(@ranges,0,1)) {
1261 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1262 0         0 push @chars1, pack 'C', $oct0;
1263             }
1264             }
1265             }
1266 0         0 return @chars1;
1267             }
1268              
1269             # 2 octets characters
1270             my @chars2 = ();
1271             sub chars2 {
1272 0 0   0 0 0 if (@chars2) {
1273 0         0 return @chars2;
1274             }
1275 0 0       0 if (exists $range_tr{2}) {
1276 0         0 my @ranges = @{ $range_tr{2} };
  0         0  
1277 0         0 while (my @range = splice(@ranges,0,2)) {
1278 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1279 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1280 0         0 push @chars2, pack 'CC', $oct0,$oct1;
1281             }
1282             }
1283             }
1284             }
1285 0         0 return @chars2;
1286             }
1287              
1288             # 3 octets characters
1289             my @chars3 = ();
1290             sub chars3 {
1291 0 0   0 0 0 if (@chars3) {
1292 0         0 return @chars3;
1293             }
1294 0 0       0 if (exists $range_tr{3}) {
1295 0         0 my @ranges = @{ $range_tr{3} };
  0         0  
1296 0         0 while (my @range = splice(@ranges,0,3)) {
1297 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1298 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1299 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1300 0         0 push @chars3, pack 'CCC', $oct0,$oct1,$oct2;
1301             }
1302             }
1303             }
1304             }
1305             }
1306 0         0 return @chars3;
1307             }
1308              
1309             # 4 octets characters
1310             my @chars4 = ();
1311             sub chars4 {
1312 0 0   0 0 0 if (@chars4) {
1313 0         0 return @chars4;
1314             }
1315 0 0       0 if (exists $range_tr{4}) {
1316 0         0 my @ranges = @{ $range_tr{4} };
  0         0  
1317 0         0 while (my @range = splice(@ranges,0,4)) {
1318 0         0 for my $oct0 (@{$range[0]}) {
  0         0  
1319 0         0 for my $oct1 (@{$range[1]}) {
  0         0  
1320 0         0 for my $oct2 (@{$range[2]}) {
  0         0  
1321 0         0 for my $oct3 (@{$range[3]}) {
  0         0  
1322 0         0 push @chars4, pack 'CCCC', $oct0,$oct1,$oct2,$oct3;
1323             }
1324             }
1325             }
1326             }
1327             }
1328             }
1329 0         0 return @chars4;
1330             }
1331              
1332             #
1333             # Windows-1257 open character list for tr
1334             #
1335             sub _charlist_tr {
1336              
1337 0     0   0 local $_ = shift @_;
1338              
1339             # unescape character
1340 0         0 my @char = ();
1341 0         0 while (not /\G \z/oxmsgc) {
1342 0 0       0 if (/\G (\\0?55|\\x2[Dd]|\\-) /oxmsgc) {
    0          
    0          
    0          
    0          
    0          
    0          
1343 0         0 push @char, '\-';
1344             }
1345             elsif (/\G \\ ([0-7]{2,3}) /oxmsgc) {
1346 0         0 push @char, CORE::chr(oct $1);
1347             }
1348             elsif (/\G \\x ([0-9A-Fa-f]{1,2}) /oxmsgc) {
1349 0         0 push @char, CORE::chr(hex $1);
1350             }
1351             elsif (/\G \\c ([\x40-\x5F]) /oxmsgc) {
1352 0         0 push @char, CORE::chr(CORE::ord($1) & 0x1F);
1353             }
1354             elsif (/\G (\\ [0nrtfbae]) /oxmsgc) {
1355             push @char, {
1356             '\0' => "\0",
1357             '\n' => "\n",
1358             '\r' => "\r",
1359             '\t' => "\t",
1360             '\f' => "\f",
1361             '\b' => "\x08", # \b means backspace in character class
1362             '\a' => "\a",
1363             '\e' => "\e",
1364 0         0 }->{$1};
1365             }
1366             elsif (/\G \\ ($q_char) /oxmsgc) {
1367 0         0 push @char, $1;
1368             }
1369             elsif (/\G ($q_char) /oxmsgc) {
1370 0         0 push @char, $1;
1371             }
1372             }
1373              
1374             # join separated multiple-octet
1375 0         0 @char = join('',@char) =~ /\G (?>\\-|$q_char) /oxmsg;
1376              
1377             # unescape '-'
1378 0         0 my @i = ();
1379 0         0 for my $i (0 .. $#char) {
1380 0 0       0 if ($char[$i] eq '\-') {
    0          
1381 0         0 $char[$i] = '-';
1382             }
1383             elsif ($char[$i] eq '-') {
1384 0 0 0     0 if ((0 < $i) and ($i < $#char)) {
1385 0         0 push @i, $i;
1386             }
1387             }
1388             }
1389              
1390             # open character list (reverse for splice)
1391 0         0 for my $i (CORE::reverse @i) {
1392 0         0 my @range = ();
1393              
1394             # range error
1395 0 0 0     0 if ((CORE::length($char[$i-1]) > CORE::length($char[$i+1])) or ($char[$i-1] gt $char[$i+1])) {
1396 0         0 croak "Invalid tr/// range \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1397             }
1398              
1399             # range of multiple-octet code
1400 0 0       0 if (CORE::length($char[$i-1]) == 1) {
    0          
    0          
    0          
1401 0 0       0 if (CORE::length($char[$i+1]) == 1) {
    0          
    0          
    0          
1402 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars1();
  0         0  
1403             }
1404             elsif (CORE::length($char[$i+1]) == 2) {
1405 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1406 0         0 push @range, grep {$_ le $char[$i+1]} chars2();
  0         0  
1407             }
1408             elsif (CORE::length($char[$i+1]) == 3) {
1409 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1410 0         0 push @range, chars2();
1411 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1412             }
1413             elsif (CORE::length($char[$i+1]) == 4) {
1414 0         0 push @range, grep {$char[$i-1] le $_} chars1();
  0         0  
1415 0         0 push @range, chars2();
1416 0         0 push @range, chars3();
1417 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1418             }
1419             else {
1420 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1421             }
1422             }
1423             elsif (CORE::length($char[$i-1]) == 2) {
1424 0 0       0 if (CORE::length($char[$i+1]) == 2) {
    0          
    0          
1425 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars2();
  0         0  
1426             }
1427             elsif (CORE::length($char[$i+1]) == 3) {
1428 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1429 0         0 push @range, grep {$_ le $char[$i+1]} chars3();
  0         0  
1430             }
1431             elsif (CORE::length($char[$i+1]) == 4) {
1432 0         0 push @range, grep {$char[$i-1] le $_} chars2();
  0         0  
1433 0         0 push @range, chars3();
1434 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1435             }
1436             else {
1437 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1438             }
1439             }
1440             elsif (CORE::length($char[$i-1]) == 3) {
1441 0 0       0 if (CORE::length($char[$i+1]) == 3) {
    0          
1442 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars3();
  0         0  
1443             }
1444             elsif (CORE::length($char[$i+1]) == 4) {
1445 0         0 push @range, grep {$char[$i-1] le $_} chars3();
  0         0  
1446 0         0 push @range, grep {$_ le $char[$i+1]} chars4();
  0         0  
1447             }
1448             else {
1449 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1450             }
1451             }
1452             elsif (CORE::length($char[$i-1]) == 4) {
1453 0 0       0 if (CORE::length($char[$i+1]) == 4) {
1454 0 0       0 push @range, grep {($char[$i-1] le $_) and ($_ le $char[$i+1])} chars4();
  0         0  
1455             }
1456             else {
1457 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1458             }
1459             }
1460             else {
1461 0         0 croak "Invalid tr/// range (over 4octets) \"\\x" . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]) . '"';
1462             }
1463              
1464 0         0 splice @char, $i-1, 3, @range;
1465             }
1466              
1467 0         0 return @char;
1468             }
1469              
1470             #
1471             # Windows-1257 open character class
1472             #
1473             sub _cc {
1474 0 0   0   0 if (scalar(@_) == 0) {
    0          
    0          
1475 0         0 die __FILE__, ": subroutine cc got no parameter.\n";
1476             }
1477             elsif (scalar(@_) == 1) {
1478 0         0 return sprintf('\x%02X',$_[0]);
1479             }
1480             elsif (scalar(@_) == 2) {
1481 0 0       0 if ($_[0] > $_[1]) {
    0          
    0          
1482 0         0 die __FILE__, ": subroutine cc got \$_[0] > \$_[1] parameters).\n";
1483             }
1484             elsif ($_[0] == $_[1]) {
1485 0         0 return sprintf('\x%02X',$_[0]);
1486             }
1487             elsif (($_[0]+1) == $_[1]) {
1488 0         0 return sprintf('[\\x%02X\\x%02X]',$_[0],$_[1]);
1489             }
1490             else {
1491 0         0 return sprintf('[\\x%02X-\\x%02X]',$_[0],$_[1]);
1492             }
1493             }
1494             else {
1495 0         0 die __FILE__, ": subroutine cc got 3 or more parameters (@{[scalar(@_)]} parameters).\n";
  0         0  
1496             }
1497             }
1498              
1499             #
1500             # Windows-1257 octet range
1501             #
1502             sub _octets {
1503 0     182   0 my $length = shift @_;
1504              
1505 182 50       338 if ($length == 1) {
1506 182         419 my($a1) = unpack 'C', $_[0];
1507 182         519 my($z1) = unpack 'C', $_[1];
1508              
1509 182 50       369 if ($a1 > $z1) {
1510 182         393 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$a1) . '-\x' . unpack('H*',$z1);
1511             }
1512              
1513 0 50       0 if ($a1 == $z1) {
    50          
1514 182         485 return sprintf('\x%02X',$a1);
1515             }
1516             elsif (($a1+1) == $z1) {
1517 0         0 return sprintf('\x%02X\x%02X',$a1,$z1);
1518             }
1519             else {
1520 0         0 return sprintf('\x%02X-\x%02X',$a1,$z1);
1521             }
1522             }
1523             else {
1524 182         1182 die __FILE__, ": subroutine _octets got invalid length ($length).\n";
1525             }
1526             }
1527              
1528             #
1529             # Windows-1257 range regexp
1530             #
1531             sub _range_regexp {
1532 0     182   0 my($length,$first,$last) = @_;
1533              
1534 182         392 my @range_regexp = ();
1535 182 50       263 if (not exists $range_tr{$length}) {
1536 182         488 return @range_regexp;
1537             }
1538              
1539 0         0 my @ranges = @{ $range_tr{$length} };
  182         275  
1540 182         453 while (my @range = splice(@ranges,0,$length)) {
1541 182         624 my $min = '';
1542 182         293 my $max = '';
1543 182         257 for (my $i=0; $i < $length; $i++) {
1544 182         521 $min .= pack 'C', $range[$i][0];
1545 182         698 $max .= pack 'C', $range[$i][-1];
1546             }
1547              
1548             # min___max
1549             # FIRST_____________LAST
1550             # (nothing)
1551              
1552 182 50 33     453 if ($max lt $first) {
    50 33        
    50 33        
    50 33        
    50 33        
    0 0        
    0 0        
1553             }
1554              
1555             # **********
1556             # min_________max
1557             # FIRST_____________LAST
1558             # **********
1559              
1560             elsif (($min le $first) and ($first le $max) and ($max le $last)) {
1561 182         1790 push @range_regexp, _octets($length,$first,$max,$min,$max);
1562             }
1563              
1564             # **********************
1565             # min________________max
1566             # FIRST_____________LAST
1567             # **********************
1568              
1569             elsif (($min eq $first) and ($max eq $last)) {
1570 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1571             }
1572              
1573             # *********
1574             # min___max
1575             # FIRST_____________LAST
1576             # *********
1577              
1578             elsif (($first le $min) and ($max le $last)) {
1579 0         0 push @range_regexp, _octets($length,$min,$max,$min,$max);
1580             }
1581              
1582             # **********************
1583             # min__________________________max
1584             # FIRST_____________LAST
1585             # **********************
1586              
1587             elsif (($min le $first) and ($last le $max)) {
1588 0         0 push @range_regexp, _octets($length,$first,$last,$min,$max);
1589             }
1590              
1591             # *********
1592             # min________max
1593             # FIRST_____________LAST
1594             # *********
1595              
1596             elsif (($first le $min) and ($min le $last) and ($last le $max)) {
1597 182         478 push @range_regexp, _octets($length,$min,$last,$min,$max);
1598             }
1599              
1600             # min___max
1601             # FIRST_____________LAST
1602             # (nothing)
1603              
1604             elsif ($last lt $min) {
1605             }
1606              
1607             else {
1608 0         0 die __FILE__, ": subroutine _range_regexp panic.\n";
1609             }
1610             }
1611              
1612 0         0 return @range_regexp;
1613             }
1614              
1615             #
1616             # Windows-1257 open character list for qr and not qr
1617             #
1618             sub _charlist {
1619              
1620 182     358   402 my $modifier = pop @_;
1621 358         775 my @char = @_;
1622              
1623 358 100       805 my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
1624              
1625             # unescape character
1626 358         809 for (my $i=0; $i <= $#char; $i++) {
1627              
1628             # escape - to ...
1629 358 100 100     1252 if ($char[$i] eq '-') {
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    100          
    100          
    100          
1630 1125 100 100     8273 if ((0 < $i) and ($i < $#char)) {
1631 206         875 $char[$i] = '...';
1632             }
1633             }
1634              
1635             # octal escape sequence
1636             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
1637 182         431 $char[$i] = octchr($1);
1638             }
1639              
1640             # hexadecimal escape sequence
1641             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
1642 0         0 $char[$i] = hexchr($1);
1643             }
1644              
1645             # \b{...} --> b\{...}
1646             # \B{...} --> B\{...}
1647             # \N{CHARNAME} --> N\{CHARNAME}
1648             # \p{PROPERTY} --> p\{PROPERTY}
1649             # \P{PROPERTY} --> P\{PROPERTY}
1650             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
1651 0         0 $char[$i] = $1 . '\\' . $2;
1652             }
1653              
1654             # \p, \P, \X --> p, P, X
1655             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
1656 0         0 $char[$i] = $1;
1657             }
1658              
1659             elsif ($char[$i] =~ /\A \\ ([0-7]{2,3}) \z/oxms) {
1660 0         0 $char[$i] = CORE::chr oct $1;
1661             }
1662             elsif ($char[$i] =~ /\A \\x ([0-9A-Fa-f]{1,2}) \z/oxms) {
1663 0         0 $char[$i] = CORE::chr hex $1;
1664             }
1665             elsif ($char[$i] =~ /\A \\c ([\x40-\x5F]) \z/oxms) {
1666 22         136 $char[$i] = CORE::chr(CORE::ord($1) & 0x1F);
1667             }
1668             elsif ($char[$i] =~ /\A (\\ [0nrtfbaedswDSWHVhvR]) \z/oxms) {
1669             $char[$i] = {
1670             '\0' => "\0",
1671             '\n' => "\n",
1672             '\r' => "\r",
1673             '\t' => "\t",
1674             '\f' => "\f",
1675             '\b' => "\x08", # \b means backspace in character class
1676             '\a' => "\a",
1677             '\e' => "\e",
1678             '\d' => '[0-9]',
1679              
1680             # Vertical tabs are now whitespace
1681             # \s in a regex now matches a vertical tab in all circumstances.
1682             # http://search.cpan.org/dist/perl-5.18.0/pod/perldelta.pod#Vertical_tabs_are_now_whitespace
1683             # \t \n \v \f \r space
1684             # '\s' => '[\x09\x0A \x0C\x0D\x20]',
1685             # '\s' => '[\x09\x0A\x0B\x0C\x0D\x20]',
1686             '\s' => '\s',
1687              
1688             '\w' => '[0-9A-Z_a-z]',
1689             '\D' => '${Ewindows1257::eD}',
1690             '\S' => '${Ewindows1257::eS}',
1691             '\W' => '${Ewindows1257::eW}',
1692              
1693             '\H' => '${Ewindows1257::eH}',
1694             '\V' => '${Ewindows1257::eV}',
1695             '\h' => '[\x09\x20]',
1696             '\v' => '[\x0A\x0B\x0C\x0D]',
1697             '\R' => '${Ewindows1257::eR}',
1698              
1699 0         0 }->{$1};
1700             }
1701              
1702             # POSIX-style character classes
1703             elsif ($ignorecase and ($char[$i] =~ /\A ( \[\: \^? (?:lower|upper) :\] ) \z/oxms)) {
1704             $char[$i] = {
1705              
1706             '[:lower:]' => '[\x41-\x5A\x61-\x7A]',
1707             '[:upper:]' => '[\x41-\x5A\x61-\x7A]',
1708             '[:^lower:]' => '${Ewindows1257::not_lower_i}',
1709             '[:^upper:]' => '${Ewindows1257::not_upper_i}',
1710              
1711 25         458 }->{$1};
1712             }
1713             elsif ($char[$i] =~ /\A ( \[\: \^? (?:alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit) :\] ) \z/oxms) {
1714             $char[$i] = {
1715              
1716             '[:alnum:]' => '[\x30-\x39\x41-\x5A\x61-\x7A]',
1717             '[:alpha:]' => '[\x41-\x5A\x61-\x7A]',
1718             '[:ascii:]' => '[\x00-\x7F]',
1719             '[:blank:]' => '[\x09\x20]',
1720             '[:cntrl:]' => '[\x00-\x1F\x7F]',
1721             '[:digit:]' => '[\x30-\x39]',
1722             '[:graph:]' => '[\x21-\x7F]',
1723             '[:lower:]' => '[\x61-\x7A]',
1724             '[:print:]' => '[\x20-\x7F]',
1725             '[:punct:]' => '[\x21-\x2F\x3A-\x3F\x40\x5B-\x5F\x60\x7B-\x7E]',
1726              
1727             # P.174 POSIX-Style Character Classes
1728             # in Chapter 5: Pattern Matching
1729             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
1730              
1731             # P.311 11.2.4 Character Classes and other Special Escapes
1732             # in Chapter 11: perlre: Perl regular expressions
1733             # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
1734              
1735             # P.210 POSIX-Style Character Classes
1736             # in Chapter 5: Pattern Matching
1737             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
1738              
1739             '[:space:]' => '[\s\x0B]', # "\s" plus vertical tab ("\cK")
1740              
1741             '[:upper:]' => '[\x41-\x5A]',
1742             '[:word:]' => '[\x30-\x39\x41-\x5A\x5F\x61-\x7A]',
1743             '[:xdigit:]' => '[\x30-\x39\x41-\x46\x61-\x66]',
1744             '[:^alnum:]' => '${Ewindows1257::not_alnum}',
1745             '[:^alpha:]' => '${Ewindows1257::not_alpha}',
1746             '[:^ascii:]' => '${Ewindows1257::not_ascii}',
1747             '[:^blank:]' => '${Ewindows1257::not_blank}',
1748             '[:^cntrl:]' => '${Ewindows1257::not_cntrl}',
1749             '[:^digit:]' => '${Ewindows1257::not_digit}',
1750             '[:^graph:]' => '${Ewindows1257::not_graph}',
1751             '[:^lower:]' => '${Ewindows1257::not_lower}',
1752             '[:^print:]' => '${Ewindows1257::not_print}',
1753             '[:^punct:]' => '${Ewindows1257::not_punct}',
1754             '[:^space:]' => '${Ewindows1257::not_space}',
1755             '[:^upper:]' => '${Ewindows1257::not_upper}',
1756             '[:^word:]' => '${Ewindows1257::not_word}',
1757             '[:^xdigit:]' => '${Ewindows1257::not_xdigit}',
1758              
1759 8         60 }->{$1};
1760             }
1761             elsif ($char[$i] =~ /\A \\ ($q_char) \z/oxms) {
1762 70         1198 $char[$i] = $1;
1763             }
1764             }
1765              
1766             # open character list
1767 7         33 my @singleoctet = ();
1768 358         675 my @multipleoctet = ();
1769 358         529 for (my $i=0; $i <= $#char; ) {
1770              
1771             # escaped -
1772 358 100 100     790 if (defined($char[$i+1]) and ($char[$i+1] eq '...')) {
    100          
    100          
    50          
    50          
    100          
1773 943         4072 $i += 1;
1774 182         290 next;
1775             }
1776              
1777             # make range regexp
1778             elsif ($char[$i] eq '...') {
1779              
1780             # range error
1781 182 50       387 if (CORE::length($char[$i-1]) > CORE::length($char[$i+1])) {
    50          
1782 182         690 croak 'Invalid [] range in regexp (length(A) > length(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1783             }
1784             elsif (CORE::length($char[$i-1]) == CORE::length($char[$i+1])) {
1785 0 50       0 if ($char[$i-1] gt $char[$i+1]) {
1786 182         451 croak 'Invalid [] range in regexp (CORE::ord(A) > CORE::ord(B)) ' . '\x' . unpack('H*',$char[$i-1]) . '-\x' . unpack('H*',$char[$i+1]);
1787             }
1788             }
1789              
1790             # make range regexp per length
1791 0         0 for my $length (CORE::length($char[$i-1]) .. CORE::length($char[$i+1])) {
1792 182         582 my @regexp = ();
1793              
1794             # is first and last
1795 182 50 33     284 if (($length == CORE::length($char[$i-1])) and ($length == CORE::length($char[$i+1]))) {
    0 0        
    0          
    0          
1796 182         730 push @regexp, _range_regexp($length, $char[$i-1], $char[$i+1]);
1797             }
1798              
1799             # is first
1800             elsif ($length == CORE::length($char[$i-1])) {
1801 182         530 push @regexp, _range_regexp($length, $char[$i-1], "\xFF" x $length);
1802             }
1803              
1804             # is inside in first and last
1805             elsif ((CORE::length($char[$i-1]) < $length) and ($length < CORE::length($char[$i+1]))) {
1806 0         0 push @regexp, _range_regexp($length, "\x00" x $length, "\xFF" x $length);
1807             }
1808              
1809             # is last
1810             elsif ($length == CORE::length($char[$i+1])) {
1811 0         0 push @regexp, _range_regexp($length, "\x00" x $length, $char[$i+1]);
1812             }
1813              
1814             else {
1815 0         0 die __FILE__, ": subroutine make_regexp panic.\n";
1816             }
1817              
1818 0 50       0 if ($length == 1) {
1819 182         474 push @singleoctet, @regexp;
1820             }
1821             else {
1822 182         436 push @multipleoctet, @regexp;
1823             }
1824             }
1825              
1826 0         0 $i += 2;
1827             }
1828              
1829             # with /i modifier
1830             elsif ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) {
1831 182 100       408 if ($modifier =~ /i/oxms) {
1832 493         838 my $uc = Ewindows1257::uc($char[$i]);
1833 24         54 my $fc = Ewindows1257::fc($char[$i]);
1834 24 100       61 if ($uc ne $fc) {
1835 24 50       60 if (CORE::length($fc) == 1) {
1836 12         32 push @singleoctet, $uc, $fc;
1837             }
1838             else {
1839 12         22 push @singleoctet, $uc;
1840 0         0 push @multipleoctet, $fc;
1841             }
1842             }
1843             else {
1844 0         0 push @singleoctet, $char[$i];
1845             }
1846             }
1847             else {
1848 12         32 push @singleoctet, $char[$i];
1849             }
1850 469         741 $i += 1;
1851             }
1852              
1853             # single character of single octet code
1854             elsif ($char[$i] =~ /\A (?: \\h ) \z/oxms) {
1855 493         893 push @singleoctet, "\t", "\x20";
1856 0         0 $i += 1;
1857             }
1858             elsif ($char[$i] =~ /\A (?: \\v ) \z/oxms) {
1859 0         0 push @singleoctet, "\x0A", "\x0B", "\x0C", "\x0D";
1860 0         0 $i += 1;
1861             }
1862             elsif ($char[$i] =~ /\A (?: \\d | \\s | \\w ) \z/oxms) {
1863 0         0 push @singleoctet, $char[$i];
1864 2         9 $i += 1;
1865             }
1866              
1867             # single character of multiple-octet code
1868             else {
1869 2         5 push @multipleoctet, $char[$i];
1870 84         174 $i += 1;
1871             }
1872             }
1873              
1874             # quote metachar
1875 84         158 for (@singleoctet) {
1876 358 50       742 if ($_ eq '...') {
    100          
    100          
    100          
    100          
1877 689         3221 $_ = '-';
1878             }
1879             elsif (/\A \n \z/oxms) {
1880 0         0 $_ = '\n';
1881             }
1882             elsif (/\A \r \z/oxms) {
1883 8         16 $_ = '\r';
1884             }
1885             elsif (/\A ([\x00-\x20\x7F-\xFF]) \z/oxms) {
1886 8         17 $_ = sprintf('\x%02X', CORE::ord $1);
1887             }
1888             elsif (/\A [\x00-\xFF] \z/oxms) {
1889 60         226 $_ = quotemeta $_;
1890             }
1891             }
1892              
1893             # return character list
1894 429         684 return \@singleoctet, \@multipleoctet;
1895             }
1896              
1897             #
1898             # Windows-1257 octal escape sequence
1899             #
1900             sub octchr {
1901 358     5 0 1325 my($octdigit) = @_;
1902              
1903 5         14 my @binary = ();
1904 5         9 for my $octal (split(//,$octdigit)) {
1905             push @binary, {
1906             '0' => '000',
1907             '1' => '001',
1908             '2' => '010',
1909             '3' => '011',
1910             '4' => '100',
1911             '5' => '101',
1912             '6' => '110',
1913             '7' => '111',
1914 5         37 }->{$octal};
1915             }
1916 50         190 my $binary = join '', @binary;
1917              
1918             my $octchr = {
1919             # 1234567
1920             1 => pack('B*', "0000000$binary"),
1921             2 => pack('B*', "000000$binary"),
1922             3 => pack('B*', "00000$binary"),
1923             4 => pack('B*', "0000$binary"),
1924             5 => pack('B*', "000$binary"),
1925             6 => pack('B*', "00$binary"),
1926             7 => pack('B*', "0$binary"),
1927             0 => pack('B*', "$binary"),
1928              
1929 5         16 }->{CORE::length($binary) % 8};
1930              
1931 5         78 return $octchr;
1932             }
1933              
1934             #
1935             # Windows-1257 hexadecimal escape sequence
1936             #
1937             sub hexchr {
1938 5     5 0 21 my($hexdigit) = @_;
1939              
1940             my $hexchr = {
1941             1 => pack('H*', "0$hexdigit"),
1942             0 => pack('H*', "$hexdigit"),
1943              
1944 5         18 }->{CORE::length($_[0]) % 2};
1945              
1946 5         47 return $hexchr;
1947             }
1948              
1949             #
1950             # Windows-1257 open character list for qr
1951             #
1952             sub charlist_qr {
1953              
1954 5     314 0 21 my $modifier = pop @_;
1955 314         652 my @char = @_;
1956              
1957 314         782 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
1958 314         952 my @singleoctet = @$singleoctet;
1959 314         685 my @multipleoctet = @$multipleoctet;
1960              
1961             # return character list
1962 314 100       485 if (scalar(@singleoctet) >= 1) {
1963              
1964             # with /i modifier
1965 314 100       742 if ($modifier =~ m/i/oxms) {
1966 236         531 my %singleoctet_ignorecase = ();
1967 22         37 for (@singleoctet) {
1968 22   100     43 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
1969 46         240 for my $ord (hex($1) .. hex($2)) {
1970 46         158 my $char = CORE::chr($ord);
1971 66         114 my $uc = Ewindows1257::uc($char);
1972 66         109 my $fc = Ewindows1257::fc($char);
1973 66 100       119 if ($uc eq $fc) {
1974 66         115 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
1975             }
1976             else {
1977 12 50       95 if (CORE::length($fc) == 1) {
1978 54         101 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1979 54         130 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
1980             }
1981             else {
1982 54         200 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
1983 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
1984             }
1985             }
1986             }
1987             }
1988 0 50       0 if ($_ ne '') {
1989 46         103 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
1990             }
1991             }
1992 0         0 my $i = 0;
1993 22         31 my @singleoctet_ignorecase = ();
1994 22         43 for my $ord (0 .. 255) {
1995 22 100       45 if (exists $singleoctet_ignorecase{$ord}) {
1996 5632         6979 push @{$singleoctet_ignorecase[$i]}, $ord;
  96         101  
1997             }
1998             else {
1999 96         196 $i++;
2000             }
2001             }
2002 5536         7452 @singleoctet = ();
2003 22         41 for my $range (@singleoctet_ignorecase) {
2004 22 100       80 if (ref $range) {
2005 3648 100       6272 if (scalar(@{$range}) == 1) {
  56 50       66  
2006 56         97 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  36         47  
2007             }
2008 36         131 elsif (scalar(@{$range}) == 2) {
2009 20         35 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2010             }
2011             else {
2012 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         24  
  20         29  
2013             }
2014             }
2015             }
2016             }
2017              
2018 20         130 my $not_anchor = '';
2019              
2020 236         415 push @multipleoctet, join('', $not_anchor, '[', @singleoctet, ']' );
2021             }
2022 236 100       1007 if (scalar(@multipleoctet) >= 2) {
2023 314         644 return '(?:' . join('|', @multipleoctet) . ')';
2024             }
2025             else {
2026 6         35 return $multipleoctet[0];
2027             }
2028             }
2029              
2030             #
2031             # Windows-1257 open character list for not qr
2032             #
2033             sub charlist_not_qr {
2034              
2035 308     44 0 1371 my $modifier = pop @_;
2036 44         112 my @char = @_;
2037              
2038 44         118 my($singleoctet, $multipleoctet) = _charlist(@char, $modifier);
2039 44         130 my @singleoctet = @$singleoctet;
2040 44         107 my @multipleoctet = @$multipleoctet;
2041              
2042             # with /i modifier
2043 44 100       70 if ($modifier =~ m/i/oxms) {
2044 44         107 my %singleoctet_ignorecase = ();
2045 10         12 for (@singleoctet) {
2046 10   66     14 while (s/ \A \\x(..) - \\x(..) //oxms or s/ \A \\x((..)) //oxms) {
2047 10         43 for my $ord (hex($1) .. hex($2)) {
2048 10         30 my $char = CORE::chr($ord);
2049 30         50 my $uc = Ewindows1257::uc($char);
2050 30         42 my $fc = Ewindows1257::fc($char);
2051 30 50       46 if ($uc eq $fc) {
2052 30         42 $singleoctet_ignorecase{unpack 'C*', $char} = 1;
2053             }
2054             else {
2055 0 50       0 if (CORE::length($fc) == 1) {
2056 30         41 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2057 30         63 $singleoctet_ignorecase{unpack 'C*', $fc} = 1;
2058             }
2059             else {
2060 30         113 $singleoctet_ignorecase{unpack 'C*', $uc} = 1;
2061 0         0 push @multipleoctet, join '', map {sprintf('\x%02X',$_)} unpack 'C*', $fc;
  0         0  
2062             }
2063             }
2064             }
2065             }
2066 0 50       0 if ($_ ne '') {
2067 10         19 $singleoctet_ignorecase{unpack 'C*', $_} = 1;
2068             }
2069             }
2070 0         0 my $i = 0;
2071 10         13 my @singleoctet_ignorecase = ();
2072 10         14 for my $ord (0 .. 255) {
2073 10 100       22 if (exists $singleoctet_ignorecase{$ord}) {
2074 2560         2927 push @{$singleoctet_ignorecase[$i]}, $ord;
  60         56  
2075             }
2076             else {
2077 60         115 $i++;
2078             }
2079             }
2080 2500         2517 @singleoctet = ();
2081 10         16 for my $range (@singleoctet_ignorecase) {
2082 10 100       23 if (ref $range) {
2083 960 50       1552 if (scalar(@{$range}) == 1) {
  20 50       20  
2084 20         36 push @singleoctet, sprintf('\x%02X', @{$range}[0]);
  0         0  
2085             }
2086 0         0 elsif (scalar(@{$range}) == 2) {
2087 20         23 push @singleoctet, sprintf('\x%02X\x%02X', @{$range}[0], @{$range}[-1]);
  0         0  
  0         0  
2088             }
2089             else {
2090 0         0 push @singleoctet, sprintf('\x%02X-\x%02X', @{$range}[0], @{$range}[-1]);
  20         23  
  20         22  
2091             }
2092             }
2093             }
2094             }
2095              
2096             # return character list
2097 20 50       86 if (scalar(@multipleoctet) >= 1) {
2098 44 0       109 if (scalar(@singleoctet) >= 1) {
2099              
2100             # any character other than multiple-octet and single octet character class
2101 0         0 return '(?!' . join('|', @multipleoctet) . ')(?:[^' . join('', @singleoctet) . '])';
2102             }
2103             else {
2104              
2105             # any character other than multiple-octet character class
2106 0         0 return '(?!' . join('|', @multipleoctet) . ")(?:$your_char)";
2107             }
2108             }
2109             else {
2110 0 50       0 if (scalar(@singleoctet) >= 1) {
2111              
2112             # any character other than single octet character class
2113 44         82 return '(?:[^' . join('', @singleoctet) . '])';
2114             }
2115             else {
2116              
2117             # any character
2118 44         272 return "(?:$your_char)";
2119             }
2120             }
2121             }
2122              
2123             #
2124             # open file in read mode
2125             #
2126             sub _open_r {
2127 0     412   0 my(undef,$file) = @_;
2128 206     206   2200 use Fcntl qw(O_RDONLY);
  206         4266  
  206         26958  
2129 412         1235 return CORE::sysopen($_[0], $file, &O_RDONLY);
2130             }
2131              
2132             #
2133             # open file in append mode
2134             #
2135             sub _open_a {
2136 412     206   17441 my(undef,$file) = @_;
2137 206     206   1440 use Fcntl qw(O_WRONLY O_APPEND O_CREAT);
  206         457  
  206         581521  
2138 206         764 return CORE::sysopen($_[0], $file, &O_WRONLY|&O_APPEND|&O_CREAT);
2139             }
2140              
2141             #
2142             # safe system
2143             #
2144             sub _systemx {
2145              
2146             # P.707 29.2.33. exec
2147             # in Chapter 29: Functions
2148             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2149             #
2150             # Be aware that in older releases of Perl, exec (and system) did not flush
2151             # your output buffer, so you needed to enable command buffering by setting $|
2152             # on one or more filehandles to avoid lost output in the case of exec, or
2153             # misordererd output in the case of system. This situation was largely remedied
2154             # in the 5.6 release of Perl. (So, 5.005 release not yet.)
2155              
2156             # P.855 exec
2157             # in Chapter 27: Functions
2158             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2159             #
2160             # In very old release of Perl (before v5.6), exec (and system) did not flush
2161             # your output buffer, so you needed to enable command buffering by setting $|
2162             # on one or more filehandles to avoid lost output with exec or misordered
2163             # output with system.
2164              
2165 206     206   42561 $| = 1;
2166              
2167             # P.565 23.1.2. Cleaning Up Your Environment
2168             # in Chapter 23: Security
2169             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2170              
2171             # P.656 Cleaning Up Your Environment
2172             # in Chapter 20: Security
2173             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2174              
2175             # local $ENV{'PATH'} = '.';
2176 206         871 local @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
2177              
2178             # P.707 29.2.33. exec
2179             # in Chapter 29: Functions
2180             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2181             #
2182             # As we mentioned earlier, exec treats a discrete list of arguments as an
2183             # indication that it should bypass shell processing. However, there is one
2184             # place where you might still get tripped up. The exec call (and system, too)
2185             # will not distinguish between a single scalar argument and an array containing
2186             # only one element.
2187             #
2188             # @args = ("echo surprise"); # just one element in list
2189             # exec @args # still subject to shell escapes
2190             # or die "exec: $!"; # because @args == 1
2191             #
2192             # To avoid this, you can use the PATHNAME syntax, explicitly duplicating the
2193             # first argument as the pathname, which forces the rest of the arguments to be
2194             # interpreted as a list, even if there is only one of them:
2195             #
2196             # exec { $args[0] } @args # safe even with one-argument list
2197             # or die "can't exec @args: $!";
2198              
2199             # P.855 exec
2200             # in Chapter 27: Functions
2201             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2202             #
2203             # As we mentioned earlier, exec treats a discrete list of arguments as a
2204             # directive to bypass shell processing. However, there is one place where
2205             # you might still get tripped up. The exec call (and system, too) cannot
2206             # distinguish between a single scalar argument and an array containing
2207             # only one element.
2208             #
2209             # @args = ("echo surprise"); # just one element in list
2210             # exec @args # still subject to shell escapes
2211             # || die "exec: $!"; # because @args == 1
2212             #
2213             # To avoid this, use the PATHNAME syntax, explicitly duplicating the first
2214             # argument as the pathname, which forces the rest of the arguments to be
2215             # interpreted as a list, even if there is only one of them:
2216             #
2217             # exec { $args[0] } @args # safe even with one-argument list
2218             # || die "can't exec @args: $!";
2219              
2220 206         2122 return CORE::system { $_[0] } @_; # safe even with one-argument list
  206         499  
2221             }
2222              
2223             #
2224             # Windows-1257 order to character (with parameter)
2225             #
2226             sub Ewindows1257::chr(;$) {
2227              
2228 206 0   0 0 14188552 my $c = @_ ? $_[0] : $_;
2229              
2230 0 0       0 if ($c == 0x00) {
2231 0         0 return "\x00";
2232             }
2233             else {
2234 0         0 my @chr = ();
2235 0         0 while ($c > 0) {
2236 0         0 unshift @chr, ($c % 0x100);
2237 0         0 $c = int($c / 0x100);
2238             }
2239 0         0 return pack 'C*', @chr;
2240             }
2241             }
2242              
2243             #
2244             # Windows-1257 order to character (without parameter)
2245             #
2246             sub Ewindows1257::chr_() {
2247              
2248 0     0 0 0 my $c = $_;
2249              
2250 0 0       0 if ($c == 0x00) {
2251 0         0 return "\x00";
2252             }
2253             else {
2254 0         0 my @chr = ();
2255 0         0 while ($c > 0) {
2256 0         0 unshift @chr, ($c % 0x100);
2257 0         0 $c = int($c / 0x100);
2258             }
2259 0         0 return pack 'C*', @chr;
2260             }
2261             }
2262              
2263             #
2264             # Windows-1257 path globbing (with parameter)
2265             #
2266             sub Ewindows1257::glob($) {
2267              
2268 0 0   0 0 0 if (wantarray) {
2269 0         0 my @glob = _DOS_like_glob(@_);
2270 0         0 for my $glob (@glob) {
2271 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2272             }
2273 0         0 return @glob;
2274             }
2275             else {
2276 0         0 my $glob = _DOS_like_glob(@_);
2277 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2278 0         0 return $glob;
2279             }
2280             }
2281              
2282             #
2283             # Windows-1257 path globbing (without parameter)
2284             #
2285             sub Ewindows1257::glob_() {
2286              
2287 0 0   0 0 0 if (wantarray) {
2288 0         0 my @glob = _DOS_like_glob();
2289 0         0 for my $glob (@glob) {
2290 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2291             }
2292 0         0 return @glob;
2293             }
2294             else {
2295 0         0 my $glob = _DOS_like_glob();
2296 0         0 $glob =~ s{ \A (?:\./)+ }{}oxms;
2297 0         0 return $glob;
2298             }
2299             }
2300              
2301             #
2302             # Windows-1257 path globbing via File::DosGlob 1.10
2303             #
2304             # Often I confuse "_dosglob" and "_doglob".
2305             # So, I renamed "_dosglob" to "_DOS_like_glob".
2306             #
2307             my %iter;
2308             my %entries;
2309             sub _DOS_like_glob {
2310              
2311             # context (keyed by second cxix argument provided by core)
2312 0     0   0 my($expr,$cxix) = @_;
2313              
2314             # glob without args defaults to $_
2315 0 0       0 $expr = $_ if not defined $expr;
2316              
2317             # represents the current user's home directory
2318             #
2319             # 7.3. Expanding Tildes in Filenames
2320             # in Chapter 7. File Access
2321             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2322             #
2323             # and File::HomeDir, File::HomeDir::Windows module
2324              
2325             # DOS-like system
2326 0 0       0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2327 0         0 $expr =~ s{ \A ~ (?= [^/\\] ) }
  0         0  
2328             { my_home_MSWin32() }oxmse;
2329             }
2330              
2331             # UNIX-like system
2332 0 0 0     0 else {
  0         0  
2333             $expr =~ s{ \A ~ ( (?:[^/])* ) }
2334             { $1 ? (CORE::eval(q{(getpwnam($1))[7]})||my_home()) : my_home() }oxmse;
2335             }
2336 0 0       0  
2337 0 0       0 # assume global context if not provided one
2338             $cxix = '_G_' if not defined $cxix;
2339             $iter{$cxix} = 0 if not exists $iter{$cxix};
2340 0 0       0  
2341 0         0 # if we're just beginning, do it all first
2342             if ($iter{$cxix} == 0) {
2343             $entries{$cxix} = [ _do_glob(1, _parse_line($expr)) ];
2344             }
2345 0 0       0  
2346 0         0 # chuck it all out, quick or slow
2347 0         0 if (wantarray) {
  0         0  
2348             delete $iter{$cxix};
2349             return @{delete $entries{$cxix}};
2350 0 0       0 }
  0         0  
2351 0         0 else {
  0         0  
2352             if ($iter{$cxix} = scalar @{$entries{$cxix}}) {
2353             return shift @{$entries{$cxix}};
2354             }
2355 0         0 else {
2356 0         0 # return undef for EOL
2357 0         0 delete $iter{$cxix};
2358             delete $entries{$cxix};
2359             return undef;
2360             }
2361             }
2362             }
2363              
2364             #
2365             # Windows-1257 path globbing subroutine
2366             #
2367 0     0   0 sub _do_glob {
2368 0         0  
2369 0         0 my($cond,@expr) = @_;
2370             my @glob = ();
2371             my $fix_drive_relative_paths = 0;
2372 0         0  
2373 0 0       0 OUTER:
2374 0 0       0 for my $expr (@expr) {
2375             next OUTER if not defined $expr;
2376 0         0 next OUTER if $expr eq '';
2377 0         0  
2378 0         0 my @matched = ();
2379 0         0 my @globdir = ();
2380 0         0 my $head = '.';
2381             my $pathsep = '/';
2382             my $tail;
2383 0 0       0  
2384 0         0 # if argument is within quotes strip em and do no globbing
2385 0 0       0 if ($expr =~ /\A " ((?:$q_char)*?) " \z/oxms) {
2386 0 0       0 $expr = $1;
2387 0         0 if ($cond eq 'd') {
2388             if (-d $expr) {
2389             push @glob, $expr;
2390             }
2391 0 0       0 }
2392 0         0 else {
2393             if (-e $expr) {
2394             push @glob, $expr;
2395 0         0 }
2396             }
2397             next OUTER;
2398             }
2399              
2400 0 0       0 # wildcards with a drive prefix such as h:*.pm must be changed
2401 0 0       0 # to h:./*.pm to expand correctly
2402 0         0 if ($^O =~ /\A (?: MSWin32 | NetWare | symbian | dos ) \z/oxms) {
2403             if ($expr =~ s# \A ((?:[A-Za-z]:)?) ([^/\\]) #$1./$2#oxms) {
2404             $fix_drive_relative_paths = 1;
2405             }
2406 0 0       0 }
2407 0 0       0  
2408 0         0 if (($head, $tail) = _parse_path($expr,$pathsep)) {
2409 0         0 if ($tail eq '') {
2410             push @glob, $expr;
2411 0 0       0 next OUTER;
2412 0 0       0 }
2413 0         0 if ($head =~ / \A (?:$q_char)*? [*?] /oxms) {
  0         0  
2414 0         0 if (@globdir = _do_glob('d', $head)) {
2415             push @glob, _do_glob($cond, map {"$_$pathsep$tail"} @globdir);
2416             next OUTER;
2417 0 0 0     0 }
2418 0         0 }
2419             if ($head eq '' or $head =~ /\A [A-Za-z]: \z/oxms) {
2420 0         0 $head .= $pathsep;
2421             }
2422             $expr = $tail;
2423             }
2424 0 0       0  
2425 0 0       0 # If file component has no wildcards, we can avoid opendir
2426 0         0 if ($expr !~ / \A (?:$q_char)*? [*?] /oxms) {
2427             if ($head eq '.') {
2428 0 0 0     0 $head = '';
2429 0         0 }
2430             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2431 0         0 $head .= $pathsep;
2432 0 0       0 }
2433 0 0       0 $head .= $expr;
2434 0         0 if ($cond eq 'd') {
2435             if (-d $head) {
2436             push @glob, $head;
2437             }
2438 0 0       0 }
2439 0         0 else {
2440             if (-e $head) {
2441             push @glob, $head;
2442 0         0 }
2443             }
2444 0 0       0 next OUTER;
2445 0         0 }
2446 0         0 opendir(*DIR, $head) or next OUTER;
2447             my @leaf = readdir DIR;
2448 0 0       0 closedir DIR;
2449 0         0  
2450             if ($head eq '.') {
2451 0 0 0     0 $head = '';
2452 0         0 }
2453             if ($head ne '' and ($head =~ / \G ($q_char) /oxmsg)[-1] ne $pathsep) {
2454             $head .= $pathsep;
2455 0         0 }
2456 0         0  
2457 0         0 my $pattern = '';
2458             while ($expr =~ / \G ($q_char) /oxgc) {
2459             my $char = $1;
2460              
2461             # 6.9. Matching Shell Globs as Regular Expressions
2462             # in Chapter 6. Pattern Matching
2463             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
2464 0 0       0 # (and so on)
    0          
    0          
2465 0         0  
2466             if ($char eq '*') {
2467             $pattern .= "(?:$your_char)*",
2468 0         0 }
2469             elsif ($char eq '?') {
2470             $pattern .= "(?:$your_char)?", # DOS style
2471             # $pattern .= "(?:$your_char)", # UNIX style
2472 0         0 }
2473             elsif ((my $fc = Ewindows1257::fc($char)) ne $char) {
2474             $pattern .= $fc;
2475 0         0 }
2476             else {
2477             $pattern .= quotemeta $char;
2478 0     0   0 }
  0         0  
2479             }
2480             my $matchsub = sub { Ewindows1257::fc($_[0]) =~ /\A $pattern \z/xms };
2481              
2482             # if ($@) {
2483             # print STDERR "$0: $@\n";
2484             # next OUTER;
2485             # }
2486 0         0  
2487 0 0 0     0 INNER:
2488 0         0 for my $leaf (@leaf) {
2489             if ($leaf eq '.' or $leaf eq '..') {
2490 0 0 0     0 next INNER;
2491 0         0 }
2492             if ($cond eq 'd' and not -d "$head$leaf") {
2493             next INNER;
2494 0 0       0 }
2495 0         0  
2496 0         0 if (&$matchsub($leaf)) {
2497             push @matched, "$head$leaf";
2498             next INNER;
2499             }
2500              
2501             # [DOS compatibility special case]
2502 0 0 0     0 # Failed, add a trailing dot and try again, but only...
      0        
2503              
2504             if (Ewindows1257::index($leaf,'.') == -1 and # if name does not have a dot in it *and*
2505             CORE::length($leaf) <= 8 and # name is shorter than or equal to 8 chars *and*
2506 0 0       0 Ewindows1257::index($pattern,'\\.') != -1 # pattern has a dot.
2507 0         0 ) {
2508 0         0 if (&$matchsub("$leaf.")) {
2509             push @matched, "$head$leaf";
2510             next INNER;
2511             }
2512 0 0       0 }
2513 0         0 }
2514             if (@matched) {
2515             push @glob, @matched;
2516 0 0       0 }
2517 0         0 }
2518 0         0 if ($fix_drive_relative_paths) {
2519             for my $glob (@glob) {
2520             $glob =~ s# \A ([A-Za-z]:) \./ #$1#oxms;
2521 0         0 }
2522             }
2523             return @glob;
2524             }
2525              
2526             #
2527             # Windows-1257 parse line
2528             #
2529 0     0   0 sub _parse_line {
2530              
2531 0         0 my($line) = @_;
2532 0         0  
2533 0         0 $line .= ' ';
2534             my @piece = ();
2535             while ($line =~ /
2536             " ( (?>(?: [^"] )* ) ) " (?>\s+) |
2537             ( (?>(?: [^"\s] )* ) ) (?>\s+)
2538 0 0       0 /oxmsg
2539             ) {
2540 0         0 push @piece, defined($1) ? $1 : $2;
2541             }
2542             return @piece;
2543             }
2544              
2545             #
2546             # Windows-1257 parse path
2547             #
2548 0     0   0 sub _parse_path {
2549              
2550 0         0 my($path,$pathsep) = @_;
2551 0         0  
2552 0         0 $path .= '/';
2553             my @subpath = ();
2554             while ($path =~ /
2555             ((?: [^\/\\] )+?) [\/\\]
2556 0         0 /oxmsg
2557             ) {
2558             push @subpath, $1;
2559 0         0 }
2560 0         0  
2561 0         0 my $tail = pop @subpath;
2562             my $head = join $pathsep, @subpath;
2563             return $head, $tail;
2564             }
2565              
2566             #
2567             # via File::HomeDir::Windows 1.00
2568             #
2569             sub my_home_MSWin32 {
2570              
2571             # A lot of unix people and unix-derived tools rely on
2572 0 0 0 0 0 0 # the ability to overload HOME. We will support it too
    0 0        
    0 0        
      0        
      0        
2573 0         0 # so that they can replace raw HOME calls with File::HomeDir.
2574             if (exists $ENV{'HOME'} and $ENV{'HOME'}) {
2575             return $ENV{'HOME'};
2576             }
2577              
2578 0         0 # Do we have a user profile?
2579             elsif (exists $ENV{'USERPROFILE'} and $ENV{'USERPROFILE'}) {
2580             return $ENV{'USERPROFILE'};
2581             }
2582              
2583 0         0 # Some Windows use something like $ENV{'HOME'}
2584             elsif (exists $ENV{'HOMEDRIVE'} and exists $ENV{'HOMEPATH'} and $ENV{'HOMEDRIVE'} and $ENV{'HOMEPATH'}) {
2585             return join '', $ENV{'HOMEDRIVE'}, $ENV{'HOMEPATH'};
2586 0         0 }
2587              
2588             return undef;
2589             }
2590              
2591             #
2592             # via File::HomeDir::Unix 1.00
2593 0     0 0 0 #
2594             sub my_home {
2595 0 0 0     0 my $home;
    0 0        
2596 0         0  
2597             if (exists $ENV{'HOME'} and defined $ENV{'HOME'}) {
2598             $home = $ENV{'HOME'};
2599             }
2600              
2601             # This is from the original code, but I'm guessing
2602 0         0 # it means "login directory" and exists on some Unixes.
2603             elsif (exists $ENV{'LOGDIR'} and $ENV{'LOGDIR'}) {
2604             $home = $ENV{'LOGDIR'};
2605             }
2606              
2607             ### More-desperate methods
2608              
2609 0         0 # Light desperation on any (Unixish) platform
2610             else {
2611             $home = CORE::eval q{ (getpwuid($<))[7] };
2612             }
2613              
2614 0 0 0     0 # On Unix in general, a non-existant home means "no home"
2615 0         0 # For example, "nobody"-like users might use /nonexistant
2616             if (defined $home and ! -d($home)) {
2617 0         0 $home = undef;
2618             }
2619             return $home;
2620             }
2621              
2622             #
2623             # ${^PREMATCH}, $PREMATCH, $` the string preceding what was matched
2624 0     0 0 0 #
2625             sub Ewindows1257::PREMATCH {
2626             return $`;
2627             }
2628              
2629             #
2630             # ${^MATCH}, $MATCH, $& the string that matched
2631 0     0 0 0 #
2632             sub Ewindows1257::MATCH {
2633             return $&;
2634             }
2635              
2636             #
2637             # ${^POSTMATCH}, $POSTMATCH, $' the string following what was matched
2638 0     0 0 0 #
2639             sub Ewindows1257::POSTMATCH {
2640             return $';
2641             }
2642              
2643             #
2644             # Windows-1257 character to order (with parameter)
2645             #
2646 0 0   0 1 0 sub Windows1257::ord(;$) {
2647              
2648 0 0       0 local $_ = shift if @_;
2649 0         0  
2650 0         0 if (/\A ($q_char) /oxms) {
2651 0         0 my @ord = unpack 'C*', $1;
2652 0         0 my $ord = 0;
2653             while (my $o = shift @ord) {
2654 0         0 $ord = $ord * 0x100 + $o;
2655             }
2656             return $ord;
2657 0         0 }
2658             else {
2659             return CORE::ord $_;
2660             }
2661             }
2662              
2663             #
2664             # Windows-1257 character to order (without parameter)
2665             #
2666 0 0   0 0 0 sub Windows1257::ord_() {
2667 0         0  
2668 0         0 if (/\A ($q_char) /oxms) {
2669 0         0 my @ord = unpack 'C*', $1;
2670 0         0 my $ord = 0;
2671             while (my $o = shift @ord) {
2672 0         0 $ord = $ord * 0x100 + $o;
2673             }
2674             return $ord;
2675 0         0 }
2676             else {
2677             return CORE::ord $_;
2678             }
2679             }
2680              
2681             #
2682             # Windows-1257 reverse
2683             #
2684 0 0   0 0 0 sub Windows1257::reverse(@) {
2685 0         0  
2686             if (wantarray) {
2687             return CORE::reverse @_;
2688             }
2689             else {
2690              
2691             # One of us once cornered Larry in an elevator and asked him what
2692             # problem he was solving with this, but he looked as far off into
2693             # the distance as he could in an elevator and said, "It seemed like
2694 0         0 # a good idea at the time."
2695              
2696             return join '', CORE::reverse(join('',@_) =~ /\G ($q_char) /oxmsg);
2697             }
2698             }
2699              
2700             #
2701             # Windows-1257 getc (with parameter, without parameter)
2702             #
2703 0     0 0 0 sub Windows1257::getc(;*@) {
2704 0 0       0  
2705 0 0 0     0 my($package) = caller;
2706             my $fh = @_ ? qualify_to_ref(shift,$package) : \*STDIN;
2707 0         0 croak 'Too many arguments for Windows1257::getc' if @_ and not wantarray;
  0         0  
2708 0         0  
2709 0         0 my @length = sort { $a <=> $b } keys %range_tr;
2710 0         0 my $getc = '';
2711 0 0       0 for my $length ($length[0] .. $length[-1]) {
2712 0 0       0 $getc .= CORE::getc($fh);
2713 0 0       0 if (exists $range_tr{CORE::length($getc)}) {
2714             if ($getc =~ /\A ${Ewindows1257::dot_s} \z/oxms) {
2715             return wantarray ? ($getc,@_) : $getc;
2716             }
2717 0 0       0 }
2718             }
2719             return wantarray ? ($getc,@_) : $getc;
2720             }
2721              
2722             #
2723             # Windows-1257 length by character
2724             #
2725 0 0   0 1 0 sub Windows1257::length(;$) {
2726              
2727 0         0 local $_ = shift if @_;
2728 0         0  
2729             local @_ = /\G ($q_char) /oxmsg;
2730             return scalar @_;
2731             }
2732              
2733             #
2734             # Windows-1257 substr by character
2735             #
2736             BEGIN {
2737              
2738             # P.232 The lvalue Attribute
2739             # in Chapter 6: Subroutines
2740             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
2741              
2742             # P.336 The lvalue Attribute
2743             # in Chapter 7: Subroutines
2744             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
2745              
2746             # P.144 8.4 Lvalue subroutines
2747             # in Chapter 8: perlsub: Perl subroutines
2748 206 50 0 206 1 139796 # of ISBN-13: 978-1-906966-02-7 The Perl Language Reference Manual (for Perl version 5.12.1)
  0 0   0   0  
  0 0   0   0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
2749              
2750             CORE::eval sprintf(<<'END', ($] >= 5.014000) ? ':lvalue' : '');
2751             # vv----------------------*******
2752             sub Windows1257::substr($$;$$) %s {
2753              
2754             my @char = $_[0] =~ /\G (?>$q_char) /oxmsg;
2755              
2756             # If the substring is beyond either end of the string, substr() returns the undefined
2757             # value and produces a warning. When used as an lvalue, specifying a substring that
2758             # is entirely outside the string raises an exception.
2759             # http://perldoc.perl.org/functions/substr.html
2760              
2761             # A return with no argument returns the scalar value undef in scalar context,
2762             # an empty list () in list context, and (naturally) nothing at all in void
2763             # context.
2764              
2765             my $offset = $_[1];
2766             if (($offset > scalar(@char)) or ($offset < (-1 * scalar(@char)))) {
2767             return;
2768             }
2769              
2770             # substr($string,$offset,$length,$replacement)
2771             if (@_ == 4) {
2772             my(undef,undef,$length,$replacement) = @_;
2773             my $substr = join '', splice(@char, $offset, $length, $replacement);
2774             $_[0] = join '', @char;
2775              
2776             # return $substr; this doesn't work, don't say "return"
2777             $substr;
2778             }
2779              
2780             # substr($string,$offset,$length)
2781             elsif (@_ == 3) {
2782             my(undef,undef,$length) = @_;
2783             my $octet_offset = 0;
2784             my $octet_length = 0;
2785             if ($offset == 0) {
2786             $octet_offset = 0;
2787             }
2788             elsif ($offset > 0) {
2789             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2790             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2791             }
2792             else {
2793             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2794             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2795             }
2796             if ($length == 0) {
2797             $octet_length = 0;
2798             }
2799             elsif ($length > 0) {
2800             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2801             $octet_length = CORE::length(join '', @char[$offset..$offset+$length-1]);
2802             }
2803             else {
2804             local $SIG{__WARN__} = sub {}; # avoid: Use of uninitialized value in join or string at here
2805             $octet_length = -1 * CORE::length(join '', @char[$#char+$length+1..$#char]);
2806             }
2807             CORE::substr($_[0], $octet_offset, $octet_length);
2808             }
2809              
2810             # substr($string,$offset)
2811             else {
2812             my $octet_offset = 0;
2813             if ($offset == 0) {
2814             $octet_offset = 0;
2815             }
2816             elsif ($offset > 0) {
2817             $octet_offset = CORE::length(join '', @char[0..$offset-1]);
2818             }
2819             else {
2820             $octet_offset = -1 * CORE::length(join '', @char[$#char+$offset+1..$#char]);
2821             }
2822             CORE::substr($_[0], $octet_offset);
2823             }
2824             }
2825             END
2826             }
2827              
2828             #
2829             # Windows-1257 index by character
2830             #
2831 0     0 1 0 sub Windows1257::index($$;$) {
2832 0 0       0  
2833 0         0 my $index;
2834             if (@_ == 3) {
2835             $index = Ewindows1257::index($_[0], $_[1], CORE::length(Windows1257::substr($_[0], 0, $_[2])));
2836 0         0 }
2837             else {
2838             $index = Ewindows1257::index($_[0], $_[1]);
2839 0 0       0 }
2840 0         0  
2841             if ($index == -1) {
2842             return -1;
2843 0         0 }
2844             else {
2845             return Windows1257::length(CORE::substr $_[0], 0, $index);
2846             }
2847             }
2848              
2849             #
2850             # Windows-1257 rindex by character
2851             #
2852 0     0 1 0 sub Windows1257::rindex($$;$) {
2853 0 0       0  
2854 0         0 my $rindex;
2855             if (@_ == 3) {
2856             $rindex = Ewindows1257::rindex($_[0], $_[1], CORE::length(Windows1257::substr($_[0], 0, $_[2])));
2857 0         0 }
2858             else {
2859             $rindex = Ewindows1257::rindex($_[0], $_[1]);
2860 0 0       0 }
2861 0         0  
2862             if ($rindex == -1) {
2863             return -1;
2864 0         0 }
2865             else {
2866             return Windows1257::length(CORE::substr $_[0], 0, $rindex);
2867             }
2868             }
2869              
2870 206     206   1781 # when 'm//', '/' means regexp match 'm//' and '?' means regexp match '??'
  206         502  
  206         39931  
2871             # when 'div', '/' means division operator and '?' means conditional operator (condition ? then : else)
2872             use vars qw($slash); $slash = 'm//';
2873              
2874             # ord() to ord() or Windows1257::ord()
2875             my $function_ord = 'ord';
2876              
2877             # ord to ord or Windows1257::ord_
2878             my $function_ord_ = 'ord';
2879              
2880             # reverse to reverse or Windows1257::reverse
2881             my $function_reverse = 'reverse';
2882              
2883             # getc to getc or Windows1257::getc
2884             my $function_getc = 'getc';
2885              
2886             # P.1023 Appendix W.9 Multibyte Anchoring
2887             # of ISBN 1-56592-224-7 CJKV Information Processing
2888              
2889 206     206   1484 my $anchor = '';
  206     0   427  
  206         7544164  
2890              
2891             use vars qw($nest);
2892              
2893             # regexp of nested parens in qqXX
2894              
2895             # P.340 Matching Nested Constructs with Embedded Code
2896             # in Chapter 7: Perl
2897             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
2898              
2899             my $qq_paren = qr{(?{local $nest=0}) (?>(?:
2900             [^\\()] |
2901             \( (?{$nest++}) |
2902             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2903             \\ [^c] |
2904             \\c[\x40-\x5F] |
2905             [\x00-\xFF]
2906             }xms;
2907              
2908             my $qq_brace = qr{(?{local $nest=0}) (?>(?:
2909             [^\\{}] |
2910             \{ (?{$nest++}) |
2911             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2912             \\ [^c] |
2913             \\c[\x40-\x5F] |
2914             [\x00-\xFF]
2915             }xms;
2916              
2917             my $qq_bracket = qr{(?{local $nest=0}) (?>(?:
2918             [^\\\[\]] |
2919             \[ (?{$nest++}) |
2920             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2921             \\ [^c] |
2922             \\c[\x40-\x5F] |
2923             [\x00-\xFF]
2924             }xms;
2925              
2926             my $qq_angle = qr{(?{local $nest=0}) (?>(?:
2927             [^\\<>] |
2928             \< (?{$nest++}) |
2929             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2930             \\ [^c] |
2931             \\c[\x40-\x5F] |
2932             [\x00-\xFF]
2933             }xms;
2934              
2935             my $qq_scalar = qr{(?: \{ (?:$qq_brace)*? \} |
2936             (?: ::)? (?:
2937             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2938             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2939             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2940             ))
2941             }xms;
2942              
2943             my $qq_variable = qr{(?: \{ (?:$qq_brace)*? \} |
2944             (?: ::)? (?:
2945             (?>[0-9]+) |
2946             [^a-zA-Z_0-9\[\]] |
2947             ^[A-Z] |
2948             (?> [a-zA-Z_][a-zA-Z_0-9]* (?: ::[a-zA-Z_][a-zA-Z_0-9]*)* )
2949             (?>(?: \[ (?: \$\[ | \$\] | $qq_char )*? \] | \{ (?:$qq_brace)*? \} )*)
2950             (?>(?: (?: -> )? (?: [\$\@\%\&\*]\* | \$\#\* | [\@\%]? \[ (?: \$\[ | \$\] | $qq_char )*? \] | [\@\%\*]? \{ (?:$qq_brace)*? \} ) )*)
2951             ))
2952             }xms;
2953              
2954             my $qq_substr = qr{(?> Char::substr | Windows1257::substr | CORE::substr | substr ) (?>\s*) \( $qq_paren \)
2955             }xms;
2956              
2957             # regexp of nested parens in qXX
2958             my $q_paren = qr{(?{local $nest=0}) (?>(?:
2959             [^()] |
2960             \( (?{$nest++}) |
2961             \) (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2962             [\x00-\xFF]
2963             }xms;
2964              
2965             my $q_brace = qr{(?{local $nest=0}) (?>(?:
2966             [^\{\}] |
2967             \{ (?{$nest++}) |
2968             \} (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2969             [\x00-\xFF]
2970             }xms;
2971              
2972             my $q_bracket = qr{(?{local $nest=0}) (?>(?:
2973             [^\[\]] |
2974             \[ (?{$nest++}) |
2975             \] (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2976             [\x00-\xFF]
2977             }xms;
2978              
2979             my $q_angle = qr{(?{local $nest=0}) (?>(?:
2980             [^<>] |
2981             \< (?{$nest++}) |
2982             \> (?(?{$nest>0})(?{$nest--})|(?!)))*) (?(?{$nest!=0})(?!)) |
2983             [\x00-\xFF]
2984             }xms;
2985              
2986             my $matched = '';
2987             my $s_matched = '';
2988              
2989             my $tr_variable = ''; # variable of tr///
2990             my $sub_variable = ''; # variable of s///
2991             my $bind_operator = ''; # =~ or !~
2992              
2993             my @heredoc = (); # here document
2994             my @heredoc_delimiter = ();
2995             my $here_script = ''; # here script
2996              
2997             #
2998             # escape Windows-1257 script
2999 0 50   206 0 0 #
3000             sub Windows1257::escape(;$) {
3001             local($_) = $_[0] if @_;
3002              
3003             # P.359 The Study Function
3004             # in Chapter 7: Perl
3005 206         699 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3006              
3007             study $_; # Yes, I studied study yesterday.
3008              
3009             # while all script
3010              
3011             # 6.14. Matching from Where the Last Pattern Left Off
3012             # in Chapter 6. Pattern Matching
3013             # of ISBN 0-596-00313-7 Perl Cookbook, 2nd Edition.
3014             # (and so on)
3015              
3016             # one member of Tag-team
3017             #
3018             # P.128 Start of match (or end of previous match): \G
3019             # P.130 Advanced Use of \G with Perl
3020             # in Chapter 3: Overview of Regular Expression Features and Flavors
3021             # P.255 Use leading anchors
3022             # P.256 Expose ^ and \G at the front expressions
3023             # in Chapter 6: Crafting an Efficient Expression
3024             # P.315 "Tag-team" matching with /gc
3025             # in Chapter 7: Perl
3026 206         455 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
3027 206         373  
3028 206         2678 my $e_script = '';
3029             while (not /\G \z/oxgc) { # member
3030             $e_script .= Windows1257::escape_token();
3031 75476         117957 }
3032              
3033             return $e_script;
3034             }
3035              
3036             #
3037             # escape Windows-1257 token of script
3038             #
3039             sub Windows1257::escape_token {
3040              
3041 206     75476 0 2716 # \n output here document
3042              
3043             my $ignore_modules = join('|', qw(
3044             utf8
3045             bytes
3046             charnames
3047             I18N::Japanese
3048             I18N::Collate
3049             I18N::JExt
3050             File::DosGlob
3051             Wild
3052             Wildcard
3053             Japanese
3054             ));
3055              
3056             # another member of Tag-team
3057             #
3058             # P.315 "Tag-team" matching with /gc
3059             # in Chapter 7: Perl
3060 75476 100 100     91071 # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    100          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    50          
3061 75476         2850561  
3062 12524 100       16497 if (/\G ( \n ) /oxgc) { # another member (and so on)
3063 12524         21835 my $heredoc = '';
3064             if (scalar(@heredoc_delimiter) >= 1) {
3065 174         230 $slash = 'm//';
3066 174         359  
3067             $heredoc = join '', @heredoc;
3068             @heredoc = ();
3069 174         292  
3070 174         306 # skip here document
3071             for my $heredoc_delimiter (@heredoc_delimiter) {
3072 174         1108 /\G .*? \n $heredoc_delimiter \n/xmsgc;
3073             }
3074 174         344 @heredoc_delimiter = ();
3075              
3076 174         240 $here_script = '';
3077             }
3078             return "\n" . $heredoc;
3079             }
3080 12524         36797  
3081             # ignore space, comment
3082             elsif (/\G ((?>\s+)|\#.*) /oxgc) { return $1; }
3083              
3084             # if (, elsif (, unless (, while (, until (, given (, and when (
3085              
3086             # given, when
3087              
3088             # P.225 The given Statement
3089             # in Chapter 15: Smart Matching and given-when
3090             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3091              
3092             # P.133 The given Statement
3093             # in Chapter 4: Statements and Declarations
3094             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3095 17937         55422  
3096 1401         2243 elsif (/\G ( (?: if | elsif | unless | while | until | given | when ) (?>\s*) \( ) /oxgc) {
3097             $slash = 'm//';
3098             return $1;
3099             }
3100              
3101             # scalar variable ($scalar = ...) =~ tr///;
3102             # scalar variable ($scalar = ...) =~ s///;
3103              
3104             # state
3105              
3106             # P.68 Persistent, Private Variables
3107             # in Chapter 4: Subroutines
3108             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
3109              
3110             # P.160 Persistent Lexically Scoped Variables: state
3111             # in Chapter 4: Statements and Declarations
3112             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
3113              
3114             # (and so on)
3115 1401         4459  
3116             elsif (/\G ( \( (?>\s*) (?: local \b | my \b | our \b | state \b )? (?>\s*) \$ $qq_scalar ) /oxgc) {
3117 86 50       177 my $e_string = e_string($1);
    50          
3118 86         2139  
3119 0         0 if (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3120 0         0 $tr_variable = $e_string . e_string($1);
3121 0         0 $bind_operator = $2;
3122             $slash = 'm//';
3123             return '';
3124 0         0 }
3125 0         0 elsif (/\G ( (?>\s*) = $qq_paren \) ) ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3126 0         0 $sub_variable = $e_string . e_string($1);
3127 0         0 $bind_operator = $2;
3128             $slash = 'm//';
3129             return '';
3130 0         0 }
3131 86         170 else {
3132             $slash = 'div';
3133             return $e_string;
3134             }
3135             }
3136              
3137 86         289 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
3138 4         7 elsif (/\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
3139             $slash = 'div';
3140             return q{Ewindows1257::PREMATCH()};
3141             }
3142              
3143 4         16 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
3144 28         73 elsif (/\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
3145             $slash = 'div';
3146             return q{Ewindows1257::MATCH()};
3147             }
3148              
3149 28         107 # $', ${'} --> $', ${'}
3150 1         2 elsif (/\G ( \$' | \$\{'\} ) /oxmsgc) {
3151             $slash = 'div';
3152             return $1;
3153             }
3154              
3155 1         5 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
3156 3         7 elsif (/\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
3157             $slash = 'div';
3158             return q{Ewindows1257::POSTMATCH()};
3159             }
3160              
3161             # scalar variable $scalar =~ tr///;
3162             # scalar variable $scalar =~ s///;
3163             # substr() =~ tr///;
3164 3         10 # substr() =~ s///;
3165             elsif (/\G ( \$ $qq_scalar | $qq_substr ) /oxgc) {
3166 1673 100       3720 my $scalar = e_string($1);
    100          
3167 1673         6428  
3168 1         3 if (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= (?: tr | y ) \b ) /oxgc) {
3169 1         2 $tr_variable = $scalar;
3170 1         3 $bind_operator = $1;
3171             $slash = 'm//';
3172             return '';
3173 1         4 }
3174 61         128 elsif (/\G ( (?>\s*) (?: =~ | !~ ) (?>\s*) ) (?= s \b ) /oxgc) {
3175 61         157 $sub_variable = $scalar;
3176 61         121 $bind_operator = $1;
3177             $slash = 'm//';
3178             return '';
3179 61         194 }
3180 1611         2451 else {
3181             $slash = 'div';
3182             return $scalar;
3183             }
3184             }
3185              
3186 1611         4645 # end of statement
3187             elsif (/\G ( [,;] ) /oxgc) {
3188             $slash = 'm//';
3189 4997         7785  
3190             # clear tr/// variable
3191             $tr_variable = '';
3192 4997         6304  
3193             # clear s/// variable
3194 4997         5747 $sub_variable = '';
3195              
3196 4997         5996 $bind_operator = '';
3197              
3198             return $1;
3199             }
3200              
3201 4997         16920 # bareword
3202             elsif (/\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
3203             return $1;
3204             }
3205              
3206 0         0 # $0 --> $0
3207 2         5 elsif (/\G ( \$ 0 ) /oxmsgc) {
3208             $slash = 'div';
3209             return $1;
3210 2         7 }
3211 0         0 elsif (/\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
3212             $slash = 'div';
3213             return $1;
3214             }
3215              
3216 0         0 # $$ --> $$
3217 1         2 elsif (/\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
3218             $slash = 'div';
3219             return $1;
3220             }
3221              
3222             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
3223 1         4 # $1, $2, $3 --> $1, $2, $3 otherwise
3224 4         6 elsif (/\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
3225             $slash = 'div';
3226             return e_capture($1);
3227 4         8 }
3228 0         0 elsif (/\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
3229             $slash = 'div';
3230             return e_capture($1);
3231             }
3232              
3233 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
3234 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
3235             $slash = 'div';
3236             return e_capture($1.'->'.$2);
3237             }
3238              
3239 0         0 # $$foo{ ... } --> $ $foo->{ ... }
3240 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
3241             $slash = 'div';
3242             return e_capture($1.'->'.$2);
3243             }
3244              
3245 0         0 # $$foo
3246 0         0 elsif (/\G \$ ( \$ (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
3247             $slash = 'div';
3248             return e_capture($1);
3249             }
3250              
3251 0         0 # ${ foo }
3252 0         0 elsif (/\G \$ (?>\s*) \{ ( (?>\s*) (?> [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* ) (?>\s*) ) \} /oxmsgc) {
3253             $slash = 'div';
3254             return '${' . $1 . '}';
3255             }
3256              
3257 0         0 # ${ ... }
3258 0         0 elsif (/\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
3259             $slash = 'div';
3260             return e_capture($1);
3261             }
3262              
3263             # variable or function
3264 0         0 # $ @ % & * $ #
3265 42         65 elsif (/\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
3266             $slash = 'div';
3267             return $1;
3268             }
3269             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
3270 42         147 # $ @ # \ ' " / ? ( ) [ ] < >
3271 62         126 elsif (/\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
3272             $slash = 'div';
3273             return $1;
3274             }
3275              
3276 62         221 # while ()
3277             elsif (/\G \b (while (?>\s*) \( (?>\s*) <[\$]?[A-Za-z_][A-Za-z_0-9]*> (?>\s*) \)) \b /oxgc) {
3278             return $1;
3279             }
3280              
3281             # while () --- glob
3282              
3283             # avoid "Error: Runtime exception" of perl version 5.005_03
3284 0         0  
3285             elsif (/\G \b while (?>\s*) \( (?>\s*) < ((?:[^>\0\a\e\f\n\r\t])+?) > (?>\s*) \) \b /oxgc) {
3286             return 'while ($_ = Ewindows1257::glob("' . $1 . '"))';
3287             }
3288              
3289 0         0 # while (glob)
3290             elsif (/\G \b while (?>\s*) \( (?>\s*) glob (?>\s*) \) /oxgc) {
3291             return 'while ($_ = Ewindows1257::glob_)';
3292             }
3293              
3294 0         0 # while (glob(WILDCARD))
3295             elsif (/\G \b while (?>\s*) \( (?>\s*) glob \b /oxgc) {
3296             return 'while ($_ = Ewindows1257::glob';
3297             }
3298 0         0  
  248         613  
3299             # doit if, doit unless, doit while, doit until, doit for, doit when
3300             elsif (/\G \b ( if | unless | while | until | for | when ) \b /oxgc) { $slash = 'm//'; return $1; }
3301 248         953  
  19         38  
3302 19         69 # subroutines of package Ewindows1257
  0         0  
3303 0         0 elsif (/\G \b (CORE:: | ->(>?\s*) (?: atan2 | [a-z]{2,})) \b /oxgc) { $slash = 'm//'; return $1; }
  13         17  
3304 13         34 elsif (/\G \b Char::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  0         0  
3305 0         0 elsif (/\G \b Windows1257::eval (?= (?>\s*) \{ ) /oxgc) { $slash = 'm//'; return 'eval'; }
  114         168  
3306 114         339 elsif (/\G \b Char::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Char::escape'; }
  2         5  
3307 2         8 elsif (/\G \b Windows1257::eval \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'eval Windows1257::escape'; }
  0         0  
3308 0         0 elsif (/\G \b bytes::substr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'substr'; }
  2         3  
3309 2         7 elsif (/\G \b chop \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::chop'; }
  0         0  
3310 0         0 elsif (/\G \b bytes::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'index'; }
  0         0  
3311 0         0 elsif (/\G \b Char::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::index'; }
  0         0  
3312 0         0 elsif (/\G \b Windows1257::index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Windows1257::index'; }
  2         5  
3313 2         7 elsif (/\G \b index \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::index'; }
  0         0  
3314 0         0 elsif (/\G \b bytes::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'rindex'; }
  0         0  
3315 0         0 elsif (/\G \b Char::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Char::rindex'; }
  0         0  
3316 0         0 elsif (/\G \b Windows1257::rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Windows1257::rindex'; }
  1         2  
3317 1         4 elsif (/\G \b rindex \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::rindex'; }
  0         0  
3318 0         0 elsif (/\G \b lc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::lc'; }
  1         4  
3319 1         4 elsif (/\G \b lcfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::lcfirst'; }
  0         0  
3320 0         0 elsif (/\G \b uc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::uc'; }
  6         8  
3321             elsif (/\G \b ucfirst (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::ucfirst'; }
3322             elsif (/\G \b fc (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::fc'; }
3323 6         17  
  0         0  
3324 0         0 # "-s '' ..." means file test "-s 'filename' ..." (not means "- s/// ...")
  0         0  
3325 0         0 elsif (/\G -s (?>\s*) (\") ((?:$qq_char)+?) (\") /oxgc) { $slash = 'm//'; return '-s ' . e_qq('', $1,$3,$2); }
  0         0  
3326 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\#) ((?:$qq_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3327 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\() ((?:$qq_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3328 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\{) ((?:$qq_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3329 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\[) ((?:$qq_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3330             elsif (/\G -s (?>\s+) qq (?>\s*) (\<) ((?:$qq_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
3331 0         0 elsif (/\G -s (?>\s+) qq (?>\s*) (\S) ((?:$qq_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_qq('qq',$1,$3,$2); }
  0         0  
3332 0         0  
  0         0  
3333 0         0 elsif (/\G -s (?>\s*) (\') ((?:\\\'|\\\\|$q_char)+?) (\') /oxgc) { $slash = 'm//'; return '-s ' . e_q ('', $1,$3,$2); }
  0         0  
3334 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\#) ((?:\\\#|\\\\|$q_char)+?) (\#) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3335 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\() ((?:\\\)|\\\\|$q_paren)+?) (\)) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3336 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\{) ((?:\\\}|\\\\|$q_brace)+?) (\}) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3337 0         0 elsif (/\G -s (?>\s+) q (?>\s*) (\[) ((?:\\\]|\\\\|$q_bracket)+?) (\]) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
  0         0  
3338             elsif (/\G -s (?>\s+) q (?>\s*) (\<) ((?:\\\>|\\\\|$q_angle)+?) (\>) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3339             elsif (/\G -s (?>\s+) q (?>\s*) (\S) ((?:\\\1|\\\\|$q_char)+?) (\1) /oxgc) { $slash = 'm//'; return '-s ' . e_q ('q', $1,$3,$2); }
3340 0         0  
  0         0  
3341 0         0 elsif (/\G -s (?>\s*) (\$ (?> \w+ (?: ::\w+)* ) (?: (?: ->)? (?: [\$\@\%\&\*]\* | \$\#\* | \( (?:$qq_paren)*? \) | [\@\%\*]? \{ (?:$qq_brace)+? \} | [\@\%]? \[ (?:$qq_bracket)+? \] ) )*) /oxgc)
  0         0  
3342 0         0 { $slash = 'm//'; return "-s $1"; }
  0         0  
3343 0         0 elsif (/\G -s (?>\s*) \( ((?:$qq_paren)*?) \) /oxgc) { $slash = 'm//'; return "-s ($1)"; }
  0         0  
3344             elsif (/\G -s (?= (?>\s+) [a-z]+) /oxgc) { $slash = 'm//'; return '-s'; }
3345 0         0 elsif (/\G -s (?>\s+) ((?>\w+)) /oxgc) { $slash = 'm//'; return "-s $1"; }
  2         6  
3346 2         8  
  2         5  
3347 2         7 elsif (/\G \b bytes::length (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'length'; }
  36         60  
3348 36         111 elsif (/\G \b bytes::chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'chr'; }
  2         7  
3349 2         7 elsif (/\G \b chr (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::chr'; }
  8         17  
3350 8         29 elsif (/\G \b bytes::ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3351 0         0 elsif (/\G \b ord (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'div'; return $function_ord; }
  0         0  
3352 0         0 elsif (/\G \b glob (?= (?>\s+)[A-Za-z_]|(?>\s*)['"`\$\@\&\*\(]) /oxgc) { $slash = 'm//'; return 'Ewindows1257::glob'; }
  0         0  
3353 0         0 elsif (/\G \b lc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::lc_'; }
  0         0  
3354 0         0 elsif (/\G \b lcfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::lcfirst_'; }
  0         0  
3355 0         0 elsif (/\G \b uc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::uc_'; }
  0         0  
3356 0         0 elsif (/\G \b ucfirst \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::ucfirst_'; }
  0         0  
3357             elsif (/\G \b fc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::fc_'; }
3358 0         0 elsif (/\G -s \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return '-s '; }
  0         0  
3359 0         0  
  0         0  
3360 0         0 elsif (/\G \b bytes::length \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'length'; }
  0         0  
3361 0         0 elsif (/\G \b bytes::chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'chr'; }
  0         0  
3362 0         0 elsif (/\G \b chr \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::chr_'; }
  0         0  
3363 0         0 elsif (/\G \b bytes::ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return 'ord'; }
  0         0  
3364 0         0 elsif (/\G \b ord \b (?! (?>\s*) => ) /oxgc) { $slash = 'div'; return $function_ord_; }
  0         0  
3365 0         0 elsif (/\G \b glob \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return 'Ewindows1257::glob_'; }
  8         19  
3366             elsif (/\G \b reverse \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_reverse; }
3367             elsif (/\G \b getc \b (?! (?>\s*) => ) /oxgc) { $slash = 'm//'; return $function_getc; }
3368 8         29 # split
3369             elsif (/\G \b (split) \b (?! (?>\s*) => ) /oxgc) {
3370 87         179 $slash = 'm//';
3371 87         145  
3372 87         319 my $e = '';
3373             while (/\G ( (?>\s+) | \( | \#.* ) /oxgc) {
3374             $e .= $1;
3375             }
3376 85 100       335  
  87 100       6078  
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
3377             # end of split
3378             if (/\G (?= [,;\)\}\]] ) /oxgc) { return 'Ewindows1257::split' . $e; }
3379 2         8  
3380             # split scalar value
3381             elsif (/\G ( [\$\@\&\*] $qq_scalar ) /oxgc) { return 'Ewindows1257::split' . $e . e_string($1); }
3382 1         5  
3383 0         0 # split literal space
3384 0         0 elsif (/\G \b qq (\#) [ ] (\#) /oxgc) { return 'Ewindows1257::split' . $e . qq {qq$1 $2}; }
3385 0         0 elsif (/\G \b qq ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ewindows1257::split' . $e . qq{$1qq$2 $3}; }
3386 0         0 elsif (/\G \b qq ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ewindows1257::split' . $e . qq{$1qq$2 $3}; }
3387 0         0 elsif (/\G \b qq ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ewindows1257::split' . $e . qq{$1qq$2 $3}; }
3388 0         0 elsif (/\G \b qq ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ewindows1257::split' . $e . qq{$1qq$2 $3}; }
3389 0         0 elsif (/\G \b qq ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ewindows1257::split' . $e . qq{$1qq$2 $3}; }
3390 0         0 elsif (/\G \b q (\#) [ ] (\#) /oxgc) { return 'Ewindows1257::split' . $e . qq {q$1 $2}; }
3391 0         0 elsif (/\G \b q ((?>\s*)) (\() [ ] (\)) /oxgc) { return 'Ewindows1257::split' . $e . qq {$1q$2 $3}; }
3392 0         0 elsif (/\G \b q ((?>\s*)) (\{) [ ] (\}) /oxgc) { return 'Ewindows1257::split' . $e . qq {$1q$2 $3}; }
3393 0         0 elsif (/\G \b q ((?>\s*)) (\[) [ ] (\]) /oxgc) { return 'Ewindows1257::split' . $e . qq {$1q$2 $3}; }
3394 0         0 elsif (/\G \b q ((?>\s*)) (\<) [ ] (\>) /oxgc) { return 'Ewindows1257::split' . $e . qq {$1q$2 $3}; }
3395 10         43 elsif (/\G \b q ((?>\s*)) (\S) [ ] (\2) /oxgc) { return 'Ewindows1257::split' . $e . qq {$1q$2 $3}; }
3396             elsif (/\G ' [ ] ' /oxgc) { return 'Ewindows1257::split' . $e . qq {' '}; }
3397             elsif (/\G " [ ] " /oxgc) { return 'Ewindows1257::split' . $e . qq {" "}; }
3398              
3399 0 0       0 # split qq//
  0         0  
3400             elsif (/\G \b (qq) \b /oxgc) {
3401 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq# # --> qr # #
3402 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3403 0         0 while (not /\G \z/oxgc) {
3404 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3405 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq ( ) --> qr ( )
3406 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq { } --> qr { }
3407 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq [ ] --> qr [ ]
3408 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq < > --> qr < >
3409             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr','{','}',$2,''); } # qq | | --> qr { }
3410 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return e_split($e.'qr',$1,$3,$2,''); } # qq * * --> qr * *
3411             }
3412             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3413             }
3414             }
3415              
3416 0 50       0 # split qr//
  12         440  
3417             elsif (/\G \b (qr) \b /oxgc) {
3418 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # qr# #
3419 12 50       67 else {
  12 50       3507  
    50          
    50          
    50          
    50          
    50          
    50          
3420 0         0 while (not /\G \z/oxgc) {
3421 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3422 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr ( )
3423 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr { }
3424 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr [ ]
3425 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr < >
3426 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # qr ' '
3427             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # qr | | --> qr { }
3428 12         90 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # qr * *
3429             }
3430             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3431             }
3432             }
3433              
3434 0 0       0 # split q//
  0         0  
3435             elsif (/\G \b (q) \b /oxgc) {
3436 0         0 if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q# # --> qr # #
3437 0 0       0 else {
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3438 0         0 while (not /\G \z/oxgc) {
3439 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3440 0         0 elsif (/\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q ( ) --> qr ( )
3441 0         0 elsif (/\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q { } --> qr { }
3442 0         0 elsif (/\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q [ ] --> qr [ ]
3443 0         0 elsif (/\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q < > --> qr < >
3444             elsif (/\G ([*\-:?\\^|]) ((?:$q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr','{','}',$2,''); } # q | | --> qr { }
3445 0         0 elsif (/\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { return e_split_q($e.'qr',$1,$3,$2,''); } # q * * --> qr * *
3446             }
3447             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3448             }
3449             }
3450              
3451 0 50       0 # split m//
  18         485  
3452             elsif (/\G \b (m) \b /oxgc) {
3453 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1,$3,$2,$4); } # m# # --> qr # #
3454 18 50       80 else {
  18 50       4025  
    50          
    50          
    50          
    50          
    50          
    50          
3455 0         0 while (not /\G \z/oxgc) {
3456 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3457 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m ( ) --> qr ( )
3458 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m { } --> qr { }
3459 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m [ ] --> qr [ ]
3460 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m < > --> qr < >
3461 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return e_split_q($e.'qr',$1, $3, $2,$4); } # m ' ' --> qr ' '
3462             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr','{','}',$2,$4); } # m | | --> qr { }
3463 18         121 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return e_split ($e.'qr',$1, $3, $2,$4); } # m * * --> qr * *
3464             }
3465             die __FILE__, ": Search pattern not terminated\n";
3466             }
3467             }
3468              
3469 0         0 # split ''
3470 0         0 elsif (/\G (\') /oxgc) {
3471 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3472 0         0 while (not /\G \z/oxgc) {
3473 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3474 0         0 elsif (/\G (\\\') /oxgc) { $q_string .= $1; } # splitqr'' --> split qr''
3475             elsif (/\G \' /oxgc) { return e_split_q($e.q{ qr},"'","'",$q_string,''); } # ' ' --> qr ' '
3476 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3477             }
3478             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3479             }
3480              
3481 0         0 # split ""
3482 0         0 elsif (/\G (\") /oxgc) {
3483 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3484 0         0 while (not /\G \z/oxgc) {
3485 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3486 0         0 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; } # splitqr"" --> split qr""
3487             elsif (/\G \" /oxgc) { return e_split($e.q{ qr},'"','"',$qq_string,''); } # " " --> qr " "
3488 0         0 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
3489             }
3490             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3491             }
3492              
3493 0         0 # split //
3494 44         116 elsif (/\G (\/) /oxgc) {
3495 44 50       159 my $regexp = '';
  381 50       1609  
    100          
    50          
3496 0         0 while (not /\G \z/oxgc) {
3497 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
3498 44         223 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; } # splitqr// --> split qr//
3499             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_split($e.q{ qr}, '/','/',$regexp,$1); } # / / --> qr / /
3500 337         794 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
3501             }
3502             die __FILE__, ": Search pattern not terminated\n";
3503             }
3504             }
3505              
3506             # tr/// or y///
3507              
3508             # about [cdsrbB]* (/B modifier)
3509             #
3510             # P.559 appendix C
3511             # of ISBN 4-89052-384-7 Programming perl
3512             # (Japanese title is: Perl puroguramingu)
3513 0         0  
3514             elsif (/\G \b ( tr | y ) \b /oxgc) {
3515             my $ope = $1;
3516 3 50       18  
3517 3         46 # $1 $2 $3 $4 $5 $6
3518 0         0 if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cdsrbB]*) /oxgc) { # tr# # #
3519             my @tr = ($tr_variable,$2);
3520             return e_tr(@tr,'',$4,$6);
3521 0         0 }
3522 3         7 else {
3523 3 50       11 my $e = '';
  3 50       273  
    50          
    50          
    50          
    50          
3524             while (not /\G \z/oxgc) {
3525 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3526 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3527 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3528 0         0 while (not /\G \z/oxgc) {
3529 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3530 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) ( )
3531 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) { }
3532 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) [ ]
3533             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) < >
3534 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr ( ) * *
3535             }
3536             die __FILE__, ": Transliteration replacement not terminated\n";
3537 0         0 }
3538 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3539 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3540 0         0 while (not /\G \z/oxgc) {
3541 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3542 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } ( )
3543 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } { }
3544 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } [ ]
3545             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } < >
3546 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr { } * *
3547             }
3548             die __FILE__, ": Transliteration replacement not terminated\n";
3549 0         0 }
3550 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3551 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3552 0         0 while (not /\G \z/oxgc) {
3553 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3554 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] ( )
3555 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] { }
3556 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] [ ]
3557             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] < >
3558 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr [ ] * *
3559             }
3560             die __FILE__, ": Transliteration replacement not terminated\n";
3561 0         0 }
3562 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3563 0 0       0 my @tr = ($tr_variable,$2);
  0 0       0  
    0          
    0          
    0          
    0          
3564 0         0 while (not /\G \z/oxgc) {
3565 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3566 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > ( )
3567 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > { }
3568 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > [ ]
3569             elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > < >
3570 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { return e_tr(@tr,$e,$2,$4); } # tr < > * *
3571             }
3572             die __FILE__, ": Transliteration replacement not terminated\n";
3573             }
3574 0         0 # $1 $2 $3 $4 $5 $6
3575 3         14 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cdsrbB]*) /oxgc) { # tr * * *
3576             my @tr = ($tr_variable,$2);
3577             return e_tr(@tr,'',$4,$6);
3578 3         12 }
3579             }
3580             die __FILE__, ": Transliteration pattern not terminated\n";
3581             }
3582             }
3583              
3584 0         0 # qq//
3585             elsif (/\G \b (qq) \b /oxgc) {
3586             my $ope = $1;
3587 2180 50       4898  
3588 2180         3976 # if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { return e_qq($ope,$1,$3,$2); } # qq# #
3589 0         0 if (/\G (\#) /oxgc) { # qq# #
3590 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3591 0         0 while (not /\G \z/oxgc) {
3592 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3593 0         0 elsif (/\G (\\\#) /oxgc) { $qq_string .= $1; }
3594             elsif (/\G (\#) /oxgc) { return e_qq($ope,'#','#',$qq_string); }
3595 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3596             }
3597             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3598             }
3599 0         0  
3600 2180         3061 else {
3601 2180 50       5011 my $e = '';
  2180 50       8114  
    100          
    50          
    50          
    0          
3602             while (not /\G \z/oxgc) {
3603             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3604              
3605 0         0 # elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq ( )
3606 0         0 elsif (/\G (\() /oxgc) { # qq ( )
3607 0         0 my $qq_string = '';
3608 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3609 0         0 while (not /\G \z/oxgc) {
3610 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3611             elsif (/\G (\\\)) /oxgc) { $qq_string .= $1; }
3612 0 0       0 elsif (/\G (\() /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3613 0         0 elsif (/\G (\)) /oxgc) {
3614             if (--$nest == 0) { return $e . e_qq($ope,'(',')',$qq_string); }
3615 0         0 else { $qq_string .= $1; }
3616             }
3617 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3618             }
3619             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3620             }
3621              
3622 0         0 # elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq { }
3623 2150         3051 elsif (/\G (\{) /oxgc) { # qq { }
3624 2150         3010 my $qq_string = '';
3625 2150 100       4470 local $nest = 1;
  84071 50       256452  
    100          
    100          
    50          
3626 722         1390 while (not /\G \z/oxgc) {
3627 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  1153         1624  
3628             elsif (/\G (\\\}) /oxgc) { $qq_string .= $1; }
3629 1153 100       1969 elsif (/\G (\{) /oxgc) { $qq_string .= $1; $nest++; }
  3303         4971  
3630 2150         4464 elsif (/\G (\}) /oxgc) {
3631             if (--$nest == 0) { return $e . e_qq($ope,'{','}',$qq_string); }
3632 1153         2288 else { $qq_string .= $1; }
3633             }
3634 78893         155102 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3635             }
3636             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3637             }
3638              
3639 0         0 # elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq [ ]
3640 0         0 elsif (/\G (\[) /oxgc) { # qq [ ]
3641 0         0 my $qq_string = '';
3642 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
3643 0         0 while (not /\G \z/oxgc) {
3644 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3645             elsif (/\G (\\\]) /oxgc) { $qq_string .= $1; }
3646 0 0       0 elsif (/\G (\[) /oxgc) { $qq_string .= $1; $nest++; }
  0         0  
3647 0         0 elsif (/\G (\]) /oxgc) {
3648             if (--$nest == 0) { return $e . e_qq($ope,'[',']',$qq_string); }
3649 0         0 else { $qq_string .= $1; }
3650             }
3651 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3652             }
3653             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3654             }
3655              
3656 0         0 # elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq < >
3657 30         54 elsif (/\G (\<) /oxgc) { # qq < >
3658 30         58 my $qq_string = '';
3659 30 100       98 local $nest = 1;
  1166 50       4298  
    50          
    100          
    50          
3660 22         59 while (not /\G \z/oxgc) {
3661 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
  0         0  
3662             elsif (/\G (\\\>) /oxgc) { $qq_string .= $1; }
3663 0 50       0 elsif (/\G (\<) /oxgc) { $qq_string .= $1; $nest++; }
  30         70  
3664 30         80 elsif (/\G (\>) /oxgc) {
3665             if (--$nest == 0) { return $e . e_qq($ope,'<','>',$qq_string); }
3666 0         0 else { $qq_string .= $1; }
3667             }
3668 1114         2391 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3669             }
3670             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3671             }
3672              
3673 0         0 # elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qq * *
3674 0         0 elsif (/\G (\S) /oxgc) { # qq * *
3675 0         0 my $delimiter = $1;
3676 0 0       0 my $qq_string = '';
  0 0       0  
    0          
    0          
3677 0         0 while (not /\G \z/oxgc) {
3678 0         0 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
3679 0         0 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $qq_string .= $1; }
3680             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_qq($ope,$delimiter,$delimiter,$qq_string); }
3681 0         0 elsif (/\G ($qq_char) /oxgc) { $qq_string .= $1; }
3682             }
3683             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3684 0         0 }
3685             }
3686             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3687             }
3688             }
3689              
3690 0         0 # qr//
3691 0 0       0 elsif (/\G \b (qr) \b /oxgc) {
3692 0         0 my $ope = $1;
3693             if (/\G (\#) ((?:$qq_char)*?) (\#) ([imosxpadlunbB]*) /oxgc) { # qr# # #
3694             return e_qr($ope,$1,$3,$2,$4);
3695 0         0 }
3696 0         0 else {
3697 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3698 0         0 while (not /\G \z/oxgc) {
3699 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3700 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr ( )
3701 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr { }
3702 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr [ ]
3703 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr < >
3704 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([imosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # qr ' '
3705             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # qr | | --> qr { }
3706 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([imosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # qr * *
3707             }
3708             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3709             }
3710             }
3711              
3712 0         0 # qw//
3713 16 50       49 elsif (/\G \b (qw) \b /oxgc) {
3714 16         88 my $ope = $1;
3715             if (/\G (\#) (.*?) (\#) /oxmsgc) { # qw# #
3716             return e_qw($ope,$1,$3,$2);
3717 0         0 }
3718 16         32 else {
3719 16 50       50 my $e = '';
  16 50       114  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3720             while (not /\G \z/oxgc) {
3721 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3722 16         72  
3723             elsif (/\G (\() ([^(]*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3724 0         0 elsif (/\G (\() ((?:$q_paren)*?) (\)) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw ( )
3725 0         0  
3726             elsif (/\G (\{) ([^{]*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3727 0         0 elsif (/\G (\{) ((?:$q_brace)*?) (\}) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw { }
3728 0         0  
3729             elsif (/\G (\[) ([^[]*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3730 0         0 elsif (/\G (\[) ((?:$q_bracket)*?) (\]) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw [ ]
3731 0         0  
3732             elsif (/\G (\<) ([^<]*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3733 0         0 elsif (/\G (\<) ((?:$q_angle)*?) (\>) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw < >
3734 0         0  
3735             elsif (/\G ([\x21-\x3F]) (.*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3736 0         0 elsif (/\G (\S) ((?:$q_char)*?) (\1) /oxmsgc) { return $e . e_qw($ope,$1,$3,$2); } # qw * *
3737             }
3738             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3739             }
3740             }
3741              
3742 0         0 # qx//
3743 0 0       0 elsif (/\G \b (qx) \b /oxgc) {
3744 0         0 my $ope = $1;
3745             if (/\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
3746             return e_qq($ope,$1,$3,$2);
3747 0         0 }
3748 0         0 else {
3749 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
3750 0         0 while (not /\G \z/oxgc) {
3751 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3752 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx ( )
3753 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx { }
3754 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx [ ]
3755 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx < >
3756             elsif (/\G (\') ((?:$qq_char)*?) (\') /oxgc) { return $e . e_q ($ope,$1,$3,$2); } # qx ' '
3757 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { return $e . e_qq($ope,$1,$3,$2); } # qx * *
3758             }
3759             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3760             }
3761             }
3762              
3763 0         0 # q//
3764             elsif (/\G \b (q) \b /oxgc) {
3765             my $ope = $1;
3766              
3767             # if (/\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { return e_q($ope,$1,$3,$2); } # q# #
3768              
3769             # avoid "Error: Runtime exception" of perl version 5.005_03
3770 410 50       1197 # (and so on)
3771 410         1128  
3772 0         0 if (/\G (\#) /oxgc) { # q# #
3773 0 0       0 my $q_string = '';
  0 0       0  
    0          
    0          
3774 0         0 while (not /\G \z/oxgc) {
3775 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3776 0         0 elsif (/\G (\\\#) /oxgc) { $q_string .= $1; }
3777             elsif (/\G (\#) /oxgc) { return e_q($ope,'#','#',$q_string); }
3778 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3779             }
3780             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3781             }
3782 0         0  
3783 410         764 else {
3784 410 50       1293 my $e = '';
  410 50       2164  
    100          
    50          
    100          
    50          
3785             while (not /\G \z/oxgc) {
3786             if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3787              
3788 0         0 # elsif (/\G (\() ((?:\\\)|\\\\|$q_paren)*?) (\)) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q ( )
3789 0         0 elsif (/\G (\() /oxgc) { # q ( )
3790 0         0 my $q_string = '';
3791 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3792 0         0 while (not /\G \z/oxgc) {
3793 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3794 0         0 elsif (/\G (\\\)) /oxgc) { $q_string .= $1; }
  0         0  
3795             elsif (/\G (\\\() /oxgc) { $q_string .= $1; }
3796 0 0       0 elsif (/\G (\() /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3797 0         0 elsif (/\G (\)) /oxgc) {
3798             if (--$nest == 0) { return $e . e_q($ope,'(',')',$q_string); }
3799 0         0 else { $q_string .= $1; }
3800             }
3801 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3802             }
3803             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3804             }
3805              
3806 0         0 # elsif (/\G (\{) ((?:\\\}|\\\\|$q_brace)*?) (\}) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q { }
3807 404         731 elsif (/\G (\{) /oxgc) { # q { }
3808 404         760 my $q_string = '';
3809 404 50       1127 local $nest = 1;
  6835 50       27142  
    50          
    100          
    100          
    50          
3810 0         0 while (not /\G \z/oxgc) {
3811 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3812 0         0 elsif (/\G (\\\}) /oxgc) { $q_string .= $1; }
  107         160  
3813             elsif (/\G (\\\{) /oxgc) { $q_string .= $1; }
3814 107 100       200 elsif (/\G (\{) /oxgc) { $q_string .= $1; $nest++; }
  511         1085  
3815 404         1182 elsif (/\G (\}) /oxgc) {
3816             if (--$nest == 0) { return $e . e_q($ope,'{','}',$q_string); }
3817 107         222 else { $q_string .= $1; }
3818             }
3819 6217         13267 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3820             }
3821             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3822             }
3823              
3824 0         0 # elsif (/\G (\[) ((?:\\\]|\\\\|$q_bracket)*?) (\]) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q [ ]
3825 0         0 elsif (/\G (\[) /oxgc) { # q [ ]
3826 0         0 my $q_string = '';
3827 0 0       0 local $nest = 1;
  0 0       0  
    0          
    0          
    0          
    0          
3828 0         0 while (not /\G \z/oxgc) {
3829 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3830 0         0 elsif (/\G (\\\]) /oxgc) { $q_string .= $1; }
  0         0  
3831             elsif (/\G (\\\[) /oxgc) { $q_string .= $1; }
3832 0 0       0 elsif (/\G (\[) /oxgc) { $q_string .= $1; $nest++; }
  0         0  
3833 0         0 elsif (/\G (\]) /oxgc) {
3834             if (--$nest == 0) { return $e . e_q($ope,'[',']',$q_string); }
3835 0         0 else { $q_string .= $1; }
3836             }
3837 0         0 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3838             }
3839             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3840             }
3841              
3842 0         0 # elsif (/\G (\<) ((?:\\\>|\\\\|$q_angle)*?) (\>) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q < >
3843 5         14 elsif (/\G (\<) /oxgc) { # q < >
3844 5         14 my $q_string = '';
3845 5 50       57 local $nest = 1;
  88 50       527  
    50          
    50          
    100          
    50          
3846 0         0 while (not /\G \z/oxgc) {
3847 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3848 0         0 elsif (/\G (\\\>) /oxgc) { $q_string .= $1; }
  0         0  
3849             elsif (/\G (\\\<) /oxgc) { $q_string .= $1; }
3850 0 50       0 elsif (/\G (\<) /oxgc) { $q_string .= $1; $nest++; }
  5         18  
3851 5         21 elsif (/\G (\>) /oxgc) {
3852             if (--$nest == 0) { return $e . e_q($ope,'<','>',$q_string); }
3853 0         0 else { $q_string .= $1; }
3854             }
3855 83         224 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3856             }
3857             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3858             }
3859              
3860 0         0 # elsif (/\G (\S) ((?:\\\1|\\\\|$q_char)*?) (\1) /oxgc) { return $e . e_q($ope,$1,$3,$2); } # q * *
3861 1         3 elsif (/\G (\S) /oxgc) { # q * *
3862 1         2 my $delimiter = $1;
3863 1 50       3 my $q_string = '';
  14 50       68  
    100          
    50          
3864 0         0 while (not /\G \z/oxgc) {
3865 0         0 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
3866 1         2 elsif (/\G (\\\Q$delimiter\E) /oxgc) { $q_string .= $1; }
3867             elsif (/\G (\Q$delimiter\E) /oxgc) { return $e . e_q($ope,$delimiter,$delimiter,$q_string); }
3868 13         26 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
3869             }
3870             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3871 0         0 }
3872             }
3873             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
3874             }
3875             }
3876              
3877 0         0 # m//
3878 209 50       499 elsif (/\G \b (m) \b /oxgc) {
3879 209         1376 my $ope = $1;
3880             if (/\G (\#) ((?:$qq_char)*?) (\#) ([cgimosxpadlunbB]*) /oxgc) { # m# #
3881             return e_qr($ope,$1,$3,$2,$4);
3882 0         0 }
3883 209         332 else {
3884 209 50       538 my $e = '';
  209 50       11382  
    50          
    50          
    50          
    50          
    100          
    50          
    50          
3885 0         0 while (not /\G \z/oxgc) {
3886 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3887 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ( )
3888 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m { }
3889 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m [ ]
3890 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m < >
3891 10         38 elsif (/\G (\?) ((?:$qq_char)*?) (\?) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m ? ?
3892 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr_q($ope,$1, $3, $2,$4); } # m ' '
3893             elsif (/\G ([*\-:\\^|]) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,'{','}',$2,$4); } # m | | --> m { }
3894 199         667 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cgimosxpadlunbB]*) /oxgc) { return $e . e_qr ($ope,$1, $3, $2,$4); } # m * *
3895             }
3896             die __FILE__, ": Search pattern not terminated\n";
3897             }
3898             }
3899              
3900             # s///
3901              
3902             # about [cegimosxpradlunbB]* (/cg modifier)
3903             #
3904             # P.67 Pattern-Matching Operators
3905             # of ISBN 0-596-00241-6 Perl in a Nutshell, Second Edition.
3906 0         0  
3907             elsif (/\G \b (s) \b /oxgc) {
3908             my $ope = $1;
3909 97 100       271  
3910 97         1795 # $1 $2 $3 $4 $5 $6
3911             if (/\G (\#) ((?:$qq_char)*?) (\#) ((?:$qq_char)*?) (\#) ([cegimosxpradlunbB]*) /oxgc) { # s# # #
3912             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3913 1         5 }
3914 96         214 else {
3915 96 50       327 my $e = '';
  96 50       12594  
    50          
    50          
    50          
    100          
    50          
    50          
    50          
3916             while (not /\G \z/oxgc) {
3917 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3918 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) /oxgc) {
3919 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3920             while (not /\G \z/oxgc) {
3921 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3922 0         0 # $1 $2 $3 $4
3923 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3924 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3925 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3926 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3927 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3928 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3929 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3930             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3931 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3932             }
3933             die __FILE__, ": Substitution replacement not terminated\n";
3934 0         0 }
3935 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) {
3936 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3937             while (not /\G \z/oxgc) {
3938 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3939 0         0 # $1 $2 $3 $4
3940 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3941 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3942 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3943 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3944 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3945 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3946 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3947             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3948 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3949             }
3950             die __FILE__, ": Substitution replacement not terminated\n";
3951 0         0 }
3952 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) {
3953 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
3954             while (not /\G \z/oxgc) {
3955 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3956 0         0 # $1 $2 $3 $4
3957 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3958 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3959 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3960 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3961 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3962             elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3963 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3964             }
3965             die __FILE__, ": Substitution replacement not terminated\n";
3966 0         0 }
3967 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) {
3968 0 0       0 my @s = ($1,$2,$3);
  0 0       0  
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
3969             while (not /\G \z/oxgc) {
3970 0         0 if (/\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
3971 0         0 # $1 $2 $3 $4
3972 0         0 elsif (/\G (\() ((?:$qq_paren)*?) (\)) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3973 0         0 elsif (/\G (\{) ((?:$qq_brace)*?) (\}) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3974 0         0 elsif (/\G (\[) ((?:$qq_bracket)*?) (\]) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3975 0         0 elsif (/\G (\<) ((?:$qq_angle)*?) (\>) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3976 0         0 elsif (/\G (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3977 0         0 elsif (/\G (\$) ((?:$qq_char)*?) (\$) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3978 0         0 elsif (/\G (\:) ((?:$qq_char)*?) (\:) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3979             elsif (/\G (\@) ((?:$qq_char)*?) (\@) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3980 0         0 elsif (/\G (\S) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) { return e_sub($sub_variable,@s,$1,$2,$3,$4); }
3981             }
3982             die __FILE__, ": Substitution replacement not terminated\n";
3983             }
3984 0         0 # $1 $2 $3 $4 $5 $6
3985             elsif (/\G (\') ((?:$qq_char)*?) (\') ((?:$qq_char)*?) (\') ([cegimosxpradlunbB]*) /oxgc) {
3986             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3987             }
3988 21         59 # $1 $2 $3 $4 $5 $6
3989             elsif (/\G ([*\-:?\\^|]) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3990             return e_sub($sub_variable,'{',$2,'}','{',$4,'}',$6); # s | | | --> s { } { }
3991             }
3992 0         0 # $1 $2 $3 $4 $5 $6
3993             elsif (/\G (\$) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3994             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3995             }
3996 0         0 # $1 $2 $3 $4 $5 $6
3997             elsif (/\G (\S) ((?:$qq_char)*?) (\1) ((?:$qq_char)*?) (\1) ([cegimosxpradlunbB]*) /oxgc) {
3998             return e_sub($sub_variable,$1,$2,$3,$3,$4,$5,$6);
3999 75         384 }
4000             }
4001             die __FILE__, ": Substitution pattern not terminated\n";
4002             }
4003             }
4004 0         0  
4005 0         0 # require ignore module
4006 0         0 elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# require$1$2"; }
4007             elsif (/\G \b require ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# require$1\n$2"; }
4008             elsif (/\G \b require ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# require$1"; }
4009 0         0  
4010 37         329 # use strict; --> use strict; no strict qw(refs);
4011 0         0 elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "use$1 no strict qw(refs);$2"; }
4012             elsif (/\G \b use ((?>\s+) strict .*? ;) ([ \t]* [^#]) /oxmsgc) { return "use$1 no strict qw(refs);\n$2"; }
4013             elsif (/\G \b use ((?>\s+) strict) \b /oxmsgc) { return "use$1; no strict qw(refs)"; }
4014              
4015 0 50 33     0 # use 5.12.0; --> use 5.12.0; no strict qw(refs);
      33        
4016 2         21 elsif (/\G \b use (?>\s+) ((?>([1-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4017             if (($2 >= 6) or (($2 == 5) and ($3 ge '012'))) {
4018             return "use $1; no strict qw(refs);";
4019 0         0 }
4020             else {
4021             return "use $1;";
4022             }
4023 2 0 0     9 }
      0        
4024 0         0 elsif (/\G \b use (?>\s+) ((?>v([0-9][0-9_]*)(?:\.([0-9_]+))*)) (?>\s*) ; /oxmsgc) {
4025             if (($2 >= 6) or (($2 == 5) and ($3 >= 12))) {
4026             return "use $1; no strict qw(refs);";
4027 0         0 }
4028             else {
4029             return "use $1;";
4030             }
4031             }
4032 0         0  
4033 2         16 # ignore use module
4034 0         0 elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# use$1$2"; }
4035             elsif (/\G \b use ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# use$1\n$2"; }
4036             elsif (/\G \b use ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# use$1"; }
4037 0         0  
4038 0         0 # ignore no module
4039 0         0 elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [#\n]) /oxmsgc) { return "# no$1$2"; }
4040             elsif (/\G \b no ((?>\s+) (?:$ignore_modules) .*? ;) ([ \t]* [^#]) /oxmsgc) { return "# no$1\n$2"; }
4041             elsif (/\G \b no ((?>\s+) (?:$ignore_modules)) \b /oxmsgc) { return "# no$1"; }
4042 0         0  
4043             # use else
4044             elsif (/\G \b use \b /oxmsgc) { return "use"; }
4045 0         0  
4046             # use else
4047             elsif (/\G \b no \b /oxmsgc) { return "no"; }
4048              
4049 2         9 # ''
4050 848         1861 elsif (/\G (?
4051 848 100       2238 my $q_string = '';
  8319 100       25922  
    100          
    50          
4052 4         14 while (not /\G \z/oxgc) {
4053 48         80 if (/\G (\\\\) /oxgc) { $q_string .= $1; }
4054 848         2066 elsif (/\G (\\\') /oxgc) { $q_string .= $1; }
4055             elsif (/\G \' /oxgc) { return e_q('', "'","'",$q_string); }
4056 7419         15029 elsif (/\G ($q_char) /oxgc) { $q_string .= $1; }
4057             }
4058             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4059             }
4060              
4061 0         0 # ""
4062 1786         3696 elsif (/\G (\") /oxgc) {
4063 1786 100       4487 my $qq_string = '';
  36076 100       104388  
    100          
    50          
4064 67         165 while (not /\G \z/oxgc) {
4065 12         29 if (/\G (\\\\) /oxgc) { $qq_string .= $1; }
4066 1786         4236 elsif (/\G (\\\") /oxgc) { $qq_string .= $1; }
4067             elsif (/\G \" /oxgc) { return e_qq('', '"','"',$qq_string); }
4068 34211         68828 elsif (/\G ($q_char) /oxgc) { $qq_string .= $1; }
4069             }
4070             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4071             }
4072              
4073 0         0 # ``
4074 1         3 elsif (/\G (\`) /oxgc) {
4075 1 50       4 my $qx_string = '';
  19 50       68  
    100          
    50          
4076 0         0 while (not /\G \z/oxgc) {
4077 0         0 if (/\G (\\\\) /oxgc) { $qx_string .= $1; }
4078 1         4 elsif (/\G (\\\`) /oxgc) { $qx_string .= $1; }
4079             elsif (/\G \` /oxgc) { return e_qq('', '`','`',$qx_string); }
4080 18         35 elsif (/\G ($q_char) /oxgc) { $qx_string .= $1; }
4081             }
4082             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4083             }
4084              
4085 0         0 # // --- not divide operator (num / num), not defined-or
4086 453         1172 elsif (($slash eq 'm//') and /\G (\/) /oxgc) {
4087 453 50       1333 my $regexp = '';
  4496 50       15400  
    100          
    50          
4088 0         0 while (not /\G \z/oxgc) {
4089 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4090 453         1321 elsif (/\G (\\\/) /oxgc) { $regexp .= $1; }
4091             elsif (/\G \/ ([cgimosxpadlunbB]*) /oxgc) { return e_qr('', '/','/',$regexp,$1); }
4092 4043         8405 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4093             }
4094             die __FILE__, ": Search pattern not terminated\n";
4095             }
4096              
4097 0         0 # ?? --- not conditional operator (condition ? then : else)
4098 0         0 elsif (($slash eq 'm//') and /\G (\?) /oxgc) {
4099 0 0       0 my $regexp = '';
  0 0       0  
    0          
    0          
4100 0         0 while (not /\G \z/oxgc) {
4101 0         0 if (/\G (\\\\) /oxgc) { $regexp .= $1; }
4102 0         0 elsif (/\G (\\\?) /oxgc) { $regexp .= $1; }
4103             elsif (/\G \? ([cgimosxpadlunbB]*) /oxgc) { return e_qr('m','?','?',$regexp,$1); }
4104 0         0 elsif (/\G ($q_char) /oxgc) { $regexp .= $1; }
4105             }
4106             die __FILE__, ": Search pattern not terminated\n";
4107             }
4108 0         0  
  0         0  
4109             # <<>> (a safer ARGV)
4110             elsif (/\G ( <<>> ) /oxgc) { $slash = 'm//'; return $1; }
4111 0         0  
  0         0  
4112             # << (bit shift) --- not here document
4113             elsif (/\G ( << (?>\s*) ) (?= [0-9\$\@\&] ) /oxgc) { $slash = 'm//'; return $1; }
4114              
4115 0         0 # <<~'HEREDOC'
4116 6         15 elsif (/\G ( <<~ [\t ]* '([a-zA-Z_0-9]*)' ) /oxgc) {
4117 6         14 $slash = 'm//';
4118             my $here_quote = $1;
4119             my $delimiter = $2;
4120 6 50       13  
4121 6         17 # get here document
4122 6         36 if ($here_script eq '') {
4123             $here_script = CORE::substr $_, pos $_;
4124 6 50       37 $here_script =~ s/.*?\n//oxm;
4125 6         78 }
4126 6         18 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4127 6         11 my $heredoc = $1;
4128 6         58 my $indent = $2;
4129 6         25 $heredoc =~ s{^$indent}{}msg; # no /ox
4130             push @heredoc, $heredoc . qq{\n$delimiter\n};
4131             push @heredoc_delimiter, qq{\\s*$delimiter};
4132 6         14 }
4133             else {
4134 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4135             }
4136             return qq{<<'$delimiter'};
4137             }
4138              
4139             # <<~\HEREDOC
4140              
4141             # P.66 2.6.6. "Here" Documents
4142             # in Chapter 2: Bits and Pieces
4143             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4144              
4145             # P.73 "Here" Documents
4146             # in Chapter 2: Bits and Pieces
4147             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4148 6         28  
4149 3         9 elsif (/\G ( <<~ \\([a-zA-Z_0-9]+) ) /oxgc) {
4150 3         9 $slash = 'm//';
4151             my $here_quote = $1;
4152             my $delimiter = $2;
4153 3 50       8  
4154 3         11 # get here document
4155 3         28 if ($here_script eq '') {
4156             $here_script = CORE::substr $_, pos $_;
4157 3 50       21 $here_script =~ s/.*?\n//oxm;
4158 3         56 }
4159 3         11 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4160 3         9 my $heredoc = $1;
4161 3         47 my $indent = $2;
4162 3         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4163             push @heredoc, $heredoc . qq{\n$delimiter\n};
4164             push @heredoc_delimiter, qq{\\s*$delimiter};
4165 3         9 }
4166             else {
4167 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4168             }
4169             return qq{<<\\$delimiter};
4170             }
4171              
4172 3         15 # <<~"HEREDOC"
4173 6         16 elsif (/\G ( <<~ [\t ]* "([a-zA-Z_0-9]*)" ) /oxgc) {
4174 6         14 $slash = 'm//';
4175             my $here_quote = $1;
4176             my $delimiter = $2;
4177 6 50       10  
4178 6         15 # get here document
4179 6         34 if ($here_script eq '') {
4180             $here_script = CORE::substr $_, pos $_;
4181 6 50       37 $here_script =~ s/.*?\n//oxm;
4182 6         75 }
4183 6         18 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4184 6         9 my $heredoc = $1;
4185 6         57 my $indent = $2;
4186 6         21 $heredoc =~ s{^$indent}{}msg; # no /ox
4187             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4188             push @heredoc_delimiter, qq{\\s*$delimiter};
4189 6         18 }
4190             else {
4191 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4192             }
4193             return qq{<<"$delimiter"};
4194             }
4195              
4196 6         27 # <<~HEREDOC
4197 3         8 elsif (/\G ( <<~ ([a-zA-Z_0-9]+) ) /oxgc) {
4198 3         8 $slash = 'm//';
4199             my $here_quote = $1;
4200             my $delimiter = $2;
4201 3 50       8  
4202 3         8 # get here document
4203 3         26 if ($here_script eq '') {
4204             $here_script = CORE::substr $_, pos $_;
4205 3 50       22 $here_script =~ s/.*?\n//oxm;
4206 3         53 }
4207 3         9 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4208 3         6 my $heredoc = $1;
4209 3         42 my $indent = $2;
4210 3         12 $heredoc =~ s{^$indent}{}msg; # no /ox
4211             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4212             push @heredoc_delimiter, qq{\\s*$delimiter};
4213 3         10 }
4214             else {
4215 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4216             }
4217             return qq{<<$delimiter};
4218             }
4219              
4220 3         16 # <<~`HEREDOC`
4221 6         29 elsif (/\G ( <<~ [\t ]* `([a-zA-Z_0-9]*)` ) /oxgc) {
4222 6         13 $slash = 'm//';
4223             my $here_quote = $1;
4224             my $delimiter = $2;
4225 6 50       28  
4226 6         17 # get here document
4227 6         16 if ($here_script eq '') {
4228             $here_script = CORE::substr $_, pos $_;
4229 6 50       53 $here_script =~ s/.*?\n//oxm;
4230 6         54 }
4231 6         14 if ($here_script =~ s/\A (.*?) \n ([\t ]*) $delimiter \n //xms) {
4232 6         7 my $heredoc = $1;
4233 6         48 my $indent = $2;
4234 6         17 $heredoc =~ s{^$indent}{}msg; # no /ox
4235             push @heredoc, e_heredoc($heredoc) . qq{\n$delimiter\n};
4236             push @heredoc_delimiter, qq{\\s*$delimiter};
4237 6         21 }
4238             else {
4239 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4240             }
4241             return qq{<<`$delimiter`};
4242             }
4243              
4244 6         26 # <<'HEREDOC'
4245 72         145 elsif (/\G ( << '([a-zA-Z_0-9]*)' ) /oxgc) {
4246 72         154 $slash = 'm//';
4247             my $here_quote = $1;
4248             my $delimiter = $2;
4249 72 50       118  
4250 72         155 # get here document
4251 72         432 if ($here_script eq '') {
4252             $here_script = CORE::substr $_, pos $_;
4253 72 50       403 $here_script =~ s/.*?\n//oxm;
4254 72         552 }
4255 72         243 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4256             push @heredoc, $1 . qq{\n$delimiter\n};
4257             push @heredoc_delimiter, $delimiter;
4258 72         115 }
4259             else {
4260 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4261             }
4262             return $here_quote;
4263             }
4264              
4265             # <<\HEREDOC
4266              
4267             # P.66 2.6.6. "Here" Documents
4268             # in Chapter 2: Bits and Pieces
4269             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4270              
4271             # P.73 "Here" Documents
4272             # in Chapter 2: Bits and Pieces
4273             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4274 72         270  
4275 0         0 elsif (/\G ( << \\([a-zA-Z_0-9]+) ) /oxgc) {
4276 0         0 $slash = 'm//';
4277             my $here_quote = $1;
4278             my $delimiter = $2;
4279 0 0       0  
4280 0         0 # get here document
4281 0         0 if ($here_script eq '') {
4282             $here_script = CORE::substr $_, pos $_;
4283 0 0       0 $here_script =~ s/.*?\n//oxm;
4284 0         0 }
4285 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4286             push @heredoc, $1 . qq{\n$delimiter\n};
4287             push @heredoc_delimiter, $delimiter;
4288 0         0 }
4289             else {
4290 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4291             }
4292             return $here_quote;
4293             }
4294              
4295 0         0 # <<"HEREDOC"
4296 36         84 elsif (/\G ( << "([a-zA-Z_0-9]*)" ) /oxgc) {
4297 36         84 $slash = 'm//';
4298             my $here_quote = $1;
4299             my $delimiter = $2;
4300 36 50       517  
4301 36         101 # get here document
4302 36         262 if ($here_script eq '') {
4303             $here_script = CORE::substr $_, pos $_;
4304 36 50       226 $here_script =~ s/.*?\n//oxm;
4305 36         861 }
4306 36         128 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4307             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4308             push @heredoc_delimiter, $delimiter;
4309 36         164 }
4310             else {
4311 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4312             }
4313             return $here_quote;
4314             }
4315              
4316 36         184 # <
4317 42         104 elsif (/\G ( << ([a-zA-Z_0-9]+) ) /oxgc) {
4318 42         96 $slash = 'm//';
4319             my $here_quote = $1;
4320             my $delimiter = $2;
4321 42 50       76  
4322 42         114 # get here document
4323 42         287 if ($here_script eq '') {
4324             $here_script = CORE::substr $_, pos $_;
4325 42 50       323 $here_script =~ s/.*?\n//oxm;
4326 42         663 }
4327 42         160 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4328             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4329             push @heredoc_delimiter, $delimiter;
4330 42         108 }
4331             else {
4332 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4333             }
4334             return $here_quote;
4335             }
4336              
4337 42         187 # <<`HEREDOC`
4338 0         0 elsif (/\G ( << `([a-zA-Z_0-9]*)` ) /oxgc) {
4339 0         0 $slash = 'm//';
4340             my $here_quote = $1;
4341             my $delimiter = $2;
4342 0 0       0  
4343 0         0 # get here document
4344 0         0 if ($here_script eq '') {
4345             $here_script = CORE::substr $_, pos $_;
4346 0 0       0 $here_script =~ s/.*?\n//oxm;
4347 0         0 }
4348 0         0 if ($here_script =~ s/\A (.*?) \n $delimiter \n //xms) {
4349             push @heredoc, e_heredoc($1) . qq{\n$delimiter\n};
4350             push @heredoc_delimiter, $delimiter;
4351 0         0 }
4352             else {
4353 0         0 die __FILE__, ": Can't find string terminator $delimiter anywhere before EOF\n";
4354             }
4355             return $here_quote;
4356             }
4357              
4358 0         0 # <<= <=> <= < operator
4359             elsif (/\G ( <<= | <=> | <= | < ) (?= (?>\s*) [A-Za-z_0-9'"`\$\@\&\*\(\+\-] )/oxgc) {
4360             return $1;
4361             }
4362              
4363 12         62 #
4364             elsif (/\G (<[\$]?[A-Za-z_][A-Za-z_0-9]*>) /oxgc) {
4365             return $1;
4366             }
4367              
4368             # --- glob
4369              
4370             # avoid "Error: Runtime exception" of perl version 5.005_03
4371 0         0  
4372             elsif (/\G < ((?:[^>\0\a\e\f\n\r\t])+?) > /oxgc) {
4373             return 'Ewindows1257::glob("' . $1 . '")';
4374             }
4375 0         0  
4376             # __DATA__
4377             elsif (/\G ^ ( __DATA__ \n .*) \z /oxmsgc) { return $1; }
4378 0         0  
4379             # __END__
4380             elsif (/\G ^ ( __END__ \n .*) \z /oxmsgc) { return $1; }
4381              
4382             # \cD Control-D
4383              
4384             # P.68 2.6.8. Other Literal Tokens
4385             # in Chapter 2: Bits and Pieces
4386             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4387              
4388             # P.76 Other Literal Tokens
4389             # in Chapter 2: Bits and Pieces
4390 204         1561 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4391              
4392             elsif (/\G ( \cD .*) \z /oxmsgc) { return $1; }
4393 0         0  
4394             # \cZ Control-Z
4395             elsif (/\G ( \cZ .*) \z /oxmsgc) { return $1; }
4396              
4397             # any operator before div
4398             elsif (/\G (
4399             -- | \+\+ |
4400 0         0 [\)\}\]]
  5083         10395  
4401              
4402             ) /oxgc) { $slash = 'div'; return $1; }
4403              
4404             # yada-yada or triple-dot operator
4405             elsif (/\G (
4406 5083         23576 \.\.\.
  7         13  
4407              
4408             ) /oxgc) { $slash = 'm//'; return q{die('Unimplemented')}; }
4409              
4410             # any operator before m//
4411              
4412             # //, //= (defined-or)
4413              
4414             # P.164 Logical Operators
4415             # in Chapter 10: More Control Structures
4416             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4417              
4418             # P.119 C-Style Logical (Short-Circuit) Operators
4419             # in Chapter 3: Unary and Binary Operators
4420             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4421              
4422             # (and so on)
4423              
4424             # ~~
4425              
4426             # P.221 The Smart Match Operator
4427             # in Chapter 15: Smart Matching and given-when
4428             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
4429              
4430             # P.112 Smartmatch Operator
4431             # in Chapter 3: Unary and Binary Operators
4432             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4433              
4434             # (and so on)
4435              
4436             elsif (/\G ((?>
4437              
4438             !~~ | !~ | != | ! |
4439             %= | % |
4440             &&= | && | &= | &\.= | &\. | & |
4441             -= | -> | - |
4442             :(?>\s*)= |
4443             : |
4444             <<>> |
4445             <<= | <=> | <= | < |
4446             == | => | =~ | = |
4447             >>= | >> | >= | > |
4448             \*\*= | \*\* | \*= | \* |
4449             \+= | \+ |
4450             \.\. | \.= | \. |
4451             \/\/= | \/\/ |
4452             \/= | \/ |
4453             \? |
4454             \\ |
4455             \^= | \^\.= | \^\. | \^ |
4456             \b x= |
4457             \|\|= | \|\| | \|= | \|\.= | \|\. | \| |
4458             ~~ | ~\. | ~ |
4459             \b(?: and | cmp | eq | ge | gt | le | lt | ne | not | or | xor | x )\b |
4460             \b(?: print )\b |
4461              
4462 7         24 [,;\(\{\[]
  8847         17181  
4463              
4464             )) /oxgc) { $slash = 'm//'; return $1; }
4465 8847         38734  
  15785         29325  
4466             # other any character
4467             elsif (/\G ($q_char) /oxgc) { $slash = 'div'; return $1; }
4468              
4469 15785         69909 # system error
4470             else {
4471             die __FILE__, ": Oops, this shouldn't happen!\n";
4472             }
4473             }
4474              
4475 0     1788 0 0 # escape Windows-1257 string
4476 1788         4145 sub e_string {
4477             my($string) = @_;
4478 1788         2547 my $e_string = '';
4479              
4480             local $slash = 'm//';
4481              
4482             # P.1024 Appendix W.10 Multibyte Processing
4483             # of ISBN 1-56592-224-7 CJKV Information Processing
4484 1788         2667 # (and so on)
4485              
4486             my @char = $string =~ / \G (?>[^\\]|\\$q_char|$q_char) /oxmsg;
4487 1788 100 66     13583  
4488 1788 50       7723 # without { ... }
4489 1769         3924 if (not (grep(/\A \{ \z/xms, @char) and grep(/\A \} \z/xms, @char))) {
4490             if ($string !~ /<
4491             return $string;
4492             }
4493             }
4494 1769         4379  
4495 19 50       65 E_STRING_LOOP:
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
4496             while ($string !~ /\G \z/oxgc) {
4497             if (0) {
4498             }
4499 223         3763  
4500 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> @{[Ewindows1257::PREMATCH()]}
4501 0         0 elsif ($string =~ /\G ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH \b | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) /oxmsgc) {
4502             $e_string .= q{Ewindows1257::PREMATCH()};
4503             $slash = 'div';
4504             }
4505              
4506 0         0 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> @{[Ewindows1257::MATCH()]}
4507 0         0 elsif ($string =~ /\G ( \$& | \$\{&\} | \$ (?>\s*) MATCH \b | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) /oxmsgc) {
4508             $e_string .= q{Ewindows1257::MATCH()};
4509             $slash = 'div';
4510             }
4511              
4512 0         0 # $', ${'} --> $', ${'}
4513 0         0 elsif ($string =~ /\G ( \$' | \$\{'\} ) /oxmsgc) {
4514             $e_string .= $1;
4515             $slash = 'div';
4516             }
4517              
4518 0         0 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> @{[Ewindows1257::POSTMATCH()]}
4519 0         0 elsif ($string =~ /\G ( \$ (?>\s*) POSTMATCH \b | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) /oxmsgc) {
4520             $e_string .= q{Ewindows1257::POSTMATCH()};
4521             $slash = 'div';
4522             }
4523              
4524 0         0 # bareword
4525 0         0 elsif ($string =~ /\G ( \{ (?>\s*) (?: tr | index | rindex | reverse ) (?>\s*) \} ) /oxmsgc) {
4526             $e_string .= $1;
4527             $slash = 'div';
4528             }
4529              
4530 0         0 # $0 --> $0
4531 0         0 elsif ($string =~ /\G ( \$ 0 ) /oxmsgc) {
4532             $e_string .= $1;
4533             $slash = 'div';
4534 0         0 }
4535 0         0 elsif ($string =~ /\G ( \$ \{ (?>\s*) 0 (?>\s*) \} ) /oxmsgc) {
4536             $e_string .= $1;
4537             $slash = 'div';
4538             }
4539              
4540 0         0 # $$ --> $$
4541 0         0 elsif ($string =~ /\G ( \$ \$ ) (?![\w\{]) /oxmsgc) {
4542             $e_string .= $1;
4543             $slash = 'div';
4544             }
4545              
4546             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4547 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4548 0         0 elsif ($string =~ /\G \$ ((?>[1-9][0-9]*)) /oxmsgc) {
4549             $e_string .= e_capture($1);
4550             $slash = 'div';
4551 0         0 }
4552 0         0 elsif ($string =~ /\G \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} /oxmsgc) {
4553             $e_string .= e_capture($1);
4554             $slash = 'div';
4555             }
4556              
4557 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4558 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ .+? \] ) /oxmsgc) {
4559             $e_string .= e_capture($1.'->'.$2);
4560             $slash = 'div';
4561             }
4562              
4563 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4564 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ .+? \} ) /oxmsgc) {
4565             $e_string .= e_capture($1.'->'.$2);
4566             $slash = 'div';
4567             }
4568              
4569 0         0 # $$foo
4570 0         0 elsif ($string =~ /\G \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) /oxmsgc) {
4571             $e_string .= e_capture($1);
4572             $slash = 'div';
4573             }
4574              
4575 0         0 # ${ foo }
4576 0         0 elsif ($string =~ /\G \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} /oxmsgc) {
4577             $e_string .= '${' . $1 . '}';
4578             $slash = 'div';
4579             }
4580              
4581 0         0 # ${ ... }
4582 3         10 elsif ($string =~ /\G \$ (?>\s*) \{ (?>\s*) ( $qq_brace ) (?>\s*) \} /oxmsgc) {
4583             $e_string .= e_capture($1);
4584             $slash = 'div';
4585             }
4586              
4587             # variable or function
4588 3         15 # $ @ % & * $ #
4589 7         36 elsif ($string =~ /\G ( (?: [\$\@\%\&\*] | \$\# | -> | \b sub \b) (?>\s*) (?: split | chop | index | rindex | lc | uc | fc | chr | ord | reverse | getc | tr | y | q | qq | qx | qw | m | s | qr | glob | lstat | opendir | stat | unlink | chdir ) ) \b /oxmsgc) {
4590             $e_string .= $1;
4591             $slash = 'div';
4592             }
4593             # $ $ $ $ $ $ $ $ $ $ $ $ $ $
4594 7         28 # $ @ # \ ' " / ? ( ) [ ] < >
4595 0         0 elsif ($string =~ /\G ( \$[\$\@\#\\\'\"\/\?\(\)\[\]\<\>] ) /oxmsgc) {
4596             $e_string .= $1;
4597             $slash = 'div';
4598             }
4599              
4600 0         0 # qq//
4601 0 0       0 elsif ($string =~ /\G \b (qq) \b /oxgc) {
4602 0         0 my $ope = $1;
4603             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qq# #
4604             $e_string .= e_qq($ope,$1,$3,$2);
4605 0         0 }
4606 0         0 else {
4607 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4608 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4609 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4610 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq ( )
  0         0  
4611 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq { }
  0         0  
4612 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq [ ]
  0         0  
4613             elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq < >
4614 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qq * *
4615             }
4616             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4617             }
4618             }
4619              
4620 0         0 # qx//
4621 0 0       0 elsif ($string =~ /\G \b (qx) \b /oxgc) {
4622 0         0 my $ope = $1;
4623             if ($string =~ /\G (\#) ((?:$qq_char)*?) (\#) /oxgc) { # qx# #
4624             $e_string .= e_qq($ope,$1,$3,$2);
4625 0         0 }
4626 0         0 else {
4627 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
    0          
4628 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4629 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4630 0         0 elsif ($string =~ /\G (\() ((?:$qq_paren)*?) (\)) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ( )
  0         0  
4631 0         0 elsif ($string =~ /\G (\{) ((?:$qq_brace)*?) (\}) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx { }
  0         0  
4632 0         0 elsif ($string =~ /\G (\[) ((?:$qq_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx [ ]
  0         0  
4633 0         0 elsif ($string =~ /\G (\<) ((?:$qq_angle)*?) (\>) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx < >
  0         0  
4634             elsif ($string =~ /\G (\') ((?:$qq_char)*?) (\') /oxgc) { $e_string .= $e . e_q ($ope,$1,$3,$2); next E_STRING_LOOP; } # qx ' '
4635 0         0 elsif ($string =~ /\G (\S) ((?:$qq_char)*?) (\1) /oxgc) { $e_string .= $e . e_qq($ope,$1,$3,$2); next E_STRING_LOOP; } # qx * *
4636             }
4637             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4638             }
4639             }
4640              
4641 0         0 # q//
4642 0 0       0 elsif ($string =~ /\G \b (q) \b /oxgc) {
4643 0         0 my $ope = $1;
4644             if ($string =~ /\G (\#) ((?:\\\#|\\\\|$q_char)*?) (\#) /oxgc) { # q# #
4645             $e_string .= e_q($ope,$1,$3,$2);
4646 0         0 }
4647 0         0 else {
4648 0 0       0 my $e = '';
  0 0       0  
    0          
    0          
    0          
    0          
4649 0         0 while ($string !~ /\G \z/oxgc) {
  0         0  
4650 0         0 if ($string =~ /\G ((?>\s+)|\#.*) /oxgc) { $e .= $1; }
  0         0  
4651 0         0 elsif ($string =~ /\G (\() ((?:\\\\|\\\)|\\\(|$q_paren)*?) (\)) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q ( )
  0         0  
4652 0         0 elsif ($string =~ /\G (\{) ((?:\\\\|\\\}|\\\{|$q_brace)*?) (\}) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q { }
  0         0  
4653 0         0 elsif ($string =~ /\G (\[) ((?:\\\\|\\\]|\\\[|$q_bracket)*?) (\]) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q [ ]
  0         0  
4654             elsif ($string =~ /\G (\<) ((?:\\\\|\\\>|\\\<|$q_angle)*?) (\>) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q < >
4655 0         0 elsif ($string =~ /\G (\S) ((?:\\\\|\\\1| $q_char)*?) (\1) /oxgc) { $e_string .= $e . e_q($ope,$1,$3,$2); next E_STRING_LOOP; } # q * *
4656             }
4657             die __FILE__, ": Can't find string terminator anywhere before EOF\n";
4658             }
4659             }
4660 0         0  
4661             # ''
4662             elsif ($string =~ /\G (?
4663 0         0  
4664             # ""
4665             elsif ($string =~ /\G (\") ((?:$qq_char)*?) (\") /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4666 0         0  
4667             # ``
4668             elsif ($string =~ /\G (\`) ((?:$qq_char)*?) (\`) /oxgc) { $e_string .= e_qq('',$1,$3,$2); }
4669 0         0  
4670             # other any character
4671             elsif ($string =~ /\G ($q_char) /oxgc) { $e_string .= $1; }
4672              
4673 213         521 # system error
4674             else {
4675             die __FILE__, ": Oops, this shouldn't happen!\n";
4676             }
4677 0         0 }
4678              
4679             return $e_string;
4680             }
4681              
4682             #
4683             # character class
4684 19     1919 0 78 #
4685             sub character_class {
4686 1919 100       3532 my($char,$modifier) = @_;
4687 1919 100       3167  
4688 52         109 if ($char eq '.') {
4689             if ($modifier =~ /s/) {
4690             return '${Ewindows1257::dot_s}';
4691 17         38 }
4692             else {
4693             return '${Ewindows1257::dot}';
4694             }
4695 35         83 }
4696             else {
4697             return Ewindows1257::classic_character_class($char);
4698             }
4699             }
4700              
4701             #
4702             # escape capture ($1, $2, $3, ...)
4703             #
4704 1867     212 0 3330 sub e_capture {
4705              
4706             return join '', '${', $_[0], '}';
4707             }
4708              
4709             #
4710             # escape transliteration (tr/// or y///)
4711 212     3 0 766 #
4712 3         15 sub e_tr {
4713 3   50     6 my($variable,$charclass,$e,$charclass2,$modifier) = @_;
4714             my $e_tr = '';
4715 3         9 $modifier ||= '';
4716              
4717             $slash = 'div';
4718 3         6  
4719             # quote character class 1
4720             $charclass = q_tr($charclass);
4721 3         8  
4722             # quote character class 2
4723             $charclass2 = q_tr($charclass2);
4724 3 50       7  
4725 3 0       10 # /b /B modifier
4726 0         0 if ($modifier =~ tr/bB//d) {
4727             if ($variable eq '') {
4728             $e_tr = qq{tr$charclass$e$charclass2$modifier};
4729 0         0 }
4730             else {
4731             $e_tr = qq{$variable${bind_operator}tr$charclass$e$charclass2$modifier};
4732             }
4733 0 100       0 }
4734 3         7 else {
4735             if ($variable eq '') {
4736             $e_tr = qq{Ewindows1257::tr(\$_,' =~ ',$charclass,$e$charclass2,'$modifier')};
4737 2         9 }
4738             else {
4739             $e_tr = qq{Ewindows1257::tr($variable,'$bind_operator',$charclass,$e$charclass2,'$modifier')};
4740             }
4741             }
4742 1         6  
4743 3         6 # clear tr/// variable
4744             $tr_variable = '';
4745 3         3 $bind_operator = '';
4746              
4747             return $e_tr;
4748             }
4749              
4750             #
4751             # quote for escape transliteration (tr/// or y///)
4752 3     6 0 17 #
4753             sub q_tr {
4754             my($charclass) = @_;
4755 6 50       11  
    0          
    0          
    0          
    0          
    0          
4756 6         15 # quote character class
4757             if ($charclass !~ /'/oxms) {
4758             return e_q('', "'", "'", $charclass); # --> q' '
4759 6         9 }
4760             elsif ($charclass !~ /\//oxms) {
4761             return e_q('q', '/', '/', $charclass); # --> q/ /
4762 0         0 }
4763             elsif ($charclass !~ /\#/oxms) {
4764             return e_q('q', '#', '#', $charclass); # --> q# #
4765 0         0 }
4766             elsif ($charclass !~ /[\<\>]/oxms) {
4767             return e_q('q', '<', '>', $charclass); # --> q< >
4768 0         0 }
4769             elsif ($charclass !~ /[\(\)]/oxms) {
4770             return e_q('q', '(', ')', $charclass); # --> q( )
4771 0         0 }
4772             elsif ($charclass !~ /[\{\}]/oxms) {
4773             return e_q('q', '{', '}', $charclass); # --> q{ }
4774 0         0 }
4775 0 0       0 else {
4776 0         0 for my $char (qw( ! " $ % & * + . : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
4777             if ($charclass !~ /\Q$char\E/xms) {
4778             return e_q('q', $char, $char, $charclass);
4779             }
4780             }
4781 0         0 }
4782              
4783             return e_q('q', '{', '}', $charclass);
4784             }
4785              
4786             #
4787             # escape q string (q//, '')
4788 0     1264 0 0 #
4789             sub e_q {
4790 1264         2990 my($ope,$delimiter,$end_delimiter,$string) = @_;
4791              
4792 1264         2175 $slash = 'div';
4793              
4794             return join '', $ope, $delimiter, $string, $end_delimiter;
4795             }
4796              
4797             #
4798             # escape qq string (qq//, "", qx//, ``)
4799 1264     4048 0 6229 #
4800             sub e_qq {
4801 4048         9107 my($ope,$delimiter,$end_delimiter,$string) = @_;
4802              
4803 4048         5502 $slash = 'div';
4804 4048         4911  
4805             my $left_e = 0;
4806             my $right_e = 0;
4807 4048         4676  
4808             # split regexp
4809             my @char = $string =~ /\G((?>
4810             [^\\\$] |
4811             \\x\{ (?>[0-9A-Fa-f]+) \} |
4812             \\o\{ (?>[0-7]+) \} |
4813             \\N\{ (?>[^0-9\}][^\}]*) \} |
4814             \\ $q_char |
4815             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
4816             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
4817             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
4818             \$ (?>\s* [0-9]+) |
4819             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
4820             \$ \$ (?![\w\{]) |
4821             \$ (?>\s*) \$ (?>\s*) $qq_variable |
4822             $q_char
4823 4048         134784 ))/oxmsg;
4824              
4825             for (my $i=0; $i <= $#char; $i++) {
4826 4048 50 33     12643  
    50 33        
    100          
    100          
    50          
4827 114829         364298 # "\L\u" --> "\u\L"
4828             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
4829             @char[$i,$i+1] = @char[$i+1,$i];
4830             }
4831              
4832 0         0 # "\U\l" --> "\l\U"
4833             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
4834             @char[$i,$i+1] = @char[$i+1,$i];
4835             }
4836              
4837 0         0 # octal escape sequence
4838             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
4839             $char[$i] = Ewindows1257::octchr($1);
4840             }
4841              
4842 1         5 # hexadecimal escape sequence
4843             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
4844             $char[$i] = Ewindows1257::hexchr($1);
4845             }
4846              
4847 1         4 # \N{CHARNAME} --> N{CHARNAME}
4848             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
4849             $char[$i] = $1;
4850 0 100       0 }
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
4851              
4852             if (0) {
4853             }
4854              
4855             # \F
4856             #
4857             # P.69 Table 2-6. Translation escapes
4858             # in Chapter 2: Bits and Pieces
4859             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4860             # (and so on)
4861 114829         905675  
4862 0 50       0 # \u \l \U \L \F \Q \E
4863 484         1062 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
4864             if ($right_e < $left_e) {
4865             $char[$i] = '\\' . $char[$i];
4866             }
4867             }
4868             elsif ($char[$i] eq '\u') {
4869              
4870             # "STRING @{[ LIST EXPR ]} MORE STRING"
4871              
4872             # P.257 Other Tricks You Can Do with Hard References
4873             # in Chapter 8: References
4874             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
4875              
4876             # P.353 Other Tricks You Can Do with Hard References
4877             # in Chapter 8: References
4878             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
4879              
4880 0         0 # (and so on)
4881 0         0  
4882             $char[$i] = '@{[Ewindows1257::ucfirst qq<';
4883             $left_e++;
4884 0         0 }
4885 0         0 elsif ($char[$i] eq '\l') {
4886             $char[$i] = '@{[Ewindows1257::lcfirst qq<';
4887             $left_e++;
4888 0         0 }
4889 0         0 elsif ($char[$i] eq '\U') {
4890             $char[$i] = '@{[Ewindows1257::uc qq<';
4891             $left_e++;
4892 0         0 }
4893 0         0 elsif ($char[$i] eq '\L') {
4894             $char[$i] = '@{[Ewindows1257::lc qq<';
4895             $left_e++;
4896 0         0 }
4897 24         28 elsif ($char[$i] eq '\F') {
4898             $char[$i] = '@{[Ewindows1257::fc qq<';
4899             $left_e++;
4900 24         42 }
4901 0         0 elsif ($char[$i] eq '\Q') {
4902             $char[$i] = '@{[CORE::quotemeta qq<';
4903             $left_e++;
4904 0 50       0 }
4905 24         37 elsif ($char[$i] eq '\E') {
4906 24         33 if ($right_e < $left_e) {
4907             $char[$i] = '>]}';
4908             $right_e++;
4909 24         55 }
4910             else {
4911             $char[$i] = '';
4912             }
4913 0         0 }
4914 0 0       0 elsif ($char[$i] eq '\Q') {
4915 0         0 while (1) {
4916             if (++$i > $#char) {
4917 0 0       0 last;
4918 0         0 }
4919             if ($char[$i] eq '\E') {
4920             last;
4921             }
4922             }
4923             }
4924             elsif ($char[$i] eq '\E') {
4925             }
4926              
4927             # $0 --> $0
4928             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
4929             }
4930             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
4931             }
4932              
4933             # $$ --> $$
4934             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
4935             }
4936              
4937             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
4938 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
4939             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
4940             $char[$i] = e_capture($1);
4941 205         398 }
4942             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
4943             $char[$i] = e_capture($1);
4944             }
4945              
4946 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
4947             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
4948             $char[$i] = e_capture($1.'->'.$2);
4949             }
4950              
4951 0         0 # $$foo{ ... } --> $ $foo->{ ... }
4952             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
4953             $char[$i] = e_capture($1.'->'.$2);
4954             }
4955              
4956 0         0 # $$foo
4957             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
4958             $char[$i] = e_capture($1);
4959             }
4960              
4961 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
4962             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
4963             $char[$i] = '@{[Ewindows1257::PREMATCH()]}';
4964             }
4965              
4966 44         112 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
4967             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
4968             $char[$i] = '@{[Ewindows1257::MATCH()]}';
4969             }
4970              
4971 45         143 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
4972             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
4973             $char[$i] = '@{[Ewindows1257::POSTMATCH()]}';
4974             }
4975              
4976             # ${ foo } --> ${ foo }
4977             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
4978             }
4979              
4980 33         90 # ${ ... }
4981             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
4982             $char[$i] = e_capture($1);
4983             }
4984             }
4985 0 50       0  
4986 4048         7876 # return string
4987             if ($left_e > $right_e) {
4988 0         0 return join '', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter;
4989             }
4990             return join '', $ope, $delimiter, @char, $end_delimiter;
4991             }
4992              
4993             #
4994             # escape qw string (qw//)
4995 4048     16 0 32563 #
4996             sub e_qw {
4997 16         133 my($ope,$delimiter,$end_delimiter,$string) = @_;
4998              
4999             $slash = 'div';
5000 16         39  
  16         244  
5001 483 50       778 # choice again delimiter
    0          
    0          
    0          
    0          
5002 16         103 my %octet = map {$_ => 1} ($string =~ /\G ([\x00-\xFF]) /oxmsg);
5003             if (not $octet{$end_delimiter}) {
5004             return join '', $ope, $delimiter, $string, $end_delimiter;
5005 16         144 }
5006             elsif (not $octet{')'}) {
5007             return join '', $ope, '(', $string, ')';
5008 0         0 }
5009             elsif (not $octet{'}'}) {
5010             return join '', $ope, '{', $string, '}';
5011 0         0 }
5012             elsif (not $octet{']'}) {
5013             return join '', $ope, '[', $string, ']';
5014 0         0 }
5015             elsif (not $octet{'>'}) {
5016             return join '', $ope, '<', $string, '>';
5017 0         0 }
5018 0 0       0 else {
5019 0         0 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5020             if (not $octet{$char}) {
5021             return join '', $ope, $char, $string, $char;
5022             }
5023             }
5024             }
5025 0         0  
5026 0         0 # qw/AAA BBB C'CC/ --> ('AAA', 'BBB', 'C\'CC')
5027 0         0 my @string = CORE::split(/\s+/, $string);
5028 0         0 for my $string (@string) {
5029 0 0       0 my @octet = $string =~ /\G ([\x00-\xFF]) /oxmsg;
5030 0         0 for my $octet (@octet) {
5031             if ($octet =~ /\A (['\\]) \z/oxms) {
5032             $octet = '\\' . $1;
5033 0         0 }
5034             }
5035 0         0 $string = join '', @octet;
  0         0  
5036             }
5037             return join '', '(', (join ', ', map { "'$_'" } @string), ')';
5038             }
5039              
5040             #
5041             # escape here document (<<"HEREDOC", <
5042 0     93 0 0 #
5043             sub e_heredoc {
5044 93         257 my($string) = @_;
5045              
5046 93         159 $slash = 'm//';
5047              
5048 93         287 my $metachar = qr/[\@\\|]/oxms; # '|' is for <<`HEREDOC`
5049 93         147  
5050             my $left_e = 0;
5051             my $right_e = 0;
5052 93         136  
5053             # split regexp
5054             my @char = $string =~ /\G((?>
5055             [^\\\$] |
5056             \\x\{ (?>[0-9A-Fa-f]+) \} |
5057             \\o\{ (?>[0-7]+) \} |
5058             \\N\{ (?>[^0-9\}][^\}]*) \} |
5059             \\ $q_char |
5060             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5061             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5062             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5063             \$ (?>\s* [0-9]+) |
5064             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5065             \$ \$ (?![\w\{]) |
5066             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5067             $q_char
5068 93         8476 ))/oxmsg;
5069              
5070             for (my $i=0; $i <= $#char; $i++) {
5071 93 50 33     428  
    50 33        
    100          
    100          
    50          
5072 3307         9940 # "\L\u" --> "\u\L"
5073             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5074             @char[$i,$i+1] = @char[$i+1,$i];
5075             }
5076              
5077 0         0 # "\U\l" --> "\l\U"
5078             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5079             @char[$i,$i+1] = @char[$i+1,$i];
5080             }
5081              
5082 0         0 # octal escape sequence
5083             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5084             $char[$i] = Ewindows1257::octchr($1);
5085             }
5086              
5087 1         4 # hexadecimal escape sequence
5088             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5089             $char[$i] = Ewindows1257::hexchr($1);
5090             }
5091              
5092 1         3 # \N{CHARNAME} --> N{CHARNAME}
5093             elsif ($char[$i] =~ /\A \\ ( N\{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5094             $char[$i] = $1;
5095 0 50       0 }
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
5096              
5097             if (0) {
5098             }
5099 3307         26020  
5100 0 0       0 # \u \l \U \L \F \Q \E
5101 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
5102             if ($right_e < $left_e) {
5103             $char[$i] = '\\' . $char[$i];
5104             }
5105 0         0 }
5106 0         0 elsif ($char[$i] eq '\u') {
5107             $char[$i] = '@{[Ewindows1257::ucfirst qq<';
5108             $left_e++;
5109 0         0 }
5110 0         0 elsif ($char[$i] eq '\l') {
5111             $char[$i] = '@{[Ewindows1257::lcfirst qq<';
5112             $left_e++;
5113 0         0 }
5114 0         0 elsif ($char[$i] eq '\U') {
5115             $char[$i] = '@{[Ewindows1257::uc qq<';
5116             $left_e++;
5117 0         0 }
5118 0         0 elsif ($char[$i] eq '\L') {
5119             $char[$i] = '@{[Ewindows1257::lc qq<';
5120             $left_e++;
5121 0         0 }
5122 0         0 elsif ($char[$i] eq '\F') {
5123             $char[$i] = '@{[Ewindows1257::fc qq<';
5124             $left_e++;
5125 0         0 }
5126 0         0 elsif ($char[$i] eq '\Q') {
5127             $char[$i] = '@{[CORE::quotemeta qq<';
5128             $left_e++;
5129 0 0       0 }
5130 0         0 elsif ($char[$i] eq '\E') {
5131 0         0 if ($right_e < $left_e) {
5132             $char[$i] = '>]}';
5133             $right_e++;
5134 0         0 }
5135             else {
5136             $char[$i] = '';
5137             }
5138 0         0 }
5139 0 0       0 elsif ($char[$i] eq '\Q') {
5140 0         0 while (1) {
5141             if (++$i > $#char) {
5142 0 0       0 last;
5143 0         0 }
5144             if ($char[$i] eq '\E') {
5145             last;
5146             }
5147             }
5148             }
5149             elsif ($char[$i] eq '\E') {
5150             }
5151              
5152             # $0 --> $0
5153             elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5154             }
5155             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5156             }
5157              
5158             # $$ --> $$
5159             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5160             }
5161              
5162             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5163 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5164             elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5165             $char[$i] = e_capture($1);
5166 0         0 }
5167             elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5168             $char[$i] = e_capture($1);
5169             }
5170              
5171 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5172             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5173             $char[$i] = e_capture($1.'->'.$2);
5174             }
5175              
5176 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5177             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5178             $char[$i] = e_capture($1.'->'.$2);
5179             }
5180              
5181 0         0 # $$foo
5182             elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5183             $char[$i] = e_capture($1);
5184             }
5185              
5186 0         0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
5187             elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5188             $char[$i] = '@{[Ewindows1257::PREMATCH()]}';
5189             }
5190              
5191 8         46 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
5192             elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5193             $char[$i] = '@{[Ewindows1257::MATCH()]}';
5194             }
5195              
5196 8         66 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
5197             elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5198             $char[$i] = '@{[Ewindows1257::POSTMATCH()]}';
5199             }
5200              
5201             # ${ foo } --> ${ foo }
5202             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ (?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* ) \} \z/oxms) {
5203             }
5204              
5205 6         34 # ${ ... }
5206             elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5207             $char[$i] = e_capture($1);
5208             }
5209             }
5210 0 50       0  
5211 93         204 # return string
5212             if ($left_e > $right_e) {
5213 0         0 return join '', @char, '>]}' x ($left_e - $right_e);
5214             }
5215             return join '', @char;
5216             }
5217              
5218             #
5219             # escape regexp (m//, qr//)
5220 93     652 0 717 #
5221 652   100     2778 sub e_qr {
5222             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5223 652         2675 $modifier ||= '';
5224 652 50       1240  
5225 652         1531 $modifier =~ tr/p//d;
5226 0         0 if ($modifier =~ /([adlu])/oxms) {
5227 0 0       0 my $line = 0;
5228 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5229 0         0 if ($filename ne __FILE__) {
5230             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5231             last;
5232 0         0 }
5233             }
5234             die qq{Unsupported modifier "$1" used at line $line.\n};
5235 0         0 }
5236              
5237             $slash = 'div';
5238 652 100       1087  
    100          
5239 652         2038 # literal null string pattern
5240 8         8 if ($string eq '') {
5241 8         10 $modifier =~ tr/bB//d;
5242             $modifier =~ tr/i//d;
5243             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5244             }
5245              
5246             # /b /B modifier
5247             elsif ($modifier =~ tr/bB//d) {
5248 8 50       51  
5249 2         8 # choice again delimiter
5250 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5251 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5252 0         0 my %octet = map {$_ => 1} @char;
5253 0         0 if (not $octet{')'}) {
5254             $delimiter = '(';
5255             $end_delimiter = ')';
5256 0         0 }
5257 0         0 elsif (not $octet{'}'}) {
5258             $delimiter = '{';
5259             $end_delimiter = '}';
5260 0         0 }
5261 0         0 elsif (not $octet{']'}) {
5262             $delimiter = '[';
5263             $end_delimiter = ']';
5264 0         0 }
5265 0         0 elsif (not $octet{'>'}) {
5266             $delimiter = '<';
5267             $end_delimiter = '>';
5268 0         0 }
5269 0 0       0 else {
5270 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5271 0         0 if (not $octet{$char}) {
5272 0         0 $delimiter = $char;
5273             $end_delimiter = $char;
5274             last;
5275             }
5276             }
5277             }
5278 0 50 33     0 }
5279 2         13  
5280             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5281             return join '', $ope, $delimiter, $string, $matched, $end_delimiter, $modifier;
5282 0         0 }
5283             else {
5284             return join '', $ope, $delimiter, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5285             }
5286 2 100       10 }
5287 642         1548  
5288             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5289             my $metachar = qr/[\@\\|[\]{^]/oxms;
5290 642         2390  
5291             # split regexp
5292             my @char = $string =~ /\G((?>
5293             [^\\\$\@\[\(] |
5294             \\x (?>[0-9A-Fa-f]{1,2}) |
5295             \\ (?>[0-7]{2,3}) |
5296             \\c [\x40-\x5F] |
5297             \\x\{ (?>[0-9A-Fa-f]+) \} |
5298             \\o\{ (?>[0-7]+) \} |
5299             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5300             \\ $q_char |
5301             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5302             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5303             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5304             [\$\@] $qq_variable |
5305             \$ (?>\s* [0-9]+) |
5306             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5307             \$ \$ (?![\w\{]) |
5308             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5309             \[\^ |
5310             \[\: (?>[a-z]+) :\] |
5311             \[\:\^ (?>[a-z]+) :\] |
5312             \(\? |
5313             $q_char
5314             ))/oxmsg;
5315 642 50       66320  
5316 642         2957 # choice again delimiter
  0         0  
5317 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5318 0         0 my %octet = map {$_ => 1} @char;
5319 0         0 if (not $octet{')'}) {
5320             $delimiter = '(';
5321             $end_delimiter = ')';
5322 0         0 }
5323 0         0 elsif (not $octet{'}'}) {
5324             $delimiter = '{';
5325             $end_delimiter = '}';
5326 0         0 }
5327 0         0 elsif (not $octet{']'}) {
5328             $delimiter = '[';
5329             $end_delimiter = ']';
5330 0         0 }
5331 0         0 elsif (not $octet{'>'}) {
5332             $delimiter = '<';
5333             $end_delimiter = '>';
5334 0         0 }
5335 0 0       0 else {
5336 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5337 0         0 if (not $octet{$char}) {
5338 0         0 $delimiter = $char;
5339             $end_delimiter = $char;
5340             last;
5341             }
5342             }
5343             }
5344 0         0 }
5345 642         1065  
5346 642         929 my $left_e = 0;
5347             my $right_e = 0;
5348             for (my $i=0; $i <= $#char; $i++) {
5349 642 50 66     1703  
    50 66        
    100          
    100          
    100          
    100          
5350 1872         9840 # "\L\u" --> "\u\L"
5351             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
5352             @char[$i,$i+1] = @char[$i+1,$i];
5353             }
5354              
5355 0         0 # "\U\l" --> "\l\U"
5356             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
5357             @char[$i,$i+1] = @char[$i+1,$i];
5358             }
5359              
5360 0         0 # octal escape sequence
5361             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
5362             $char[$i] = Ewindows1257::octchr($1);
5363             }
5364              
5365 1         4 # hexadecimal escape sequence
5366             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
5367             $char[$i] = Ewindows1257::hexchr($1);
5368             }
5369              
5370             # \b{...} --> b\{...}
5371             # \B{...} --> B\{...}
5372             # \N{CHARNAME} --> N\{CHARNAME}
5373             # \p{PROPERTY} --> p\{PROPERTY}
5374 1         4 # \P{PROPERTY} --> P\{PROPERTY}
5375             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
5376             $char[$i] = $1 . '\\' . $2;
5377             }
5378              
5379 6         18 # \p, \P, \X --> p, P, X
5380             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
5381             $char[$i] = $1;
5382 4 100 100     12 }
    100 100        
    100 100        
    100          
    100          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
5383              
5384             if (0) {
5385             }
5386 1872         5594  
5387 0 50 33     0 # join separated multiple-octet
    50 33        
    50 33        
      33        
      66        
      33        
5388 6         114 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
5389             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
5390             $char[$i] .= join '', splice @char, $i+1, 3;
5391 0         0 }
5392             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
5393             $char[$i] .= join '', splice @char, $i+1, 2;
5394 0         0 }
5395             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
5396             $char[$i] .= join '', splice @char, $i+1, 1;
5397             }
5398             }
5399              
5400 0         0 # open character class [...]
5401             elsif ($char[$i] eq '[') {
5402             my $left = $i;
5403              
5404             # [] make die "Unmatched [] in regexp ...\n"
5405 328 100       474 # (and so on)
5406 328         804  
5407             if ($char[$i+1] eq ']') {
5408             $i++;
5409 3         6 }
5410 328 50       414  
5411 1379         2129 while (1) {
5412             if (++$i > $#char) {
5413 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5414 1379         2334 }
5415             if ($char[$i] eq ']') {
5416             my $right = $i;
5417 328 100       446  
5418 328         1762 # [...]
  30         94  
5419             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5420             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5421 90         163 }
5422             else {
5423             splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
5424 298         1064 }
5425 328         624  
5426             $i = $left;
5427             last;
5428             }
5429             }
5430             }
5431              
5432 328         900 # open character class [^...]
5433             elsif ($char[$i] eq '[^') {
5434             my $left = $i;
5435              
5436             # [^] make die "Unmatched [] in regexp ...\n"
5437 74 100       113 # (and so on)
5438 74         184  
5439             if ($char[$i+1] eq ']') {
5440             $i++;
5441 4         8 }
5442 74 50       127  
5443 272         457 while (1) {
5444             if (++$i > $#char) {
5445 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
5446 272         514 }
5447             if ($char[$i] eq ']') {
5448             my $right = $i;
5449 74 100       100  
5450 74         396 # [^...]
  30         89  
5451             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
5452             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
5453 90         162 }
5454             else {
5455             splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5456 44         174 }
5457 74         145  
5458             $i = $left;
5459             last;
5460             }
5461             }
5462             }
5463              
5464 74         208 # rewrite character class or escape character
5465             elsif (my $char = character_class($char[$i],$modifier)) {
5466             $char[$i] = $char;
5467             }
5468              
5469 139 50       360 # /i modifier
5470 20         31 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
5471             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
5472             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
5473 20         35 }
5474             else {
5475             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
5476             }
5477             }
5478              
5479 0 50       0 # \u \l \U \L \F \Q \E
5480 1         4 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
5481             if ($right_e < $left_e) {
5482             $char[$i] = '\\' . $char[$i];
5483             }
5484 0         0 }
5485 0         0 elsif ($char[$i] eq '\u') {
5486             $char[$i] = '@{[Ewindows1257::ucfirst qq<';
5487             $left_e++;
5488 0         0 }
5489 0         0 elsif ($char[$i] eq '\l') {
5490             $char[$i] = '@{[Ewindows1257::lcfirst qq<';
5491             $left_e++;
5492 0         0 }
5493 1         12 elsif ($char[$i] eq '\U') {
5494             $char[$i] = '@{[Ewindows1257::uc qq<';
5495             $left_e++;
5496 1         4 }
5497 1         3 elsif ($char[$i] eq '\L') {
5498             $char[$i] = '@{[Ewindows1257::lc qq<';
5499             $left_e++;
5500 1         3 }
5501 18         24 elsif ($char[$i] eq '\F') {
5502             $char[$i] = '@{[Ewindows1257::fc qq<';
5503             $left_e++;
5504 18         42 }
5505 1         2 elsif ($char[$i] eq '\Q') {
5506             $char[$i] = '@{[CORE::quotemeta qq<';
5507             $left_e++;
5508 1 50       3 }
5509 21         38 elsif ($char[$i] eq '\E') {
5510 21         30 if ($right_e < $left_e) {
5511             $char[$i] = '>]}';
5512             $right_e++;
5513 21         41 }
5514             else {
5515             $char[$i] = '';
5516             }
5517 0         0 }
5518 0 0       0 elsif ($char[$i] eq '\Q') {
5519 0         0 while (1) {
5520             if (++$i > $#char) {
5521 0 0       0 last;
5522 0         0 }
5523             if ($char[$i] eq '\E') {
5524             last;
5525             }
5526             }
5527             }
5528             elsif ($char[$i] eq '\E') {
5529             }
5530              
5531 0 0       0 # $0 --> $0
5532 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
5533             if ($ignorecase) {
5534             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5535             }
5536 0 0       0 }
5537 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
5538             if ($ignorecase) {
5539             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5540             }
5541             }
5542              
5543             # $$ --> $$
5544             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
5545             }
5546              
5547             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
5548 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
5549 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
5550 0         0 $char[$i] = e_capture($1);
5551             if ($ignorecase) {
5552             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5553             }
5554 0         0 }
5555 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
5556 0         0 $char[$i] = e_capture($1);
5557             if ($ignorecase) {
5558             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5559             }
5560             }
5561              
5562 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
5563 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
5564 0         0 $char[$i] = e_capture($1.'->'.$2);
5565             if ($ignorecase) {
5566             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5567             }
5568             }
5569              
5570 0         0 # $$foo{ ... } --> $ $foo->{ ... }
5571 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
5572 0         0 $char[$i] = e_capture($1.'->'.$2);
5573             if ($ignorecase) {
5574             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5575             }
5576             }
5577              
5578 0         0 # $$foo
5579 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
5580 0         0 $char[$i] = e_capture($1);
5581             if ($ignorecase) {
5582             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5583             }
5584             }
5585              
5586 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
5587 8         21 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
5588             if ($ignorecase) {
5589             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::PREMATCH())]}';
5590 0         0 }
5591             else {
5592             $char[$i] = '@{[Ewindows1257::PREMATCH()]}';
5593             }
5594             }
5595              
5596 8 50       23 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
5597 8         25 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
5598             if ($ignorecase) {
5599             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::MATCH())]}';
5600 0         0 }
5601             else {
5602             $char[$i] = '@{[Ewindows1257::MATCH()]}';
5603             }
5604             }
5605              
5606 8 50       29 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
5607 6         16 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
5608             if ($ignorecase) {
5609             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::POSTMATCH())]}';
5610 0         0 }
5611             else {
5612             $char[$i] = '@{[Ewindows1257::POSTMATCH()]}';
5613             }
5614             }
5615              
5616 6 0       18 # ${ foo }
5617 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
5618             if ($ignorecase) {
5619             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5620             }
5621             }
5622              
5623 0         0 # ${ ... }
5624 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
5625 0         0 $char[$i] = e_capture($1);
5626             if ($ignorecase) {
5627             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5628             }
5629             }
5630              
5631 0         0 # $scalar or @array
5632 21 100       49 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
5633 21         55 $char[$i] = e_string($char[$i]);
5634             if ($ignorecase) {
5635             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
5636             }
5637             }
5638              
5639 11 100 33     34 # quote character before ? + * {
    50          
5640             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5641             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
5642 138         1041 }
5643 0 0       0 elsif (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5644 0         0 my $char = $char[$i-1];
5645             if ($char[$i] eq '{') {
5646             die __FILE__, qq{: "MULTIBYTE{n}" should be "(MULTIBYTE){n}" in m?? (and shift \$1,\$2,\$3,...) ($char){n}\n};
5647 0         0 }
5648             else {
5649             die __FILE__, qq{: "MULTIBYTE$char[$i]" should be "(MULTIBYTE)$char[$i]" in m?? (and shift \$1,\$2,\$3,...) ($char)$char[$i]\n};
5650             }
5651 0         0 }
5652             else {
5653             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5654             }
5655             }
5656             }
5657 127         499  
5658 642 50       1243 # make regexp string
5659 642 0 0     1373 $modifier =~ tr/i//d;
5660 0         0 if ($left_e > $right_e) {
5661             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5662             return join '', $ope, $delimiter, $anchor, @char, '>]}' x ($left_e - $right_e), $matched, $end_delimiter, $modifier;
5663 0         0 }
5664             else {
5665             return join '', $ope, $delimiter, $anchor, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
5666 0 50 33     0 }
5667 642         3667 }
5668             if (($ope =~ /\A m? \z/oxms) and ($delimiter eq '?')) {
5669             return join '', $ope, $delimiter, $anchor, @char, $matched, $end_delimiter, $modifier;
5670 0         0 }
5671             else {
5672             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5673             }
5674             }
5675              
5676             #
5677             # double quote stuff
5678 642     180 0 5396 #
5679             sub qq_stuff {
5680             my($delimiter,$end_delimiter,$stuff) = @_;
5681 180 100       296  
5682 180         398 # scalar variable or array variable
5683             if ($stuff =~ /\A [\$\@] /oxms) {
5684             return $stuff;
5685             }
5686 100         411  
  80         211  
5687 80         293 # quote by delimiter
5688 80 50       231 my %octet = map {$_ => 1} ($stuff =~ /\G ([\x00-\xFF]) /oxmsg);
5689 80 50       151 for my $char (qw( ! " $ % & * + - . / : = ? @ ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5690 80 50       137 next if $char eq $delimiter;
5691 80         151 next if $char eq $end_delimiter;
5692             if (not $octet{$char}) {
5693             return join '', 'qq', $char, $stuff, $char;
5694 80         426 }
5695             }
5696             return join '', 'qq', '<', $stuff, '>';
5697             }
5698              
5699             #
5700             # escape regexp (m'', qr'', and m''b, qr''b)
5701 0     10 0 0 #
5702 10   50     38 sub e_qr_q {
5703             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5704 10         40 $modifier ||= '';
5705 10 50       13  
5706 10         20 $modifier =~ tr/p//d;
5707 0         0 if ($modifier =~ /([adlu])/oxms) {
5708 0 0       0 my $line = 0;
5709 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5710 0         0 if ($filename ne __FILE__) {
5711             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5712             last;
5713 0         0 }
5714             }
5715             die qq{Unsupported modifier "$1" used at line $line.\n};
5716 0         0 }
5717              
5718             $slash = 'div';
5719 10 100       15  
    50          
5720 10         19 # literal null string pattern
5721 8         10 if ($string eq '') {
5722 8         8 $modifier =~ tr/bB//d;
5723             $modifier =~ tr/i//d;
5724             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5725             }
5726              
5727 8         37 # with /b /B modifier
5728             elsif ($modifier =~ tr/bB//d) {
5729             return e_qr_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
5730             }
5731              
5732 0         0 # without /b /B modifier
5733             else {
5734             return e_qr_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
5735             }
5736             }
5737              
5738             #
5739             # escape regexp (m'', qr'')
5740 2     2 0 8 #
5741             sub e_qr_qt {
5742 2 50       7 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5743              
5744             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5745 2         5  
5746             # split regexp
5747             my @char = $string =~ /\G((?>
5748             [^\\\[\$\@\/] |
5749             [\x00-\xFF] |
5750             \[\^ |
5751             \[\: (?>[a-z]+) \:\] |
5752             \[\:\^ (?>[a-z]+) \:\] |
5753             [\$\@\/] |
5754             \\ (?:$q_char) |
5755             (?:$q_char)
5756             ))/oxmsg;
5757 2         60  
5758 2 50 33     9 # unescape character
    50 33        
    50 33        
    50          
    50          
    50          
5759             for (my $i=0; $i <= $#char; $i++) {
5760             if (0) {
5761             }
5762 2         15  
5763 0         0 # open character class [...]
5764 0 0       0 elsif ($char[$i] eq '[') {
5765 0         0 my $left = $i;
5766             if ($char[$i+1] eq ']') {
5767 0         0 $i++;
5768 0 0       0 }
5769 0         0 while (1) {
5770             if (++$i > $#char) {
5771 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5772 0         0 }
5773             if ($char[$i] eq ']') {
5774             my $right = $i;
5775 0         0  
5776             # [...]
5777 0         0 splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
5778 0         0  
5779             $i = $left;
5780             last;
5781             }
5782             }
5783             }
5784              
5785 0         0 # open character class [^...]
5786 0 0       0 elsif ($char[$i] eq '[^') {
5787 0         0 my $left = $i;
5788             if ($char[$i+1] eq ']') {
5789 0         0 $i++;
5790 0 0       0 }
5791 0         0 while (1) {
5792             if (++$i > $#char) {
5793 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
5794 0         0 }
5795             if ($char[$i] eq ']') {
5796             my $right = $i;
5797 0         0  
5798             # [^...]
5799 0         0 splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
5800 0         0  
5801             $i = $left;
5802             last;
5803             }
5804             }
5805             }
5806              
5807 0         0 # escape $ @ / and \
5808             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5809             $char[$i] = '\\' . $char[$i];
5810             }
5811              
5812 0         0 # rewrite character class or escape character
5813             elsif (my $char = character_class($char[$i],$modifier)) {
5814             $char[$i] = $char;
5815             }
5816              
5817 0 0       0 # /i modifier
5818 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
5819             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
5820             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
5821 0         0 }
5822             else {
5823             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
5824             }
5825             }
5826              
5827 0 0       0 # quote character before ? + * {
5828             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
5829             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
5830 0         0 }
5831             else {
5832             $char[$i-1] = '(?:' . $char[$i-1] . ')';
5833             }
5834             }
5835 0         0 }
5836 2         5  
5837             $delimiter = '/';
5838 2         4 $end_delimiter = '/';
5839 2         5  
5840             $modifier =~ tr/i//d;
5841             return join '', $ope, $delimiter, $anchor, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5842             }
5843              
5844             #
5845             # escape regexp (m''b, qr''b)
5846 2     0 0 15 #
5847             sub e_qr_qb {
5848             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5849 0         0  
5850             # split regexp
5851             my @char = $string =~ /\G ((?>[^\\]|\\\\)) /oxmsg;
5852 0         0  
5853 0 0       0 # unescape character
    0          
5854             for (my $i=0; $i <= $#char; $i++) {
5855             if (0) {
5856             }
5857 0         0  
5858             # remain \\
5859             elsif ($char[$i] eq '\\\\') {
5860             }
5861              
5862 0         0 # escape $ @ / and \
5863             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
5864             $char[$i] = '\\' . $char[$i];
5865             }
5866 0         0 }
5867 0         0  
5868 0         0 $delimiter = '/';
5869             $end_delimiter = '/';
5870             return join '', $ope, $delimiter, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
5871             }
5872              
5873             #
5874             # escape regexp (s/here//)
5875 0     76 0 0 #
5876 76   100     244 sub e_s1 {
5877             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
5878 76         333 $modifier ||= '';
5879 76 50       142  
5880 76         253 $modifier =~ tr/p//d;
5881 0         0 if ($modifier =~ /([adlu])/oxms) {
5882 0 0       0 my $line = 0;
5883 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
5884 0         0 if ($filename ne __FILE__) {
5885             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
5886             last;
5887 0         0 }
5888             }
5889             die qq{Unsupported modifier "$1" used at line $line.\n};
5890 0         0 }
5891              
5892             $slash = 'div';
5893 76 100       148  
    50          
5894 76         260 # literal null string pattern
5895 8         21 if ($string eq '') {
5896 8         9 $modifier =~ tr/bB//d;
5897             $modifier =~ tr/i//d;
5898             return join '', $ope, $delimiter, $end_delimiter, $modifier;
5899             }
5900              
5901             # /b /B modifier
5902             elsif ($modifier =~ tr/bB//d) {
5903 8 0       43  
5904 0         0 # choice again delimiter
5905 0         0 if ($delimiter =~ / [\@:] /oxms) {
  0         0  
5906 0 0       0 my @char = $string =~ /\G ([\x00-\xFF]) /oxmsg;
    0          
    0          
    0          
5907 0         0 my %octet = map {$_ => 1} @char;
5908 0         0 if (not $octet{')'}) {
5909             $delimiter = '(';
5910             $end_delimiter = ')';
5911 0         0 }
5912 0         0 elsif (not $octet{'}'}) {
5913             $delimiter = '{';
5914             $end_delimiter = '}';
5915 0         0 }
5916 0         0 elsif (not $octet{']'}) {
5917             $delimiter = '[';
5918             $end_delimiter = ']';
5919 0         0 }
5920 0         0 elsif (not $octet{'>'}) {
5921             $delimiter = '<';
5922             $end_delimiter = '>';
5923 0         0 }
5924 0 0       0 else {
5925 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5926 0         0 if (not $octet{$char}) {
5927 0         0 $delimiter = $char;
5928             $end_delimiter = $char;
5929             last;
5930             }
5931             }
5932             }
5933 0         0 }
5934 0         0  
5935             my $prematch = '';
5936             return join '', $ope, $delimiter, $prematch, '(?:', $string, ')', $matched, $end_delimiter, $modifier;
5937 0 100       0 }
5938 68         203  
5939             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
5940             my $metachar = qr/[\@\\|[\]{^]/oxms;
5941 68         278  
5942             # split regexp
5943             my @char = $string =~ /\G((?>
5944             [^\\\$\@\[\(] |
5945             \\ (?>[1-9][0-9]*) |
5946             \\g (?>\s*) (?>[1-9][0-9]*) |
5947             \\g (?>\s*) \{ (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5948             \\g (?>\s*) \{ (?>\s*) - (?>\s*) (?>[1-9][0-9]*) (?>\s*) \} |
5949             \\x (?>[0-9A-Fa-f]{1,2}) |
5950             \\ (?>[0-7]{2,3}) |
5951             \\c [\x40-\x5F] |
5952             \\x\{ (?>[0-9A-Fa-f]+) \} |
5953             \\o\{ (?>[0-7]+) \} |
5954             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
5955             \\ $q_char |
5956             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
5957             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
5958             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
5959             [\$\@] $qq_variable |
5960             \$ (?>\s* [0-9]+) |
5961             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
5962             \$ \$ (?![\w\{]) |
5963             \$ (?>\s*) \$ (?>\s*) $qq_variable |
5964             \[\^ |
5965             \[\: (?>[a-z]+) :\] |
5966             \[\:\^ (?>[a-z]+) :\] |
5967             \(\? |
5968             $q_char
5969             ))/oxmsg;
5970 68 50       16938  
5971 68         484 # choice again delimiter
  0         0  
5972 0 0       0 if ($delimiter =~ / [\@:] /oxms) {
    0          
    0          
    0          
5973 0         0 my %octet = map {$_ => 1} @char;
5974 0         0 if (not $octet{')'}) {
5975             $delimiter = '(';
5976             $end_delimiter = ')';
5977 0         0 }
5978 0         0 elsif (not $octet{'}'}) {
5979             $delimiter = '{';
5980             $end_delimiter = '}';
5981 0         0 }
5982 0         0 elsif (not $octet{']'}) {
5983             $delimiter = '[';
5984             $end_delimiter = ']';
5985 0         0 }
5986 0         0 elsif (not $octet{'>'}) {
5987             $delimiter = '<';
5988             $end_delimiter = '>';
5989 0         0 }
5990 0 0       0 else {
5991 0         0 for my $char (qw( ! " $ % & * + - . / = ? ^ ` | ~ ), "\x00".."\x1F", "\x7F", "\xFF") {
5992 0         0 if (not $octet{$char}) {
5993 0         0 $delimiter = $char;
5994             $end_delimiter = $char;
5995             last;
5996             }
5997             }
5998             }
5999             }
6000 0         0  
  68         148  
6001             # count '('
6002 253         457 my $parens = grep { $_ eq '(' } @char;
6003 68         109  
6004 68         111 my $left_e = 0;
6005             my $right_e = 0;
6006             for (my $i=0; $i <= $#char; $i++) {
6007 68 50 33     210  
    50 33        
    100          
    100          
    50          
    50          
6008 195         1225 # "\L\u" --> "\u\L"
6009             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6010             @char[$i,$i+1] = @char[$i+1,$i];
6011             }
6012              
6013 0         0 # "\U\l" --> "\l\U"
6014             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6015             @char[$i,$i+1] = @char[$i+1,$i];
6016             }
6017              
6018 0         0 # octal escape sequence
6019             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6020             $char[$i] = Ewindows1257::octchr($1);
6021             }
6022              
6023 1         6 # hexadecimal escape sequence
6024             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6025             $char[$i] = Ewindows1257::hexchr($1);
6026             }
6027              
6028             # \b{...} --> b\{...}
6029             # \B{...} --> B\{...}
6030             # \N{CHARNAME} --> N\{CHARNAME}
6031             # \p{PROPERTY} --> p\{PROPERTY}
6032 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6033             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6034             $char[$i] = $1 . '\\' . $2;
6035             }
6036              
6037 0         0 # \p, \P, \X --> p, P, X
6038             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6039             $char[$i] = $1;
6040 0 50 66     0 }
    100 66        
    50 100        
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6041              
6042             if (0) {
6043             }
6044 195         872  
6045 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6046 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6047             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
6048             $char[$i] .= join '', splice @char, $i+1, 3;
6049 0         0 }
6050             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
6051             $char[$i] .= join '', splice @char, $i+1, 2;
6052 0         0 }
6053             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
6054             $char[$i] .= join '', splice @char, $i+1, 1;
6055             }
6056             }
6057              
6058 0         0 # open character class [...]
6059 13 50       35 elsif ($char[$i] eq '[') {
6060 13         45 my $left = $i;
6061             if ($char[$i+1] eq ']') {
6062 0         0 $i++;
6063 13 50       18 }
6064 58         103 while (1) {
6065             if (++$i > $#char) {
6066 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6067 58         108 }
6068             if ($char[$i] eq ']') {
6069             my $right = $i;
6070 13 50       18  
6071 13         86 # [...]
  0         0  
6072             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6073             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6074 0         0 }
6075             else {
6076             splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
6077 13         56 }
6078 13         24  
6079             $i = $left;
6080             last;
6081             }
6082             }
6083             }
6084              
6085 13         49 # open character class [^...]
6086 0 0       0 elsif ($char[$i] eq '[^') {
6087 0         0 my $left = $i;
6088             if ($char[$i+1] eq ']') {
6089 0         0 $i++;
6090 0 0       0 }
6091 0         0 while (1) {
6092             if (++$i > $#char) {
6093 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6094 0         0 }
6095             if ($char[$i] eq ']') {
6096             my $right = $i;
6097 0 0       0  
6098 0         0 # [^...]
  0         0  
6099             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6100             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6101 0         0 }
6102             else {
6103             splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6104 0         0 }
6105 0         0  
6106             $i = $left;
6107             last;
6108             }
6109             }
6110             }
6111              
6112 0         0 # rewrite character class or escape character
6113             elsif (my $char = character_class($char[$i],$modifier)) {
6114             $char[$i] = $char;
6115             }
6116              
6117 7 50       17 # /i modifier
6118 3         17 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
6119             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
6120             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
6121 3         8 }
6122             else {
6123             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
6124             }
6125             }
6126              
6127 0 0       0 # \u \l \U \L \F \Q \E
6128 0         0 elsif ($char[$i] =~ /\A [<>] \z/oxms) {
6129             if ($right_e < $left_e) {
6130             $char[$i] = '\\' . $char[$i];
6131             }
6132 0         0 }
6133 0         0 elsif ($char[$i] eq '\u') {
6134             $char[$i] = '@{[Ewindows1257::ucfirst qq<';
6135             $left_e++;
6136 0         0 }
6137 0         0 elsif ($char[$i] eq '\l') {
6138             $char[$i] = '@{[Ewindows1257::lcfirst qq<';
6139             $left_e++;
6140 0         0 }
6141 0         0 elsif ($char[$i] eq '\U') {
6142             $char[$i] = '@{[Ewindows1257::uc qq<';
6143             $left_e++;
6144 0         0 }
6145 0         0 elsif ($char[$i] eq '\L') {
6146             $char[$i] = '@{[Ewindows1257::lc qq<';
6147             $left_e++;
6148 0         0 }
6149 0         0 elsif ($char[$i] eq '\F') {
6150             $char[$i] = '@{[Ewindows1257::fc qq<';
6151             $left_e++;
6152 0         0 }
6153 0         0 elsif ($char[$i] eq '\Q') {
6154             $char[$i] = '@{[CORE::quotemeta qq<';
6155             $left_e++;
6156 0 0       0 }
6157 0         0 elsif ($char[$i] eq '\E') {
6158 0         0 if ($right_e < $left_e) {
6159             $char[$i] = '>]}';
6160             $right_e++;
6161 0         0 }
6162             else {
6163             $char[$i] = '';
6164             }
6165 0         0 }
6166 0 0       0 elsif ($char[$i] eq '\Q') {
6167 0         0 while (1) {
6168             if (++$i > $#char) {
6169 0 0       0 last;
6170 0         0 }
6171             if ($char[$i] eq '\E') {
6172             last;
6173             }
6174             }
6175             }
6176             elsif ($char[$i] eq '\E') {
6177             }
6178              
6179             # \0 --> \0
6180             elsif ($char[$i] =~ /\A \\ (?>\s*) 0 \z/oxms) {
6181             }
6182              
6183             # \g{N}, \g{-N}
6184              
6185             # P.108 Using Simple Patterns
6186             # in Chapter 7: In the World of Regular Expressions
6187             # of ISBN 978-0-596-52010-6 Learning Perl, Fifth Edition
6188              
6189             # P.221 Capturing
6190             # in Chapter 5: Pattern Matching
6191             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6192              
6193             # \g{-1}, \g{-2}, \g{-3} --> \g{-1}, \g{-2}, \g{-3}
6194             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) - (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6195             }
6196              
6197             # \g{1}, \g{2}, \g{3} --> \g{2}, \g{3}, \g{4} (only when multibyte anchoring is enable)
6198             elsif ($char[$i] =~ /\A \\g (?>\s*) \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6199             }
6200              
6201             # \g1, \g2, \g3 --> \g2, \g3, \g4 (only when multibyte anchoring is enable)
6202             elsif ($char[$i] =~ /\A \\g (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6203             }
6204              
6205             # \1, \2, \3 --> \2, \3, \4 (only when multibyte anchoring is enable)
6206             elsif ($char[$i] =~ /\A \\ (?>\s*) ((?>[1-9][0-9]*)) \z/oxms) {
6207             }
6208              
6209 0 0       0 # $0 --> $0
6210 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6211             if ($ignorecase) {
6212             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6213             }
6214 0 0       0 }
6215 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6216             if ($ignorecase) {
6217             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6218             }
6219             }
6220              
6221             # $$ --> $$
6222             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6223             }
6224              
6225             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6226 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6227 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6228 0         0 $char[$i] = e_capture($1);
6229             if ($ignorecase) {
6230             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6231             }
6232 0         0 }
6233 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6234 0         0 $char[$i] = e_capture($1);
6235             if ($ignorecase) {
6236             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6237             }
6238             }
6239              
6240 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6241 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
6242 0         0 $char[$i] = e_capture($1.'->'.$2);
6243             if ($ignorecase) {
6244             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6245             }
6246             }
6247              
6248 0         0 # $$foo{ ... } --> $ $foo->{ ... }
6249 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
6250 0         0 $char[$i] = e_capture($1.'->'.$2);
6251             if ($ignorecase) {
6252             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6253             }
6254             }
6255              
6256 0         0 # $$foo
6257 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
6258 0         0 $char[$i] = e_capture($1);
6259             if ($ignorecase) {
6260             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6261             }
6262             }
6263              
6264 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
6265 4         15 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
6266             if ($ignorecase) {
6267             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::PREMATCH())]}';
6268 0         0 }
6269             else {
6270             $char[$i] = '@{[Ewindows1257::PREMATCH()]}';
6271             }
6272             }
6273              
6274 4 50       14 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
6275 4         17 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
6276             if ($ignorecase) {
6277             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::MATCH())]}';
6278 0         0 }
6279             else {
6280             $char[$i] = '@{[Ewindows1257::MATCH()]}';
6281             }
6282             }
6283              
6284 4 50       16 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
6285 3         10 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
6286             if ($ignorecase) {
6287             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::POSTMATCH())]}';
6288 0         0 }
6289             else {
6290             $char[$i] = '@{[Ewindows1257::POSTMATCH()]}';
6291             }
6292             }
6293              
6294 3 0       11 # ${ foo }
6295 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
6296             if ($ignorecase) {
6297             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6298             }
6299             }
6300              
6301 0         0 # ${ ... }
6302 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
6303 0         0 $char[$i] = e_capture($1);
6304             if ($ignorecase) {
6305             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6306             }
6307             }
6308              
6309 0         0 # $scalar or @array
6310 4 50       21 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
6311 4         27 $char[$i] = e_string($char[$i]);
6312             if ($ignorecase) {
6313             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6314             }
6315             }
6316              
6317 0 50       0 # quote character before ? + * {
6318             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6319             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
6320 13         68 }
6321             else {
6322             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6323             }
6324             }
6325             }
6326 13         65  
6327 68         159 # make regexp string
6328 68 50       124 my $prematch = '';
6329 68         220 $modifier =~ tr/i//d;
6330             if ($left_e > $right_e) {
6331 0         0 return join '', $ope, $delimiter, $prematch, '(?:', @char, '>]}' x ($left_e - $right_e), ')', $matched, $end_delimiter, $modifier;
6332             }
6333             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6334             }
6335              
6336             #
6337             # escape regexp (s'here'' or s'here''b)
6338 68     21 0 816 #
6339 21   100     49 sub e_s1_q {
6340             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6341 21         66 $modifier ||= '';
6342 21 50       30  
6343 21         46 $modifier =~ tr/p//d;
6344 0         0 if ($modifier =~ /([adlu])/oxms) {
6345 0 0       0 my $line = 0;
6346 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6347 0         0 if ($filename ne __FILE__) {
6348             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6349             last;
6350 0         0 }
6351             }
6352             die qq{Unsupported modifier "$1" used at line $line.\n};
6353 0         0 }
6354              
6355             $slash = 'div';
6356 21 100       31  
    50          
6357 21         56 # literal null string pattern
6358 8         7 if ($string eq '') {
6359 8         14 $modifier =~ tr/bB//d;
6360             $modifier =~ tr/i//d;
6361             return join '', $ope, $delimiter, $end_delimiter, $modifier;
6362             }
6363              
6364 8         40 # with /b /B modifier
6365             elsif ($modifier =~ tr/bB//d) {
6366             return e_s1_qb($ope,$delimiter,$end_delimiter,$string,$modifier);
6367             }
6368              
6369 0         0 # without /b /B modifier
6370             else {
6371             return e_s1_qt($ope,$delimiter,$end_delimiter,$string,$modifier);
6372             }
6373             }
6374              
6375             #
6376             # escape regexp (s'here'')
6377 13     13 0 28 #
6378             sub e_s1_qt {
6379 13 50       32 my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6380              
6381             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6382 13         23  
6383             # split regexp
6384             my @char = $string =~ /\G((?>
6385             [^\\\[\$\@\/] |
6386             [\x00-\xFF] |
6387             \[\^ |
6388             \[\: (?>[a-z]+) \:\] |
6389             \[\:\^ (?>[a-z]+) \:\] |
6390             [\$\@\/] |
6391             \\ (?:$q_char) |
6392             (?:$q_char)
6393             ))/oxmsg;
6394 13         197  
6395 13 50 33     43 # unescape character
    50 33        
    50 66        
    100          
    50          
    50          
6396             for (my $i=0; $i <= $#char; $i++) {
6397             if (0) {
6398             }
6399 25         108  
6400 0         0 # open character class [...]
6401 0 0       0 elsif ($char[$i] eq '[') {
6402 0         0 my $left = $i;
6403             if ($char[$i+1] eq ']') {
6404 0         0 $i++;
6405 0 0       0 }
6406 0         0 while (1) {
6407             if (++$i > $#char) {
6408 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6409 0         0 }
6410             if ($char[$i] eq ']') {
6411             my $right = $i;
6412 0         0  
6413             # [...]
6414 0         0 splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
6415 0         0  
6416             $i = $left;
6417             last;
6418             }
6419             }
6420             }
6421              
6422 0         0 # open character class [^...]
6423 0 0       0 elsif ($char[$i] eq '[^') {
6424 0         0 my $left = $i;
6425             if ($char[$i+1] eq ']') {
6426 0         0 $i++;
6427 0 0       0 }
6428 0         0 while (1) {
6429             if (++$i > $#char) {
6430 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6431 0         0 }
6432             if ($char[$i] eq ']') {
6433             my $right = $i;
6434 0         0  
6435             # [^...]
6436 0         0 splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6437 0         0  
6438             $i = $left;
6439             last;
6440             }
6441             }
6442             }
6443              
6444 0         0 # escape $ @ / and \
6445             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6446             $char[$i] = '\\' . $char[$i];
6447             }
6448              
6449 0         0 # rewrite character class or escape character
6450             elsif (my $char = character_class($char[$i],$modifier)) {
6451             $char[$i] = $char;
6452             }
6453              
6454 6 0       14 # /i modifier
6455 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
6456             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
6457             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
6458 0         0 }
6459             else {
6460             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
6461             }
6462             }
6463              
6464 0 0       0 # quote character before ? + * {
6465             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
6466             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
6467 0         0 }
6468             else {
6469             $char[$i-1] = '(?:' . $char[$i-1] . ')';
6470             }
6471             }
6472 0         0 }
6473 13         24  
6474 13         20 $modifier =~ tr/i//d;
6475 13         28 $delimiter = '/';
6476 13         19 $end_delimiter = '/';
6477             my $prematch = '';
6478             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6479             }
6480              
6481             #
6482             # escape regexp (s'here''b)
6483 13     0 0 119 #
6484             sub e_s1_qb {
6485             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6486 0         0  
6487             # split regexp
6488             my @char = $string =~ /\G (?>[^\\]|\\\\) /oxmsg;
6489 0         0  
6490 0 0       0 # unescape character
    0          
6491             for (my $i=0; $i <= $#char; $i++) {
6492             if (0) {
6493             }
6494 0         0  
6495             # remain \\
6496             elsif ($char[$i] eq '\\\\') {
6497             }
6498              
6499 0         0 # escape $ @ / and \
6500             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6501             $char[$i] = '\\' . $char[$i];
6502             }
6503 0         0 }
6504 0         0  
6505 0         0 $delimiter = '/';
6506 0         0 $end_delimiter = '/';
6507             my $prematch = '';
6508             return join '', $ope, $delimiter, $prematch, '(?:', @char, ')', $matched, $end_delimiter, $modifier;
6509             }
6510              
6511             #
6512             # escape regexp (s''here')
6513 0     16 0 0 #
6514             sub e_s2_q {
6515 16         39 my($ope,$delimiter,$end_delimiter,$string) = @_;
6516              
6517 16         21 $slash = 'div';
6518 16         93  
6519 16 100       41 my @char = $string =~ / \G (?>[^\\]|\\\\|$q_char) /oxmsg;
    100          
6520             for (my $i=0; $i <= $#char; $i++) {
6521             if (0) {
6522             }
6523 9         32  
6524             # not escape \\
6525             elsif ($char[$i] =~ /\A \\\\ \z/oxms) {
6526             }
6527              
6528 0         0 # escape $ @ / and \
6529             elsif ($char[$i] =~ /\A [\$\@\/\\] \z/oxms) {
6530             $char[$i] = '\\' . $char[$i];
6531             }
6532 5         11 }
6533              
6534             return join '', $ope, $delimiter, @char, $end_delimiter;
6535             }
6536              
6537             #
6538             # escape regexp (s/here/and here/modifier)
6539 16     97 0 44 #
6540 97   100     736 sub e_sub {
6541             my($variable,$delimiter1,$pattern,$end_delimiter1,$delimiter2,$replacement,$end_delimiter2,$modifier) = @_;
6542 97         426 $modifier ||= '';
6543 97 50       213  
6544 97         322 $modifier =~ tr/p//d;
6545 0         0 if ($modifier =~ /([adlu])/oxms) {
6546 0 0       0 my $line = 0;
6547 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6548 0         0 if ($filename ne __FILE__) {
6549             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6550             last;
6551 0         0 }
6552             }
6553             die qq{Unsupported modifier "$1" used at line $line.\n};
6554 0 100       0 }
6555 97         261  
6556 36         44 if ($variable eq '') {
6557             $variable = '$_';
6558             $bind_operator = ' =~ ';
6559 36         49 }
6560              
6561             $slash = 'div';
6562              
6563             # P.128 Start of match (or end of previous match): \G
6564             # P.130 Advanced Use of \G with Perl
6565             # in Chapter 3: Overview of Regular Expression Features and Flavors
6566             # P.312 Iterative Matching: Scalar Context, with /g
6567             # in Chapter 7: Perl
6568             # of ISBN 0-596-00289-0 Mastering Regular Expressions, Second edition
6569              
6570             # P.181 Where You Left Off: The \G Assertion
6571             # in Chapter 5: Pattern Matching
6572             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6573              
6574             # P.220 Where You Left Off: The \G Assertion
6575             # in Chapter 5: Pattern Matching
6576 97         159 # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6577 97         154  
6578             my $e_modifier = $modifier =~ tr/e//d;
6579 97         175 my $r_modifier = $modifier =~ tr/r//d;
6580 97 50       184  
6581 97         286 my $my = '';
6582 0         0 if ($variable =~ s/\A \( (?>\s*) ( (?>(?: local \b | my \b | our \b | state \b )?) .+ ) \) \z/$1/oxms) {
6583 0         0 $my = $variable;
6584             $variable =~ s/ (?: local \b | my \b | our \b | state \b ) (?>\s*) //oxms;
6585             $variable =~ s/ = .+ \z//oxms;
6586 0         0 }
6587 97         244  
6588             (my $variable_basename = $variable) =~ s/ [\[\{].* \z//oxms;
6589             $variable_basename =~ s/ \s+ \z//oxms;
6590 97         190  
6591 97 100       185 # quote replacement string
6592 97         217 my $e_replacement = '';
6593 17         35 if ($e_modifier >= 1) {
6594             $e_replacement = e_qq('', '', '', $replacement);
6595             $e_modifier--;
6596 17 100       27 }
6597 80         199 else {
6598             if ($delimiter2 eq "'") {
6599             $e_replacement = e_s2_q('qq', '/', '/', $replacement);
6600 16         31 }
6601             else {
6602             $e_replacement = e_qq ('qq', $delimiter2, $end_delimiter2, $replacement);
6603             }
6604 64         162 }
6605              
6606             my $sub = '';
6607 97 100       188  
6608 97 100       247 # with /r
6609             if ($r_modifier) {
6610             if (0) {
6611             }
6612 8         24  
6613 0 50       0 # s///gr without multibyte anchoring
6614             elsif ($modifier =~ /g/oxms) {
6615             $sub = sprintf(
6616             # 1 2 3 4 5
6617             q,
6618              
6619             $variable, # 1
6620             ($delimiter1 eq "'") ? # 2
6621             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6622             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6623             $s_matched, # 3
6624             $e_replacement, # 4
6625             '$Ewindows1257::re_r=CORE::eval $Ewindows1257::re_r; ' x $e_modifier, # 5
6626             );
6627             }
6628              
6629             # s///r
6630 4         21 else {
6631              
6632 4 50       7 my $prematch = q{$`};
6633              
6634             $sub = sprintf(
6635             # 1 2 3 4 5 6 7
6636             q<(%s =~ %s) ? CORE::eval{%s local $^W=0; local $Ewindows1257::re_r=%s; %s"%s$Ewindows1257::re_r$'" } : %s>,
6637              
6638             $variable, # 1
6639             ($delimiter1 eq "'") ? # 2
6640             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6641             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6642             $s_matched, # 3
6643             $e_replacement, # 4
6644             '$Ewindows1257::re_r=CORE::eval $Ewindows1257::re_r; ' x $e_modifier, # 5
6645             $prematch, # 6
6646             $variable, # 7
6647             );
6648             }
6649 4 50       17  
6650 8         26 # $var !~ s///r doesn't make sense
6651             if ($bind_operator =~ / !~ /oxms) {
6652             $sub = q{die("$0: Using !~ with s///r doesn't make sense"), } . $sub;
6653             }
6654             }
6655              
6656 0 100       0 # without /r
6657             else {
6658             if (0) {
6659             }
6660 89         257  
6661 0 100       0 # s///g without multibyte anchoring
    100          
6662             elsif ($modifier =~ /g/oxms) {
6663             $sub = sprintf(
6664             # 1 2 3 4 5 6 7 8
6665             q,
6666              
6667             $variable, # 1
6668             ($delimiter1 eq "'") ? # 2
6669             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6670             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6671             $s_matched, # 3
6672             $e_replacement, # 4
6673             '$Ewindows1257::re_r=CORE::eval $Ewindows1257::re_r; ' x $e_modifier, # 5
6674             $variable, # 6
6675             $variable, # 7
6676             ($bind_operator =~ / !~ /oxms) ? '!' : '', # 8
6677             );
6678             }
6679              
6680             # s///
6681 22         91 else {
6682              
6683 67 100       132 my $prematch = q{$`};
    100          
6684              
6685             $sub = sprintf(
6686              
6687             ($bind_operator =~ / =~ /oxms) ?
6688              
6689             # 1 2 3 4 5 6 7 8
6690             q<(%s%s%s) ? CORE::eval{%s local $^W=0; local $Ewindows1257::re_r=%s; %s%s="%s$Ewindows1257::re_r$'"; 1 } : undef> :
6691              
6692             # 1 2 3 4 5 6 7 8
6693             q<(%s%s%s) ? 1 : CORE::eval{%s local $^W=0; local $Ewindows1257::re_r=%s; %s%s="%s$Ewindows1257::re_r$'"; undef }>,
6694              
6695             $variable, # 1
6696             $bind_operator, # 2
6697             ($delimiter1 eq "'") ? # 3
6698             e_s1_q('m', $delimiter1, $end_delimiter1, $pattern, $modifier) : # :
6699             e_s1 ('m', $delimiter1, $end_delimiter1, $pattern, $modifier), # :
6700             $s_matched, # 4
6701             $e_replacement, # 5
6702             '$Ewindows1257::re_r=CORE::eval $Ewindows1257::re_r; ' x $e_modifier, # 6
6703             $variable, # 7
6704             $prematch, # 8
6705             );
6706             }
6707             }
6708 67 50       402  
6709 97         288 # (my $foo = $bar) =~ s/// --> (my $foo = $bar, CORE::eval { ... })[1]
6710             if ($my ne '') {
6711             $sub = "($my, $sub)[1]";
6712             }
6713 0         0  
6714 97         188 # clear s/// variable
6715             $sub_variable = '';
6716 97         134 $bind_operator = '';
6717              
6718             return $sub;
6719             }
6720              
6721             #
6722             # escape regexp of split qr//
6723 97     74 0 763 #
6724 74   100     347 sub e_split {
6725             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
6726 74         384 $modifier ||= '';
6727 74 50       141  
6728 74         334 $modifier =~ tr/p//d;
6729 0         0 if ($modifier =~ /([adlu])/oxms) {
6730 0 0       0 my $line = 0;
6731 0         0 for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
6732 0         0 if ($filename ne __FILE__) {
6733             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
6734             last;
6735 0         0 }
6736             }
6737             die qq{Unsupported modifier "$1" used at line $line.\n};
6738 0         0 }
6739              
6740             $slash = 'div';
6741 74 50       152  
6742 74         172 # /b /B modifier
6743             if ($modifier =~ tr/bB//d) {
6744             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
6745 0 50       0 }
6746 74         179  
6747             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
6748             my $metachar = qr/[\@\\|[\]{^]/oxms;
6749 74         344  
6750             # split regexp
6751             my @char = $string =~ /\G((?>
6752             [^\\\$\@\[\(] |
6753             \\x (?>[0-9A-Fa-f]{1,2}) |
6754             \\ (?>[0-7]{2,3}) |
6755             \\c [\x40-\x5F] |
6756             \\x\{ (?>[0-9A-Fa-f]+) \} |
6757             \\o\{ (?>[0-7]+) \} |
6758             \\[bBNpP]\{ (?>[^0-9\}][^\}]*) \} |
6759             \\ $q_char |
6760             \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} |
6761             \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} |
6762             \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} |
6763             [\$\@] $qq_variable |
6764             \$ (?>\s* [0-9]+) |
6765             \$ (?>\s*) \{ (?>\s* [0-9]+ \s*) \} |
6766             \$ \$ (?![\w\{]) |
6767             \$ (?>\s*) \$ (?>\s*) $qq_variable |
6768             \[\^ |
6769             \[\: (?>[a-z]+) :\] |
6770             \[\:\^ (?>[a-z]+) :\] |
6771             \(\? |
6772             $q_char
6773 74         9738 ))/oxmsg;
6774 74         250  
6775 74         118 my $left_e = 0;
6776             my $right_e = 0;
6777             for (my $i=0; $i <= $#char; $i++) {
6778 74 50 33     301  
    50 33        
    100          
    100          
    50          
    50          
6779 249         1343 # "\L\u" --> "\u\L"
6780             if (($char[$i] eq '\L') and ($char[$i+1] eq '\u')) {
6781             @char[$i,$i+1] = @char[$i+1,$i];
6782             }
6783              
6784 0         0 # "\U\l" --> "\l\U"
6785             elsif (($char[$i] eq '\U') and ($char[$i+1] eq '\l')) {
6786             @char[$i,$i+1] = @char[$i+1,$i];
6787             }
6788              
6789 0         0 # octal escape sequence
6790             elsif ($char[$i] =~ /\A \\o \{ ([0-7]+) \} \z/oxms) {
6791             $char[$i] = Ewindows1257::octchr($1);
6792             }
6793              
6794 1         6 # hexadecimal escape sequence
6795             elsif ($char[$i] =~ /\A \\x \{ ([0-9A-Fa-f]+) \} \z/oxms) {
6796             $char[$i] = Ewindows1257::hexchr($1);
6797             }
6798              
6799             # \b{...} --> b\{...}
6800             # \B{...} --> B\{...}
6801             # \N{CHARNAME} --> N\{CHARNAME}
6802             # \p{PROPERTY} --> p\{PROPERTY}
6803 1         4 # \P{PROPERTY} --> P\{PROPERTY}
6804             elsif ($char[$i] =~ /\A \\ ([bBNpP]) ( \{ ([^0-9\}][^\}]*) \} ) \z/oxms) {
6805             $char[$i] = $1 . '\\' . $2;
6806             }
6807              
6808 0         0 # \p, \P, \X --> p, P, X
6809             elsif ($char[$i] =~ /\A \\ ( [pPX] ) \z/oxms) {
6810             $char[$i] = $1;
6811 0 50 100     0 }
    100 33        
    50 33        
    100 100        
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    100          
    100          
    50          
    50          
    100          
    100          
6812              
6813             if (0) {
6814             }
6815 249         817  
6816 0 0 0     0 # join separated multiple-octet
    0 0        
    0 0        
      0        
      0        
      0        
6817 0         0 elsif ($char[$i] =~ /\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms) {
6818             if ( ($i+3 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+3]) == 3) and (CORE::eval(sprintf '"%s%s%s%s"', @char[$i..$i+3]) =~ /\A $q_char \z/oxms)) {
6819             $char[$i] .= join '', splice @char, $i+1, 3;
6820 0         0 }
6821             elsif (($i+2 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, @char[$i+1..$i+2]) == 2) and (CORE::eval(sprintf '"%s%s%s"', @char[$i..$i+2]) =~ /\A $q_char \z/oxms)) {
6822             $char[$i] .= join '', splice @char, $i+1, 2;
6823 0         0 }
6824             elsif (($i+1 <= $#char) and (grep(/\A (?: \\ [0-7]{2,3} | \\x [0-9A-Fa-f]{1,2}) \z/oxms, $char[$i+1 ]) == 1) and (CORE::eval(sprintf '"%s%s"', @char[$i..$i+1]) =~ /\A $q_char \z/oxms)) {
6825             $char[$i] .= join '', splice @char, $i+1, 1;
6826             }
6827             }
6828              
6829 0         0 # open character class [...]
6830 3 50       7 elsif ($char[$i] eq '[') {
6831 3         10 my $left = $i;
6832             if ($char[$i+1] eq ']') {
6833 0         0 $i++;
6834 3 50       4 }
6835 7         16 while (1) {
6836             if (++$i > $#char) {
6837 0 100       0 die __FILE__, ": Unmatched [] in regexp\n";
6838 7         14 }
6839             if ($char[$i] eq ']') {
6840             my $right = $i;
6841 3 50       6  
6842 3         19 # [...]
  0         0  
6843             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6844             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6845 0         0 }
6846             else {
6847             splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
6848 3         31 }
6849 3         6  
6850             $i = $left;
6851             last;
6852             }
6853             }
6854             }
6855              
6856 3         9 # open character class [^...]
6857 0 0       0 elsif ($char[$i] eq '[^') {
6858 0         0 my $left = $i;
6859             if ($char[$i+1] eq ']') {
6860 0         0 $i++;
6861 0 0       0 }
6862 0         0 while (1) {
6863             if (++$i > $#char) {
6864 0 0       0 die __FILE__, ": Unmatched [] in regexp\n";
6865 0         0 }
6866             if ($char[$i] eq ']') {
6867             my $right = $i;
6868 0 0       0  
6869 0         0 # [^...]
  0         0  
6870             if (grep(/\A [\$\@]/oxms,@char[$left+1..$right-1]) >= 1) {
6871             splice @char, $left, $right-$left+1, sprintf(q{@{[Ewindows1257::charlist_not_qr(%s,'%s')]}}, join(',', map {qq_stuff($delimiter,$end_delimiter,$_)} @char[$left+1..$right-1]), $modifier);
6872 0         0 }
6873             else {
6874             splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
6875 0         0 }
6876 0         0  
6877             $i = $left;
6878             last;
6879             }
6880             }
6881             }
6882              
6883 0         0 # rewrite character class or escape character
6884             elsif (my $char = character_class($char[$i],$modifier)) {
6885             $char[$i] = $char;
6886             }
6887              
6888             # P.794 29.2.161. split
6889             # in Chapter 29: Functions
6890             # of ISBN 0-596-00027-8 Programming Perl Third Edition.
6891              
6892             # P.951 split
6893             # in Chapter 27: Functions
6894             # of ISBN 978-0-596-00492-7 Programming Perl 4th Edition.
6895              
6896             # said "The //m modifier is assumed when you split on the pattern /^/",
6897             # but perl5.008 is not so. Therefore, this software adds //m.
6898             # (and so on)
6899              
6900 1         3 # split(m/^/) --> split(m/^/m)
6901             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
6902             $modifier .= 'm';
6903             }
6904              
6905 7 0       22 # /i modifier
6906 0         0 elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
6907             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
6908             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
6909 0         0 }
6910             else {
6911             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
6912             }
6913             }
6914              
6915 0 0       0 # \u \l \U \L \F \Q \E
6916 0         0 elsif ($char[$i] =~ /\A ([<>]) \z/oxms) {
6917             if ($right_e < $left_e) {
6918             $char[$i] = '\\' . $char[$i];
6919             }
6920 0         0 }
6921 0         0 elsif ($char[$i] eq '\u') {
6922             $char[$i] = '@{[Ewindows1257::ucfirst qq<';
6923             $left_e++;
6924 0         0 }
6925 0         0 elsif ($char[$i] eq '\l') {
6926             $char[$i] = '@{[Ewindows1257::lcfirst qq<';
6927             $left_e++;
6928 0         0 }
6929 0         0 elsif ($char[$i] eq '\U') {
6930             $char[$i] = '@{[Ewindows1257::uc qq<';
6931             $left_e++;
6932 0         0 }
6933 0         0 elsif ($char[$i] eq '\L') {
6934             $char[$i] = '@{[Ewindows1257::lc qq<';
6935             $left_e++;
6936 0         0 }
6937 0         0 elsif ($char[$i] eq '\F') {
6938             $char[$i] = '@{[Ewindows1257::fc qq<';
6939             $left_e++;
6940 0         0 }
6941 0         0 elsif ($char[$i] eq '\Q') {
6942             $char[$i] = '@{[CORE::quotemeta qq<';
6943             $left_e++;
6944 0 0       0 }
6945 0         0 elsif ($char[$i] eq '\E') {
6946 0         0 if ($right_e < $left_e) {
6947             $char[$i] = '>]}';
6948             $right_e++;
6949 0         0 }
6950             else {
6951             $char[$i] = '';
6952             }
6953 0         0 }
6954 0 0       0 elsif ($char[$i] eq '\Q') {
6955 0         0 while (1) {
6956             if (++$i > $#char) {
6957 0 0       0 last;
6958 0         0 }
6959             if ($char[$i] eq '\E') {
6960             last;
6961             }
6962             }
6963             }
6964             elsif ($char[$i] eq '\E') {
6965             }
6966              
6967 0 0       0 # $0 --> $0
6968 0         0 elsif ($char[$i] =~ /\A \$ 0 \z/oxms) {
6969             if ($ignorecase) {
6970             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6971             }
6972 0 0       0 }
6973 0         0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) 0 (?>\s*) \} \z/oxms) {
6974             if ($ignorecase) {
6975             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6976             }
6977             }
6978              
6979             # $$ --> $$
6980             elsif ($char[$i] =~ /\A \$\$ \z/oxms) {
6981             }
6982              
6983             # $1, $2, $3 --> $2, $3, $4 after s/// with multibyte anchoring
6984 0         0 # $1, $2, $3 --> $1, $2, $3 otherwise
6985 0 0       0 elsif ($char[$i] =~ /\A \$ ((?>[1-9][0-9]*)) \z/oxms) {
6986 0         0 $char[$i] = e_capture($1);
6987             if ($ignorecase) {
6988             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6989             }
6990 0         0 }
6991 0 0       0 elsif ($char[$i] =~ /\A \$ \{ (?>\s*) ((?>[1-9][0-9]*)) (?>\s*) \} \z/oxms) {
6992 0         0 $char[$i] = e_capture($1);
6993             if ($ignorecase) {
6994             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
6995             }
6996             }
6997              
6998 0         0 # $$foo[ ... ] --> $ $foo->[ ... ]
6999 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \[ (?:$qq_bracket)*? \] ) \z/oxms) {
7000 0         0 $char[$i] = e_capture($1.'->'.$2);
7001             if ($ignorecase) {
7002             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
7003             }
7004             }
7005              
7006 0         0 # $$foo{ ... } --> $ $foo->{ ... }
7007 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) ( \{ (?:$qq_brace)*? \} ) \z/oxms) {
7008 0         0 $char[$i] = e_capture($1.'->'.$2);
7009             if ($ignorecase) {
7010             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
7011             }
7012             }
7013              
7014 0         0 # $$foo
7015 0 0       0 elsif ($char[$i] =~ /\A \$ ((?> \$ [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* )) \z/oxms) {
7016 0         0 $char[$i] = e_capture($1);
7017             if ($ignorecase) {
7018             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
7019             }
7020             }
7021              
7022 0 50       0 # $`, ${`}, $PREMATCH, ${PREMATCH}, ${^PREMATCH} --> Ewindows1257::PREMATCH()
7023 12         33 elsif ($char[$i] =~ /\A ( \$` | \$\{`\} | \$ (?>\s*) PREMATCH | \$ (?>\s*) \{ (?>\s*) PREMATCH (?>\s*) \} | \$ (?>\s*) \{\^PREMATCH\} ) \z/oxmsgc) {
7024             if ($ignorecase) {
7025             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::PREMATCH())]}';
7026 0         0 }
7027             else {
7028             $char[$i] = '@{[Ewindows1257::PREMATCH()]}';
7029             }
7030             }
7031              
7032 12 50       52 # $&, ${&}, $MATCH, ${MATCH}, ${^MATCH} --> Ewindows1257::MATCH()
7033 12         44 elsif ($char[$i] =~ /\A ( \$& | \$\{&\} | \$ (?>\s*) MATCH | \$ (?>\s*) \{ (?>\s*) MATCH (?>\s*) \} | \$ (?>\s*) \{\^MATCH\} ) \z/oxmsgc) {
7034             if ($ignorecase) {
7035             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::MATCH())]}';
7036 0         0 }
7037             else {
7038             $char[$i] = '@{[Ewindows1257::MATCH()]}';
7039             }
7040             }
7041              
7042 12 50       63 # $POSTMATCH, ${POSTMATCH}, ${^POSTMATCH} --> Ewindows1257::POSTMATCH()
7043 9         31 elsif ($char[$i] =~ /\A ( \$ (?>\s*) POSTMATCH | \$ (?>\s*) \{ (?>\s*) POSTMATCH (?>\s*) \} | \$ (?>\s*) \{\^POSTMATCH\} ) \z/oxmsgc) {
7044             if ($ignorecase) {
7045             $char[$i] = '@{[Ewindows1257::ignorecase(Ewindows1257::POSTMATCH())]}';
7046 0         0 }
7047             else {
7048             $char[$i] = '@{[Ewindows1257::POSTMATCH()]}';
7049             }
7050             }
7051              
7052 9 0       40 # ${ foo }
7053 0         0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ((?> \s* [A-Za-z_][A-Za-z0-9_]*(?: ::[A-Za-z_][A-Za-z0-9_]*)* \s* )) \} \z/oxms) {
7054             if ($ignorecase) {
7055             $char[$i] = '@{[Ewindows1257::ignorecase(' . $1 . ')]}';
7056             }
7057             }
7058              
7059 0         0 # ${ ... }
7060 0 0       0 elsif ($char[$i] =~ /\A \$ (?>\s*) \{ ( .+ ) \} \z/oxms) {
7061 0         0 $char[$i] = e_capture($1);
7062             if ($ignorecase) {
7063             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
7064             }
7065             }
7066              
7067 0         0 # $scalar or @array
7068 3 50       12 elsif ($char[$i] =~ /\A [\$\@].+ /oxms) {
7069 3         17 $char[$i] = e_string($char[$i]);
7070             if ($ignorecase) {
7071             $char[$i] = '@{[Ewindows1257::ignorecase(' . $char[$i] . ')]}';
7072             }
7073             }
7074              
7075 0 50       0 # quote character before ? + * {
7076             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7077             if ($char[$i-1] =~ /\A (?:[\x00-\xFF]|\\[0-7]{2,3}|\\x[0-9-A-Fa-f]{1,2}) \z/oxms) {
7078 1         7 }
7079             else {
7080             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7081             }
7082             }
7083             }
7084 0         0  
7085 74 50       148 # make regexp string
7086 74         164 $modifier =~ tr/i//d;
7087             if ($left_e > $right_e) {
7088 0         0 return join '', 'Ewindows1257::split', $ope, $delimiter, @char, '>]}' x ($left_e - $right_e), $end_delimiter, $modifier;
7089             }
7090             return join '', 'Ewindows1257::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7091             }
7092              
7093             #
7094             # escape regexp of split qr''
7095 74     0 0 733 #
7096 0   0       sub e_split_q {
7097             my($ope,$delimiter,$end_delimiter,$string,$modifier) = @_;
7098 0           $modifier ||= '';
7099 0 0          
7100 0           $modifier =~ tr/p//d;
7101 0           if ($modifier =~ /([adlu])/oxms) {
7102 0 0         my $line = 0;
7103 0           for (my $i=0; my($package,$filename,$use_line,$subroutine) = caller($i); $i++) {
7104 0           if ($filename ne __FILE__) {
7105             $line = $use_line + (CORE::substr($_,0,pos($_)) =~ tr/\n//) + 1;
7106             last;
7107 0           }
7108             }
7109             die qq{Unsupported modifier "$1" used at line $line.\n};
7110 0           }
7111              
7112             $slash = 'div';
7113 0 0          
7114 0           # /b /B modifier
7115             if ($modifier =~ tr/bB//d) {
7116             return join '', 'split', $ope, $delimiter, $string, $end_delimiter, $modifier;
7117 0 0         }
7118              
7119             my $ignorecase = ($modifier =~ /i/oxms) ? 1 : 0;
7120 0            
7121             # split regexp
7122             my @char = $string =~ /\G((?>
7123             [^\\\[] |
7124             [\x00-\xFF] |
7125             \[\^ |
7126             \[\: (?>[a-z]+) \:\] |
7127             \[\:\^ (?>[a-z]+) \:\] |
7128             \\ (?:$q_char) |
7129             (?:$q_char)
7130             ))/oxmsg;
7131 0            
7132 0 0 0       # unescape character
    0 0        
    0 0        
    0 0        
    0          
    0          
7133             for (my $i=0; $i <= $#char; $i++) {
7134             if (0) {
7135             }
7136 0            
7137 0           # open character class [...]
7138 0 0         elsif ($char[$i] eq '[') {
7139 0           my $left = $i;
7140             if ($char[$i+1] eq ']') {
7141 0           $i++;
7142 0 0         }
7143 0           while (1) {
7144             if (++$i > $#char) {
7145 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7146 0           }
7147             if ($char[$i] eq ']') {
7148             my $right = $i;
7149 0            
7150             # [...]
7151 0           splice @char, $left, $right-$left+1, Ewindows1257::charlist_qr(@char[$left+1..$right-1], $modifier);
7152 0            
7153             $i = $left;
7154             last;
7155             }
7156             }
7157             }
7158              
7159 0           # open character class [^...]
7160 0 0         elsif ($char[$i] eq '[^') {
7161 0           my $left = $i;
7162             if ($char[$i+1] eq ']') {
7163 0           $i++;
7164 0 0         }
7165 0           while (1) {
7166             if (++$i > $#char) {
7167 0 0         die __FILE__, ": Unmatched [] in regexp\n";
7168 0           }
7169             if ($char[$i] eq ']') {
7170             my $right = $i;
7171 0            
7172             # [^...]
7173 0           splice @char, $left, $right-$left+1, Ewindows1257::charlist_not_qr(@char[$left+1..$right-1], $modifier);
7174 0            
7175             $i = $left;
7176             last;
7177             }
7178             }
7179             }
7180              
7181 0           # rewrite character class or escape character
7182             elsif (my $char = character_class($char[$i],$modifier)) {
7183             $char[$i] = $char;
7184             }
7185              
7186 0           # split(m/^/) --> split(m/^/m)
7187             elsif (($char[$i] eq '^') and ($modifier !~ /m/oxms)) {
7188             $modifier .= 'm';
7189             }
7190              
7191 0 0         # /i modifier
7192 0           elsif ($ignorecase and ($char[$i] =~ /\A [\x00-\xFF] \z/oxms) and (Ewindows1257::uc($char[$i]) ne Ewindows1257::fc($char[$i]))) {
7193             if (CORE::length(Ewindows1257::fc($char[$i])) == 1) {
7194             $char[$i] = '[' . Ewindows1257::uc($char[$i]) . Ewindows1257::fc($char[$i]) . ']';
7195 0           }
7196             else {
7197             $char[$i] = '(?:' . Ewindows1257::uc($char[$i]) . '|' . Ewindows1257::fc($char[$i]) . ')';
7198             }
7199             }
7200              
7201 0 0         # quote character before ? + * {
7202             elsif (($i >= 1) and ($char[$i] =~ /\A [\?\+\*\{] \z/oxms)) {
7203             if ($char[$i-1] =~ /\A [\x00-\xFF] \z/oxms) {
7204 0           }
7205             else {
7206             $char[$i-1] = '(?:' . $char[$i-1] . ')';
7207             }
7208             }
7209 0           }
7210 0            
7211             $modifier =~ tr/i//d;
7212             return join '', 'Ewindows1257::split', $ope, $delimiter, @char, $end_delimiter, $modifier;
7213             }
7214              
7215             #
7216             # instead of Carp::carp
7217 0     0 0   #
7218 0           sub carp {
7219             my($package,$filename,$line) = caller(1);
7220             print STDERR "@_ at $filename line $line.\n";
7221             }
7222              
7223             #
7224             # instead of Carp::croak
7225 0     0 0   #
7226 0           sub croak {
7227 0           my($package,$filename,$line) = caller(1);
7228             print STDERR "@_ at $filename line $line.\n";
7229             die "\n";
7230             }
7231              
7232             #
7233             # instead of Carp::cluck
7234 0     0 0   #
7235 0           sub cluck {
7236 0           my $i = 0;
7237 0           my @cluck = ();
7238 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7239             push @cluck, "[$i] $filename($line) $package::$subroutine\n";
7240 0           $i++;
7241 0           }
7242 0           print STDERR CORE::reverse @cluck;
7243             print STDERR "\n";
7244             print STDERR @_;
7245             }
7246              
7247             #
7248             # instead of Carp::confess
7249 0     0 0   #
7250 0           sub confess {
7251 0           my $i = 0;
7252 0           my @confess = ();
7253 0           while (my($package,$filename,$line,$subroutine) = caller($i)) {
7254             push @confess, "[$i] $filename($line) $package::$subroutine\n";
7255 0           $i++;
7256 0           }
7257 0           print STDERR CORE::reverse @confess;
7258 0           print STDERR "\n";
7259             print STDERR @_;
7260             die "\n";
7261             }
7262              
7263             1;
7264              
7265             __END__