File Coverage

blib/lib/String/Multibyte.pm
Criterion Covered Total %
statement 290 312 92.9
branch 265 334 79.3
condition 78 110 70.9
subroutine 27 28 96.4
pod 13 13 100.0
total 673 797 84.4


line stmt bran cond sub pod time code
1             package String::Multibyte;
2              
3             #
4             # /o never allowed!
5             #
6              
7             BEGIN {
8 22     22   13938 if (ord("A") == 193) {
9             die "String::Multibyte not ported to EBCDIC\n";
10             }
11             }
12              
13 22     22   116 use strict;
  22         21  
  22         626  
14 22     22   94 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  22         23  
  22         1445  
15 22     22   109 use Carp;
  22         21  
  22         3587  
16             require Exporter;
17              
18             @ISA = qw(Exporter);
19             @EXPORT = qw();
20              
21             $VERSION = '1.11';
22              
23             my $PACKAGE = 'String::Multibyte'; # __PACKAGE__
24              
25             my $Msg_malfo = $PACKAGE ." malformed %s character";
26             my $Msg_undef = $PACKAGE ." undefined %s";
27             my $Msg_panic = $PACKAGE ." panic in %s";
28             my $Msg_revrs = $PACKAGE ." reverse in %s";
29             my $Msg_outstr = $PACKAGE ." substr outside of string";
30             my $Msg_lastc = $PACKAGE ." reach the last char before end of char range";
31              
32             (my $Path = $INC{'String/Multibyte.pm'}) =~ s/\.pm$//;
33              
34 22     22   97 use vars qw($hasFS);
  22         26  
  22         77799  
35             eval { require File::Spec; };
36             $hasFS = $@ ? 0 : 1;
37              
38             #==========
39             # new
40             #
41             sub new {
42 148     148 1 11043 my $class = shift;
43 148         225 my $charset = shift;
44 148         177 my $verbose = shift;
45 148         184 my ($pm, $self);
46 148 100       352 if (ref $charset) {
47 8         33 $self = { %$charset };
48             } else {
49 140 50       2340 $pm = $hasFS
50             ? File::Spec->catfile($Path, "$charset.pm")
51             : "$Path/$charset.pm";
52 140 50       61443 $self = do($pm) or croak "not exist $pm";
53             }
54 148 50       603 defined $self->{regexp}
55             or croak sprintf $Msg_undef, "regexp";
56 148 50       9452 $] < 5.005
57             or eval q{ $self->{regexp} = qr/$self->{regexp}/; };
58              
59 148 100       798 $verbose and $self->{verbose} = $verbose;
60 148 100       374 defined $self->{charset}
61             or $self->{charset} = "$charset"; # stringified
62 148         711 return bless $self, $class;
63             }
64              
65             #==========
66             # islegal
67             #
68             sub islegal {
69 47127     47127 1 38238 my $obj = shift;
70 47127 50       79538 my $re = $obj->{regexp}
71             or croak sprintf $Msg_undef, "regexp";
72 47127         55646 for (@_) {
73 64791         54844 my $str = $_;
74 64791         415614 $str =~ s/$re//g;
75 64791 100       133921 return '' if CORE::length($str);
76             }
77 47084         136805 return 1;
78             }
79              
80             #==========
81             # length
82             #
83             sub length {
84 118     118 1 811 my $obj = shift;
85 118         118 my $str = shift;
86 118 50       263 my $re = $obj->{regexp}
87             or croak sprintf $Msg_undef, "regexp";
88              
89 118 50 66     387 if ($obj->{verbose} && ! $obj->islegal($str)) {
90 0         0 carp sprintf $Msg_malfo, $obj->{charset};
91             }
92 118         9304 return 0 + $str =~ s/$re//g;
93             }
94              
95             #==========
96             # __strlen: for internal use
97             #
98             sub __strlen {
99 14231     14231   14451 my ($re, $str) = @_;
100 14231         125739 return 0 + $str =~ s/$re//g;
101             }
102              
103              
104             #==========
105             # strrev
106             #
107             sub strrev {
108 54     54 1 954 my $obj = shift;
109 54         68 my $str = shift;
110 54 50       189 my $re = $obj->{regexp}
111             or croak sprintf $Msg_undef, "regexp";
112              
113 54 50 66     179 if ($obj->{verbose} && ! $obj->islegal($str)) {
114 0         0 carp sprintf $Msg_malfo, $obj->{charset};
115             }
116 54         15011 return join '', reverse $str =~ /$re/g;
117             }
118              
119              
120             #==========
121             # _check_n($re, $str, $sub, $len), internally used, non-OO
122             #
123             # like ($obj->substr($str, 0, $len) eq $sub);
124             # $len must be equal to $obj->length($sub);
125             #
126             sub _check_n {
127 4828     4828   21107 my($re, $str, $sub, $len) = @_;
128 4828         3888 my $cnt = 0;
129 4828         3572 my $temp = "";
130 4828         19830 while ($str =~ /($re)/g) {
131 13587 100       19784 last unless $cnt < $len;
132 8906         9961 $temp .= $1;
133 8906         25260 $cnt++;
134             }
135 4828         17079 return $sub eq $temp;
136             }
137              
138             #==========
139             # index
140             #
141             sub index {
142 553     553 1 2441 my $obj = shift;
143 553 50       927 my $re = $obj->{regexp}
144             or croak sprintf $Msg_undef, "regexp";
145              
146 553         389 my $cnt = 0;
147 553         507 my($str,$sub) = @_;
148 553 50 66     1123 if ($obj->{verbose} && ! $obj->islegal($str, $sub)) {
149 0         0 carp sprintf $Msg_malfo, $obj->{charset};
150             }
151 553         633 my $len = __strlen($re, $str);
152 553 100       753 my $pos = @_ == 3 ? $_[2] : 0;
153              
154 553 100       794 if ($sub eq "") {
155 117 100       300 return $pos <= 0 ? 0 : $len < $pos ? $len : $pos;
    100          
156             }
157 436 100       603 return -1 if $len < $pos;
158 404         770 my $pat = quotemeta($sub);
159 404         439 my $sublen = __strlen($re, $sub);
160 404 50 100     8634 $str =~ s/^$re// ? $cnt++ : croak
161             while CORE::length($str) && $cnt < $pos;
162 404         519 while (CORE::length($str)) {
163             last
164 71179 100 100     146522 if $str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen);
165 70855 50       332018 $str =~ s/^$re// ? $cnt++ : croak;
166             }
167 404 100       863 return CORE::length($str) ? $cnt : -1;
168             }
169              
170             #==========
171             # rindex
172             #
173             sub rindex {
174 534     534 1 3108 my $obj = shift;
175 534 50       913 my $re = $obj->{regexp}
176             or croak sprintf $Msg_undef, "regexp";
177              
178 534         377 my $cnt = 0;
179 534         614 my($str,$sub) = @_;
180 534 50 66     1114 if ($obj->{verbose} && ! $obj->islegal($str, $sub)) {
181 0         0 carp sprintf $Msg_malfo, $obj->{charset};
182             }
183 534         625 my $len = __strlen($re, $str);
184 534 100       765 my $pos = @_ == 3 ? $_[2] : $len;
185 534 100       789 if ($sub eq "") {
186 117 100       297 return $pos <= 0 ? 0 : $len <= $pos ? $len : $pos;
    100          
187             }
188 417 100       672 return -1 if $pos < 0;
189 295         285 my $pat = quotemeta($sub);
190 295         331 my $sublen = __strlen($re, $sub);
191 295         269 my $ret = -1;
192 295   100     947 while ($cnt <= $pos && CORE::length($str)) {
193 71821 100 100     158981 $ret = $cnt
194             if $str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen);
195 71821 50       447104 $str =~ s/^$re// ? $cnt++ : croak;
196             }
197 295         492 return $ret;
198             }
199              
200             #==========
201             # _splitlist
202             #
203             sub _splitlist {
204 84     84   69 my @ret;
205 84         84 my ($list, $re) = @_;
206 84 100       151 for (ref $list eq 'ARRAY' ? @$list : $list) {
207 87         700 push @ret, /\G$re/g;
208             }
209 84         380 return @ret;
210             }
211              
212              
213             #==========
214             # strspn
215             #
216             sub strspn {
217 46     46 1 764 my $obj = shift;
218 46 50       106 my $re = $obj->{regexp}
219             or croak sprintf $Msg_undef, "regexp";
220              
221 46         63 my($str, $lst) = @_;
222 46 50 33     148 if ($obj->{verbose} && ! $obj->islegal($str, $lst)) {
223 0         0 carp sprintf $Msg_malfo, $obj->{charset};
224             }
225 46         49 my $ret = 0;
226 46         40 my(%lst);
227 46         80 @lst{ _splitlist($lst, $re) } = ();
228 46         385 while ($str =~ /($re)/g) {
229 35162 100       49796 last unless exists $lst{$1};
230 35137         84361 $ret++;
231             }
232 46         128 return $ret;
233             }
234              
235              
236             #==========
237             # strcspn
238             #
239             sub strcspn {
240 38     38 1 529 my $obj = shift;
241 38 50       87 my $re = $obj->{regexp}
242             or croak sprintf $Msg_undef, "regexp";
243              
244 38         49 my($str, $lst) = @_;
245 38 50 33     119 if ($obj->{verbose} && ! $obj->islegal($str, $lst)) {
246 0         0 carp sprintf $Msg_malfo, $obj->{charset};
247             }
248 38         44 my $ret = 0;
249 38         28 my(%lst);
250 38         72 @lst{ _splitlist($lst, $re) } = ();
251 38         353 while ($str =~ /($re)/g) {
252 35109 100       49592 last if exists $lst{$1};
253 35091         83638 $ret++;
254             }
255 38         100 return $ret;
256             }
257              
258             #==========
259             # substr
260             #
261             sub substr {
262 12319     12319 1 338172 my $obj = shift;
263 12319 50       25433 my $re = $obj->{regexp}
264             or croak sprintf $Msg_undef, "regexp";
265 12319         9111 my(@chars, $slen, $ini, $fin, $except);
266 12319         10896 my $arg = $_[0];
267 12319         10246 my $off = $_[1];
268 12319         8894 my $len = $_[2];
269 12319 100       18647 my $rep = @_ > 3 ? $_[3] : '';
270              
271 12319 100       16300 my $str = ref $arg ? $$arg : $arg;
272 12319 50 33     27037 if ($obj->{verbose} && ! $obj->islegal($str, $rep)) {
273 0         0 carp sprintf $Msg_malfo, $obj->{charset};
274             }
275              
276 12319         15870 $slen = __strlen($re, $str);
277 12319 100       20888 $except = 1 if $slen < $off;
278 12319 100       18411 if (@_ == 2) {
279 384         364 $len = $slen - $off;
280             } else {
281 11935 100 100     21894 $except = 1 if $off + $slen < 0 && $len + $slen < 0;
282 11935 100 100     32472 $except = 1 if 0 <= $len && $off + $len + $slen < 0;
283             }
284 12319 100       16436 if ($except) {
285 550 50       713 if(@_ > 3) {
286 0         0 croak $Msg_outstr;
287             } else {
288 550         1011 return;
289             }
290             }
291 11769 100       16285 $ini = $off < 0 ? $slen + $off : $off;
292 11769 100       14733 $fin = $len < 0 ? $slen + $len : $ini + $len;
293 11769 100       16303 $ini = 0 if $ini < 0;
294 11769 100       17049 $fin = $ini if $ini > $fin;
295 11769 50       14567 $ini = $slen if $slen < $ini;
296 11769 100       14228 $fin = $slen if $slen < $fin;
297              
298 11769         8301 my $cnt = 0;
299 11769         7779 my $plen = 0;
300 11769         8917 my $clen = 0;
301 11769         46914 while ($str =~ /($re)/g) {
302 122068 100       144325 if ($cnt < $ini) {
    100          
303 87888         84331 $plen += CORE::length($1);
304             } elsif ($cnt < $fin) {
305 26576         27340 $clen += CORE::length($1);
306             } else {
307 7604         7974 last;
308             }
309 114464         297298 $cnt++;
310             }
311 11769 100       21284 my $temp = ref $arg
312             ? \ CORE::substr($$arg, $plen, $clen)
313             : CORE::substr($str, $plen, $clen);
314              
315 11769 100       18093 if (@_ > 3) {
316 3570         6790 $_[0] = CORE::substr($str, 0, $plen) .$rep.
317             CORE::substr($str, $plen + $clen);
318             }
319 11769         28739 return $temp;
320             }
321              
322             #==========
323             # mkrange
324             #
325             sub mkrange {
326 6478     6478 1 9014 my($s, @retv, $range);
327 6478         6058 my $obj = shift;
328 6478 50       11320 my $re = $obj->{regexp}
329             or croak sprintf $Msg_undef, "regexp";
330 6478         6799 my($str,$rev) = @_;
331 6478 100       10274 my $hyp = exists $obj->{hyphen} ? $obj->{hyphen} : '-';
332 6478 100       8471 my $esc = exists $obj->{escape} ? $obj->{escape} : '\\';
333              
334 6478 50 66     14165 if ($obj->{verbose} && ! $obj->islegal($str)) {
335 0         0 carp sprintf "$Msg_malfo in mkrange", $obj->{charset};
336             }
337 6478 100       11333 if (!defined $obj->{nextchar}) {
338 22 50       176 return wantarray ? $str =~ /$re/g : $str;
339             }
340 6456         13113 $str =~ s/^\Q$hyp\E/$esc$hyp/;
341 6456         5460 $range = 0;
342 6456         41623 foreach $s ($str =~ /\G(?:\Q$esc$esc\E|\Q$esc$hyp\E|$re)/g) {
343 21673 100       24396 if ($range) {
344 567 50       1282 if ($s eq "$esc$hyp") {
    50          
345 0         0 $s = $hyp;
346             } elsif ($s eq "$esc$esc") {
347 0         0 $s = $esc;
348             }
349 567 50       936 my $p = @retv
350             ? pop(@retv)
351             : croak(sprintf $Msg_panic, "mkrange: Parse exception" .
352             "; no initial character in a range");
353 567         1567 push @retv, $obj->__expand($p, $s, $rev);
354 567         1249 $range = 0;
355             }
356             else {
357 21106 100       43514 if ($s eq $hyp) {
    100          
    100          
358 603         667 $range = 1;
359             } elsif($s eq "$esc$hyp") {
360 64         84 push @retv, $hyp;
361             } elsif ($s eq "$esc$esc") {
362 36         44 push @retv, $esc;
363             } else {
364 20403         26654 push @retv, $s;
365             }
366             }
367             }
368 6456 100       11622 push @retv, $hyp if $range;
369 6456 100       25002 wantarray ? @retv : @retv ? join('', @retv) : '';
    100          
370             }
371              
372             sub __expand {
373 567     567   484 my $obj = shift;
374 567         678 my($fr,$to,$rev) = @_;
375              
376 567 100 66     1155 if (defined $obj->{cmpchar} &&
  567         1396  
377             &{ $obj->{cmpchar} }($fr,$to) > 0) {
378 57 100       84 return if ! $rev;
379 53         74 ($fr,$to) = ($to,$fr);
380             } else {
381 510         472 $rev = 0;
382             }
383              
384 563         615 my $c = $fr;
385 563         433 my @retv;
386 563         562 my $nextchar = $obj->{nextchar};
387 563         432 while (1) {
388 11948         10161 push @retv, $c;
389 11948 100       16649 last if $c eq $to;
390 11385         16491 $c = &$nextchar($c);
391 11385 50       16488 croak $Msg_lastc if !defined $c;
392             }
393 563 100       4092 return $rev ? reverse(@retv) : @retv;
394             }
395              
396             #==========
397             # strtr
398             #
399             my %Cache;
400              
401             sub strtr {
402 2956     2956 1 287022 my $obj = shift;
403 2956 50       6942 my $re = $obj->{regexp}
404             or croak sprintf $Msg_undef, "regexp";
405 2956         2599 my $str = shift;
406              
407 2956 100 66     12362 if ($obj->{verbose} && ! $obj->islegal(ref $str ? $$str : $str)) {
    50          
408 0         0 carp sprintf "$Msg_malfo in strtr", $obj->{charset};
409             }
410 2956         2676 my $coderef;
411 2956 50 66     11701 if (defined $_[2] && $_[2] =~ /o/) {
412 0 0 0     0 $coderef = (
413             $Cache{ $obj->{charset} }{ $_[0] }{ $_[1] }
414             { defined $_[2] ? $_[2] : ''} ||= $obj->trclosure(@_)
415             );
416             }
417             else {
418 2956         4701 $coderef = $obj->trclosure(@_);
419             }
420 2956         4762 &$coderef($str);
421             }
422              
423             #============
424             # trclosure
425             #
426             sub trclosure {
427 3082     3082 1 3786 my(@fr, @to, $h, $r, $R, $c, $d, $s, $v, $i, %hash);
428 3082         2951 my $obj = shift;
429 3082 50       5688 my $re = $obj->{regexp} or croak sprintf $Msg_undef, "regexp";
430              
431 3082         2810 my $fr = shift;
432 3082         2330 my $to = shift;
433 3082 100       4014 my $mod = @_ ? shift : '';
434              
435 3082 50 66     7208 if ($obj->{verbose} && ! $obj->islegal($fr, $to)) {
436 0         0 carp sprintf "$Msg_malfo in trclosure", $obj->{charset};
437             }
438 3082         10949 my $msg = sprintf "$Msg_malfo in closure", $obj->{charset};
439              
440 3082         3933 $h = $mod =~ /h/;
441 3082         3239 $r = $mod =~ /r/;
442 3082         2806 $R = $mod =~ /R/;
443 3082         2934 $v = $obj->{verbose};
444              
445 3082 100       6073 for (ref $fr eq 'ARRAY' ? @$fr: $fr) {
446 3086 100       7407 push @fr, $R ? /\G$re/g : $obj->mkrange($_, $r);
447             }
448              
449 3082 100       5315 for (ref $to eq 'ARRAY' ? @$to : $to) {
450 3084 100       6418 push @to, $R ? /\G$re/g : $obj->mkrange($_, $r);
451             }
452              
453 3082         4486 $c = $mod =~ /c/;
454 3082         3440 $d = $mod =~ /d/;
455 3082         3235 $s = $mod =~ /s/;
456 3082         4709 $mod = $s * 4 + $d * 2 + $c;
457              
458 3082         6088 for ($i = 0; $i < @fr; $i++) {
459 14941 100       22005 next if exists $hash{ $fr[$i] };
460 13981 100 100     47902 $hash{ $fr[$i] } = @to
    100          
    100          
    100          
461             ? defined $to[$i] ? $to[$i] : $d ? '' : $to[-1]
462             : $d && !$c ? '' : $fr[$i];
463             }
464             return
465             $mod == 3 || $mod == 7 ?
466             sub { # $c: true, $d: true, $s: true/false, $mod: 3 or 7
467 722     722   727 my $str = shift;
468 722 50 33     2456 if ($v && !$obj->islegal(ref $str ? $$str : $str)) {
    50          
469 0         0 carp $msg;
470             }
471 722         729 my $cnt = 0;
472 722         1050 my %cnt = ();
473 722 50       3762 (ref $str ? $$str : $str) =~ s{($re)}{
474 23060 100       52089 exists $hash{$1} ? $1 : ($h ? ++$cnt{$1} : ++$cnt, '');
    100          
475             }ge;
476 722 50       6235 return $h
    50          
    100          
477             ? wantarray ? %cnt : \%cnt
478             : ref $str ? $cnt : $str;
479             } :
480             $mod == 5 ?
481             sub { # $c: true, $d: false, $s: true, $mod: 5
482 364     364   356 my $str = shift;
483 364 100 33     1231 if ($v && !$obj->islegal(ref $str ? $$str : $str)) {
    50          
484 0         0 carp $msg;
485             }
486 364         347 my $cnt = 0;
487 364         512 my %cnt = ();
488 364         306 my $pre = '';
489 364         374 my $now;
490 364 100       2111 (ref $str ? $$str : $str) =~ s{($re)}{
491 11580 50       35356 exists $hash{$1}
    100          
    100          
    100          
492             ? ($pre = '', $1)
493             : ($h ? ++$cnt{$1} : ++$cnt,
494             $now = @to ? $to[-1] : $1,
495             $now eq $pre ? '' : ($pre = $now) );
496             }ge;
497 364 0       3664 return $h
    100          
    50          
498             ? wantarray ? %cnt : \%cnt
499             : ref $str ? $cnt : $str;
500             } :
501             $mod == 4 || $mod == 6 ?
502             sub { # $c: false, $d: true/false, $s: true, $mod: 4 or 6
503 724     724   864 my $str = shift;
504 724 100 33     2408 if ($v && !$obj->islegal(ref $str ? $$str : $str)) {
    50          
505 0         0 carp $msg;
506             }
507 724         680 my $cnt = 0;
508 724         1020 my %cnt = ();
509 724         708 my $pre = '';
510 724 100       3781 (ref $str ? $$str : $str) =~ s{($re)}{
511 23092 50 100     64328 exists $hash{$1}
    100          
    100          
512             ? ($h ? ++$cnt{$1} : ++$cnt,
513             $hash{$1} eq '' || $hash{$1} eq $pre
514             ? '' : ($pre = $hash{$1}))
515             : ($pre = '', $1);
516             }ge;
517 724 0       7179 return $h
    100          
    50          
518             ? wantarray ? %cnt : \%cnt
519             : ref $str ? $cnt : $str;
520             } :
521             $mod == 1 ?
522             sub { # $c: true, $d: false, $s: false, $mod: 1
523 364     364   354 my $str = shift;
524 364 50 33     1205 if ($v && !$obj->islegal(ref $str ? $$str : $str)) {
    50          
525 0         0 carp $msg;
526             }
527 364         381 my $cnt = 0;
528 364         521 my %cnt = ();
529 364 50       2119 (ref $str ? $$str : $str) =~ s{($re)}{
530 11566 100       31366 exists $hash{$1}
    100          
    100          
531             ? $1
532             : ($h ? ++$cnt{$1} : ++$cnt, @to) ? $to[-1] : $1;
533             }ge;
534 364 50       3717 return $h
    50          
    100          
535             ? wantarray ? %cnt : \%cnt
536             : ref $str ? $cnt : $str;
537             } :
538             $mod == 0 || $mod == 2 ?
539             sub { # $c: false, $d: true/false, $s: false, $mod: 0 or 2
540 17564     17564   101857 my $str = shift;
541 17564 100 66     48881 if ($v && !$obj->islegal(ref $str ? $$str : $str)) {
    50          
542 0         0 carp $msg;
543             }
544 17564         16454 my $cnt = 0;
545 17564         21090 my %cnt = ();
546 17564 100       63977 (ref $str ? $$str : $str) =~ s{($re)}{
547 128087 100       326958 exists $hash{$1}
    100          
548             ? ($h ? ++$cnt{$1} : ++$cnt, $hash{$1})
549             : $1;
550             }ge;
551 17564 100       69049 return $h
    100          
    100          
552             ? wantarray ? %cnt : \%cnt
553             : ref $str ? $cnt : $str;
554             } :
555             sub {
556 0     0   0 croak sprintf $Msg_panic, "trclosure! Invalid Closure!";
557             }
558 3082 50 100     31079 }
    100 100        
    100 66        
    100          
    100          
559              
560             #============
561             # strsplit
562             #
563             sub strsplit {
564 1097     1097 1 17518 my $obj = shift;
565 1097 50       2155 my $re = $obj->{regexp} or croak sprintf $Msg_undef, "regexp";
566 1097         908 my $sub = shift;
567 1097         851 my $str = shift;
568 1097   100     1598 my $lim = shift || 0;
569              
570 1097 50 33     2467 if ($obj->{verbose} && ! $obj->islegal($str, $sub)) {
571 0         0 carp sprintf $Msg_malfo, $obj->{charset};
572             }
573 1097 100       2098 if ($str eq '') {
574 510 100       1032 return wantarray ? () : 0;
575             }
576 587 100 100     1585 if ($sub eq '' && $lim <= 0) {
577             return wantarray
578 40 100       340 ? ($str =~ /$re/g, $lim < 0 ? '' : ())
    100          
579             : ($lim < 0) + $obj->length($str);
580             }
581 547 100       834 if ($lim == 1) {
582 41 100       123 return wantarray ? ($str) : 1;
583             }
584              
585 506         420 my $cnt = 0;
586 506 100       975 my @ret = CORE::length($sub) ? ('') : ();
587              
588 506 100       605 if (CORE::length($sub)) {
589 126         148 my $pat = quotemeta $sub;
590 126         176 my $sublen = __strlen($re, $sub);
591              
592 126   100     690 while(($lim <= 0 || $cnt < $lim) && CORE::length($str)) {
      100        
593 1379 100 100     5656 if ($str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen)) {
    50          
594 652 0       2159 $str =~ s/^$pat//
    50          
595             or croak sprintf($Msg_panic, "strsplit"),
596             unpack('H*', CORE::length($str) > 15
597             ? CORE::substr($str, 0, 15) : $str);
598 652         2946 $cnt = push @ret, '';
599             } elsif ($str =~ s/^($re)//) {
600 727         3248 $ret[-1] .= $1;
601             } else {
602 0 0       0 croak sprintf($Msg_panic, "strsplit").
603             unpack('H*', CORE::length($str) > 10
604             ? CORE::substr($str, 0, 10) : $str);
605             }
606             }
607             } else {
608 380   66     1203 while ($cnt < $lim && CORE::length($str)) {
609 4180 50       13088 $str =~ s/^($re)//
610             or croak sprintf $Msg_panic, "strsplit ''";
611 4180         13928 $cnt = push @ret, $1;
612             }
613             }
614 506 100       932 $ret[-1] .= $str if CORE::length($str);
615 506 100       800 if ($lim == 0) {
616             pop @ret
617 24   66     145 while defined $ret[-1] && $ret[-1] eq '';
618             }
619 506         1639 return @ret;
620             }
621              
622             1;
623             __END__