| 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 |  | 23980 | if (ord("A") == 193) { | 
| 9 |  |  |  |  |  |  | die "String::Multibyte not ported to EBCDIC\n"; | 
| 10 |  |  |  |  |  |  | } | 
| 11 |  |  |  |  |  |  | } | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 22 |  |  | 22 |  | 137 | use strict; | 
|  | 22 |  |  |  |  | 38 |  | 
|  | 22 |  |  |  |  | 617 |  | 
| 14 | 22 |  |  | 22 |  | 112 | use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); | 
|  | 22 |  |  |  |  | 37 |  | 
|  | 22 |  |  |  |  | 1721 |  | 
| 15 | 22 |  |  | 22 |  | 117 | use Carp; | 
|  | 22 |  |  |  |  | 39 |  | 
|  | 22 |  |  |  |  | 4647 |  | 
| 16 |  |  |  |  |  |  | require Exporter; | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | @ISA = qw(Exporter); | 
| 19 |  |  |  |  |  |  | @EXPORT = qw(); | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | $VERSION = '1.12'; | 
| 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 |  | 116 | use vars qw($hasFS); | 
|  | 22 |  |  |  |  | 40 |  | 
|  | 22 |  |  |  |  | 104289 |  | 
| 35 |  |  |  |  |  |  | eval { require File::Spec; }; | 
| 36 |  |  |  |  |  |  | $hasFS = $@ ? 0 : 1; | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | #========== | 
| 39 |  |  |  |  |  |  | # new | 
| 40 |  |  |  |  |  |  | # | 
| 41 |  |  |  |  |  |  | sub new { | 
| 42 | 148 |  |  | 148 | 1 | 21493 | my $class   = shift; | 
| 43 | 148 |  |  |  |  | 260 | my $charset = shift; | 
| 44 | 148 |  |  |  |  | 236 | my $verbose = shift; | 
| 45 | 148 |  |  |  |  | 221 | my ($pm, $self); | 
| 46 | 148 | 100 |  |  |  | 388 | if (ref $charset) { | 
| 47 | 8 |  |  |  |  | 36 | $self = { %$charset }; | 
| 48 |  |  |  |  |  |  | } else { | 
| 49 | 140 | 50 |  |  |  | 2615 | $pm = $hasFS | 
| 50 |  |  |  |  |  |  | ? File::Spec->catfile($Path, "$charset.pm") | 
| 51 |  |  |  |  |  |  | : "$Path/$charset.pm"; | 
| 52 | 140 | 50 |  |  |  | 80139 | $self = do($pm) or croak "not exist $pm"; | 
| 53 |  |  |  |  |  |  | } | 
| 54 |  |  |  |  |  |  | defined $self->{regexp} | 
| 55 | 148 | 50 |  |  |  | 602 | or croak sprintf $Msg_undef, "regexp"; | 
| 56 | 148 | 50 |  |  |  | 10659 | $] < 5.005 | 
| 57 |  |  |  |  |  |  | or eval q{ $self->{regexp} = qr/$self->{regexp}/; }; | 
| 58 |  |  |  |  |  |  |  | 
| 59 | 148 | 100 |  |  |  | 925 | $verbose and $self->{verbose} = $verbose; | 
| 60 |  |  |  |  |  |  | defined $self->{charset} | 
| 61 | 148 | 100 |  |  |  | 503 | or $self->{charset} = "$charset"; # stringified | 
| 62 | 148 |  |  |  |  | 690 | return bless $self, $class; | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | #========== | 
| 66 |  |  |  |  |  |  | # islegal | 
| 67 |  |  |  |  |  |  | # | 
| 68 |  |  |  |  |  |  | sub islegal { | 
| 69 | 47127 |  |  | 47127 | 1 | 63285 | my $obj = shift; | 
| 70 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 71 | 47127 | 50 |  |  |  | 112969 | or croak sprintf $Msg_undef, "regexp"; | 
| 72 | 47127 |  |  |  |  | 85762 | for (@_) { | 
| 73 | 64791 |  |  |  |  | 95857 | my $str = $_; | 
| 74 | 64791 |  |  |  |  | 550998 | $str =~ s/$re//g; | 
| 75 | 64791 | 100 |  |  |  | 183637 | return '' if CORE::length($str); | 
| 76 |  |  |  |  |  |  | } | 
| 77 | 47084 |  |  |  |  | 177457 | return 1; | 
| 78 |  |  |  |  |  |  | } | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | #========== | 
| 81 |  |  |  |  |  |  | # length | 
| 82 |  |  |  |  |  |  | # | 
| 83 |  |  |  |  |  |  | sub length { | 
| 84 | 118 |  |  | 118 | 1 | 2290 | my $obj = shift; | 
| 85 | 118 |  |  |  |  | 188 | my $str = shift; | 
| 86 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 87 | 118 | 50 |  |  |  | 325 | or croak sprintf $Msg_undef, "regexp"; | 
| 88 |  |  |  |  |  |  |  | 
| 89 | 118 | 50 | 66 |  |  | 539 | if ($obj->{verbose} && ! $obj->islegal($str)) { | 
| 90 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 91 |  |  |  |  |  |  | } | 
| 92 | 118 |  |  |  |  | 11749 | return 0 + $str =~ s/$re//g; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | #========== | 
| 96 |  |  |  |  |  |  | # __strlen: for internal use | 
| 97 |  |  |  |  |  |  | # | 
| 98 |  |  |  |  |  |  | sub __strlen { | 
| 99 | 14231 |  |  | 14231 |  | 22265 | my ($re, $str) = @_; | 
| 100 | 14231 |  |  |  |  | 176550 | return 0 + $str =~ s/$re//g; | 
| 101 |  |  |  |  |  |  | } | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | #========== | 
| 105 |  |  |  |  |  |  | # strrev | 
| 106 |  |  |  |  |  |  | # | 
| 107 |  |  |  |  |  |  | sub strrev { | 
| 108 | 54 |  |  | 54 | 1 | 1747 | my $obj = shift; | 
| 109 | 54 |  |  |  |  | 80 | my $str = shift; | 
| 110 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 111 | 54 | 50 |  |  |  | 167 | or croak sprintf $Msg_undef, "regexp"; | 
| 112 |  |  |  |  |  |  |  | 
| 113 | 54 | 50 | 66 |  |  | 185 | if ($obj->{verbose} && ! $obj->islegal($str)) { | 
| 114 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 115 |  |  |  |  |  |  | } | 
| 116 | 54 |  |  |  |  | 20137 | 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 |  | 32054 | my($re, $str, $sub, $len) = @_; | 
| 128 | 4828 |  |  |  |  | 6098 | my $cnt = 0; | 
| 129 | 4828 |  |  |  |  | 6612 | my $temp = ""; | 
| 130 | 4828 |  |  |  |  | 27186 | while ($str =~ /($re)/g) { | 
| 131 | 13587 | 100 |  |  |  | 31087 | last unless $cnt < $len; | 
| 132 | 8906 |  |  |  |  | 14896 | $temp .= $1; | 
| 133 | 8906 |  |  |  |  | 40524 | $cnt++; | 
| 134 |  |  |  |  |  |  | } | 
| 135 | 4828 |  |  |  |  | 23649 | return $sub eq $temp; | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | #========== | 
| 139 |  |  |  |  |  |  | # index | 
| 140 |  |  |  |  |  |  | # | 
| 141 |  |  |  |  |  |  | sub index { | 
| 142 | 553 |  |  | 553 | 1 | 4020 | my $obj = shift; | 
| 143 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 144 | 553 | 50 |  |  |  | 1368 | or croak sprintf $Msg_undef, "regexp"; | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 553 |  |  |  |  | 658 | my $cnt = 0; | 
| 147 | 553 |  |  |  |  | 863 | my($str,$sub) = @_; | 
| 148 | 553 | 50 | 66 |  |  | 1814 | if ($obj->{verbose} && ! $obj->islegal($str, $sub)) { | 
| 149 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 150 |  |  |  |  |  |  | } | 
| 151 | 553 |  |  |  |  | 1130 | my $len = __strlen($re, $str); | 
| 152 | 553 | 100 |  |  |  | 1333 | my $pos = @_ == 3 ? $_[2] : 0; | 
| 153 |  |  |  |  |  |  |  | 
| 154 | 553 | 100 |  |  |  | 1193 | if ($sub eq "") { | 
| 155 | 117 | 100 |  |  |  | 476 | return $pos <= 0 ? 0 : $len < $pos ? $len : $pos; | 
|  |  | 100 |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | } | 
| 157 | 436 | 100 |  |  |  | 887 | return -1 if $len < $pos; | 
| 158 | 404 |  |  |  |  | 565 | my $pat = quotemeta($sub); | 
| 159 | 404 |  |  |  |  | 730 | my $sublen = __strlen($re, $sub); | 
| 160 | 404 | 50 | 100 |  |  | 13768 | $str =~ s/^$re// ? $cnt++ : croak | 
| 161 |  |  |  |  |  |  | while CORE::length($str) && $cnt < $pos; | 
| 162 | 404 |  |  |  |  | 881 | while (CORE::length($str)) { | 
| 163 |  |  |  |  |  |  | last | 
| 164 | 71179 | 100 | 100 |  |  | 215529 | if $str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen); | 
| 165 | 70855 | 50 |  |  |  | 518020 | $str =~ s/^$re// ? $cnt++ : croak; | 
| 166 |  |  |  |  |  |  | } | 
| 167 | 404 | 100 |  |  |  | 1355 | return CORE::length($str) ? $cnt : -1; | 
| 168 |  |  |  |  |  |  | } | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | #========== | 
| 171 |  |  |  |  |  |  | # rindex | 
| 172 |  |  |  |  |  |  | # | 
| 173 |  |  |  |  |  |  | sub rindex { | 
| 174 | 534 |  |  | 534 | 1 | 5903 | my $obj = shift; | 
| 175 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 176 | 534 | 50 |  |  |  | 1514 | or croak sprintf $Msg_undef, "regexp"; | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 534 |  |  |  |  | 628 | my $cnt = 0; | 
| 179 | 534 |  |  |  |  | 903 | my($str,$sub) = @_; | 
| 180 | 534 | 50 | 66 |  |  | 1843 | if ($obj->{verbose} && ! $obj->islegal($str, $sub)) { | 
| 181 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 182 |  |  |  |  |  |  | } | 
| 183 | 534 |  |  |  |  | 985 | my $len = __strlen($re, $str); | 
| 184 | 534 | 100 |  |  |  | 1280 | my $pos = @_ == 3 ? $_[2] : $len; | 
| 185 | 534 | 100 |  |  |  | 1151 | if ($sub eq "") { | 
| 186 | 117 | 100 |  |  |  | 491 | return $pos <= 0 ? 0 : $len <= $pos ? $len : $pos; | 
|  |  | 100 |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | } | 
| 188 | 417 | 100 |  |  |  | 1050 | return -1 if $pos < 0; | 
| 189 | 295 |  |  |  |  | 470 | my $pat = quotemeta($sub); | 
| 190 | 295 |  |  |  |  | 499 | my $sublen = __strlen($re, $sub); | 
| 191 | 295 |  |  |  |  | 423 | my $ret = -1; | 
| 192 | 295 |  | 100 |  |  | 1295 | while ($cnt <= $pos && CORE::length($str)) { | 
| 193 | 71821 | 100 | 100 |  |  | 263729 | $ret = $cnt | 
| 194 |  |  |  |  |  |  | if $str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen); | 
| 195 | 71821 | 50 |  |  |  | 725374 | $str =~ s/^$re// ? $cnt++ : croak; | 
| 196 |  |  |  |  |  |  | } | 
| 197 | 295 |  |  |  |  | 805 | return $ret; | 
| 198 |  |  |  |  |  |  | } | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | #========== | 
| 201 |  |  |  |  |  |  | # _splitlist | 
| 202 |  |  |  |  |  |  | # | 
| 203 |  |  |  |  |  |  | sub _splitlist { | 
| 204 | 84 |  |  | 84 |  | 102 | my @ret; | 
| 205 | 84 |  |  |  |  | 126 | my ($list, $re) = @_; | 
| 206 | 84 | 100 |  |  |  | 224 | for (ref $list eq 'ARRAY' ? @$list : $list) { | 
| 207 | 87 |  |  |  |  | 857 | push @ret, /\G$re/g; | 
| 208 |  |  |  |  |  |  | } | 
| 209 | 84 |  |  |  |  | 424 | return @ret; | 
| 210 |  |  |  |  |  |  | } | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | #========== | 
| 214 |  |  |  |  |  |  | # strspn | 
| 215 |  |  |  |  |  |  | # | 
| 216 |  |  |  |  |  |  | sub strspn { | 
| 217 | 46 |  |  | 46 | 1 | 3108 | my $obj = shift; | 
| 218 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 219 | 46 | 50 |  |  |  | 138 | or croak sprintf $Msg_undef, "regexp"; | 
| 220 |  |  |  |  |  |  |  | 
| 221 | 46 |  |  |  |  | 91 | my($str, $lst) = @_; | 
| 222 | 46 | 50 | 33 |  |  | 186 | if ($obj->{verbose} && ! $obj->islegal($str, $lst)) { | 
| 223 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 224 |  |  |  |  |  |  | } | 
| 225 | 46 |  |  |  |  | 73 | my $ret = 0; | 
| 226 | 46 |  |  |  |  | 55 | my(%lst); | 
| 227 | 46 |  |  |  |  | 108 | @lst{ _splitlist($lst, $re) } = (); | 
| 228 | 46 |  |  |  |  | 466 | while ($str =~ /($re)/g) { | 
| 229 | 35162 | 100 |  |  |  | 75800 | last unless exists $lst{$1}; | 
| 230 | 35137 |  |  |  |  | 128804 | $ret++; | 
| 231 |  |  |  |  |  |  | } | 
| 232 | 46 |  |  |  |  | 163 | return $ret; | 
| 233 |  |  |  |  |  |  | } | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | #========== | 
| 237 |  |  |  |  |  |  | # strcspn | 
| 238 |  |  |  |  |  |  | # | 
| 239 |  |  |  |  |  |  | sub strcspn { | 
| 240 | 38 |  |  | 38 | 1 | 1347 | my $obj = shift; | 
| 241 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 242 | 38 | 50 |  |  |  | 117 | or croak sprintf $Msg_undef, "regexp"; | 
| 243 |  |  |  |  |  |  |  | 
| 244 | 38 |  |  |  |  | 63 | my($str, $lst) = @_; | 
| 245 | 38 | 50 | 33 |  |  | 153 | if ($obj->{verbose} && ! $obj->islegal($str, $lst)) { | 
| 246 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 247 |  |  |  |  |  |  | } | 
| 248 | 38 |  |  |  |  | 50 | my $ret = 0; | 
| 249 | 38 |  |  |  |  | 51 | my(%lst); | 
| 250 | 38 |  |  |  |  | 88 | @lst{ _splitlist($lst, $re) } = (); | 
| 251 | 38 |  |  |  |  | 461 | while ($str =~ /($re)/g) { | 
| 252 | 35109 | 100 |  |  |  | 69714 | last if exists $lst{$1}; | 
| 253 | 35091 |  |  |  |  | 133682 | $ret++; | 
| 254 |  |  |  |  |  |  | } | 
| 255 | 38 |  |  |  |  | 133 | return $ret; | 
| 256 |  |  |  |  |  |  | } | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | #========== | 
| 259 |  |  |  |  |  |  | # substr | 
| 260 |  |  |  |  |  |  | # | 
| 261 |  |  |  |  |  |  | sub substr { | 
| 262 | 12319 |  |  | 12319 | 1 | 422296 | my $obj = shift; | 
| 263 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 264 | 12319 | 50 |  |  |  | 34861 | or croak sprintf $Msg_undef, "regexp"; | 
| 265 | 12319 |  |  |  |  | 14167 | my(@chars, $slen, $ini, $fin, $except); | 
| 266 | 12319 |  |  |  |  | 16086 | my $arg = $_[0]; | 
| 267 | 12319 |  |  |  |  | 14906 | my $off = $_[1]; | 
| 268 | 12319 |  |  |  |  | 13823 | my $len = $_[2]; | 
| 269 | 12319 | 100 |  |  |  | 23989 | my $rep = @_ > 3 ? $_[3] : ''; | 
| 270 |  |  |  |  |  |  |  | 
| 271 | 12319 | 100 |  |  |  | 22902 | my $str = ref $arg ? $$arg : $arg; | 
| 272 | 12319 | 50 | 33 |  |  | 39693 | if ($obj->{verbose} && ! $obj->islegal($str, $rep)) { | 
| 273 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 274 |  |  |  |  |  |  | } | 
| 275 |  |  |  |  |  |  |  | 
| 276 | 12319 |  |  |  |  | 22488 | $slen = __strlen($re, $str); | 
| 277 | 12319 | 100 |  |  |  | 29440 | $except = 1 if $slen < $off; | 
| 278 | 12319 | 100 |  |  |  | 21650 | if (@_ == 2) { | 
| 279 | 384 |  |  |  |  | 499 | $len = $slen - $off; | 
| 280 |  |  |  |  |  |  | } else { | 
| 281 | 11935 | 100 | 100 |  |  | 30338 | $except = 1 if $off + $slen < 0 && $len + $slen < 0; | 
| 282 | 11935 | 100 | 100 |  |  | 43014 | $except = 1 if 0 <= $len && $off + $len + $slen < 0; | 
| 283 |  |  |  |  |  |  | } | 
| 284 | 12319 | 100 |  |  |  | 23334 | if ($except) { | 
| 285 | 550 | 50 |  |  |  | 916 | if(@_ > 3) { | 
| 286 | 0 |  |  |  |  | 0 | croak $Msg_outstr; | 
| 287 |  |  |  |  |  |  | } else { | 
| 288 | 550 |  |  |  |  | 1427 | return; | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  | } | 
| 291 | 11769 | 100 |  |  |  | 22460 | $ini = $off < 0 ? $slen + $off : $off; | 
| 292 | 11769 | 100 |  |  |  | 21774 | $fin = $len < 0 ? $slen + $len : $ini + $len; | 
| 293 | 11769 | 100 |  |  |  | 21373 | $ini = 0     if $ini < 0; | 
| 294 | 11769 | 100 |  |  |  | 22021 | $fin = $ini  if $ini > $fin; | 
| 295 | 11769 | 50 |  |  |  | 22187 | $ini = $slen if $slen < $ini; | 
| 296 | 11769 | 100 |  |  |  | 22813 | $fin = $slen if $slen < $fin; | 
| 297 |  |  |  |  |  |  |  | 
| 298 | 11769 |  |  |  |  | 13960 | my $cnt  = 0; | 
| 299 | 11769 |  |  |  |  | 13022 | my $plen = 0; | 
| 300 | 11769 |  |  |  |  | 12897 | my $clen = 0; | 
| 301 | 11769 |  |  |  |  | 59487 | while ($str =~ /($re)/g) { | 
| 302 | 122068 | 100 |  |  |  | 224642 | if ($cnt < $ini) { | 
|  |  | 100 |  |  |  |  |  | 
| 303 | 87888 |  |  |  |  | 141110 | $plen += CORE::length($1); | 
| 304 |  |  |  |  |  |  | } elsif ($cnt < $fin) { | 
| 305 | 26576 |  |  |  |  | 40945 | $clen += CORE::length($1); | 
| 306 |  |  |  |  |  |  | } else { | 
| 307 | 7604 |  |  |  |  | 11772 | last; | 
| 308 |  |  |  |  |  |  | } | 
| 309 | 114464 |  |  |  |  | 472991 | $cnt++; | 
| 310 |  |  |  |  |  |  | } | 
| 311 | 11769 | 100 |  |  |  | 29340 | my $temp = ref $arg | 
| 312 |  |  |  |  |  |  | ? \ CORE::substr($$arg, $plen, $clen) | 
| 313 |  |  |  |  |  |  | :   CORE::substr($str,  $plen, $clen); | 
| 314 |  |  |  |  |  |  |  | 
| 315 | 11769 | 100 |  |  |  | 25707 | if (@_ > 3) { | 
| 316 | 3570 |  |  |  |  | 9289 | $_[0] = CORE::substr($str, 0,      $plen) .$rep. | 
| 317 |  |  |  |  |  |  | CORE::substr($str, $plen + $clen); | 
| 318 |  |  |  |  |  |  | } | 
| 319 | 11769 |  |  |  |  | 40407 | return $temp; | 
| 320 |  |  |  |  |  |  | } | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | #========== | 
| 323 |  |  |  |  |  |  | # mkrange | 
| 324 |  |  |  |  |  |  | # | 
| 325 |  |  |  |  |  |  | sub mkrange { | 
| 326 | 6478 |  |  | 6478 | 1 | 17538 | my($s, @retv, $range); | 
| 327 | 6478 |  |  |  |  | 8631 | my $obj = shift; | 
| 328 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 329 | 6478 | 50 |  |  |  | 15176 | or croak sprintf $Msg_undef, "regexp"; | 
| 330 | 6478 |  |  |  |  | 10619 | my($str,$rev) = @_; | 
| 331 | 6478 | 100 |  |  |  | 14376 | my $hyp = exists $obj->{hyphen} ? $obj->{hyphen} : '-'; | 
| 332 | 6478 | 100 |  |  |  | 13340 | my $esc = exists $obj->{escape} ? $obj->{escape} : '\\'; | 
| 333 |  |  |  |  |  |  |  | 
| 334 | 6478 | 50 | 66 |  |  | 21260 | if ($obj->{verbose} && ! $obj->islegal($str)) { | 
| 335 | 0 |  |  |  |  | 0 | carp sprintf "$Msg_malfo in mkrange", $obj->{charset}; | 
| 336 |  |  |  |  |  |  | } | 
| 337 | 6478 | 100 |  |  |  | 15851 | if (!defined $obj->{nextchar}) { | 
| 338 | 22 | 50 |  |  |  | 165 | return wantarray ? $str =~ /$re/g : $str; | 
| 339 |  |  |  |  |  |  | } | 
| 340 | 6456 |  |  |  |  | 18253 | $str =~ s/^\Q$hyp\E/$esc$hyp/; | 
| 341 | 6456 |  |  |  |  | 8013 | $range = 0; | 
| 342 | 6456 |  |  |  |  | 56694 | foreach $s ($str =~ /\G(?:\Q$esc$esc\E|\Q$esc$hyp\E|$re)/g) { | 
| 343 | 21673 | 100 |  |  |  | 37754 | if ($range) { | 
| 344 | 567 | 50 |  |  |  | 1644 | 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 |  |  |  | 1251 | my $p = @retv | 
| 350 |  |  |  |  |  |  | ? pop(@retv) | 
| 351 |  |  |  |  |  |  | : croak(sprintf $Msg_panic, "mkrange: Parse exception" . | 
| 352 |  |  |  |  |  |  | "; no initial character in a range"); | 
| 353 | 567 |  |  |  |  | 1366 | push @retv, $obj->__expand($p, $s, $rev); | 
| 354 | 567 |  |  |  |  | 1571 | $range = 0; | 
| 355 |  |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  | else { | 
| 357 | 21106 | 100 |  |  |  | 66568 | if ($s eq $hyp) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 358 | 603 |  |  |  |  | 913 | $range = 1; | 
| 359 |  |  |  |  |  |  | } elsif($s eq "$esc$hyp") { | 
| 360 | 64 |  |  |  |  | 116 | push @retv, $hyp; | 
| 361 |  |  |  |  |  |  | } elsif ($s eq "$esc$esc") { | 
| 362 | 36 |  |  |  |  | 68 | push @retv, $esc; | 
| 363 |  |  |  |  |  |  | } else { | 
| 364 | 20403 |  |  |  |  | 40295 | push @retv, $s; | 
| 365 |  |  |  |  |  |  | } | 
| 366 |  |  |  |  |  |  | } | 
| 367 |  |  |  |  |  |  | } | 
| 368 | 6456 | 100 |  |  |  | 16125 | push @retv, $hyp if $range; | 
| 369 | 6456 | 100 |  |  |  | 35781 | wantarray ? @retv : @retv ? join('', @retv) : ''; | 
|  |  | 100 |  |  |  |  |  | 
| 370 |  |  |  |  |  |  | } | 
| 371 |  |  |  |  |  |  |  | 
| 372 |  |  |  |  |  |  | sub __expand { | 
| 373 | 567 |  |  | 567 |  | 761 | my $obj = shift; | 
| 374 | 567 |  |  |  |  | 938 | my($fr,$to,$rev) = @_; | 
| 375 |  |  |  |  |  |  |  | 
| 376 | 567 | 100 | 66 |  |  | 1555 | if (defined $obj->{cmpchar} && | 
| 377 | 567 |  |  |  |  | 1702 | &{ $obj->{cmpchar} }($fr,$to) > 0) { | 
| 378 | 57 | 100 |  |  |  | 113 | return if ! $rev; | 
| 379 | 53 |  |  |  |  | 117 | ($fr,$to) = ($to,$fr); | 
| 380 |  |  |  |  |  |  | } else { | 
| 381 | 510 |  |  |  |  | 697 | $rev = 0; | 
| 382 |  |  |  |  |  |  | } | 
| 383 |  |  |  |  |  |  |  | 
| 384 | 563 |  |  |  |  | 877 | my $c = $fr; | 
| 385 | 563 |  |  |  |  | 619 | my @retv; | 
| 386 | 563 |  |  |  |  | 776 | my $nextchar = $obj->{nextchar}; | 
| 387 | 563 |  |  |  |  | 698 | while (1) { | 
| 388 | 11948 |  |  |  |  | 18501 | push @retv, $c; | 
| 389 | 11948 | 100 |  |  |  | 23444 | last if $c eq $to; | 
| 390 | 11385 |  |  |  |  | 26027 | $c = &$nextchar($c); | 
| 391 | 11385 | 50 |  |  |  | 24438 | croak $Msg_lastc if !defined $c; | 
| 392 |  |  |  |  |  |  | } | 
| 393 | 563 | 100 |  |  |  | 5369 | return $rev ? reverse(@retv) : @retv; | 
| 394 |  |  |  |  |  |  | } | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | #========== | 
| 397 |  |  |  |  |  |  | # strtr | 
| 398 |  |  |  |  |  |  | # | 
| 399 |  |  |  |  |  |  | my %Cache; | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | sub strtr { | 
| 402 | 2956 |  |  | 2956 | 1 | 381116 | my $obj = shift; | 
| 403 |  |  |  |  |  |  | my $re  = $obj->{regexp} | 
| 404 | 2956 | 50 |  |  |  | 8669 | or croak sprintf $Msg_undef, "regexp"; | 
| 405 | 2956 |  |  |  |  | 3944 | my $str = shift; | 
| 406 |  |  |  |  |  |  |  | 
| 407 | 2956 | 100 | 66 |  |  | 13670 | if ($obj->{verbose} && ! $obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 408 | 0 |  |  |  |  | 0 | carp sprintf "$Msg_malfo in strtr", $obj->{charset}; | 
| 409 |  |  |  |  |  |  | } | 
| 410 | 2956 |  |  |  |  | 3883 | my $coderef; | 
| 411 | 2956 | 50 | 66 |  |  | 13257 | if (defined $_[2] && $_[2] =~ /o/) { | 
| 412 |  |  |  |  |  |  | $coderef = ( | 
| 413 |  |  |  |  |  |  | $Cache{ $obj->{charset} }{ $_[0] }{ $_[1] } | 
| 414 | 0 | 0 | 0 |  |  | 0 | { defined $_[2] ? $_[2] : ''} ||= $obj->trclosure(@_) | 
| 415 |  |  |  |  |  |  | ); | 
| 416 |  |  |  |  |  |  | } | 
| 417 |  |  |  |  |  |  | else { | 
| 418 | 2956 |  |  |  |  | 6438 | $coderef = $obj->trclosure(@_); | 
| 419 |  |  |  |  |  |  | } | 
| 420 | 2956 |  |  |  |  | 7299 | &$coderef($str); | 
| 421 |  |  |  |  |  |  | } | 
| 422 |  |  |  |  |  |  |  | 
| 423 |  |  |  |  |  |  | #============ | 
| 424 |  |  |  |  |  |  | # trclosure | 
| 425 |  |  |  |  |  |  | # | 
| 426 |  |  |  |  |  |  | sub trclosure { | 
| 427 | 3082 |  |  | 3082 | 1 | 5675 | my(@fr, @to, $h, $r, $R, $c, $d, $s, $v, $i, %hash); | 
| 428 | 3082 |  |  |  |  | 4267 | my $obj = shift; | 
| 429 | 3082 | 50 |  |  |  | 7894 | my $re  = $obj->{regexp} or croak sprintf $Msg_undef, "regexp"; | 
| 430 |  |  |  |  |  |  |  | 
| 431 | 3082 |  |  |  |  | 4329 | my $fr  = shift; | 
| 432 | 3082 |  |  |  |  | 4155 | my $to  = shift; | 
| 433 | 3082 | 100 |  |  |  | 6753 | my $mod = @_ ? shift : ''; | 
| 434 |  |  |  |  |  |  |  | 
| 435 | 3082 | 50 | 66 |  |  | 10290 | if ($obj->{verbose} && ! $obj->islegal($fr, $to)) { | 
| 436 | 0 |  |  |  |  | 0 | carp sprintf "$Msg_malfo in trclosure", $obj->{charset}; | 
| 437 |  |  |  |  |  |  | } | 
| 438 | 3082 |  |  |  |  | 11708 | my $msg = sprintf "$Msg_malfo in closure", $obj->{charset}; | 
| 439 |  |  |  |  |  |  |  | 
| 440 | 3082 |  |  |  |  | 6175 | $h = $mod =~ /h/; | 
| 441 | 3082 |  |  |  |  | 4621 | $r = $mod =~ /r/; | 
| 442 | 3082 |  |  |  |  | 4129 | $R = $mod =~ /R/; | 
| 443 | 3082 |  |  |  |  | 4327 | $v = $obj->{verbose}; | 
| 444 |  |  |  |  |  |  |  | 
| 445 | 3082 | 100 |  |  |  | 8133 | for (ref $fr eq 'ARRAY' ? @$fr: $fr) { | 
| 446 | 3086 | 100 |  |  |  | 9633 | push @fr, $R ? /\G$re/g : $obj->mkrange($_, $r); | 
| 447 |  |  |  |  |  |  | } | 
| 448 |  |  |  |  |  |  |  | 
| 449 | 3082 | 100 |  |  |  | 8276 | for (ref $to eq 'ARRAY' ? @$to : $to) { | 
| 450 | 3084 | 100 |  |  |  | 9356 | push @to, $R ? /\G$re/g : $obj->mkrange($_, $r); | 
| 451 |  |  |  |  |  |  | } | 
| 452 |  |  |  |  |  |  |  | 
| 453 | 3082 |  |  |  |  | 6086 | $c = $mod =~ /c/; | 
| 454 | 3082 |  |  |  |  | 4691 | $d = $mod =~ /d/; | 
| 455 | 3082 |  |  |  |  | 4920 | $s = $mod =~ /s/; | 
| 456 | 3082 |  |  |  |  | 5540 | $mod = $s * 4 + $d * 2 + $c; | 
| 457 |  |  |  |  |  |  |  | 
| 458 | 3082 |  |  |  |  | 8566 | for ($i = 0; $i < @fr; $i++) { | 
| 459 | 14941 | 100 |  |  |  | 33105 | next if exists $hash{ $fr[$i] }; | 
| 460 | 13981 | 100 | 100 |  |  | 68603 | $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 |  | 1022 | my $str = shift; | 
| 468 | 722 | 50 | 33 |  |  | 3340 | if ($v && !$obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 469 | 0 |  |  |  |  | 0 | carp $msg; | 
| 470 |  |  |  |  |  |  | } | 
| 471 | 722 |  |  |  |  | 984 | my $cnt = 0; | 
| 472 | 722 |  |  |  |  | 1256 | my %cnt = (); | 
| 473 | 722 | 50 |  |  |  | 4613 | (ref $str ? $$str : $str) =~ s{($re)}{ | 
| 474 | 23060 | 100 |  |  |  | 89043 | exists $hash{$1} ? $1 : ($h ? ++$cnt{$1} : ++$cnt, ''); | 
|  |  | 100 |  |  |  |  |  | 
| 475 |  |  |  |  |  |  | }ge; | 
| 476 | 722 | 50 |  |  |  | 8018 | 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 |  | 600 | my $str = shift; | 
| 483 | 364 | 100 | 33 |  |  | 1715 | if ($v && !$obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 484 | 0 |  |  |  |  | 0 | carp $msg; | 
| 485 |  |  |  |  |  |  | } | 
| 486 | 364 |  |  |  |  | 497 | my $cnt = 0; | 
| 487 | 364 |  |  |  |  | 611 | my %cnt = (); | 
| 488 | 364 |  |  |  |  | 495 | my $pre = ''; | 
| 489 | 364 |  |  |  |  | 545 | my $now; | 
| 490 | 364 | 100 |  |  |  | 2616 | (ref $str ? $$str : $str) =~ s{($re)}{ | 
| 491 |  |  |  |  |  |  | exists $hash{$1} | 
| 492 |  |  |  |  |  |  | ? ($pre = '', $1) | 
| 493 | 11580 | 50 |  |  |  | 61259 | : ($h ? ++$cnt{$1} : ++$cnt, | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | $now = @to ? $to[-1] : $1, | 
| 495 |  |  |  |  |  |  | $now eq $pre ? '' : ($pre = $now) ); | 
| 496 |  |  |  |  |  |  | }ge; | 
| 497 | 364 | 0 |  |  |  | 4748 | 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 |  | 1104 | my $str = shift; | 
| 504 | 724 | 100 | 33 |  |  | 3432 | if ($v && !$obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 505 | 0 |  |  |  |  | 0 | carp $msg; | 
| 506 |  |  |  |  |  |  | } | 
| 507 | 724 |  |  |  |  | 989 | my $cnt = 0; | 
| 508 | 724 |  |  |  |  | 1242 | my %cnt = (); | 
| 509 | 724 |  |  |  |  | 987 | my $pre = ''; | 
| 510 | 724 | 100 |  |  |  | 4952 | (ref $str ? $$str : $str) =~ s{($re)}{ | 
| 511 |  |  |  |  |  |  | exists $hash{$1} | 
| 512 |  |  |  |  |  |  | ? ($h ? ++$cnt{$1} : ++$cnt, | 
| 513 |  |  |  |  |  |  | $hash{$1} eq '' || $hash{$1} eq $pre | 
| 514 | 23092 | 50 | 100 |  |  | 105338 | ? '' : ($pre = $hash{$1})) | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 515 |  |  |  |  |  |  | : ($pre = '', $1); | 
| 516 |  |  |  |  |  |  | }ge; | 
| 517 | 724 | 0 |  |  |  | 8874 | 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 |  | 523 | my $str = shift; | 
| 524 | 364 | 50 | 33 |  |  | 1742 | if ($v && !$obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 525 | 0 |  |  |  |  | 0 | carp $msg; | 
| 526 |  |  |  |  |  |  | } | 
| 527 | 364 |  |  |  |  | 527 | my $cnt = 0; | 
| 528 | 364 |  |  |  |  | 629 | my %cnt = (); | 
| 529 | 364 | 50 |  |  |  | 2674 | (ref $str ? $$str : $str) =~ s{($re)}{ | 
| 530 |  |  |  |  |  |  | exists $hash{$1} | 
| 531 |  |  |  |  |  |  | ? $1 | 
| 532 | 11566 | 100 |  |  |  | 52482 | : ($h ? ++$cnt{$1} : ++$cnt, @to) ? $to[-1] : $1; | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | }ge; | 
| 534 | 364 | 50 |  |  |  | 4780 | 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 |  | 125807 | my $str = shift; | 
| 541 | 17564 | 100 | 66 |  |  | 68302 | if ($v && !$obj->islegal(ref $str ? $$str : $str)) { | 
|  |  | 50 |  |  |  |  |  | 
| 542 | 0 |  |  |  |  | 0 | carp $msg; | 
| 543 |  |  |  |  |  |  | } | 
| 544 | 17564 |  |  |  |  | 22317 | my $cnt = 0; | 
| 545 | 17564 |  |  |  |  | 26946 | my %cnt = (); | 
| 546 | 17564 | 100 |  |  |  | 85559 | (ref $str ? $$str : $str) =~ s{($re)}{ | 
| 547 |  |  |  |  |  |  | exists $hash{$1} | 
| 548 | 128087 | 100 |  |  |  | 510055 | ? ($h ? ++$cnt{$1} : ++$cnt, $hash{$1}) | 
|  |  | 100 |  |  |  |  |  | 
| 549 |  |  |  |  |  |  | : $1; | 
| 550 |  |  |  |  |  |  | }ge; | 
| 551 | 17564 | 100 |  |  |  | 93537 | 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 |  |  | 36471 | } | 
|  |  | 100 | 100 |  |  |  |  | 
|  |  | 100 | 66 |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 559 |  |  |  |  |  |  |  | 
| 560 |  |  |  |  |  |  | #============ | 
| 561 |  |  |  |  |  |  | # strsplit | 
| 562 |  |  |  |  |  |  | # | 
| 563 |  |  |  |  |  |  | sub strsplit { | 
| 564 | 1097 |  |  | 1097 | 1 | 36758 | my $obj = shift; | 
| 565 | 1097 | 50 |  |  |  | 3236 | my $re  = $obj->{regexp} or croak sprintf $Msg_undef, "regexp"; | 
| 566 | 1097 |  |  |  |  | 1713 | my $sub = shift; | 
| 567 | 1097 |  |  |  |  | 1829 | my $str = shift; | 
| 568 | 1097 |  | 100 |  |  | 2786 | my $lim = shift || 0; | 
| 569 |  |  |  |  |  |  |  | 
| 570 | 1097 | 50 | 33 |  |  | 3977 | if ($obj->{verbose} && ! $obj->islegal($str, $sub)) { | 
| 571 | 0 |  |  |  |  | 0 | carp sprintf $Msg_malfo, $obj->{charset}; | 
| 572 |  |  |  |  |  |  | } | 
| 573 | 1097 | 100 |  |  |  | 2752 | if ($str eq '') { | 
| 574 | 510 | 100 |  |  |  | 1809 | return wantarray ? () : 0; | 
| 575 |  |  |  |  |  |  | } | 
| 576 | 587 | 100 | 100 |  |  | 2446 | if ($sub eq '' && $lim <= 0) { | 
| 577 |  |  |  |  |  |  | return wantarray | 
| 578 | 40 | 100 |  |  |  | 608 | ? ($str =~ /$re/g, $lim < 0 ? '' : ()) | 
|  |  | 100 |  |  |  |  |  | 
| 579 |  |  |  |  |  |  | : ($lim < 0) + $obj->length($str); | 
| 580 |  |  |  |  |  |  | } | 
| 581 | 547 | 100 |  |  |  | 1290 | if ($lim == 1) { | 
| 582 | 41 | 100 |  |  |  | 161 | return wantarray ? ($str) : 1; | 
| 583 |  |  |  |  |  |  | } | 
| 584 |  |  |  |  |  |  |  | 
| 585 | 506 |  |  |  |  | 684 | my $cnt = 0; | 
| 586 | 506 | 100 |  |  |  | 1361 | my @ret = CORE::length($sub) ? ('') : (); | 
| 587 |  |  |  |  |  |  |  | 
| 588 | 506 | 100 |  |  |  | 919 | if (CORE::length($sub)) { | 
| 589 | 126 |  |  |  |  | 228 | my $pat = quotemeta $sub; | 
| 590 | 126 |  |  |  |  | 260 | my $sublen = __strlen($re, $sub); | 
| 591 |  |  |  |  |  |  |  | 
| 592 | 126 |  | 100 |  |  | 889 | while(($lim <= 0 || $cnt < $lim) && CORE::length($str)) { | 
|  |  |  | 100 |  |  |  |  | 
| 593 | 1379 | 100 | 100 |  |  | 9731 | if ($str =~ /^$pat/ && _check_n($re, $str, $sub, $sublen)) { | 
|  |  | 50 |  |  |  |  |  | 
| 594 | 652 | 0 |  |  |  | 3734 | $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 |  |  |  |  | 4579 | $cnt = push @ret, ''; | 
| 599 |  |  |  |  |  |  | } elsif ($str =~ s/^($re)//) { | 
| 600 | 727 |  |  |  |  | 5240 | $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 |  |  | 1728 | while ($cnt < $lim && CORE::length($str)) { | 
| 609 | 4180 | 50 |  |  |  | 24302 | $str =~ s/^($re)// | 
| 610 |  |  |  |  |  |  | or croak sprintf $Msg_panic, "strsplit ''"; | 
| 611 | 4180 |  |  |  |  | 24001 | $cnt = push @ret, $1; | 
| 612 |  |  |  |  |  |  | } | 
| 613 |  |  |  |  |  |  | } | 
| 614 | 506 | 100 |  |  |  | 1491 | $ret[-1] .= $str if CORE::length($str); | 
| 615 | 506 | 100 |  |  |  | 1188 | if ($lim == 0) { | 
| 616 |  |  |  |  |  |  | pop @ret | 
| 617 | 24 |  | 66 |  |  | 204 | while defined $ret[-1] && $ret[-1] eq ''; | 
| 618 |  |  |  |  |  |  | } | 
| 619 | 506 |  |  |  |  | 2649 | return @ret; | 
| 620 |  |  |  |  |  |  | } | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | 1; | 
| 623 |  |  |  |  |  |  | __END__ |