line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package Zoidberg::Utils::Output; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
our $VERSION = '0.981'; |
5
|
|
|
|
|
|
|
|
6
|
22
|
|
|
22
|
|
138
|
use strict; |
|
22
|
|
|
|
|
47
|
|
|
22
|
|
|
|
|
887
|
|
7
|
22
|
|
|
22
|
|
3364
|
use Data::Dumper; |
|
22
|
|
|
|
|
23281
|
|
|
22
|
|
|
|
|
1660
|
|
8
|
22
|
|
|
22
|
|
3161
|
use POSIX qw/floor ceil/; |
|
22
|
|
|
|
|
25741
|
|
|
22
|
|
|
|
|
233
|
|
9
|
|
|
|
|
|
|
use Exporter::Tidy |
10
|
22
|
|
|
|
|
245
|
default => [qw/output message debug complain/], |
11
|
22
|
|
|
22
|
|
5702
|
other => [qw/typed_output output_is_captured/]; |
|
22
|
|
|
|
|
31
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our %colours = ( # Copied from Term::ANSIScreen |
14
|
|
|
|
|
|
|
'clear' => 0, 'reset' => 0, |
15
|
|
|
|
|
|
|
'bold' => 1, 'dark' => 2, |
16
|
|
|
|
|
|
|
'underline' => 4, 'underscore' => 4, |
17
|
|
|
|
|
|
|
'blink' => 5, 'reverse' => 7, |
18
|
|
|
|
|
|
|
'concealed' => 8, |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
'black' => 30, 'on_black' => 40, |
21
|
|
|
|
|
|
|
'red' => 31, 'on_red' => 41, |
22
|
|
|
|
|
|
|
'green' => 32, 'on_green' => 42, |
23
|
|
|
|
|
|
|
'yellow' => 33, 'on_yellow' => 43, |
24
|
|
|
|
|
|
|
'blue' => 34, 'on_blue' => 44, |
25
|
|
|
|
|
|
|
'magenta' => 35, 'on_magenta' => 45, |
26
|
|
|
|
|
|
|
'cyan' => 36, 'on_cyan' => 46, |
27
|
|
|
|
|
|
|
'white' => 37, 'on_white' => 47, |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub output_is_captured { |
31
|
0
|
0
|
|
0
|
1
|
0
|
return $Zoidberg::CURRENT->{_builtin_output} ? 1 : 0; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub output { |
35
|
0
|
0
|
|
0
|
1
|
0
|
if ($Zoidberg::CURRENT->{_builtin_output}) { # capturing output from builtin |
36
|
0
|
|
|
|
|
0
|
push @{ $Zoidberg::CURRENT->{_builtin_output} }, @_; |
|
0
|
|
|
|
|
0
|
|
37
|
0
|
|
|
|
|
0
|
return 1; |
38
|
|
|
|
|
|
|
} |
39
|
0
|
|
|
|
|
0
|
else { typed_output('output', @_) } |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub message { |
43
|
0
|
0
|
|
0
|
1
|
0
|
return 1 if ! $Zoidberg::CURRENT->{settings}{interactive}; |
44
|
0
|
|
|
|
|
0
|
typed_output('message', @_); |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub debug { |
48
|
7985
|
|
|
7985
|
1
|
27478
|
my $class = caller; |
49
|
22
|
|
|
22
|
|
7447
|
no strict 'refs'; |
|
22
|
|
|
|
|
29
|
|
|
22
|
|
|
|
|
1395781
|
|
50
|
|
|
|
|
|
|
#local $Data::Dumper::Maxdepth = 2; |
51
|
7985
|
50
|
33
|
|
|
63469
|
return 1 unless $Zoidberg::CURRENT->{settings}{debug} || ${$class.'::DEBUG'}; |
|
7985
|
|
|
|
|
69796
|
|
52
|
0
|
|
|
|
|
0
|
my $fh = select STDERR; |
53
|
0
|
|
|
|
|
0
|
my @caller = caller; |
54
|
0
|
|
|
|
|
0
|
typed_output('debug', "$caller[0]: $caller[2]: ", @_); |
55
|
0
|
|
|
|
|
0
|
select $fh; |
56
|
0
|
|
|
|
|
0
|
1; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub complain { # strip @INC: for little less verbose output |
60
|
10
|
50
|
33
|
10
|
1
|
118
|
return 0 unless @_ || $@; |
61
|
10
|
50
|
|
|
|
46
|
my @error = @_ ? (@_) : ($@); |
62
|
10
|
|
|
|
|
112
|
my $fh = select STDERR; |
63
|
10
|
|
|
|
|
26
|
typed_output('error', map {s/\(\@INC contains\: (.*?)\)\s*//g; $_} @error); |
|
10
|
|
|
|
|
36
|
|
|
10
|
|
|
|
|
52
|
|
64
|
10
|
|
|
|
|
80
|
select $fh; |
65
|
10
|
|
|
|
|
68
|
1; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub typed_output { |
69
|
10
|
|
|
10
|
1
|
44
|
my $type = shift; |
70
|
10
|
|
|
|
|
30
|
my @dinge = @_; |
71
|
10
|
50
|
|
|
|
32
|
return unless @dinge > 0; |
72
|
|
|
|
|
|
|
|
73
|
10
|
|
33
|
|
|
64
|
$type = $Zoidberg::CURRENT->{settings}{output}{$type} || $type; |
74
|
10
|
50
|
|
|
|
48
|
return 1 if $type eq 'mute'; |
75
|
|
|
|
|
|
|
|
76
|
10
|
|
|
|
|
10
|
my $coloured; |
77
|
10
|
50
|
0
|
|
|
118
|
print "\e[$colours{$type}m" and $coloured = 1 |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
78
|
|
|
|
|
|
|
if exists $colours{$type} |
79
|
|
|
|
|
|
|
and $Zoidberg::CURRENT->{settings}{interactive} and $ENV{CLICOLOR}; |
80
|
|
|
|
|
|
|
|
81
|
10
|
50
|
|
|
|
42
|
$dinge[-1] .= "\n" unless ref $dinge[-1]; |
82
|
10
|
|
|
|
|
20
|
for (@dinge) { |
83
|
10
|
50
|
|
|
|
48
|
$_ = $_->scalar() if ref($_) eq 'Zoidberg::Utils::Output::Scalar'; |
84
|
10
|
50
|
33
|
|
|
92
|
unless (ref $_) { print $_ } |
|
0
|
50
|
|
|
|
0
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
|
85
|
0
|
|
|
|
|
0
|
elsif (ref($_) eq 'ARRAY' and ! grep { ref($_) } @$_) { output_list(@$_) } |
86
|
|
|
|
|
|
|
elsif (ref($_) eq 'Zoidberg::Utils::Error') { |
87
|
10
|
50
|
|
|
|
36
|
if ($$_{debug}) { print map {s/^\$VAR1 = //; $_} Dumper $_ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
88
|
|
|
|
|
|
|
else { |
89
|
10
|
50
|
33
|
|
|
68
|
next if $$_{silent} || $$_{printed}++; |
90
|
0
|
|
|
|
|
0
|
print $_->stringify(format => 'gnu'); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
elsif (ref($_) =~ /Zoidberg/) { |
94
|
0
|
|
|
|
|
0
|
complain 'Cowardly refusing to dump object of class '.ref($_); |
95
|
|
|
|
|
|
|
} |
96
|
0
|
|
|
|
|
0
|
else { print map {s/^\$VAR1 = //; $_} Dumper $_ } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
10
|
50
|
|
|
|
36
|
print "\e[$colours{reset}m" if $coloured; |
100
|
|
|
|
|
|
|
|
101
|
10
|
|
|
|
|
16
|
1; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub output_list { # takes minimum number of rows, but fills cols first |
105
|
0
|
|
|
0
|
0
|
0
|
my (@items) = @_; |
106
|
0
|
|
|
|
|
0
|
my $width = $ENV{COLUMNS}; |
107
|
|
|
|
|
|
|
|
108
|
0
|
0
|
|
|
|
0
|
return print join("\n", @items), "\n" unless $Zoidberg::CURRENT->{settings}{interactive}; |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
0
|
my $len = 0; |
111
|
0
|
|
0
|
|
|
0
|
$_ > $len and $len = $_ for map {s/\t/ /g; length $_} @items; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
112
|
0
|
|
|
|
|
0
|
$len += 2; # spacing |
113
|
0
|
0
|
|
|
|
0
|
return print join("\n", @items), "\n" if $width < (2 * $len); # rows == items |
114
|
0
|
0
|
|
|
|
0
|
return print join(' ', @items), "\n" if $width > (@items * $len); # 1 row |
115
|
|
|
|
|
|
|
|
116
|
0
|
|
|
|
|
0
|
my $cols = int($width / $len ) - 1; # 0 based |
117
|
0
|
|
|
|
|
0
|
my $rows = int(@items / ($cols+1)); # 0 based ceil |
118
|
0
|
0
|
|
|
|
0
|
$rows -= 1 unless @items % ($cols+1); # tune ceil |
119
|
0
|
|
|
|
|
0
|
my @rows; |
120
|
0
|
|
|
|
|
0
|
for my $r (0 .. $rows) { |
121
|
0
|
|
|
|
|
0
|
my @row = map { $items[ ($_ * ($rows+1)) + $r] } 0 .. $cols; |
|
0
|
|
|
|
|
0
|
|
122
|
0
|
|
|
|
|
0
|
push @rows, join '', map { $_ .= ' 'x($len - length $_) } @row; |
|
0
|
|
|
|
|
0
|
|
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
#print STDERR scalar(@items)." items, $len long, $width width, $cols+1 cols, $rows+1 rows\n"; |
125
|
0
|
|
|
|
|
0
|
print join("\n", @rows), "\n"; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub output_sql { # kan vast schoner |
129
|
0
|
0
|
|
0
|
0
|
0
|
shift unless ref($_[0]) eq 'ARRAY'; |
130
|
0
|
|
|
|
|
0
|
my $width = $ENV{COLUMNS}; |
131
|
0
|
0
|
0
|
|
|
0
|
if (! $Zoidberg::CURRENT->{settings}{interactive} || !defined $width) { |
132
|
0
|
|
|
|
|
0
|
return (print join("\n", map {join(', ', @{$_})} @_)."\n"); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
133
|
|
|
|
|
|
|
} |
134
|
0
|
|
|
|
|
0
|
my @records = @_; |
135
|
0
|
|
|
|
|
0
|
my @longest = (); |
136
|
0
|
|
|
|
|
0
|
@records = map {[map {s/\'/\\\'/g; "'".$_."'"} @{$_}]} @records; # escape quotes + safety quotes |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
137
|
0
|
|
|
|
|
0
|
foreach my $i (0..$#{$records[0]}) { |
|
0
|
|
|
|
|
0
|
|
138
|
0
|
0
|
|
|
|
0
|
map {if (length($_) > $longest[$i]) {$longest[$i] = length($_);} } map {$_->[$i]} @records; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
#print "debug: records: ".Dumper(\@records)." longest: ".Dumper(\@longest); |
141
|
0
|
|
|
|
|
0
|
my $record_length = 0; # '[' + ']' - ', ' |
142
|
0
|
|
|
|
|
0
|
for (@longest) { $record_length += $_ + 2; } # length (', ') = 2 |
|
0
|
|
|
|
|
0
|
|
143
|
0
|
0
|
|
|
|
0
|
if ($record_length <= $width) { # it fits ! => horizontal lay-out |
144
|
0
|
|
|
|
|
0
|
my $cols = floor($width / ($record_length+2)); # we want two spaces to saperate coloms |
145
|
0
|
|
|
|
|
0
|
my @strings = (); |
146
|
0
|
|
|
|
|
0
|
for (@records) { |
147
|
0
|
|
|
|
|
0
|
my @record = @{$_}; |
|
0
|
|
|
|
|
0
|
|
148
|
0
|
|
|
|
|
0
|
for (0..$#record-1) { $record[$_] .= ', '.(' 'x($longest[$_] - length($record[$_]))); } |
|
0
|
|
|
|
|
0
|
|
149
|
0
|
|
|
|
|
0
|
$record[$#record] .= (' 'x($longest[$#record] - length($record[$#record]))); |
150
|
0
|
0
|
|
|
|
0
|
if ($cols > 1) { push @strings, "[".join('', @record)."]"; } |
|
0
|
|
|
|
|
0
|
|
151
|
0
|
|
|
|
|
0
|
else { print "[".join('', @record)."]\n"; } |
152
|
|
|
|
|
|
|
} |
153
|
0
|
0
|
|
|
|
0
|
if ($cols > 1) { |
154
|
0
|
|
|
|
|
0
|
my $rows = ceil(($#strings+1) / $cols); |
155
|
0
|
|
|
|
|
0
|
foreach my $i (0..$rows-1) { |
156
|
0
|
|
|
|
|
0
|
for (0..$cols) { print $strings[$_*$rows+$i]." "; } |
|
0
|
|
|
|
|
0
|
|
157
|
0
|
|
|
|
|
0
|
print "\n"; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
0
|
|
|
|
|
0
|
else { for (@records) { print "[\n ".join(",\n ", @{$_})."\n]\n"; } } # vertical lay-out |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
162
|
0
|
|
|
|
|
0
|
return 1; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
package Zoidberg::Utils::Output::Scalar; |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
our $VERSION = '0.981'; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
use overload |
170
|
22
|
|
|
|
|
438
|
'""' => \&scalar, |
171
|
|
|
|
|
|
|
'bool' => \&error, |
172
|
|
|
|
|
|
|
'@{}' => \&array, |
173
|
22
|
|
|
22
|
|
209
|
fallback => 'TRUE'; |
|
22
|
|
|
|
|
68
|
|
174
|
|
|
|
|
|
|
|
175
|
168
|
|
|
168
|
|
5887
|
sub new { bless \[@_[1,2,3]], $_[0] } |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
0
|
|
0
|
sub error { my $s = ${ shift() }; $$s[0] } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub scalar { |
180
|
6
|
|
|
6
|
|
415
|
my $s = ${ shift() }; |
|
6
|
|
|
|
|
75
|
|
181
|
6
|
50
|
33
|
|
|
108
|
$$s[1] = join "\n", @{$$s[2]} if ! defined $$s[1] and $$s[2]; |
|
0
|
|
|
|
|
0
|
|
182
|
6
|
|
|
|
|
628
|
return $$s[1]; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub array { |
186
|
0
|
|
|
0
|
|
|
my $s = ${ shift() }; |
|
0
|
|
|
|
|
|
|
187
|
0
|
0
|
|
|
|
|
if (! defined $$s[2]) { |
188
|
0
|
0
|
|
|
|
|
$$s[2] = (ref($$s[1]) eq 'ARRAY') ? $$s[1] : |
|
|
0
|
|
|
|
|
|
189
|
|
|
|
|
|
|
ref($$s[1]) ? [$$s[1]] : [ split /\n/, $$s[1] ]; |
190
|
|
|
|
|
|
|
} |
191
|
0
|
|
|
|
|
|
return $$s[2]; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
1; |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
__END__ |