line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
RSH::Logging::TextTable - Extension of Text::SimpleTable to handle chunking. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use RSH::Logging::TextTable; |
8
|
|
|
|
|
|
|
my $table = RSH::Logging::TextTable->new(); |
9
|
|
|
|
|
|
|
... |
10
|
|
|
|
|
|
|
my $str = $table->draw(); # use original logic |
11
|
|
|
|
|
|
|
$table->draw($fh); # write to the filehandle |
12
|
|
|
|
|
|
|
my $code = sub { |
13
|
|
|
|
|
|
|
$logger->debug(@_); |
14
|
|
|
|
|
|
|
} |
15
|
|
|
|
|
|
|
$table->draw($code); # send lines/chunks to $code->($line); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 DESCRIPTION |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
When sending the timing table to Log4Perl, if the table is too large, |
20
|
|
|
|
|
|
|
Log4Perl will generate an OOM error. Chunking solves this. |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=cut |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
package RSH::Logging::TextTable; |
25
|
|
|
|
|
|
|
|
26
|
4
|
|
|
4
|
|
121
|
use 5.008; |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
162
|
|
27
|
4
|
|
|
4
|
|
23
|
use strict; |
|
4
|
|
|
|
|
14
|
|
|
4
|
|
|
|
|
147
|
|
28
|
4
|
|
|
4
|
|
20
|
use warnings; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
147
|
|
29
|
|
|
|
|
|
|
|
30
|
4
|
|
|
4
|
|
23
|
use base qw(Exporter Text::SimpleTable); |
|
4
|
|
|
|
|
14
|
|
|
4
|
|
|
|
|
5540
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# use/imports go here |
33
|
4
|
|
|
4
|
|
23284
|
use Text::SimpleTable; |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
114
|
|
34
|
4
|
|
|
4
|
|
28
|
use Scalar::Util qw(blessed); |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
5553
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
37
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
38
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head2 EXPORT |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
None by default. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=cut |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
our @EXPORT = qw( |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# ******************** Class Methods ******************** |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# ******************** Constructor Methods ******************** |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=head2 CONSTRUCTORS |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=over |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=cut |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=item new(%ARGS) |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Creates a new RSH::Logging::TextTable object. C<%ARGS> contains |
67
|
|
|
|
|
|
|
arguments to use in initializing the new instance. |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
B<Returns:> A new RSH::Logging::TextTable object. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=cut |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub new { |
74
|
16
|
|
|
16
|
1
|
43
|
my($class, @args) = @_; |
75
|
|
|
|
|
|
|
|
76
|
16
|
|
|
|
|
112
|
my $self = Text::SimpleTable->new(@args); |
77
|
|
|
|
|
|
|
|
78
|
16
|
|
|
|
|
1503
|
bless $self, $class; |
79
|
|
|
|
|
|
|
|
80
|
16
|
|
|
|
|
1297
|
return $self; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=back |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=cut |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# ******************** PUBLIC Instance Methods ******************** |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head2 INSTANCE METHODS |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=over |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=cut |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
## ******************** Accessors ******************** |
96
|
|
|
|
|
|
|
# |
97
|
|
|
|
|
|
|
#=back |
98
|
|
|
|
|
|
|
# |
99
|
|
|
|
|
|
|
#=head3 Accessors |
100
|
|
|
|
|
|
|
# |
101
|
|
|
|
|
|
|
#=over |
102
|
|
|
|
|
|
|
# |
103
|
|
|
|
|
|
|
#=cut |
104
|
|
|
|
|
|
|
# |
105
|
|
|
|
|
|
|
## place field accessors here |
106
|
|
|
|
|
|
|
# |
107
|
|
|
|
|
|
|
# |
108
|
|
|
|
|
|
|
#=back |
109
|
|
|
|
|
|
|
# |
110
|
|
|
|
|
|
|
#=cut |
111
|
|
|
|
|
|
|
# |
112
|
|
|
|
|
|
|
# ******************** Functionality ******************** |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=back |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head3 Functionality |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=over |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=cut |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=item draw([$io_handle | $code_ref ]) |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Override Text::SimpleTable::draw, allowing optional chunking. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
I'm not tremendously wild about copy and pasting the original. I should probably send |
127
|
|
|
|
|
|
|
this method as a patch to Text::SimpleTable. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=cut |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub draw { |
132
|
16
|
|
|
16
|
1
|
31
|
my $self = shift; |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# if there are no parameters or they aren't what we expect, just do the original logic |
135
|
16
|
|
|
|
|
33
|
my ($target) = @_; |
136
|
16
|
50
|
33
|
|
|
65
|
unless ($target and ( (ref($target) eq 'CODE') or (blessed($target) and $target->isa('IO::Handle')) ) ) { |
|
|
|
66
|
|
|
|
|
137
|
12
|
|
|
|
|
74
|
return $self->SUPER::draw(@_); |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Otherwise, support chunking |
141
|
|
|
|
|
|
|
# (below is copy and pasted from Text::SimpleTable, modified to chunk) |
142
|
|
|
|
|
|
|
# Shortcut |
143
|
4
|
50
|
|
|
|
13
|
return unless $self->{columns}; |
144
|
|
|
|
|
|
|
|
145
|
4
|
|
|
|
|
8
|
my $out; |
146
|
4
|
50
|
|
|
|
14
|
if (ref($target) eq 'CODE') { |
147
|
|
|
|
|
|
|
$out = sub { |
148
|
57
|
|
|
57
|
|
144
|
$target->(@_); |
149
|
4
|
|
|
|
|
33
|
}; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
else { |
152
|
|
|
|
|
|
|
$out = sub { |
153
|
0
|
|
|
0
|
|
0
|
print $target @_; |
154
|
0
|
|
|
|
|
0
|
}; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
4
|
|
|
|
|
7
|
my $rows = @{$self->{columns}->[0]->[1]} - 1; |
|
4
|
|
|
|
|
11
|
|
158
|
4
|
|
|
|
|
7
|
my $columns = @{$self->{columns}} - 1; |
|
4
|
|
|
|
|
8
|
|
159
|
4
|
|
|
|
|
8
|
my $output = ''; |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# Top border |
162
|
4
|
|
|
|
|
10
|
for my $j (0 .. $columns) { |
163
|
|
|
|
|
|
|
|
164
|
8
|
|
|
|
|
17
|
my $column = $self->{columns}->[$j]; |
165
|
8
|
|
|
|
|
13
|
my $width = $column->[0]; |
166
|
8
|
|
|
|
|
16
|
my $text = $Text::SimpleTable::TOP_BORDER x $width; |
167
|
|
|
|
|
|
|
|
168
|
8
|
50
|
66
|
|
|
41
|
if (($j == 0) && ($columns == 0)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
169
|
0
|
|
|
|
|
0
|
$text = $Text::SimpleTable::TOP_LEFT . $text . $Text::SimpleTable::TOP_RIGHT; |
170
|
|
|
|
|
|
|
} |
171
|
4
|
|
|
|
|
13
|
elsif ($j == 0) { $text = $Text::SimpleTable::TOP_LEFT . $text . $Text::SimpleTable::TOP_SEPARATOR } |
172
|
4
|
|
|
|
|
78
|
elsif ($j == $columns) { $text = $text . $Text::SimpleTable::TOP_RIGHT } |
173
|
0
|
|
|
|
|
0
|
else { $text = $text . $Text::SimpleTable::TOP_SEPARATOR } |
174
|
|
|
|
|
|
|
|
175
|
8
|
|
|
|
|
23
|
$output .= $text; |
176
|
|
|
|
|
|
|
} |
177
|
4
|
|
|
|
|
9
|
$output .= "\n"; |
178
|
4
|
|
|
|
|
13
|
$out->($output); $output = ''; |
|
4
|
|
|
|
|
593
|
|
179
|
|
|
|
|
|
|
|
180
|
4
|
|
|
|
|
9
|
my $title = 0; |
181
|
4
|
|
|
|
|
8
|
for my $column (@{$self->{columns}}) { |
|
4
|
|
|
|
|
15
|
|
182
|
8
|
100
|
|
|
|
8
|
$title = @{$column->[2]} if $title < @{$column->[2]}; |
|
4
|
|
|
|
|
9
|
|
|
8
|
|
|
|
|
27
|
|
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
4
|
50
|
|
|
|
13
|
if ($title) { |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Titles |
188
|
4
|
|
|
|
|
12
|
for my $i (0 .. $title - 1) { |
189
|
|
|
|
|
|
|
|
190
|
4
|
|
|
|
|
9
|
for my $j (0 .. $columns) { |
191
|
|
|
|
|
|
|
|
192
|
8
|
|
|
|
|
14
|
my $column = $self->{columns}->[$j]; |
193
|
8
|
|
|
|
|
12
|
my $width = $column->[0]; |
194
|
8
|
|
50
|
|
|
22
|
my $text = $column->[2]->[$i] || ''; |
195
|
|
|
|
|
|
|
|
196
|
8
|
|
|
|
|
25
|
$text = sprintf "%-${width}s", $text; |
197
|
|
|
|
|
|
|
|
198
|
8
|
50
|
66
|
|
|
41
|
if (($j == 0) && ($columns == 0)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
199
|
0
|
|
|
|
|
0
|
$text = $Text::SimpleTable::LEFT_BORDER . $text . $Text::SimpleTable::RIGHT_BORDER; |
200
|
|
|
|
|
|
|
} |
201
|
4
|
|
|
|
|
12
|
elsif ($j == 0) { $text = $Text::SimpleTable::LEFT_BORDER . $text . $Text::SimpleTable::SEPARATOR } |
202
|
4
|
|
|
|
|
7
|
elsif ($j == $columns) { $text = $text . $Text::SimpleTable::RIGHT_BORDER } |
203
|
0
|
|
|
|
|
0
|
else { $text = $text . $Text::SimpleTable::SEPARATOR } |
204
|
|
|
|
|
|
|
|
205
|
8
|
|
|
|
|
25
|
$output .= $text; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
4
|
|
|
|
|
8
|
$output .= "\n"; |
209
|
4
|
|
|
|
|
9
|
$out->($output); $output = ''; |
|
4
|
|
|
|
|
558
|
|
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# Title separator |
213
|
4
|
|
|
|
|
23
|
$output .= $self->_draw_hr; |
214
|
4
|
|
|
|
|
127
|
$out->($output); $output = ''; |
|
4
|
|
|
|
|
545
|
|
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# Rows |
219
|
4
|
|
|
|
|
10
|
for my $i (0 .. $rows) { |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# Check for hr |
222
|
41
|
50
|
|
|
|
84
|
if (!grep { defined $self->{columns}->[$_]->[1]->[$i] } 0 .. $columns) |
|
82
|
|
|
|
|
372
|
|
223
|
|
|
|
|
|
|
{ |
224
|
0
|
|
|
|
|
0
|
$output .= $self->_draw_hr; |
225
|
0
|
|
|
|
|
0
|
$out->($output); $output = ''; |
|
0
|
|
|
|
|
0
|
|
226
|
0
|
|
|
|
|
0
|
next; |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
41
|
|
|
|
|
70
|
for my $j (0 .. $columns) { |
230
|
|
|
|
|
|
|
|
231
|
82
|
|
|
|
|
129
|
my $column = $self->{columns}->[$j]; |
232
|
82
|
|
|
|
|
90
|
my $width = $column->[0]; |
233
|
82
|
50
|
|
|
|
165
|
my $text = (defined $column->[1]->[$i]) ? $column->[1]->[$i] : ''; |
234
|
|
|
|
|
|
|
|
235
|
82
|
|
|
|
|
212
|
$text = sprintf "%-${width}s", $text; |
236
|
|
|
|
|
|
|
|
237
|
82
|
50
|
66
|
|
|
309
|
if (($j == 0) && ($columns == 0)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
238
|
0
|
|
|
|
|
0
|
$text = $Text::SimpleTable::LEFT_BORDER . $text . $Text::SimpleTable::RIGHT_BORDER; |
239
|
|
|
|
|
|
|
} |
240
|
41
|
|
|
|
|
75
|
elsif ($j == 0) { $text = $Text::SimpleTable::LEFT_BORDER . $text . $Text::SimpleTable::SEPARATOR } |
241
|
41
|
|
|
|
|
55
|
elsif ($j == $columns) { $text = $text . $Text::SimpleTable::RIGHT_BORDER } |
242
|
0
|
|
|
|
|
0
|
else { $text = $text . $Text::SimpleTable::SEPARATOR } |
243
|
|
|
|
|
|
|
|
244
|
82
|
|
|
|
|
160
|
$output .= $text; |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
41
|
|
|
|
|
62
|
$output .= "\n"; |
248
|
41
|
|
|
|
|
131
|
$out->($output); $output = ''; |
|
41
|
|
|
|
|
9210
|
|
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Bottom border |
252
|
4
|
|
|
|
|
9
|
for my $j (0 .. $columns) { |
253
|
|
|
|
|
|
|
|
254
|
8
|
|
|
|
|
16
|
my $column = $self->{columns}->[$j]; |
255
|
8
|
|
|
|
|
13
|
my $width = $column->[0]; |
256
|
8
|
|
|
|
|
17
|
my $text = $Text::SimpleTable::BOTTOM_BORDER x $width; |
257
|
|
|
|
|
|
|
|
258
|
8
|
50
|
66
|
|
|
41
|
if (($j == 0) && ($columns == 0)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
259
|
0
|
|
|
|
|
0
|
$text = $Text::SimpleTable::BOTTOM_LEFT . $text . $Text::SimpleTable::BOTTOM_RIGHT; |
260
|
|
|
|
|
|
|
} |
261
|
4
|
|
|
|
|
11
|
elsif ($j == 0) { $text = $Text::SimpleTable::BOTTOM_LEFT . $text . $Text::SimpleTable::BOTTOM_SEPARATOR } |
262
|
4
|
|
|
|
|
8
|
elsif ($j == $columns) { $text = $text . $Text::SimpleTable::BOTTOM_RIGHT } |
263
|
0
|
|
|
|
|
0
|
else { $text = $text . $Text::SimpleTable::BOTTOM_SEPARATOR } |
264
|
|
|
|
|
|
|
|
265
|
8
|
|
|
|
|
24
|
$output .= $text; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
4
|
|
|
|
|
7
|
$output .= "\n"; |
269
|
4
|
|
|
|
|
7
|
$out->($output); $output = ''; |
|
4
|
|
|
|
|
585
|
|
270
|
|
|
|
|
|
|
|
271
|
4
|
|
|
|
|
20
|
return $output; |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=back |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=cut |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
# #################### RSH::Logging::TextTable.pm ENDS #################### |
279
|
|
|
|
|
|
|
1; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head1 SEE ALSO |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
L<Other::Module> |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
L<http://website/> |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=head1 AUTHOR |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
Matt Luker, E<lt>mluker@rshtech.comE<gt> |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
Copyright 2012 by Matt Luker |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
296
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=cut |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
__END__ |
301
|
|
|
|
|
|
|
# TTGOG |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
# --------------------------------------------------------------------- |
304
|
|
|
|
|
|
|
# $Log$ |
305
|
|
|
|
|
|
|
# --------------------------------------------------------------------- |