| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package Cisco::Reconfig; |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
|
5
|
|
|
|
|
|
|
@EXPORT = qw(readconfig); |
|
6
|
|
|
|
|
|
|
@EXPORT_OK = qw(readconfig stringconfig $minus_one_indent_rx); |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
$VERSION = '0.912'; |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
require Exporter; |
|
11
|
9
|
|
|
9
|
|
5343
|
use strict; |
|
|
9
|
|
|
|
|
29
|
|
|
|
9
|
|
|
|
|
356
|
|
|
12
|
9
|
|
|
9
|
|
5759
|
use Text::Tabs; |
|
|
9
|
|
|
|
|
7776
|
|
|
|
9
|
|
|
|
|
1563
|
|
|
13
|
9
|
|
|
9
|
|
83
|
use Carp; |
|
|
9
|
|
|
|
|
31
|
|
|
|
9
|
|
|
|
|
762
|
|
|
14
|
9
|
|
|
9
|
|
70
|
use Carp qw(verbose confess); |
|
|
9
|
|
|
|
|
24
|
|
|
|
9
|
|
|
|
|
1225
|
|
|
15
|
9
|
|
|
9
|
|
6044
|
use IO::File; |
|
|
9
|
|
|
|
|
98165
|
|
|
|
9
|
|
|
|
|
1366
|
|
|
16
|
9
|
|
|
9
|
|
116
|
use Scalar::Util qw(weaken); |
|
|
9
|
|
|
|
|
26
|
|
|
|
9
|
|
|
|
|
2022
|
|
|
17
|
|
|
|
|
|
|
my $iostrings; |
|
18
|
|
|
|
|
|
|
our $allow_minus_one_indent = qr/class /; |
|
19
|
|
|
|
|
|
|
our $allow_plus_one_indent = qr/service-policy |quit$/; |
|
20
|
|
|
|
|
|
|
our $bad_indent_policy = 'DIE'; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
BEGIN { |
|
24
|
9
|
|
|
9
|
|
764
|
eval " use IO::String "; |
|
|
9
|
|
|
9
|
|
2512
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
25
|
9
|
50
|
|
|
|
1931
|
$iostrings = $@ ? 0 : 1; |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $debug_get = 0; |
|
30
|
|
|
|
|
|
|
my $debug_mget = 0; |
|
31
|
|
|
|
|
|
|
my $debug_set = 0; |
|
32
|
|
|
|
|
|
|
my $debug_context = 0; |
|
33
|
|
|
|
|
|
|
my $debug_text = 0; |
|
34
|
|
|
|
|
|
|
my $ddata = $debug_get |
|
35
|
|
|
|
|
|
|
|| $debug_mget |
|
36
|
|
|
|
|
|
|
|| $debug_set |
|
37
|
|
|
|
|
|
|
|| $debug_context |
|
38
|
|
|
|
|
|
|
|| $debug_text |
|
39
|
|
|
|
|
|
|
|| 0; # add debugging data to data structures |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my $spec = qr{^ }; |
|
42
|
|
|
|
|
|
|
my $text = " text"; |
|
43
|
|
|
|
|
|
|
my $subs = " subs"; |
|
44
|
|
|
|
|
|
|
my $next = " next"; |
|
45
|
|
|
|
|
|
|
my $cntx = " cntx"; |
|
46
|
|
|
|
|
|
|
my $word = " word"; |
|
47
|
|
|
|
|
|
|
my $seqn = " seqn"; |
|
48
|
|
|
|
|
|
|
my $dupl = " dupl"; |
|
49
|
|
|
|
|
|
|
my $debg = " debg"; |
|
50
|
|
|
|
|
|
|
my $bloc = " bloc"; |
|
51
|
|
|
|
|
|
|
my $UNDEFDESC = "! undefined\n"; |
|
52
|
|
|
|
|
|
|
my $undef = bless { $debg => $UNDEFDESC, $text => '' }, __PACKAGE__; |
|
53
|
|
|
|
|
|
|
my $dseq = "O0000000"; |
|
54
|
|
|
|
|
|
|
our $nonext; |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
my $line; |
|
57
|
|
|
|
|
|
|
my $fh; |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
use overload |
|
60
|
9
|
|
|
|
|
103
|
'bool' => \&defined, |
|
61
|
|
|
|
|
|
|
'""' => \&text, |
|
62
|
9
|
|
|
9
|
|
12411
|
'fallback' => 1; |
|
|
9
|
|
|
|
|
10468
|
|
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub stringconfig |
|
65
|
|
|
|
|
|
|
{ |
|
66
|
1
|
50
|
|
1
|
0
|
364
|
Carp::croak 'IO::Strings need to be installed to use "stringconfig"' |
|
67
|
|
|
|
|
|
|
. ' install it or use "readconfig" instead.' unless $iostrings; |
|
68
|
0
|
|
|
|
|
0
|
readconfig(IO::String->new(join("\n",@_))); |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub readconfig |
|
72
|
|
|
|
|
|
|
{ |
|
73
|
8
|
|
|
8
|
0
|
103
|
my ($file) = @_; |
|
74
|
|
|
|
|
|
|
|
|
75
|
8
|
50
|
|
|
|
43
|
$fh = ref($file) ? $file : IO::File->new($file, "r"); |
|
76
|
|
|
|
|
|
|
|
|
77
|
8
|
|
|
|
|
36
|
$line = <$fh>; |
|
78
|
8
|
|
|
|
|
45
|
return rc1(0, 'aaaa', $undef, "! whole enchalada\n"); |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub rc1 |
|
82
|
|
|
|
|
|
|
{ |
|
83
|
92
|
|
|
92
|
0
|
276
|
my ($indent, $seq, $parent, $dcon) = @_; |
|
84
|
92
|
|
|
|
|
165
|
my $last; |
|
85
|
92
|
|
|
|
|
319
|
my $config = bless { $bloc => 1 }, __PACKAGE__; |
|
86
|
|
|
|
|
|
|
|
|
87
|
92
|
50
|
|
|
|
385
|
$config->{$debg} = "BLOCK:$dseq:$dcon" if $ddata; |
|
88
|
|
|
|
|
|
|
|
|
89
|
92
|
|
|
|
|
563
|
$config->{$cntx} = $parent; |
|
90
|
92
|
|
|
|
|
390
|
weaken $config->{$cntx}; |
|
91
|
|
|
|
|
|
|
|
|
92
|
92
|
|
|
|
|
178
|
$dseq++; |
|
93
|
92
|
|
|
|
|
174
|
my $prev; |
|
94
|
|
|
|
|
|
|
my $ciscobug; |
|
95
|
92
|
|
|
|
|
229
|
for(;$line;$prev = $line, $line = <$fh>) { |
|
96
|
888
|
|
|
|
|
1968
|
$_ = $line; |
|
97
|
888
|
|
|
|
|
3883
|
s/^( *)//; |
|
98
|
888
|
|
|
|
|
2431
|
my $in = length($1); |
|
99
|
888
|
|
|
|
|
1800
|
s/^(no +)//; |
|
100
|
888
|
|
|
|
|
1852
|
my $no = $1; |
|
101
|
888
|
100
|
|
|
|
2946
|
if ($in > $indent) { |
|
|
|
100
|
|
|
|
|
|
|
102
|
81
|
100
|
|
|
|
212
|
if ($last) { |
|
103
|
79
|
|
|
|
|
398
|
$last->{$subs} = rc1($in, "$last->{$seqn}aaa", $last, $line); |
|
104
|
79
|
|
|
|
|
166
|
undef $last; |
|
105
|
79
|
100
|
|
|
|
246
|
redo if $line; |
|
106
|
|
|
|
|
|
|
} else { |
|
107
|
|
|
|
|
|
|
# This really shouldn't happen. But it does. It's a violation of |
|
108
|
|
|
|
|
|
|
# the usual indentation rules. |
|
109
|
|
|
|
|
|
|
# |
|
110
|
|
|
|
|
|
|
# An exclamation marks a reset of the indentation to zero. |
|
111
|
|
|
|
|
|
|
# |
|
112
|
2
|
50
|
33
|
|
|
62
|
if ($indent + 1 == $in && $allow_plus_one_indent && $line =~ /^\s*$allow_plus_one_indent/) { |
|
|
|
|
33
|
|
|
|
|
|
113
|
0
|
|
|
|
|
0
|
$indent = $indent + 1; |
|
114
|
0
|
|
|
|
|
0
|
redo; |
|
115
|
|
|
|
|
|
|
} |
|
116
|
2
|
50
|
33
|
|
|
12
|
if ($indent != 0 || ($prev ne "!\n" && $prev !~ /^!.*$/)) { |
|
|
|
|
33
|
|
|
|
|
|
117
|
0
|
0
|
|
|
|
0
|
if ($bad_indent_policy eq 'IGNORE') { |
|
|
|
0
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
# okay then |
|
119
|
|
|
|
|
|
|
} elsif ($bad_indent_policy eq 'WARN') { |
|
120
|
0
|
|
|
|
|
0
|
warn "Unexpected indentation change <$.:$_>"; |
|
121
|
|
|
|
|
|
|
} else { |
|
122
|
0
|
|
|
|
|
0
|
confess "Unexpected indentation change <$.:$_>"; |
|
123
|
|
|
|
|
|
|
} |
|
124
|
|
|
|
|
|
|
} |
|
125
|
2
|
|
|
|
|
3
|
$ciscobug = 1; |
|
126
|
2
|
|
|
|
|
5
|
$indent = $in; |
|
127
|
|
|
|
|
|
|
} |
|
128
|
|
|
|
|
|
|
} elsif ($in < $indent) { |
|
129
|
90
|
100
|
66
|
|
|
458
|
if ($ciscobug && $in == 0) { |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
130
|
2
|
|
|
|
|
4
|
$indent = 0; |
|
131
|
|
|
|
|
|
|
} elsif ($last && $indent - 1 == $in && $allow_minus_one_indent && $line =~ /^\s*$allow_minus_one_indent/) { |
|
132
|
5
|
50
|
|
|
|
16
|
confess unless $last->{$seqn}; |
|
133
|
5
|
|
|
|
|
32
|
$last->{$subs} = rc1($in, "$last->{$seqn}aaa", $last, $line); |
|
134
|
5
|
|
|
|
|
8
|
undef $last; |
|
135
|
5
|
50
|
|
|
|
14
|
redo if $line; |
|
136
|
|
|
|
|
|
|
} else { |
|
137
|
83
|
|
|
|
|
354
|
return $config; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
} |
|
140
|
722
|
100
|
|
|
|
2311
|
next if /^$/; |
|
141
|
716
|
100
|
|
|
|
2603
|
next if /^\s*!/; |
|
142
|
551
|
|
|
|
|
946
|
my $context = $config; |
|
143
|
551
|
|
|
|
|
1934
|
my (@x) = split; |
|
144
|
551
|
|
|
|
|
1062
|
my $owords = @x; |
|
145
|
551
|
|
100
|
|
|
3014
|
while (@x && ref $context->{$x[0]}) { |
|
146
|
432
|
|
|
|
|
957
|
$context = $context->{$x[0]}; |
|
147
|
432
|
|
|
|
|
2018
|
shift @x; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
551
|
100
|
|
|
|
1901
|
if (! @x) { |
|
|
|
50
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# A duplicate line. Not fun. |
|
151
|
|
|
|
|
|
|
# As far as we know this can only occur as a remark inside |
|
152
|
|
|
|
|
|
|
# filter list. |
|
153
|
|
|
|
|
|
|
# Q: what's the point of keeping track of these? Need to be |
|
154
|
|
|
|
|
|
|
# able to accurately dump filter list definitions |
|
155
|
|
|
|
|
|
|
# |
|
156
|
|
|
|
|
|
|
$context->{$dupl} = [] |
|
157
|
15
|
100
|
|
|
|
60
|
unless $context->{$dupl}; |
|
158
|
|
|
|
|
|
|
my $n = bless { |
|
159
|
|
|
|
|
|
|
$ddata |
|
160
|
|
|
|
|
|
|
? ( $debg => "$dseq:DUP:$line", |
|
161
|
15
|
50
|
|
|
|
51
|
$word => $context->{$word}, ) |
|
162
|
|
|
|
|
|
|
: (), |
|
163
|
|
|
|
|
|
|
}, __PACKAGE__; |
|
164
|
15
|
|
|
|
|
30
|
$dseq++; |
|
165
|
|
|
|
|
|
|
|
|
166
|
15
|
|
|
|
|
22
|
push(@{$context->{$dupl}}, $n); |
|
|
15
|
|
|
|
|
34
|
|
|
167
|
15
|
|
|
|
|
27
|
$context = $n; |
|
168
|
|
|
|
|
|
|
} elsif (defined $context->{$x[0]}) { |
|
169
|
0
|
|
|
|
|
0
|
confess "already $.: '$x[0]' $line"; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
551
|
|
|
|
|
1416
|
while (@x) { |
|
172
|
1468
|
|
|
|
|
2957
|
my $x = shift @x; |
|
173
|
1468
|
50
|
|
|
|
3543
|
confess unless defined $x; |
|
174
|
1468
|
50
|
|
|
|
3364
|
confess unless defined $dseq; |
|
175
|
1468
|
100
|
|
|
|
3296
|
$line = "" unless defined $line; |
|
176
|
1468
|
50
|
|
|
|
5272
|
$context = $context->{$x} = bless { |
|
177
|
|
|
|
|
|
|
$ddata |
|
178
|
|
|
|
|
|
|
? ( $debg => "$dseq:$x:$line", |
|
179
|
|
|
|
|
|
|
$word => $x, ) |
|
180
|
|
|
|
|
|
|
: (), |
|
181
|
|
|
|
|
|
|
}, __PACKAGE__; |
|
182
|
1468
|
|
|
|
|
4095
|
$dseq++; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
551
|
|
|
|
|
1667
|
$context->{$seqn} = $seq++; |
|
185
|
551
|
|
|
|
|
1351
|
$context->{$text} = $line; |
|
186
|
551
|
50
|
|
|
|
1434
|
confess if $context->{$cntx}; |
|
187
|
|
|
|
|
|
|
|
|
188
|
551
|
|
|
|
|
1140
|
$context->{$cntx} = $config; |
|
189
|
551
|
|
|
|
|
1914
|
weaken $context->{$cntx}; |
|
190
|
|
|
|
|
|
|
|
|
191
|
551
|
50
|
|
|
|
1382
|
unless ($nonext) { |
|
192
|
551
|
100
|
|
|
|
1441
|
if ($last) { |
|
193
|
392
|
|
|
|
|
831
|
$last->{$next} = $context; |
|
194
|
392
|
|
|
|
|
1257
|
weaken $last->{$next}; |
|
195
|
|
|
|
|
|
|
} else { |
|
196
|
159
|
|
|
|
|
315
|
$config->{$next} = $context; |
|
197
|
159
|
|
|
|
|
452
|
weaken $config->{$next}; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
551
|
|
|
|
|
1031
|
$last = $context; |
|
202
|
|
|
|
|
|
|
|
|
203
|
551
|
100
|
100
|
|
|
5673
|
if ($line && |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
204
|
|
|
|
|
|
|
($line =~ /(\^C)/ && $line !~ /\^C.*\^C/) |
|
205
|
|
|
|
|
|
|
|| |
|
206
|
|
|
|
|
|
|
($line =~ /banner [a-z\-]+ ((?!\^C).+)/)) |
|
207
|
|
|
|
|
|
|
{ |
|
208
|
|
|
|
|
|
|
# |
|
209
|
|
|
|
|
|
|
# big special case for banners 'cause they don't follow |
|
210
|
|
|
|
|
|
|
# normal indenting rules |
|
211
|
|
|
|
|
|
|
# |
|
212
|
8
|
50
|
|
|
|
26
|
die unless defined $1; |
|
213
|
8
|
|
|
|
|
57
|
my $sep = qr/\Q$1\E/; |
|
214
|
8
|
|
|
|
|
31
|
my $sub = $last->{$subs} = bless { $bloc => 1 }, __PACKAGE__; |
|
215
|
8
|
|
|
|
|
23
|
$sub->{$cntx} = $last; |
|
216
|
8
|
|
|
|
|
26
|
weaken $sub->{$cntx}; |
|
217
|
8
|
|
|
|
|
28
|
my $subnull = $sub->{''} = bless { $bloc => 1, $dupl => [] }, __PACKAGE__; |
|
218
|
8
|
|
|
|
|
21
|
$subnull->{$cntx} = $sub; |
|
219
|
8
|
|
|
|
|
34
|
weaken $subnull->{$cntx}; |
|
220
|
8
|
|
|
|
|
13
|
for(;;) { |
|
221
|
48
|
|
|
|
|
113
|
$line = <$fh>; |
|
222
|
48
|
50
|
|
|
|
107
|
last unless $line; |
|
223
|
48
|
50
|
|
|
|
131
|
my $l = bless { |
|
224
|
|
|
|
|
|
|
$ddata ? ( $debg => "$dseq:DUP:$line" ) : (), |
|
225
|
|
|
|
|
|
|
}, __PACKAGE__; |
|
226
|
48
|
|
|
|
|
82
|
$dseq++; |
|
227
|
48
|
|
|
|
|
134
|
$l->{$seqn} = $seq++; |
|
228
|
48
|
|
|
|
|
123
|
$l->{$text} = $line; |
|
229
|
48
|
|
|
|
|
86
|
$l->{$cntx} = $subnull; |
|
230
|
48
|
|
|
|
|
149
|
weaken($l->{$cntx}); |
|
231
|
48
|
|
|
|
|
71
|
push(@{$subnull->{$dupl}}, $l); |
|
|
48
|
|
|
|
|
120
|
|
|
232
|
48
|
100
|
|
|
|
265
|
last if $line =~ /$sep[\r]?$/; |
|
233
|
|
|
|
|
|
|
} |
|
234
|
8
|
50
|
33
|
|
|
112
|
warn "parse probably failed" |
|
235
|
|
|
|
|
|
|
unless $line && $line =~ /$sep[\r]?$/; |
|
236
|
|
|
|
|
|
|
} |
|
237
|
|
|
|
|
|
|
} |
|
238
|
9
|
|
|
|
|
59
|
return $config; |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
#sub word { $_[0]->{$word} }; |
|
242
|
79
|
|
|
79
|
1
|
306
|
sub block { $_[0]->{$bloc} } |
|
243
|
13367
|
50
|
66
|
13367
|
0
|
46822
|
sub seqn { $_[0]->{$seqn} || $_[0]->endpt->{$seqn} || confess }; |
|
244
|
225
|
100
|
100
|
225
|
1
|
1051
|
sub subs { $_[0]->{$subs} || $_[0]->zoom->{$subs} || $undef }; |
|
245
|
28
|
50
|
66
|
28
|
1
|
79
|
sub next { $_[0]->{$next} || $_[0]->zoom->{$next} || $undef }; |
|
246
|
|
|
|
|
|
|
#sub undefined { $_[0] eq $undef } |
|
247
|
|
|
|
|
|
|
#sub defined { $_[0] ne $undef } |
|
248
|
77752
|
100
|
|
77752
|
0
|
231154
|
sub defined { $_[0]->{$debg} ? $_[0]->{$debg} ne $UNDEFDESC : 1 } |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub destroy |
|
251
|
|
|
|
|
|
|
{ |
|
252
|
0
|
|
|
0
|
0
|
0
|
warn "Cisco::Reconfig::destroy is deprecated"; |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub single |
|
256
|
|
|
|
|
|
|
{ |
|
257
|
42
|
|
|
42
|
1
|
109
|
my ($self) = @_; |
|
258
|
42
|
100
|
|
|
|
218
|
return $self if defined $self->{$text}; |
|
259
|
17
|
|
|
|
|
125
|
my (@p) = grep(! /$spec/o, keys %$self); |
|
260
|
17
|
100
|
|
|
|
82
|
return undef if @p > 1; |
|
261
|
16
|
50
|
|
|
|
64
|
return $self unless @p; |
|
262
|
16
|
|
33
|
|
|
83
|
return $self->{$p[0]}->single || $self; |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub kids |
|
266
|
|
|
|
|
|
|
{ |
|
267
|
15
|
|
|
15
|
1
|
39
|
my ($self) = @_; |
|
268
|
15
|
50
|
|
|
|
39
|
return $self if ! $self; |
|
269
|
15
|
|
|
|
|
119
|
my (@p) = $self->sortit(grep(! /$spec/o, keys %$self)); |
|
270
|
15
|
100
|
|
|
|
64
|
return $self if ! @p; |
|
271
|
3
|
|
|
|
|
12
|
return (map { $self->{$_} } @p); |
|
|
42
|
|
|
|
|
85
|
|
|
272
|
|
|
|
|
|
|
} |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub zoom |
|
275
|
|
|
|
|
|
|
{ |
|
276
|
400
|
|
|
400
|
1
|
1140
|
my ($self) = @_; |
|
277
|
400
|
100
|
|
|
|
1520
|
return $self if defined $self->{$text}; |
|
278
|
235
|
|
|
|
|
2440
|
my (@p) = $self->sortit(grep(! /$spec/o, keys %$self)); |
|
279
|
235
|
100
|
|
|
|
2267
|
return $self if @p > 1; |
|
280
|
71
|
50
|
|
|
|
239
|
return $self unless @p; |
|
281
|
71
|
|
|
|
|
254
|
return $self->{$p[0]}->zoom; |
|
282
|
|
|
|
|
|
|
} |
|
283
|
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub endpt |
|
285
|
|
|
|
|
|
|
{ |
|
286
|
36864
|
|
|
36864
|
1
|
73419
|
my ($self) = @_; |
|
287
|
36864
|
50
|
|
|
|
79315
|
return $self if ! $self; |
|
288
|
36864
|
|
|
|
|
167388
|
my (@p) = grep(! /$spec/o, keys %$self); |
|
289
|
36864
|
100
|
100
|
|
|
195236
|
return $self if defined($self->{$text}) && ! @p; |
|
290
|
25292
|
50
|
|
|
|
65295
|
confess unless @p; |
|
291
|
25292
|
|
|
|
|
65560
|
return $self->{$p[0]}->endpt; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub text |
|
296
|
|
|
|
|
|
|
{ |
|
297
|
429
|
|
|
429
|
1
|
1176
|
my ($self) = @_; |
|
298
|
429
|
100
|
|
|
|
986
|
return '' unless $self; |
|
299
|
418
|
100
|
|
|
|
1502
|
if (defined $self->{$text}) { |
|
300
|
|
|
|
|
|
|
return $debug_text |
|
301
|
|
|
|
|
|
|
? $self->{$word} . " " . $self->{$text} |
|
302
|
133
|
50
|
|
|
|
811
|
: $self->{$text}; |
|
303
|
|
|
|
|
|
|
} |
|
304
|
285
|
|
|
|
|
1373
|
my (@p) = $self->sortit(grep(! /$spec/o, keys %$self)); |
|
305
|
285
|
100
|
|
|
|
1210
|
if (@p > 1) { |
|
|
|
100
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
# |
|
307
|
|
|
|
|
|
|
# This is nasty because the lines may not be ordered |
|
308
|
|
|
|
|
|
|
# in the tree-hiearchy used by Cisco::Reconfig |
|
309
|
|
|
|
|
|
|
# |
|
310
|
9
|
|
|
|
|
30
|
my %temp = map { $self->{$_}->sequenced_text(0) } @p; |
|
|
37
|
|
|
|
|
131
|
|
|
311
|
9
|
|
|
|
|
71
|
return join('', map { $temp{$_} } sort keys %temp); |
|
|
46
|
|
|
|
|
209
|
|
|
312
|
|
|
|
|
|
|
} elsif ($self->{$dupl}) { |
|
313
|
6
|
50
|
|
|
|
23
|
return join('', map { $_->{$word} . " " . $_->{$text} } @{$self->{$dupl}}) |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
314
|
|
|
|
|
|
|
if $debug_text; |
|
315
|
6
|
|
|
|
|
17
|
return join('', map { $_->{$text} } @{$self->{$dupl}}); |
|
|
34
|
|
|
|
|
131
|
|
|
|
6
|
|
|
|
|
18
|
|
|
316
|
|
|
|
|
|
|
} |
|
317
|
270
|
50
|
|
|
|
756
|
confess unless @p; |
|
318
|
270
|
|
|
|
|
930
|
return $self->{$p[0]}->text; |
|
319
|
|
|
|
|
|
|
} |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub sequenced_text |
|
322
|
|
|
|
|
|
|
{ |
|
323
|
282
|
|
|
282
|
0
|
583
|
my ($self, $all) = @_; |
|
324
|
282
|
|
|
|
|
524
|
my @t = (); |
|
325
|
282
|
100
|
|
|
|
760
|
if (defined $self->{$text}) { |
|
326
|
|
|
|
|
|
|
push(@t, $debug_text |
|
327
|
|
|
|
|
|
|
? ($self->seqn => $self->{$word} . " " . $self->{$text}) |
|
328
|
98
|
50
|
|
|
|
354
|
: ($self->seqn => $self->{$text})); |
|
329
|
|
|
|
|
|
|
} |
|
330
|
282
|
100
|
|
|
|
705
|
if (exists $self->{$dupl}) { |
|
331
|
|
|
|
|
|
|
push (@t, $debug_text |
|
332
|
0
|
|
|
|
|
0
|
? map { $_->seqn => $_->{$word} . " " . $_->{$text} } @{$self->{$dupl}} |
|
|
0
|
|
|
|
|
0
|
|
|
333
|
1
|
50
|
|
|
|
8
|
: map { $_->seqn => $_->{$text} } @{$self->{$dupl}}); |
|
|
1
|
|
|
|
|
14
|
|
|
|
1
|
|
|
|
|
6
|
|
|
334
|
|
|
|
|
|
|
} |
|
335
|
282
|
|
|
|
|
1387
|
my (@p) = $self->sortit(grep(! /$spec/o, keys %$self)); |
|
336
|
282
|
100
|
|
|
|
800
|
if (@p) { |
|
337
|
|
|
|
|
|
|
# |
|
338
|
|
|
|
|
|
|
# This is nasty because the lines may not be ordered |
|
339
|
|
|
|
|
|
|
# in the tree-hiearchy used by Cisco::Reconfig |
|
340
|
|
|
|
|
|
|
# |
|
341
|
190
|
|
|
|
|
354
|
return (@t, map { $self->{$_}->sequenced_text($all) } @p); |
|
|
224
|
|
|
|
|
710
|
|
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
push(@t, $self->{$subs}->sequenced_text($all)) |
|
344
|
92
|
100
|
100
|
|
|
348
|
if $all && $self->{$subs}; |
|
345
|
92
|
50
|
|
|
|
799
|
return @t if @t; |
|
346
|
0
|
0
|
|
|
|
0
|
confess unless @p; |
|
347
|
0
|
|
|
|
|
0
|
return $self->{$p[0]}->sequenced_text($all); |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub alltext |
|
351
|
|
|
|
|
|
|
{ |
|
352
|
6
|
|
|
6
|
1
|
28
|
my ($self) = @_; |
|
353
|
6
|
100
|
|
|
|
19
|
return '' unless $self; |
|
354
|
5
|
|
|
|
|
31
|
my %temp = $self->sequenced_text(1); |
|
355
|
5
|
|
|
|
|
59
|
return join('', map { $temp{$_} } sort keys %temp); |
|
|
53
|
|
|
|
|
226
|
|
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
sub chomptext |
|
359
|
|
|
|
|
|
|
{ |
|
360
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
361
|
0
|
|
|
|
|
0
|
my $t = $self->text; |
|
362
|
0
|
|
|
|
|
0
|
chomp($t); |
|
363
|
0
|
|
|
|
|
0
|
return $t; |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
sub returns |
|
367
|
|
|
|
|
|
|
{ |
|
368
|
16
|
|
|
16
|
0
|
67
|
my (@o) = @_; |
|
369
|
16
|
|
|
|
|
56
|
for my $o (@o) { |
|
370
|
55
|
50
|
33
|
|
|
329
|
$o .= "\n" |
|
371
|
|
|
|
|
|
|
if defined($o) && $o !~ /\n$/; |
|
372
|
|
|
|
|
|
|
} |
|
373
|
16
|
50
|
|
|
|
52
|
return $o[0] unless wantarray; |
|
374
|
16
|
|
|
|
|
174
|
return @o; |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
sub openangle |
|
378
|
|
|
|
|
|
|
{ |
|
379
|
9
|
|
33
|
9
|
0
|
127
|
my (@l) = grep(defined && /\S/, @_); |
|
380
|
9
|
|
|
|
|
31
|
my $x = 0; |
|
381
|
9
|
|
|
|
|
42
|
for my $l (@l) { |
|
382
|
12
|
|
|
|
|
70
|
substr($l, 0, 0) = (' ' x $x++); |
|
383
|
|
|
|
|
|
|
} |
|
384
|
9
|
50
|
|
|
|
35
|
return $l[0] unless wantarray; |
|
385
|
9
|
|
|
|
|
42
|
return @l; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub closeangle |
|
389
|
|
|
|
|
|
|
{ |
|
390
|
11
|
|
33
|
11
|
0
|
132
|
my (@l) = grep(defined && /\S/, @_); |
|
391
|
11
|
|
|
|
|
38
|
my $x = $#l; |
|
392
|
11
|
|
|
|
|
46
|
for my $l (@l) { |
|
393
|
14
|
|
|
|
|
60
|
substr($l, 0, 0) = (' ' x $x--); |
|
394
|
|
|
|
|
|
|
} |
|
395
|
11
|
50
|
|
|
|
47
|
return $l[0] unless wantarray; |
|
396
|
11
|
|
|
|
|
47
|
return @l; |
|
397
|
|
|
|
|
|
|
} |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub context |
|
400
|
|
|
|
|
|
|
{ |
|
401
|
|
|
|
|
|
|
defined($_[0]->{$cntx}) |
|
402
|
|
|
|
|
|
|
? $_[0]->{$cntx} |
|
403
|
127
|
100
|
33
|
127
|
1
|
500
|
: $_[0]->endpt->{$cntx} |
|
404
|
|
|
|
|
|
|
|| ($_[0] ? confess "$_[0]" : $undef) |
|
405
|
|
|
|
|
|
|
}; |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# |
|
408
|
|
|
|
|
|
|
# interface Loopback7 |
|
409
|
|
|
|
|
|
|
# ip address x y |
|
410
|
|
|
|
|
|
|
# |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
sub setcontext |
|
413
|
|
|
|
|
|
|
{ |
|
414
|
74
|
|
|
74
|
1
|
216
|
my ($self, @extras) = @_; |
|
415
|
74
|
50
|
|
|
|
244
|
print STDERR "\nSETCONTEXT\n" if $debug_context; |
|
416
|
74
|
100
|
|
|
|
230
|
unless ($self->block) { |
|
417
|
10
|
50
|
|
|
|
34
|
print STDERR "\nNOT_A_BLOCK $self->{$debg}\n" if $debug_context; |
|
418
|
10
|
|
|
|
|
33
|
$self = $self->context; |
|
419
|
|
|
|
|
|
|
} |
|
420
|
|
|
|
|
|
|
printf STDERR "\nSELF %sCONTEXT %sCCONTEXT %sEXTRAS$#extras @extras\n", |
|
421
|
|
|
|
|
|
|
$self->{$debg}, $self->context->{$debg}, |
|
422
|
74
|
50
|
|
|
|
225
|
$self->context->context->{$debg} |
|
423
|
|
|
|
|
|
|
if $debug_context; |
|
424
|
74
|
|
|
|
|
194
|
my $x = $self->context; |
|
425
|
|
|
|
|
|
|
return (grep defined, |
|
426
|
|
|
|
|
|
|
$x->context->setcontext, |
|
427
|
74
|
100
|
|
|
|
207
|
trim($x->zoom->{$text}), |
|
428
|
|
|
|
|
|
|
@extras) |
|
429
|
|
|
|
|
|
|
if $x; |
|
430
|
38
|
|
|
|
|
190
|
return @extras; |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub contextcount |
|
434
|
|
|
|
|
|
|
{ |
|
435
|
27
|
|
|
27
|
0
|
131
|
my $self = shift; |
|
436
|
27
|
|
|
|
|
136
|
my (@a) = $self->setcontext(@_); |
|
437
|
27
|
50
|
|
|
|
100
|
printf STDERR "CONTEXTCOUNT = %d\n", scalar(@a) if $debug_context; |
|
438
|
27
|
50
|
|
|
|
121
|
print STDERR map { "CC: $_\n" } @a if $debug_context; |
|
|
0
|
|
|
|
|
0
|
|
|
439
|
27
|
|
|
|
|
136
|
return scalar(@a); |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
sub unsetcontext |
|
443
|
|
|
|
|
|
|
{ |
|
444
|
11
|
|
|
11
|
1
|
38
|
my $self = shift; |
|
445
|
11
|
|
|
|
|
50
|
return (("exit") x $self->contextcount(@_)); |
|
446
|
|
|
|
|
|
|
} |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub teql |
|
449
|
|
|
|
|
|
|
{ |
|
450
|
27
|
|
|
27
|
0
|
87
|
my ($self, $b) = @_; |
|
451
|
27
|
|
|
|
|
88
|
my $a = $self->text; |
|
452
|
27
|
|
|
|
|
138
|
$a =~ s/^\s+/ /g; |
|
453
|
27
|
|
|
|
|
99
|
$a =~ s/^ //; |
|
454
|
27
|
|
|
|
|
67
|
$a =~ s/ $//; |
|
455
|
27
|
|
|
|
|
62
|
chomp($a); |
|
456
|
27
|
|
|
|
|
113
|
$b =~ s/^\s+/ /g; |
|
457
|
27
|
|
|
|
|
86
|
$b =~ s/^ //; |
|
458
|
27
|
|
|
|
|
65
|
$b =~ s/ $//; |
|
459
|
27
|
|
|
|
|
53
|
chomp($b); |
|
460
|
27
|
|
|
|
|
114
|
return $a eq $b; |
|
461
|
|
|
|
|
|
|
} |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
sub set |
|
464
|
|
|
|
|
|
|
{ |
|
465
|
16
|
|
|
16
|
1
|
2418
|
my $self = shift; |
|
466
|
16
|
|
|
|
|
56
|
my $new = pop; |
|
467
|
16
|
|
|
|
|
73
|
my (@designators) = @_; |
|
468
|
|
|
|
|
|
|
#my ($self, $designator, $new) = @_; |
|
469
|
16
|
50
|
|
|
|
71
|
print STDERR "\nSET\n" if $debug_set; |
|
470
|
16
|
50
|
|
|
|
51
|
return undef unless $self; |
|
471
|
16
|
|
|
|
|
39
|
my $old; |
|
472
|
|
|
|
|
|
|
#my @designators; |
|
473
|
16
|
50
|
|
|
|
55
|
print STDERR "\nSELF $self->{$debg}" if $debug_set; |
|
474
|
|
|
|
|
|
|
# move into the block if possible |
|
475
|
16
|
100
|
|
|
|
68
|
$self = $self->subs |
|
476
|
|
|
|
|
|
|
if $self->subs; |
|
477
|
16
|
50
|
|
|
|
75
|
print STDERR "\nSELF $self->{$debg}" if $debug_set; |
|
478
|
|
|
|
|
|
|
#if (ref $designator eq 'ARRAY') { |
|
479
|
|
|
|
|
|
|
# @designators = @$designator; |
|
480
|
|
|
|
|
|
|
# $old = $self->get(@designators); |
|
481
|
|
|
|
|
|
|
# $designator = pop(@designators); |
|
482
|
|
|
|
|
|
|
#} elsif ($designator) { |
|
483
|
|
|
|
|
|
|
# $old = $self->get($designator); |
|
484
|
|
|
|
|
|
|
#} else { |
|
485
|
|
|
|
|
|
|
# $old = $self; |
|
486
|
|
|
|
|
|
|
#} |
|
487
|
16
|
|
|
|
|
45
|
my $designator; |
|
488
|
16
|
100
|
|
|
|
78
|
if (@designators) { |
|
489
|
10
|
|
|
|
|
57
|
$old = $self->get(@designators); |
|
490
|
10
|
|
|
|
|
55
|
$designator = pop(@designators); |
|
491
|
|
|
|
|
|
|
} else { |
|
492
|
6
|
|
|
|
|
17
|
$old = $self; |
|
493
|
|
|
|
|
|
|
} |
|
494
|
16
|
50
|
|
|
|
113
|
print STDERR "\nOLD $old->{$debg}" if $debug_set; |
|
495
|
16
|
|
|
|
|
307
|
my (@lines) = expand(grep(/./, split(/\n/, $new))); |
|
496
|
16
|
100
|
|
|
|
1903
|
if ($lines[0] =~ /^(\s+)/) { |
|
497
|
11
|
|
|
|
|
59
|
my $ls = $1; |
|
498
|
11
|
|
|
|
|
35
|
my $m = 1; |
|
499
|
11
|
50
|
|
|
|
37
|
map { substr($_, 0, length($ls)) eq $ls or $m = 0 } @lines; |
|
|
51
|
|
|
|
|
217
|
|
|
500
|
11
|
50
|
|
|
|
53
|
map { substr($_, 0, length($ls)) = '' } @lines |
|
|
51
|
|
|
|
|
253
|
|
|
501
|
|
|
|
|
|
|
if $m; |
|
502
|
|
|
|
|
|
|
} |
|
503
|
16
|
|
|
|
|
112
|
my $indent = (' ' x $self->contextcount(@designators)); |
|
504
|
16
|
|
|
|
|
66
|
for $_ (@lines) { |
|
505
|
56
|
|
|
|
|
632
|
s/(\S)\s+/$1 /g; |
|
506
|
56
|
|
|
|
|
242
|
s/\s+$//; |
|
507
|
56
|
100
|
|
|
|
199
|
$_ = 'exit' if /^\s*!\s*$/; |
|
508
|
56
|
|
|
|
|
168
|
$_ = "$indent$_"; |
|
509
|
|
|
|
|
|
|
} |
|
510
|
16
|
50
|
|
|
|
70
|
print STDERR "SET TO {\n@lines\n}\n" if $debug_set; |
|
511
|
16
|
|
|
|
|
65
|
my $desig = shift(@lines); |
|
512
|
16
|
|
|
|
|
50
|
my @o; |
|
513
|
16
|
100
|
|
|
|
61
|
undef $old |
|
514
|
|
|
|
|
|
|
if ! $old; |
|
515
|
16
|
100
|
100
|
|
|
67
|
if (! $old) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
516
|
1
|
50
|
|
|
|
8
|
print STDERR "NO OLD\n" if $debug_set; |
|
517
|
1
|
|
|
|
|
7
|
push(@o, openangle($self->setcontext(@designators))); |
|
518
|
1
|
|
|
|
|
5
|
push(@o, $desig); |
|
519
|
|
|
|
|
|
|
} elsif (! $designator && ! looks_like_a_block($desig,@lines)) { |
|
520
|
5
|
100
|
66
|
|
|
16
|
if ($self->block && $self->context) { |
|
521
|
2
|
|
|
|
|
7
|
unshift(@lines, $desig); |
|
522
|
2
|
|
|
|
|
8
|
$old = $self->context; |
|
523
|
2
|
|
|
|
|
7
|
undef $desig; |
|
524
|
|
|
|
|
|
|
} else { |
|
525
|
3
|
|
|
|
|
9
|
unshift(@lines, $desig); |
|
526
|
3
|
50
|
|
|
|
12
|
print STDERR "IN NASTY BIT\n" if $debug_set; |
|
527
|
|
|
|
|
|
|
# |
|
528
|
|
|
|
|
|
|
# this is a messy situation: we've got a random |
|
529
|
|
|
|
|
|
|
# block of stuff to set inside a random block. |
|
530
|
|
|
|
|
|
|
# In theorey we could avoid the die, I'll leave |
|
531
|
|
|
|
|
|
|
# that as an exercise for the reader. |
|
532
|
|
|
|
|
|
|
# |
|
533
|
3
|
50
|
|
|
|
53
|
confess "You cannot set nested configurations with set(undef, \$config) -- use a designator on the set method" |
|
534
|
|
|
|
|
|
|
if grep(/^$indent\s/, @lines); |
|
535
|
3
|
|
|
|
|
19
|
my (@t) = split(/\n/, $self->text); |
|
536
|
3
|
|
|
|
|
9
|
my (%t); |
|
537
|
3
|
|
|
|
|
18
|
@t{strim(@t)} = @t; |
|
538
|
3
|
|
|
|
|
19
|
while (@lines) { |
|
539
|
23
|
|
|
|
|
68
|
my $l = strim(shift(@lines)); |
|
540
|
23
|
100
|
|
|
|
77
|
if ($t{$l}) { |
|
541
|
22
|
|
|
|
|
75
|
delete $t{$l}; |
|
542
|
|
|
|
|
|
|
} else { |
|
543
|
1
|
|
|
|
|
8
|
push(@o, "$indent$l"); |
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
} |
|
546
|
3
|
|
|
|
|
14
|
for my $k (keys %t) { |
|
547
|
2
|
|
|
|
|
10
|
unshift(@o, iinvert($indent, $k)); |
|
548
|
|
|
|
|
|
|
} |
|
549
|
3
|
100
|
|
|
|
20
|
unshift(@o, $self->setcontext) |
|
550
|
|
|
|
|
|
|
if @o; |
|
551
|
|
|
|
|
|
|
} |
|
552
|
|
|
|
|
|
|
} elsif ($old->teql($desig)) { |
|
553
|
4
|
50
|
|
|
|
17
|
print STDERR "DESIGNATOR EQUAL\n" if $debug_set; |
|
554
|
|
|
|
|
|
|
# okay |
|
555
|
|
|
|
|
|
|
} else { |
|
556
|
6
|
50
|
|
|
|
45
|
print STDERR "DESIGNATOR DIFERENT\n" if $debug_set; |
|
557
|
6
|
|
|
|
|
27
|
push(@o, openangle($self->setcontext(@designators))); |
|
558
|
6
|
100
|
|
|
|
30
|
if (defined $designator) { |
|
559
|
5
|
|
|
|
|
32
|
push(@o, iinvert($indent, $designator)); |
|
560
|
|
|
|
|
|
|
} else { |
|
561
|
1
|
|
|
|
|
7
|
push(@o, iinvert($indent, split(/\n/, $self->text))); |
|
562
|
|
|
|
|
|
|
} |
|
563
|
6
|
|
|
|
|
22
|
push(@o, $desig); |
|
564
|
|
|
|
|
|
|
} |
|
565
|
16
|
100
|
|
|
|
82
|
if (@lines) { |
|
566
|
6
|
50
|
66
|
|
|
16
|
if ($old && ! @o && $old->subs && $old->subs->next) { |
|
|
|
|
66
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
567
|
5
|
50
|
|
|
|
17
|
print STDERR "OLD= $old->{$debg}" if $debug_set; |
|
568
|
5
|
|
|
|
|
11
|
my $ok = 1; |
|
569
|
5
|
|
|
|
|
16
|
my $f = $old->subs->next; |
|
570
|
5
|
50
|
|
|
|
19
|
print STDERR "F= $f->{$debg}" if $debug_set; |
|
571
|
5
|
|
|
|
|
19
|
for my $l (@lines) { |
|
572
|
19
|
100
|
|
|
|
64
|
next if $l =~ /^\s*exit\s*$/; |
|
573
|
17
|
100
|
|
|
|
43
|
next if $f->teql($l); |
|
574
|
2
|
50
|
|
|
|
10
|
print STDERR "LINE DIFF ON $l\n" if $debug_set; |
|
575
|
2
|
|
|
|
|
5
|
$ok = 0; |
|
576
|
2
|
|
|
|
|
6
|
last; |
|
577
|
|
|
|
|
|
|
} continue { |
|
578
|
17
|
|
|
|
|
39
|
$f = $f->next; |
|
579
|
17
|
50
|
|
|
|
51
|
print STDERR "F= $f->{$debg}" if $debug_set; |
|
580
|
|
|
|
|
|
|
} |
|
581
|
5
|
100
|
66
|
|
|
28
|
if (! $ok || $f) { |
|
582
|
2
|
|
|
|
|
10
|
push(@o, openangle($self->setcontext(@designators))); |
|
583
|
2
|
|
|
|
|
10
|
push(@o, iinvert($indent, $designator)); |
|
584
|
2
|
|
|
|
|
7
|
push(@o, $desig); |
|
585
|
|
|
|
|
|
|
} |
|
586
|
|
|
|
|
|
|
} |
|
587
|
6
|
100
|
|
|
|
27
|
push(@o, @lines) if @o; |
|
588
|
|
|
|
|
|
|
} |
|
589
|
16
|
|
|
|
|
89
|
@o = grep(defined, @o); |
|
590
|
16
|
100
|
|
|
|
123
|
push(@o, closeangle($self->unsetcontext(@designators))) |
|
591
|
|
|
|
|
|
|
if @o; |
|
592
|
16
|
50
|
|
|
|
104
|
return join('', returns(@o)) unless wantarray; |
|
593
|
0
|
|
|
|
|
0
|
return returns(@o); |
|
594
|
|
|
|
|
|
|
} |
|
595
|
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
sub looks_like_a_block |
|
597
|
|
|
|
|
|
|
{ |
|
598
|
6
|
|
|
6
|
0
|
36
|
my ($first, @l) = @_; |
|
599
|
6
|
|
|
|
|
16
|
my $last = pop(@l); |
|
600
|
6
|
100
|
|
|
|
45
|
return 1 if ! defined $last; |
|
601
|
5
|
50
|
|
|
|
31
|
return 0 if grep(/^\S/, @l); |
|
602
|
5
|
50
|
|
|
|
47
|
return 0 if $first =~ /^\s/; |
|
603
|
0
|
0
|
|
|
|
0
|
return 0 if $last =~ /^\s/; |
|
604
|
0
|
|
|
|
|
0
|
return 1; |
|
605
|
|
|
|
|
|
|
} |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
sub iinvert |
|
608
|
|
|
|
|
|
|
{ |
|
609
|
10
|
|
|
10
|
0
|
46
|
my ($indent,@l) = @_; |
|
610
|
10
|
50
|
|
|
|
46
|
confess unless @l; |
|
611
|
10
|
|
|
|
|
44
|
for $_ (@l) { |
|
612
|
10
|
100
|
|
|
|
42
|
next unless defined; |
|
613
|
9
|
50
|
|
|
|
128
|
s/^\s*no /$indent/ or s/^\s*(\S)/${indent}no $1/ |
|
614
|
|
|
|
|
|
|
} |
|
615
|
10
|
50
|
|
|
|
47
|
return $l[0] unless wantarray; |
|
616
|
10
|
|
|
|
|
50
|
return @l; |
|
617
|
|
|
|
|
|
|
} |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub all |
|
620
|
|
|
|
|
|
|
{ |
|
621
|
9
|
|
|
9
|
1
|
44
|
my ($self, $regex) = @_; |
|
622
|
9
|
|
|
|
|
45
|
$self = $self->zoom; |
|
623
|
9
|
100
|
66
|
|
|
176
|
return (map { $self->{$_} } $self->sortit(grep(/$regex/ && ! /$spec/o, keys %$self))) |
|
|
11
|
|
|
|
|
40
|
|
|
624
|
|
|
|
|
|
|
if $regex; |
|
625
|
6
|
|
|
|
|
63
|
return (map { $self->{$_} } $self->sortit(grep(! /$spec/o, keys %$self))); |
|
|
72
|
|
|
|
|
198
|
|
|
626
|
|
|
|
|
|
|
} |
|
627
|
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
sub get |
|
629
|
|
|
|
|
|
|
{ |
|
630
|
153
|
|
|
153
|
1
|
24999
|
my ($self, @designators) = @_; |
|
631
|
153
|
100
|
100
|
|
|
686
|
return $self->mget(@designators) |
|
632
|
|
|
|
|
|
|
if wantarray && @designators > 1; |
|
633
|
|
|
|
|
|
|
|
|
634
|
152
|
50
|
|
|
|
462
|
print STDERR "\nGET <@designators> $self->{$debg}" if $debug_get; |
|
635
|
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
|
|
637
|
152
|
50
|
|
|
|
466
|
return $self unless $self; |
|
638
|
152
|
|
|
|
|
513
|
my $zoom = $self->zoom->subs; |
|
639
|
152
|
100
|
|
|
|
441
|
$self = $zoom if $zoom; |
|
640
|
|
|
|
|
|
|
|
|
641
|
152
|
50
|
|
|
|
1061
|
print STDERR "\nZOOMSUB $self->{$debg}" if $debug_get; |
|
642
|
|
|
|
|
|
|
|
|
643
|
152
|
|
|
|
|
533
|
while (@designators) { |
|
644
|
175
|
|
|
|
|
490
|
my $designator = shift(@designators); |
|
645
|
|
|
|
|
|
|
# $self = $self->zoom; |
|
646
|
|
|
|
|
|
|
# $self = $self->single || $self; |
|
647
|
175
|
50
|
|
|
|
562
|
print STDERR "\nDESIGNATOR: $designator. ZOOMED: $self->{$debg}\n" |
|
648
|
|
|
|
|
|
|
if $debug_get; |
|
649
|
175
|
|
|
|
|
780
|
for my $d (split(' ',$designator)) { |
|
650
|
272
|
50
|
|
|
|
757
|
print STDERR "\nDO WE HAVE A: $d?\n" if $debug_get; |
|
651
|
272
|
100
|
|
|
|
908
|
return $undef unless $self->{$d}; |
|
652
|
258
|
|
|
|
|
604
|
$self = $self->{$d}; |
|
653
|
258
|
50
|
|
|
|
810
|
print STDERR "\nWE DO: $self->{$debg}\n" if $debug_get; |
|
654
|
|
|
|
|
|
|
} |
|
655
|
161
|
100
|
|
|
|
686
|
last unless @designators; |
|
656
|
23
|
50
|
|
|
|
158
|
if ($self->single) { |
|
657
|
23
|
|
|
|
|
99
|
$self = $self->subs; |
|
658
|
23
|
50
|
|
|
|
126
|
print STDERR "\nSINGLETON: $self->{$debg}\n" if $debug_get; |
|
659
|
|
|
|
|
|
|
} else { |
|
660
|
0
|
0
|
|
|
|
0
|
print STDERR "\nNOT SINGLE\n" if $debug_get; |
|
661
|
0
|
|
|
|
|
0
|
return $undef; |
|
662
|
|
|
|
|
|
|
} |
|
663
|
|
|
|
|
|
|
} |
|
664
|
138
|
50
|
|
|
|
476
|
print STDERR "\nDONE\n" if $debug_get; |
|
665
|
138
|
100
|
|
|
|
458
|
if (wantarray) { |
|
666
|
15
|
|
|
|
|
45
|
$self = $self->zoom; |
|
667
|
15
|
|
|
|
|
52
|
my (@k) = $self->kids; |
|
668
|
15
|
50
|
|
|
|
82
|
return @k if @k; |
|
669
|
0
|
|
|
|
|
0
|
return $self; |
|
670
|
|
|
|
|
|
|
} |
|
671
|
123
|
|
|
|
|
698
|
return $self; |
|
672
|
|
|
|
|
|
|
} |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
sub strim |
|
675
|
|
|
|
|
|
|
{ |
|
676
|
26
|
|
|
26
|
0
|
70
|
my (@l) = @_; |
|
677
|
26
|
|
|
|
|
64
|
for $_ (@l) { |
|
678
|
47
|
|
|
|
|
170
|
s/^\s+//; |
|
679
|
47
|
|
|
|
|
161
|
s/\s+$//; |
|
680
|
47
|
|
|
|
|
99
|
s/\n$//; |
|
681
|
|
|
|
|
|
|
} |
|
682
|
26
|
100
|
|
|
|
122
|
return $l[0] unless wantarray; |
|
683
|
3
|
|
|
|
|
42
|
return @l; |
|
684
|
|
|
|
|
|
|
} |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
sub trim |
|
687
|
|
|
|
|
|
|
{ |
|
688
|
36
|
|
|
36
|
0
|
117
|
my (@l) = @_; |
|
689
|
36
|
|
|
|
|
104
|
for $_ (@l) { |
|
690
|
36
|
|
|
|
|
144
|
s/^\s+//; |
|
691
|
36
|
|
|
|
|
253
|
s/\s+$//; |
|
692
|
|
|
|
|
|
|
} |
|
693
|
36
|
50
|
|
|
|
121
|
return $l[0] unless wantarray; |
|
694
|
36
|
|
|
|
|
236
|
return @l; |
|
695
|
|
|
|
|
|
|
} |
|
696
|
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
sub display |
|
698
|
|
|
|
|
|
|
{ |
|
699
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
|
700
|
0
|
|
|
|
|
0
|
my @o; |
|
701
|
0
|
|
|
|
|
0
|
push(@o, $self->setcontext); |
|
702
|
|
|
|
|
|
|
push(@o, trim($self->single->{$text})) |
|
703
|
0
|
0
|
0
|
|
|
0
|
if $self->single && $self->single->{$text} |
|
|
|
|
0
|
|
|
|
|
|
704
|
|
|
|
|
|
|
&& $self->subs->undefined; |
|
705
|
0
|
0
|
|
|
|
0
|
push(@o, "! the whole enchalada") |
|
706
|
|
|
|
|
|
|
if $self->context->undefined; |
|
707
|
0
|
|
|
|
|
0
|
my (@r) = returns(openangle(@o)); |
|
708
|
0
|
0
|
|
|
|
0
|
return @r if wantarray; |
|
709
|
0
|
|
|
|
|
0
|
return join('', @r); |
|
710
|
|
|
|
|
|
|
} |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
sub callerlevels |
|
713
|
|
|
|
|
|
|
{ |
|
714
|
15
|
|
|
15
|
0
|
33
|
my $n = 1; |
|
715
|
15
|
|
|
|
|
97
|
1 while caller($n++); |
|
716
|
15
|
|
|
|
|
33
|
return $n; |
|
717
|
|
|
|
|
|
|
} |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
sub mget |
|
720
|
|
|
|
|
|
|
{ |
|
721
|
15
|
|
|
15
|
0
|
48
|
my ($self, @designators) = @_; |
|
722
|
|
|
|
|
|
|
|
|
723
|
15
|
|
|
|
|
44
|
my $cl = callerlevels; |
|
724
|
15
|
|
|
|
|
30
|
my @newset; |
|
725
|
15
|
100
|
|
|
|
40
|
if (@designators > 1) { |
|
726
|
|
|
|
|
|
|
|
|
727
|
1
|
50
|
|
|
|
4
|
print STDERR "\nGET$cl $designators[0]----------\n" if $debug_mget; |
|
728
|
|
|
|
|
|
|
|
|
729
|
1
|
|
|
|
|
9
|
my (@set) = $self->get(shift @designators); |
|
730
|
1
|
|
|
|
|
5
|
for my $item (@set) { |
|
731
|
|
|
|
|
|
|
|
|
732
|
14
|
50
|
|
|
|
41
|
print STDERR "\nMGET$cl $item ----------\n" if $debug_mget; |
|
733
|
14
|
50
|
|
|
|
39
|
print STDERR "\nMGET$cl $item->{$debg}\n" if $debug_mget; |
|
734
|
|
|
|
|
|
|
|
|
735
|
14
|
|
|
|
|
44
|
my (@got) = $item->mget(@designators); |
|
736
|
|
|
|
|
|
|
|
|
737
|
14
|
50
|
|
|
|
39
|
print STDERR map { "\nRESULTS$cl: $_->{$debg}\n" } @got |
|
|
0
|
|
|
|
|
0
|
|
|
738
|
|
|
|
|
|
|
if $debug_mget; |
|
739
|
|
|
|
|
|
|
|
|
740
|
14
|
|
|
|
|
43
|
push(@newset, @got); |
|
741
|
|
|
|
|
|
|
} |
|
742
|
|
|
|
|
|
|
} else { |
|
743
|
|
|
|
|
|
|
|
|
744
|
14
|
50
|
|
|
|
34
|
print STDERR "\nxGET$cl $designators[0] -------\n" if $debug_mget; |
|
745
|
|
|
|
|
|
|
|
|
746
|
14
|
|
|
|
|
43
|
(@newset) = $self->get(shift @designators); |
|
747
|
|
|
|
|
|
|
|
|
748
|
14
|
50
|
|
|
|
48
|
print STDERR map { "\nxRESULTS$cl: $_->{$debg}\n" } @newset |
|
|
0
|
|
|
|
|
0
|
|
|
749
|
|
|
|
|
|
|
if $debug_mget; |
|
750
|
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
} |
|
752
|
15
|
|
|
|
|
52
|
return @newset; |
|
753
|
|
|
|
|
|
|
} |
|
754
|
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
sub sortit |
|
756
|
|
|
|
|
|
|
{ |
|
757
|
826
|
|
|
826
|
0
|
1871
|
my $self = shift; |
|
758
|
826
|
|
|
|
|
3297
|
return sort { $self->{$a}->seqn cmp $self->{$b}->seqn } @_; |
|
|
6634
|
|
|
|
|
21050
|
|
|
759
|
|
|
|
|
|
|
} |
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
1; |
|
762
|
|
|
|
|
|
|
|