line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# $Id: Context.pm,v 1.77 1998/10/03 22:21:23 martin Exp $ |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# Convert::Context, an attributed text data type |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# Copyright (C) 1996, 1997 Martin Schwartz |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify |
9
|
|
|
|
|
|
|
# it under the terms of the GNU General Public License as published by |
10
|
|
|
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or |
11
|
|
|
|
|
|
|
# (at your option) any later version. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful, |
14
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
|
|
|
|
|
|
|
# GNU General Public License for more details. |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License |
19
|
|
|
|
|
|
|
# along with this program; if not, you should find it at: |
20
|
|
|
|
|
|
|
# |
21
|
|
|
|
|
|
|
# http://wwwwbs.cs.tu-berlin.de/~schwartz/pmh/COPYING |
22
|
|
|
|
|
|
|
# |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
package Convert::Context; |
25
|
1
|
|
|
1
|
|
751
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5413
|
|
26
|
|
|
|
|
|
|
my $VERSION=do{my@R=('$Revision: 1.77 $'=~/\d+/g);sprintf"%d."."%d"x$#R,@R}; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub CS () {"C"}; |
29
|
|
|
|
|
|
|
my $Debug = 0; |
30
|
|
|
|
|
|
|
my $default_acmp = sub { $_[0] cmp $_[1] }; |
31
|
|
|
|
|
|
|
|
32
|
456
|
|
|
456
|
1
|
859
|
sub acmp { shift->_member("A", @_) } |
33
|
244
|
50
|
|
244
|
0
|
602
|
sub docmode { shift->_mode(@_ ? ("DOC"):()) eq "DOC" } |
34
|
207
|
50
|
|
207
|
0
|
477
|
sub textmode { shift->_mode(@_ ? ("TEXT"):()) eq "TEXT" } |
35
|
|
|
|
|
|
|
|
36
|
1305
|
|
|
1305
|
|
2321
|
sub _attrib { shift->_member("ATT", @_) } |
37
|
1853
|
|
|
1853
|
|
3913
|
sub _charsize { shift->_member(CS, @_) } |
38
|
455
|
|
|
455
|
|
857
|
sub _mode { shift->_member("MOD", @_) } |
39
|
1336
|
|
|
1336
|
|
2246
|
sub _offset { shift->_member("O", @_) } |
40
|
2873
|
|
|
2873
|
|
5189
|
sub _text { shift->_member("T", @_) } |
41
|
|
|
|
|
|
|
|
42
|
8278
|
100
|
|
8278
|
|
8988
|
sub _member { my $S=shift; my $n=shift; $S->{$n}=shift if @_; $S->{$n} } |
|
8278
|
|
|
|
|
8719
|
|
|
8278
|
|
|
|
|
15805
|
|
|
8278
|
|
|
|
|
23756
|
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub append { |
45
|
|
|
|
|
|
|
# |
46
|
|
|
|
|
|
|
# $Ct1 = $Ct1 -> append (($Ctn||$strn||$strRn)*) |
47
|
|
|
|
|
|
|
# |
48
|
76
|
|
|
76
|
1
|
171
|
my $S = shift; |
49
|
76
|
|
|
|
|
132
|
my $acmp = $S->acmp(); |
50
|
|
|
|
|
|
|
|
51
|
76
|
|
|
|
|
105
|
my ($Ct2, $o); |
52
|
76
|
|
|
|
|
156
|
while (@_) { |
53
|
137
|
|
|
|
|
156
|
$Ct2 = shift; |
54
|
137
|
100
|
|
|
|
331
|
if (!ref($Ct2)) { |
|
|
50
|
|
|
|
|
|
55
|
56
|
|
|
|
|
61
|
${$S->_text} .= $Ct2; |
|
56
|
|
|
|
|
96
|
|
56
|
56
|
|
|
|
|
133
|
next; |
57
|
|
|
|
|
|
|
} elsif (ref ($Ct2) =~ /^SCALAR$/) { |
58
|
0
|
|
|
|
|
0
|
${$S->_text} .= $$Ct2; |
|
0
|
|
|
|
|
0
|
|
59
|
0
|
|
|
|
|
0
|
next; |
60
|
|
|
|
|
|
|
} |
61
|
81
|
|
|
|
|
168
|
$o = $S->length(); |
62
|
|
|
|
|
|
|
|
63
|
81
|
100
|
|
|
|
172
|
if (!$o) { |
64
|
6
|
|
|
|
|
8
|
${$S->_text} .= ${$Ct2->_text}; |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
11
|
|
65
|
6
|
|
|
|
|
10
|
@{$S->_offset}=(); |
|
6
|
|
|
|
|
11
|
|
66
|
6
|
|
|
|
|
10
|
@{$S->_attrib}=(); |
|
6
|
|
|
|
|
11
|
|
67
|
6
|
|
|
|
|
8
|
push (@{$S->_offset}, @{$Ct2->_offset}); |
|
6
|
|
|
|
|
11
|
|
|
6
|
|
|
|
|
16
|
|
68
|
6
|
|
|
|
|
10
|
push (@{$S->_attrib}, @{$Ct2->_attrib}); |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
11
|
|
69
|
6
|
|
|
|
|
16
|
next; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
75
|
|
|
|
|
81
|
${$S->_text} .= ${$Ct2->_text}; |
|
75
|
|
|
|
|
117
|
|
|
75
|
|
|
|
|
117
|
|
73
|
75
|
50
|
|
|
|
138
|
next if $S->textmode; |
74
|
75
|
|
|
|
|
163
|
my $cs = $S->_charsize; |
75
|
75
|
|
|
|
|
136
|
my $cs2 = $Ct2->_charsize; |
76
|
75
|
|
|
|
|
120
|
my $flag = ($cs==$cs2); |
77
|
|
|
|
|
|
|
|
78
|
75
|
100
|
|
|
|
176
|
if (! &$acmp ($S->_attrib->[$#{$S->_attrib}], $Ct2->_attrib->[0])) { |
|
75
|
|
|
|
|
122
|
|
79
|
19
|
|
|
|
|
19
|
my $end = $#{$Ct2->_offset}; |
|
19
|
|
|
|
|
29
|
|
80
|
19
|
0
|
|
|
|
35
|
push (@{$S->_offset}, map |
|
0
|
|
|
|
|
0
|
|
81
|
19
|
|
|
|
|
24
|
{$flag ? $_+$o : $o+$_/$cs2*$cs} @{$Ct2->_offset}[1..$end] |
|
19
|
|
|
|
|
32
|
|
82
|
|
|
|
|
|
|
); |
83
|
19
|
|
|
|
|
22
|
push (@{$S->_attrib}, @{$Ct2->_attrib}[1..$end]); |
|
19
|
|
|
|
|
27
|
|
|
19
|
|
|
|
|
27
|
|
84
|
|
|
|
|
|
|
} else { |
85
|
56
|
100
|
|
|
|
96
|
push (@{$S->_offset}, map |
|
58
|
|
|
|
|
203
|
|
86
|
56
|
|
|
|
|
68
|
{$flag ? $_+$o : $o+$_/$cs2*$cs} @{$Ct2->_offset} |
|
56
|
|
|
|
|
92
|
|
87
|
|
|
|
|
|
|
); |
88
|
56
|
|
|
|
|
75
|
push (@{$S->_attrib}, @{$Ct2->_attrib}); |
|
56
|
|
|
|
|
114
|
|
|
56
|
|
|
|
|
95
|
|
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
} |
91
|
76
|
|
|
|
|
266
|
$S; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub attrib { |
95
|
|
|
|
|
|
|
# |
96
|
|
|
|
|
|
|
# (1) $attrib = $Ct -> attrib ($o, [$attrib]) |
97
|
|
|
|
|
|
|
# (2) ([@attrib], [@o]) = $Ct -> attrib ($o, $l) |
98
|
|
|
|
|
|
|
# (3) $attrib = $Ct -> attrib ($o, $l, $attrib) |
99
|
|
|
|
|
|
|
# (4) 1 || undef = $Ct -> attrib ($o1, $l1, [@attrib], [@o]) |
100
|
|
|
|
|
|
|
# (5) 1 || undef = $Ct -> attrib ($o1, $l1, [@attrib], [@o], $o2, $l2) |
101
|
|
|
|
|
|
|
# (6) 1 || undef = $Ct1 -> attrib ($o, $l, $Ct2) |
102
|
|
|
|
|
|
|
# (7) 1 || undef = $Ct1 -> attrib ($o1, $l1, $Ct2, $o2, $l2) |
103
|
|
|
|
|
|
|
# |
104
|
102
|
|
|
102
|
1
|
217
|
my $S = shift; |
105
|
102
|
50
|
|
|
|
162
|
return undef if $S->textmode; |
106
|
|
|
|
|
|
|
|
107
|
102
|
100
|
100
|
|
|
533
|
if (!$#_ || ($#_==1) && ref($_[1])) { |
|
|
|
66
|
|
|
|
|
108
|
|
|
|
|
|
|
# case (1) |
109
|
19
|
50
|
|
|
|
40
|
my $o = @_ ? shift : 0; |
110
|
19
|
100
|
|
|
|
42
|
$o += $S->length() if $o<0; |
111
|
19
|
100
|
|
|
|
43
|
return undef if $o<0; |
112
|
|
|
|
|
|
|
|
113
|
18
|
|
|
|
|
33
|
my $i = $S->_index($o); |
114
|
18
|
100
|
|
|
|
38
|
$S->_attrib->[$i] = shift->[0] if @_; |
115
|
18
|
|
|
|
|
34
|
return $S->_attrib->[$i]; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
83
|
50
|
|
|
|
177
|
my $o1 = @_ ? shift : 0; |
119
|
83
|
50
|
|
|
|
167
|
$o1 += $S->length() if $o1<0; |
120
|
83
|
50
|
|
|
|
139
|
return undef if $o1<0; |
121
|
83
|
50
|
|
|
|
126
|
my $l1 = @_ ? shift : 0; |
122
|
83
|
100
|
|
|
|
148
|
if (!@_) { |
123
|
|
|
|
|
|
|
# case (2) |
124
|
66
|
|
100
|
|
|
131
|
my $il = $S->_index($o1) || 0; |
125
|
66
|
|
100
|
|
|
155
|
my $ir = $S->_index($o1+$l1-1) || 0; |
126
|
|
|
|
|
|
|
return ( |
127
|
66
|
|
|
|
|
109
|
[@{$S->_attrib}[$il, $il+1..$ir]], |
|
66
|
|
|
|
|
165
|
|
128
|
66
|
|
|
|
|
114
|
[0, map $_-$o1, @{$S->_offset}[$il+1..$ir]] |
129
|
|
|
|
|
|
|
); |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
17
|
50
|
|
|
|
42
|
my $ref = @_ ? ref($_[0]) : ""; |
133
|
17
|
100
|
|
|
|
76
|
if (!$ref) { |
|
|
100
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# case (3) |
135
|
1
|
50
|
|
|
|
3
|
my $attrib = @_ ? shift: 0; |
136
|
1
|
|
33
|
|
|
7
|
return $S->_subattr($o1, $l1, [$attrib], [0]) && $attrib; |
137
|
|
|
|
|
|
|
} elsif ($ref =~ /^ARRAY$/) { |
138
|
|
|
|
|
|
|
# case (4) and (5) |
139
|
12
|
|
|
|
|
29
|
return $S->_subattr($o1, $l1, @_); |
140
|
|
|
|
|
|
|
} else { |
141
|
|
|
|
|
|
|
# case (6) and (7) |
142
|
4
|
|
|
|
|
6
|
my $Ct2 = shift; |
143
|
4
|
50
|
|
|
|
10
|
push (@_, $_[2]) if $#_==2; |
144
|
4
|
|
|
|
|
10
|
return $S->_subattr($o1, $l1, $Ct2->_attrib, $Ct2->_offset, @_); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
0
|
undef; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub charsize { |
151
|
652
|
|
|
652
|
1
|
845
|
my ($S, $cs) = @_; |
152
|
652
|
|
|
|
|
1033
|
my $cs_orig = $S->_charsize(); |
153
|
652
|
100
|
66
|
|
|
2154
|
return $cs_orig if !$cs || $cs_orig==$cs; |
154
|
3
|
|
|
|
|
6
|
my $O = $S->_offset; |
155
|
3
|
|
|
|
|
7
|
for (@$O) { |
156
|
6
|
|
|
|
|
7
|
$_*=$cs_orig; $_/=$cs; |
|
6
|
|
|
|
|
13
|
|
157
|
|
|
|
|
|
|
} |
158
|
3
|
|
|
|
|
8
|
$S->_charsize($cs); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub chunks { |
162
|
|
|
|
|
|
|
# |
163
|
|
|
|
|
|
|
# [ [$str1, $attr1], [$str2, $attr2], [$str3, $attr3] ...] = $S->chunks |
164
|
|
|
|
|
|
|
# |
165
|
1
|
|
|
1
|
1
|
9
|
my $S = shift; |
166
|
1
|
|
|
|
|
3
|
my $A = $S->_attrib; |
167
|
1
|
|
|
|
|
4
|
my $O = $S->_offset; |
168
|
1
|
|
|
|
|
3
|
my $T = $S->_text; |
169
|
1
|
|
|
|
|
2
|
my $n = $#{$S->_offset}; |
|
1
|
|
|
|
|
3
|
|
170
|
1
|
|
|
|
|
3
|
my $left = 0; |
171
|
1
|
|
|
|
|
3
|
my $cs = $S->_charsize; |
172
|
1
|
|
|
|
|
22
|
[ map ( |
173
|
|
|
|
|
|
|
[substr($$T, $O->[$_-1]*$cs, $O->[$_]*$cs-$O->[$_-1]*$cs), $A->[$_-1]], |
174
|
|
|
|
|
|
|
(1..$n) |
175
|
|
|
|
|
|
|
), |
176
|
|
|
|
|
|
|
[ substr($$T, $O->[$n]*$cs, $S->length()*$cs-$O->[$n]*$cs), $A->[$n] ] |
177
|
|
|
|
|
|
|
]; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub clone { |
181
|
2
|
|
|
2
|
1
|
11
|
my $S = shift; |
182
|
2
|
|
|
|
|
5
|
my $N = $S->new( |
183
|
|
|
|
|
|
|
$S->_charsize, |
184
|
2
|
|
|
|
|
5
|
\(my $text = ${$S->_text}), |
185
|
2
|
|
|
|
|
5
|
[@{$S->_attrib}], |
186
|
2
|
|
|
|
|
6
|
[@{$S->_offset}], |
187
|
|
|
|
|
|
|
1 |
188
|
|
|
|
|
|
|
); |
189
|
2
|
|
|
|
|
7
|
$N->_mode($S->_mode); |
190
|
2
|
|
|
|
|
5
|
$N->acmp($S->acmp); |
191
|
2
|
|
|
|
|
8
|
$N; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub dump { |
195
|
0
|
|
|
0
|
1
|
0
|
my ($S, $mode) = @_; |
196
|
0
|
|
|
|
|
0
|
print "Dumping (mode $mode), object ". |
197
|
|
|
|
|
|
|
(($S =~ /(^[^=]*)/) && $1). |
198
|
0
|
|
0
|
|
|
0
|
"\n" . ${$S->sdump($mode)} . "Done.\n\n\n" |
199
|
|
|
|
|
|
|
; |
200
|
0
|
|
|
|
|
0
|
$S; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub eq { |
204
|
|
|
|
|
|
|
# |
205
|
|
|
|
|
|
|
# 1||0 = $Ct1 -> eq ($Ct2) |
206
|
|
|
|
|
|
|
# |
207
|
84
|
|
|
84
|
1
|
154
|
my ($S, $Ct2) = @_; |
208
|
84
|
50
|
|
|
|
180
|
return undef if !$Ct2; |
209
|
84
|
100
|
|
|
|
248
|
return 1 if $S eq $Ct2; |
210
|
80
|
50
|
|
|
|
169
|
return 0 if !ref($Ct2); |
211
|
80
|
50
|
|
|
|
168
|
return 0 if ref($S) ne ref($Ct2); |
212
|
80
|
100
|
|
|
|
136
|
return 0 if $S->_charsize != $Ct2->_charsize; |
213
|
77
|
100
|
|
|
|
103
|
return 0 if ${$S->_text} ne ${$Ct2->_text}; |
|
77
|
|
|
|
|
126
|
|
|
77
|
|
|
|
|
132
|
|
214
|
75
|
|
|
|
|
167
|
$S->_cmp_attribs($Ct2); |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub index { |
218
|
|
|
|
|
|
|
# |
219
|
|
|
|
|
|
|
# $pos = $Ct -> index ($string [,$pos]) |
220
|
|
|
|
|
|
|
# |
221
|
379
|
|
|
379
|
1
|
2118
|
my ($S, $str, $pos) = @_; |
222
|
379
|
|
|
|
|
636
|
my $cs = $S->charsize; |
223
|
379
|
|
100
|
|
|
1214
|
my $i = ($pos||0) * $cs - $cs; |
224
|
379
|
|
|
|
|
391
|
while (1) { |
225
|
1219
|
|
66
|
|
|
1148
|
$i = index(${$S->_text}, $str, $i+(($i%$cs)||$cs)); |
|
1219
|
|
|
|
|
2033
|
|
226
|
1219
|
100
|
|
|
|
2287
|
return $i if $cs == 1; |
227
|
1166
|
100
|
|
|
|
1968
|
return $i if $i == -1; |
228
|
1153
|
100
|
|
|
|
2052
|
if (!($i % $cs)) { |
229
|
313
|
|
|
|
|
839
|
return $i / $cs; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub join { |
235
|
|
|
|
|
|
|
# |
236
|
|
|
|
|
|
|
# $Ct = Convert::Context -> join ($expr, ($Ctn||$strn||$strRn)*) |
237
|
|
|
|
|
|
|
# |
238
|
|
|
|
|
|
|
# $Ct1 = $Ct1 -> join ($expr, ($Ctn||$strn||$strRn)*) |
239
|
|
|
|
|
|
|
# |
240
|
6
|
|
|
6
|
1
|
30
|
my $S = shift; |
241
|
6
|
50
|
|
|
|
17
|
return undef if !@_; |
242
|
6
|
|
|
|
|
8
|
my $expr = shift; |
243
|
6
|
|
|
|
|
11
|
my @extra = (); |
244
|
|
|
|
|
|
|
|
245
|
6
|
100
|
|
|
|
14
|
if (!ref($S)) { |
246
|
5
|
|
|
|
|
9
|
$S = $S -> new (eval {$_[0]->charsize}); |
|
5
|
|
|
|
|
33
|
|
247
|
|
|
|
|
|
|
} else { |
248
|
1
|
|
|
|
|
2
|
@extra = ($expr); |
249
|
|
|
|
|
|
|
} |
250
|
6
|
50
|
|
|
|
16
|
return $S if !@_; |
251
|
|
|
|
|
|
|
|
252
|
6
|
|
|
|
|
14
|
$S->append( @extra, shift, map {($expr, $_)} @_ ); |
|
28
|
|
|
|
|
58
|
|
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
1
|
|
|
1
|
1
|
12
|
sub lc { shift->_apply_f_to_t("CORE::lc") } |
256
|
1
|
|
|
1
|
1
|
8
|
sub lcfirst { shift->_apply_f_to_t("CORE::lcfirst") } |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
sub length { |
259
|
|
|
|
|
|
|
# |
260
|
|
|
|
|
|
|
# $len = $Ct -> length () |
261
|
|
|
|
|
|
|
# |
262
|
450
|
|
|
450
|
1
|
852
|
length(${$_[0]->_text}) / $_[0]->_charsize(); |
|
450
|
|
|
|
|
817
|
|
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub ne { |
266
|
72
|
|
|
72
|
1
|
209
|
!shift->eq(@_); |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub new { |
270
|
244
|
|
|
244
|
1
|
1914
|
my $proto = shift; |
271
|
244
|
|
66
|
|
|
1071
|
my $S = bless ({}, ref($proto) || $proto); |
272
|
244
|
|
|
|
|
537
|
$S->docmode (1); |
273
|
244
|
|
|
|
|
482
|
$S->acmp ($default_acmp); |
274
|
|
|
|
|
|
|
|
275
|
244
|
100
|
100
|
|
|
990
|
if (@_ && !ref($_[0])) { |
276
|
104
|
|
|
|
|
199
|
$S->_charsize(shift()); |
277
|
|
|
|
|
|
|
} else { |
278
|
140
|
|
|
|
|
310
|
$S->_charsize(1); |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
244
|
100
|
100
|
|
|
1110
|
if (@_ && ref($_[0])=~ /^ARRAY/) { |
282
|
5
|
|
|
|
|
8
|
$S->_entry(@{shift()}); |
|
5
|
|
|
|
|
14
|
|
283
|
5
|
|
|
|
|
13
|
for (@_) { $S->append( $S->new(@{$_}) ) } |
|
34
|
|
|
|
|
44
|
|
|
34
|
|
|
|
|
87
|
|
284
|
|
|
|
|
|
|
} else { |
285
|
239
|
|
|
|
|
515
|
$S->_entry(@_); |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# Offsets and Attribute pairs doesn't match |
289
|
244
|
50
|
|
|
|
226
|
return 0 if $#{$S->_offset} != $#{$S->_attrib}; |
|
244
|
|
|
|
|
439
|
|
|
244
|
|
|
|
|
379
|
|
290
|
|
|
|
|
|
|
|
291
|
244
|
|
|
|
|
1311
|
$S; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub replace { |
295
|
24
|
|
|
24
|
1
|
84
|
my ($S, $pattern, $replace, $option) = @_; |
296
|
24
|
50
|
|
|
|
60
|
return 0 if !defined $pattern; |
297
|
24
|
50
|
|
|
|
54
|
$replace = "" if !defined $replace; |
298
|
24
|
100
|
|
|
|
44
|
$option = "" if !defined $option; |
299
|
|
|
|
|
|
|
|
300
|
24
|
|
|
|
|
44
|
my @L = (); |
301
|
24
|
|
|
|
|
36
|
my %R_Context = (); |
302
|
24
|
|
|
|
|
30
|
my %R_scalar = (); |
303
|
24
|
|
|
|
|
38
|
my $array = ""; |
304
|
24
|
|
|
|
|
27
|
my $code = ""; |
305
|
24
|
|
|
|
|
32
|
my $Ct = ""; |
306
|
24
|
|
|
|
|
25
|
my $s_pattern = ""; |
307
|
24
|
|
|
|
|
30
|
my $s_replace = ""; |
308
|
|
|
|
|
|
|
|
309
|
24
|
100
|
|
|
|
86
|
if ($array = ref ($pattern) =~ /^ARRAY/) { |
|
|
100
|
|
|
|
|
|
310
|
3
|
|
|
|
|
4
|
for (0..$#{$pattern}) { |
|
3
|
|
|
|
|
11
|
|
311
|
13
|
100
|
|
|
|
28
|
if (ref($pattern->[$_])) { |
312
|
2
|
|
|
|
|
3
|
$R_Context {${$pattern->[$_]->_text}} = $_; |
|
2
|
|
|
|
|
6
|
|
313
|
2
|
|
|
|
|
3
|
$s_pattern .= ${$pattern->[$_]->_text}; |
|
2
|
|
|
|
|
7
|
|
314
|
|
|
|
|
|
|
} else { |
315
|
11
|
|
|
|
|
18
|
$R_scalar {$pattern->[$_]} = $_; |
316
|
11
|
|
|
|
|
13
|
$s_pattern .= $pattern->[$_]; |
317
|
|
|
|
|
|
|
} |
318
|
13
|
|
|
|
|
19
|
$s_pattern .= '|'; |
319
|
|
|
|
|
|
|
}; |
320
|
3
|
|
|
|
|
15
|
$s_pattern =~ s/\|$//; |
321
|
|
|
|
|
|
|
} elsif (ref ($pattern)) { |
322
|
4
|
|
|
|
|
6
|
$Ct = $pattern; |
323
|
4
|
|
|
|
|
7
|
$s_pattern = ${$pattern->_text}; |
|
4
|
|
|
|
|
8
|
|
324
|
4
|
|
|
|
|
9
|
$code = (ref ($replace) =~ /^CODE/); |
325
|
|
|
|
|
|
|
} else { |
326
|
17
|
|
|
|
|
27
|
$s_pattern = $pattern; |
327
|
17
|
|
|
|
|
31
|
$code = (ref ($replace) =~ /^CODE/); |
328
|
|
|
|
|
|
|
} |
329
|
24
|
|
|
|
|
32
|
$s_replace=$replace; |
330
|
|
|
|
|
|
|
|
331
|
24
|
|
|
|
|
28
|
my ($i, $m, $n, $oc, $lc); |
332
|
24
|
|
|
|
|
45
|
my $cs = $S ->_charsize; |
333
|
24
|
|
100
|
|
|
8810
|
$n = eval '${$S->text} =~ '. |
334
|
|
|
|
|
|
|
's#$s_pattern#{ |
335
|
|
|
|
|
|
|
$oc=CORE::length($`); return $& if ($oc%$cs); $oc/=$cs; |
336
|
|
|
|
|
|
|
$lc=CORE::length($&); |
337
|
|
|
|
|
|
|
if ($lc%$cs) { |
338
|
|
|
|
|
|
|
$lc+=($lc%$cs); |
339
|
|
|
|
|
|
|
$m = CORE::substr(${$S->_text}, $oc*$cs, $lc); |
340
|
|
|
|
|
|
|
} else { |
341
|
|
|
|
|
|
|
$m = $&; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
$lc/=$cs; |
344
|
|
|
|
|
|
|
if ($array) { |
345
|
|
|
|
|
|
|
if (defined ($i = $R_Context{$&})) { |
346
|
|
|
|
|
|
|
$Ct = $pattern->[$i]; |
347
|
|
|
|
|
|
|
$s_replace = $replace->[$i]; |
348
|
|
|
|
|
|
|
} elsif (defined ($i = $R_scalar{$&})) { |
349
|
|
|
|
|
|
|
$Ct = ""; |
350
|
|
|
|
|
|
|
$s_replace = $replace->[$i]; |
351
|
|
|
|
|
|
|
} else { |
352
|
|
|
|
|
|
|
$Ct = ""; |
353
|
|
|
|
|
|
|
$s_replace = ""; |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
$code = (ref ($s_replace) =~ /^CODE/); |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
if (!$Ct || $Ct->_cmp_attribs($S->attrib($oc, $lc))) { |
358
|
|
|
|
|
|
|
push (@L, [$oc, $lc, $code ? &$s_replace($m, $S, $oc):$s_replace]); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
$&; |
361
|
|
|
|
|
|
|
}#e'.($option||"") |
362
|
|
|
|
|
|
|
; |
363
|
24
|
|
|
|
|
190
|
while (@L) { |
364
|
68
|
|
|
|
|
79
|
$S->substr(@{pop(@L)}); |
|
68
|
|
|
|
|
245
|
|
365
|
|
|
|
|
|
|
} |
366
|
24
|
|
|
|
|
94
|
$n; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub sdump { |
370
|
|
|
|
|
|
|
# |
371
|
|
|
|
|
|
|
# \$buf = $S->sdump($mode) |
372
|
|
|
|
|
|
|
# |
373
|
0
|
|
|
0
|
0
|
0
|
my ($S, $mode) = @_; |
374
|
0
|
|
|
|
|
0
|
my $n; |
375
|
0
|
|
|
|
|
0
|
my $buf=""; |
376
|
|
|
|
|
|
|
|
377
|
0
|
0
|
|
|
|
0
|
if ($mode) { |
378
|
0
|
|
|
|
|
0
|
$buf .= "\""; |
379
|
0
|
|
|
|
|
0
|
for (@{$S->chunks}) { |
|
0
|
|
|
|
|
0
|
|
380
|
0
|
0
|
|
|
|
0
|
$buf .= sprintf ("<%s>", $_->[1]) if defined $_->[1]; |
381
|
0
|
|
|
|
|
0
|
$buf .= $_->[0]; |
382
|
|
|
|
|
|
|
} |
383
|
0
|
|
|
|
|
0
|
$buf .= "\"\n"; |
384
|
|
|
|
|
|
|
} else { |
385
|
0
|
|
|
|
|
0
|
$buf .= " text => \"" . ${$S->_text} . "\"\n"; |
|
0
|
|
|
|
|
0
|
|
386
|
|
|
|
|
|
|
} |
387
|
0
|
0
|
|
|
|
0
|
if ($S->charsize()!=1) { |
388
|
0
|
|
|
|
|
0
|
$buf .= sprintf (" charsize=%d, textlen=%d\n", |
389
|
|
|
|
|
|
|
$S->charsize(), $S->length() |
390
|
|
|
|
|
|
|
); |
391
|
|
|
|
|
|
|
} |
392
|
0
|
|
|
|
|
0
|
$n = $#{$S->_attrib}+1; |
|
0
|
|
|
|
|
0
|
|
393
|
0
|
|
|
|
|
0
|
$buf .= sprintf (" attrib => [ " . ("%3s " x $n) . "]\n", @{$S->_attrib}); |
|
0
|
|
|
|
|
0
|
|
394
|
0
|
|
|
|
|
0
|
$n = $#{$S->_offset}+1; |
|
0
|
|
|
|
|
0
|
|
395
|
0
|
|
|
|
|
0
|
$buf .= sprintf (" offset => [ " . ("%03x " x $n) . "]\n", @{$S->_offset}); |
|
0
|
|
|
|
|
0
|
|
396
|
0
|
|
|
|
|
0
|
\$buf; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub split { |
400
|
|
|
|
|
|
|
# |
401
|
|
|
|
|
|
|
# @Ct = $Ct -> split ($pattern, $option, $limit) |
402
|
|
|
|
|
|
|
# |
403
|
3
|
|
|
3
|
1
|
6
|
my ($S, $pattern, $option, $limit) = @_; |
404
|
3
|
|
|
|
|
6
|
my @L = (); |
405
|
|
|
|
|
|
|
|
406
|
3
|
50
|
|
|
|
9
|
my $Ct = ref ($pattern) ? $pattern : ""; |
407
|
3
|
50
|
|
|
|
5
|
$pattern = ${$Ct->_text} if $Ct; |
|
0
|
|
|
|
|
0
|
|
408
|
3
|
|
|
|
|
8
|
my $cs = $S->_charsize; |
409
|
|
|
|
|
|
|
|
410
|
3
|
|
|
|
|
6
|
my $o = 0; |
411
|
3
|
|
|
|
|
5
|
my ($l, $ml); |
412
|
3
|
|
50
|
|
|
548
|
eval '${$S->text} =~ '. |
413
|
|
|
|
|
|
|
's#$pattern#{ |
414
|
|
|
|
|
|
|
$l = CORE::length($`); |
415
|
|
|
|
|
|
|
$ml = CORE::length($&); $ml+=($ml%$cs); $ml/=$cs; |
416
|
|
|
|
|
|
|
if (!($l % $cs) && |
417
|
|
|
|
|
|
|
(!$Ct || |
418
|
|
|
|
|
|
|
$Ct->_cmp_attribs($S->attrib($l/$cs, $ml)) |
419
|
|
|
|
|
|
|
) |
420
|
|
|
|
|
|
|
) { |
421
|
|
|
|
|
|
|
push (@L, $S->substr($o, $l/$cs-$o)); |
422
|
|
|
|
|
|
|
$o = ($l/$cs+$ml); |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
$&; |
425
|
|
|
|
|
|
|
}#e'."g".($option||"") |
426
|
|
|
|
|
|
|
; |
427
|
3
|
|
|
|
|
20
|
push (@L, $S->substr($o)); |
428
|
3
|
50
|
|
|
|
8
|
if ($limit) { |
429
|
|
|
|
|
|
|
# no better idea, how to limit, sigh... |
430
|
0
|
|
|
|
|
0
|
@L[0..$limit-1]; |
431
|
|
|
|
|
|
|
} else { |
432
|
|
|
|
|
|
|
# Split strips "trailing null fields", when no $limit given. |
433
|
3
|
100
|
|
|
|
8
|
while (@L) { last if $L[$#L]->length(); pop(@L) } |
|
4
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
5
|
|
434
|
3
|
|
|
|
|
19
|
@L; |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
sub substr { |
439
|
|
|
|
|
|
|
# |
440
|
|
|
|
|
|
|
# $Context1 = $Context1 -> substr ( |
441
|
|
|
|
|
|
|
# $o1||undef, $l1||undef, $Context2, $o2||undef, $l2||undef |
442
|
|
|
|
|
|
|
# ) |
443
|
|
|
|
|
|
|
# |
444
|
|
|
|
|
|
|
# Substitutes $Context1->substr($o1, $l1) with $Context2->substr($o2, $l2) |
445
|
|
|
|
|
|
|
# |
446
|
|
|
|
|
|
|
# o1|o2: undef => 0 |
447
|
|
|
|
|
|
|
# l1|l2: undef => length($Contextn) |
448
|
|
|
|
|
|
|
# |
449
|
115
|
|
|
115
|
1
|
223
|
my ($S, $o1, $l1, $Ct2, $o2, $l2) = @_; |
450
|
|
|
|
|
|
|
|
451
|
115
|
|
|
|
|
191
|
my $len1 = $S->length(); |
452
|
115
|
50
|
|
|
|
262
|
$o1 = 0 if !defined $o1; |
453
|
115
|
100
|
|
|
|
204
|
$o1 += $len1 if $o1<0; |
454
|
115
|
100
|
|
|
|
181
|
return undef if $o1<0; |
455
|
114
|
|
|
|
|
206
|
my $cs = $S->_charsize; |
456
|
|
|
|
|
|
|
|
457
|
114
|
100
|
|
|
|
226
|
$l1 = $len1 - $o1 if !defined $l1; |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
# |
460
|
|
|
|
|
|
|
# Case 1: Return a new partial Context |
461
|
|
|
|
|
|
|
# |
462
|
114
|
100
|
|
|
|
189
|
if (!$Ct2) { |
463
|
41
|
|
|
|
|
66
|
return $S->new( |
464
|
|
|
|
|
|
|
$cs, |
465
|
41
|
|
|
|
|
43
|
\(my $text = substr(${$S->_text}, $o1*$cs, $l1*$cs)), |
466
|
|
|
|
|
|
|
$S->attrib($o1, $l1), |
467
|
|
|
|
|
|
|
1 |
468
|
|
|
|
|
|
|
); |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
|
471
|
73
|
|
|
|
|
77
|
my $len2; |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
# |
474
|
|
|
|
|
|
|
# Case 2: Substitute argument is a simple string |
475
|
|
|
|
|
|
|
# |
476
|
73
|
100
|
|
|
|
156
|
if (!ref $Ct2) { |
477
|
56
|
|
|
|
|
53
|
$len2 = CORE::length($Ct2); |
478
|
56
|
50
|
|
|
|
107
|
$o2 = 0 if !defined $o2; |
479
|
56
|
50
|
|
|
|
93
|
$o2 += $len2 if $o2<0; |
480
|
56
|
50
|
|
|
|
102
|
$l2 = $len2 - $o2 if !defined $l2; |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
# Special case: same string lengths: change only string. |
483
|
56
|
100
|
|
|
|
117
|
if ($l1*$cs == $l2) { |
484
|
43
|
|
|
|
|
64
|
substr(${$S->_text}, $o1*$cs, $l1*$cs) = |
|
43
|
|
|
|
|
75
|
|
485
|
|
|
|
|
|
|
substr($Ct2, $o2, $l2) |
486
|
|
|
|
|
|
|
; |
487
|
43
|
|
|
|
|
155
|
return $S; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
# Normal case: different string lengths: create Context on the fly. |
490
|
13
|
|
|
|
|
29
|
$Ct2 = $S->new( |
491
|
|
|
|
|
|
|
$S->_charsize, \substr($Ct2, $o2, $l2), $S->attrib($o1, $l1) |
492
|
|
|
|
|
|
|
); |
493
|
13
|
|
|
|
|
37
|
$o2 = 0; |
494
|
13
|
|
|
|
|
24
|
$l2 /= $cs; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
# |
498
|
|
|
|
|
|
|
# Case 3: Substitute argument is another Context |
499
|
|
|
|
|
|
|
# |
500
|
|
|
|
|
|
|
# |
501
|
|
|
|
|
|
|
# Note: The following 3 lines could do a similar job like the messy |
502
|
|
|
|
|
|
|
# looking code afterwards. Everything would look fine and easy. |
503
|
|
|
|
|
|
|
# The problem: That code would construct a new Context and would not |
504
|
|
|
|
|
|
|
# change the old Context; further more I suspect it to be slower. |
505
|
|
|
|
|
|
|
# |
506
|
|
|
|
|
|
|
# return = $S->substr(0, $o1) |
507
|
|
|
|
|
|
|
# ->join($Ct2) |
508
|
|
|
|
|
|
|
# ->join($S->substr($o1+$l1)) |
509
|
|
|
|
|
|
|
# ; |
510
|
|
|
|
|
|
|
# |
511
|
|
|
|
|
|
|
|
512
|
30
|
|
|
|
|
53
|
my $cs2 = $Ct2->_charsize; |
513
|
30
|
|
|
|
|
66
|
$len2 = $Ct2->length(); |
514
|
30
|
100
|
|
|
|
80
|
$o2 = 0 if !defined $o2; |
515
|
30
|
50
|
|
|
|
64
|
$o2 += $len2 if $o2<0; |
516
|
30
|
100
|
|
|
|
60
|
$l2 = $len2 - $o2 if !defined $l2; |
517
|
|
|
|
|
|
|
|
518
|
30
|
50
|
|
|
|
57
|
if (!$S->textmode) { |
519
|
30
|
|
|
|
|
61
|
$S->_subattr($o1, $l1, $Ct2->_attrib, $Ct2->_offset, $o2, $l2, $l2); |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
|
522
|
30
|
|
|
|
|
53
|
substr(${$S->_text}, $o1*$cs, $l1*$cs) = |
|
30
|
|
|
|
|
55
|
|
523
|
30
|
|
|
|
|
47
|
substr(${$Ct2->_text}, $o2*$cs2, $l2*$cs2) |
524
|
|
|
|
|
|
|
; |
525
|
|
|
|
|
|
|
|
526
|
30
|
|
|
|
|
142
|
$S; |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
sub rindex { |
530
|
|
|
|
|
|
|
# |
531
|
|
|
|
|
|
|
# $pos = $Ct -> rindex ($string [,$pos]) |
532
|
|
|
|
|
|
|
# |
533
|
265
|
|
|
265
|
1
|
1518
|
my ($S, $str, $pos) = @_; |
534
|
265
|
100
|
|
|
|
678
|
$pos = $S->length() if !defined $pos; |
535
|
265
|
|
|
|
|
520
|
my $cs = $S->charsize; |
536
|
265
|
|
|
|
|
412
|
my $i = $pos * $cs + $cs; |
537
|
265
|
|
|
|
|
272
|
while (1) { |
538
|
365
|
|
66
|
|
|
342
|
$i = rindex(${$S->_text}, $str, $i-(($i%$cs)||$cs)); |
|
365
|
|
|
|
|
610
|
|
539
|
365
|
100
|
|
|
|
766
|
return $i if $cs == 1; |
540
|
312
|
100
|
|
|
|
522
|
return $i if $i == -1; |
541
|
308
|
100
|
|
|
|
602
|
if (!($i % $cs)) { |
542
|
208
|
|
|
|
|
626
|
return $i / $cs; |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub text { |
548
|
39
|
|
|
39
|
1
|
136
|
shift->_text(); |
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
|
551
|
3
|
|
|
3
|
1
|
18
|
sub tr { goto &y } |
552
|
1
|
|
|
1
|
1
|
4
|
sub uc { shift->_apply_f_to_t("CORE::uc") } |
553
|
1
|
|
|
1
|
1
|
3
|
sub ucfirst { shift->_apply_f_to_t("CORE::ucfirst") } |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
sub y { |
556
|
|
|
|
|
|
|
# |
557
|
|
|
|
|
|
|
# $Ct -> y ($search_str, $replace_str, $mode) |
558
|
|
|
|
|
|
|
# $Ct -> y (\@search[0..n], \@replace[0..n], $mode) |
559
|
|
|
|
|
|
|
# |
560
|
3
|
|
|
3
|
1
|
5
|
my ($S, $search, $replace, $mode) = @_; |
561
|
3
|
50
|
|
|
|
8
|
$search = "" if !defined $search; |
562
|
3
|
50
|
|
|
|
5
|
$replace = "" if !defined $replace; |
563
|
3
|
50
|
|
|
|
7
|
$mode = "" if !defined $mode; |
564
|
3
|
|
|
|
|
6
|
my $cs = $S->_charsize; |
565
|
3
|
100
|
|
|
|
8
|
if (ref($search)) { |
|
|
100
|
|
|
|
|
|
566
|
1
|
|
|
|
|
5
|
$S->replace($search, $replace, "g$mode"); |
567
|
|
|
|
|
|
|
} elsif ($cs==1) { |
568
|
1
|
|
|
|
|
2
|
$mode =~ s/g//g; |
569
|
1
|
|
50
|
|
|
109
|
eval '${$S->_text} =~ y/'. |
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
570
|
|
|
|
|
|
|
($search||"")."/".($replace||"")."/".($mode||"") |
571
|
|
|
|
|
|
|
; |
572
|
|
|
|
|
|
|
} else { |
573
|
1
|
|
|
|
|
14
|
$S->replace( |
574
|
|
|
|
|
|
|
[map CORE::substr($search, $_*$cs, $cs), (0..(CORE::length($search)/$cs-1))], |
575
|
|
|
|
|
|
|
[map CORE::substr($replace, $_*$cs, $cs), (0..(CORE::length($replace)/$cs-1))], |
576
|
|
|
|
|
|
|
"g$mode" |
577
|
|
|
|
|
|
|
); |
578
|
|
|
|
|
|
|
} |
579
|
3
|
|
|
|
|
11
|
$S; |
580
|
|
|
|
|
|
|
} |
581
|
0
|
|
|
0
|
|
0
|
sub _dl { my ($lR,$str)=@_; |
582
|
0
|
0
|
|
|
|
0
|
print "$str: " if $str; printf "(".("'%s', "x($#{$lR}+1)).")\n", @{$lR}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub _apply_f_to_t { |
586
|
|
|
|
|
|
|
# |
587
|
|
|
|
|
|
|
# lc, lcfirst, uc, ucfirst |
588
|
|
|
|
|
|
|
# |
589
|
4
|
|
|
4
|
|
8
|
my ($S, $apply) = @_; |
590
|
4
|
|
|
|
|
9
|
$S->new ( |
591
|
|
|
|
|
|
|
$S->_charsize, |
592
|
|
|
|
|
|
|
\(eval "$apply".'(${$S->_text})'), |
593
|
4
|
|
|
|
|
9
|
[@{$S->_attrib}], [@{$S->_offset}], |
|
4
|
|
|
|
|
9
|
|
594
|
|
|
|
|
|
|
1 |
595
|
|
|
|
|
|
|
); |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
sub _cmp_attribs { |
599
|
|
|
|
|
|
|
# |
600
|
|
|
|
|
|
|
# 1||0 = $Ct1 -> _cmp_attribs ($Ct2) |
601
|
|
|
|
|
|
|
# 1||0 = $Ct1 -> _cmp_attribs ([@attrib], [@offset]) |
602
|
|
|
|
|
|
|
# |
603
|
85
|
|
|
85
|
|
120
|
my ($S, $a2R, $o2R) = @_; |
604
|
85
|
100
|
|
|
|
297
|
if (!defined $o2R) { |
605
|
75
|
|
|
|
|
75
|
my $Ct2 = $a2R; |
606
|
75
|
|
|
|
|
127
|
$a2R = $Ct2->_attrib; |
607
|
75
|
|
|
|
|
130
|
$o2R = $Ct2->_offset; |
608
|
|
|
|
|
|
|
} |
609
|
85
|
100
|
|
|
|
162
|
return 0 if !$S->_cmp_slist($S->_attrib, $a2R); |
610
|
75
|
100
|
|
|
|
147
|
return 0 if !$S->_cmp_nlist($S->_offset, $o2R); |
611
|
74
|
|
|
|
|
396
|
1} |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
sub _cmp_nlist { |
614
|
|
|
|
|
|
|
# |
615
|
|
|
|
|
|
|
# 1||0 = _cmp_nlist ([@list1], [@list2]) |
616
|
|
|
|
|
|
|
# |
617
|
75
|
|
|
75
|
|
110
|
my ($S, $aR, $bR) = @_; |
618
|
75
|
50
|
|
|
|
152
|
return 0 unless @$aR == @$bR; |
619
|
75
|
100
|
|
|
|
146
|
for (0..$#$aR) { return 0 if $aR->[$_] != $bR->[$_] } |
|
215
|
|
|
|
|
562
|
|
620
|
74
|
|
|
|
|
209
|
1} |
621
|
|
|
|
|
|
|
sub _cmp_slist { |
622
|
|
|
|
|
|
|
# |
623
|
|
|
|
|
|
|
# 1||0 = _cmp_slist ([@list1], [@list2]) |
624
|
|
|
|
|
|
|
# |
625
|
85
|
|
|
85
|
|
128
|
my ($S, $aR, $bR) = @_; |
626
|
85
|
|
|
|
|
137
|
my $acmp = $S->acmp(); |
627
|
85
|
100
|
|
|
|
195
|
return 0 unless @$aR == @$bR; |
628
|
84
|
100
|
|
|
|
192
|
for (0..$#$aR) { return 0 if &$acmp ($aR->[$_], $bR->[$_]) } |
|
224
|
|
|
|
|
434
|
|
629
|
75
|
|
|
|
|
205
|
1} |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
sub _entry { |
632
|
|
|
|
|
|
|
# |
633
|
|
|
|
|
|
|
# 1 = $S -> entry (\$text, [@attrib], [@offset], $mode) |
634
|
|
|
|
|
|
|
# |
635
|
|
|
|
|
|
|
# mode = 0: make copies of text, attrib and offset (store values) |
636
|
|
|
|
|
|
|
# 1: use given references (store references) |
637
|
|
|
|
|
|
|
# |
638
|
244
|
|
|
244
|
|
363
|
my ($S, $textR, $attribR, $offsetR, $mode) = @_; |
639
|
|
|
|
|
|
|
|
640
|
244
|
100
|
|
|
|
374
|
if (!$mode) { |
641
|
197
|
100
|
|
|
|
606
|
$S->_text (\(my $text = $textR ? $$textR : "")); |
642
|
197
|
100
|
|
|
|
685
|
$S->_attrib ($attribR ? [@$attribR] : [0]); |
643
|
197
|
100
|
|
|
|
630
|
$S->_offset ($offsetR ? [@$offsetR] : [0]); |
644
|
|
|
|
|
|
|
} else { |
645
|
47
|
50
|
|
|
|
110
|
$S->_text ($textR ? $textR : \("")); |
646
|
47
|
50
|
|
|
|
101
|
$S->_attrib ($attribR ? $attribR : [0]); |
647
|
47
|
50
|
|
|
|
99
|
$S->_offset ($offsetR ? $offsetR : [0]); |
648
|
|
|
|
|
|
|
} |
649
|
244
|
|
|
|
|
356
|
1} |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
sub _index { |
652
|
|
|
|
|
|
|
# |
653
|
|
|
|
|
|
|
# $context_index = -> _index ($position [,[@offset]]) |
654
|
|
|
|
|
|
|
# |
655
|
317
|
|
|
317
|
|
428
|
my ($S, $pos, $oR) = @_; |
656
|
317
|
100
|
|
|
|
617
|
return 0 if !$pos; |
657
|
266
|
100
|
|
|
|
478
|
return undef if $pos < 0; |
658
|
265
|
100
|
|
|
|
598
|
$oR = $S->_offset if !defined $oR; |
659
|
|
|
|
|
|
|
|
660
|
265
|
|
|
|
|
305
|
my $og = $#{$oR}; |
|
265
|
|
|
|
|
374
|
|
661
|
265
|
100
|
|
|
|
690
|
return $og if $pos >= ($oR->[$og]); |
662
|
163
|
|
|
|
|
168
|
my $ug = 0; |
663
|
163
|
|
|
|
|
156
|
my $step; |
664
|
|
|
|
|
|
|
|
665
|
163
|
|
|
|
|
318
|
while ($step = ($og-$ug) >> 1) { |
666
|
462
|
100
|
|
|
|
808
|
if ($oR->[$ug+$step] <= $pos) { |
667
|
219
|
|
|
|
|
447
|
$ug += $step; |
668
|
|
|
|
|
|
|
} else { |
669
|
243
|
|
|
|
|
475
|
$og -= $step; |
670
|
|
|
|
|
|
|
} |
671
|
|
|
|
|
|
|
} |
672
|
|
|
|
|
|
|
|
673
|
163
|
|
|
|
|
931
|
$ug; |
674
|
|
|
|
|
|
|
} |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
sub _subattr { |
677
|
|
|
|
|
|
|
# |
678
|
|
|
|
|
|
|
# ([@attrib], [@o]) = |
679
|
|
|
|
|
|
|
# $Ct -> _subattr ($o1, $l1, [@attrib], [@o] [,$o2, $al2 [,$tl2]]) |
680
|
|
|
|
|
|
|
# |
681
|
|
|
|
|
|
|
# Substitutes $Ct's attributes from position o1 and length l1 with |
682
|
|
|
|
|
|
|
# @attrib and @o. The substituted textlength will stay l1, unless tl2 given. |
683
|
|
|
|
|
|
|
# |
684
|
47
|
|
|
47
|
|
86
|
my ($S, $o1, $l1, $aR2, $oR2, $o2, $al2, $tl2) = @_; |
685
|
47
|
50
|
|
|
|
93
|
return undef if !defined $oR2; |
686
|
|
|
|
|
|
|
|
687
|
47
|
|
|
|
|
100
|
my $len1 = $S->length(); |
688
|
47
|
50
|
|
|
|
119
|
$o1 += $len1 if $o1<0; |
689
|
47
|
50
|
|
|
|
87
|
return undef if $o1<0; |
690
|
47
|
50
|
|
|
|
107
|
return undef if ($o1+$l1) > $len1; |
691
|
47
|
100
|
100
|
|
|
172
|
return 1 if ($o1 && ($o1==$len1)); |
692
|
|
|
|
|
|
|
|
693
|
46
|
100
|
|
|
|
99
|
$al2 = $l1 if !defined $al2; |
694
|
46
|
100
|
|
|
|
86
|
$tl2 = $l1 if !defined $tl2; |
695
|
46
|
100
|
|
|
|
80
|
$o2 = 0 if !defined $o2; |
696
|
46
|
50
|
|
|
|
82
|
return undef if $o2<0; |
697
|
|
|
|
|
|
|
|
698
|
46
|
100
|
|
|
|
117
|
my $i1_right = $o1 ? $S->_index($o1-1) : 0; |
699
|
46
|
|
|
|
|
101
|
my $i2_left = $S->_index($o2, $oR2); |
700
|
46
|
100
|
|
|
|
145
|
my $i2_right = ($o2+$al2-1) ? $S->_index($o2+$al2-1, $oR2) : 0; |
701
|
46
|
|
|
|
|
145
|
my $i3_left = $S->_index($o1+$l1); |
702
|
|
|
|
|
|
|
|
703
|
46
|
|
|
|
|
93
|
my $a1_right = $S->_attrib->[$i1_right]; |
704
|
46
|
|
|
|
|
73
|
my $a2_left = $aR2->[$i2_left]; |
705
|
46
|
|
|
|
|
63
|
my $a2_right = $aR2->[$i2_right]; |
706
|
46
|
|
|
|
|
90
|
my $a3_left = $S->_attrib->[$i3_left]; |
707
|
|
|
|
|
|
|
|
708
|
46
|
|
|
|
|
95
|
my $o1_right = $S->_offset->[$i1_right]; |
709
|
46
|
|
|
|
|
128
|
my $o2_left = $oR2->[$i2_left]; |
710
|
|
|
|
|
|
|
|
711
|
46
|
|
|
|
|
76
|
my @a_left=(); my @o_left=(); |
|
46
|
|
|
|
|
58
|
|
712
|
46
|
|
|
|
|
55
|
my @a_right=(); my @o_right=(); |
|
46
|
|
|
|
|
59
|
|
713
|
|
|
|
|
|
|
|
714
|
46
|
|
|
|
|
71
|
my $diff_middle = $tl2 - $l1; |
715
|
46
|
|
|
|
|
51
|
my $diff_right = $o1 - $o2; |
716
|
|
|
|
|
|
|
|
717
|
46
|
|
|
|
|
84
|
my $acmp = $S->acmp(); |
718
|
|
|
|
|
|
|
|
719
|
46
|
100
|
|
|
|
99
|
if ($o1) { |
720
|
33
|
|
|
|
|
64
|
push (@a_left, $a1_right); |
721
|
33
|
|
|
|
|
44
|
push (@o_left, $o1_right); |
722
|
|
|
|
|
|
|
} |
723
|
|
|
|
|
|
|
|
724
|
46
|
100
|
100
|
|
|
144
|
if ((!$o1) || &$acmp($a1_right, $a2_left)) { |
725
|
31
|
|
|
|
|
54
|
push (@a_left, $a2_left); |
726
|
31
|
|
|
|
|
86
|
push (@o_left, $o1); |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
46
|
100
|
100
|
|
|
144
|
if ( (($o1+$l1) < $len1) && |
730
|
|
|
|
|
|
|
&$acmp ($a2_right, $a3_left) |
731
|
|
|
|
|
|
|
) { |
732
|
25
|
|
|
|
|
42
|
push (@a_right, $a3_left); |
733
|
25
|
|
|
|
|
35
|
push (@o_right, $o1+$tl2); |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
#print "a1r=$a1_right a2l=$a2_left a2r=$a2_right a3l=$a3_left\n"; |
736
|
|
|
|
|
|
|
#print "i1r=$i1_right i2l=$i2_left i2r=$i2_right i3l=$i3_left\n"; |
737
|
|
|
|
|
|
|
#print "o1=$o1 l1=$l1 o2=$o2 al2=$al2 tl2=$tl2 o1r=$o1_right o2l=$o2_left\n"; |
738
|
|
|
|
|
|
|
#print "len1=$len1\n"; |
739
|
|
|
|
|
|
|
#print "al=(@a_left) ar=(@a_right) ol=(@o_left) or=(@o_right)\n\n"; |
740
|
|
|
|
|
|
|
|
741
|
46
|
|
|
|
|
84
|
splice (@{$S->_attrib}, |
|
46
|
|
|
|
|
152
|
|
742
|
|
|
|
|
|
|
$i1_right, |
743
|
|
|
|
|
|
|
$i3_left-$i1_right+1, |
744
|
|
|
|
|
|
|
(@a_left, |
745
|
46
|
|
|
|
|
53
|
@{$aR2}[$i2_left+1..$i2_right], |
746
|
|
|
|
|
|
|
@a_right |
747
|
|
|
|
|
|
|
) |
748
|
|
|
|
|
|
|
); |
749
|
|
|
|
|
|
|
|
750
|
46
|
|
|
|
|
82
|
for (@{$S->_offset}[$i3_left+1 .. $#{$S->_offset}]) { |
|
46
|
|
|
|
|
84
|
|
|
46
|
|
|
|
|
89
|
|
751
|
142
|
|
|
|
|
190
|
$_ += $diff_middle |
752
|
|
|
|
|
|
|
} |
753
|
|
|
|
|
|
|
|
754
|
46
|
|
|
|
|
83
|
splice (@{$S->_offset}, |
|
30
|
|
|
|
|
133
|
|
755
|
|
|
|
|
|
|
$i1_right, |
756
|
|
|
|
|
|
|
$i3_left-$i1_right+1, |
757
|
|
|
|
|
|
|
(@o_left, |
758
|
46
|
|
|
|
|
77
|
(map {$_+$diff_right} @{$oR2}[$i2_left+1..$i2_right]), |
|
46
|
|
|
|
|
111
|
|
759
|
|
|
|
|
|
|
@o_right |
760
|
|
|
|
|
|
|
) |
761
|
|
|
|
|
|
|
); |
762
|
46
|
|
|
|
|
183
|
1} |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
"Atomkraft? Nein, danke!" |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
__END__ |