| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Error::Pure::Output::ANSIColor; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 2 |  |  | 2 |  | 15837 | use base qw(Exporter); | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 168 |  | 
| 4 | 2 |  |  | 2 |  | 7 | use strict; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 33 |  | 
| 5 | 2 |  |  | 2 |  | 6 | use warnings; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 38 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 2 |  |  | 2 |  | 897 | use Readonly; | 
|  | 2 |  |  |  |  | 5464 |  | 
|  | 2 |  |  |  |  | 89 |  | 
| 8 | 2 |  |  | 2 |  | 1038 | use Term::ANSIColor; | 
|  | 2 |  |  |  |  | 9740 |  | 
|  | 2 |  |  |  |  | 2446 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | Readonly::Array our @EXPORT_OK => qw(err_bt_pretty err_bt_pretty_rev err_die | 
| 11 |  |  |  |  |  |  | err_line err_line_all err_print err_print_var); | 
| 12 |  |  |  |  |  |  | Readonly::Scalar our $EMPTY_STR => q{}; | 
| 13 |  |  |  |  |  |  | Readonly::Scalar our $SPACE => q{ }; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | our $EPANSI_CLASS_COLOR = 'blue'; | 
| 16 |  |  |  |  |  |  | our $EPANSI_ERROR_COLOR = 'red'; | 
| 17 |  |  |  |  |  |  | our $EPANSI_LINE_COLOR = 'yellow'; | 
| 18 |  |  |  |  |  |  | our $EPANSI_OTHER_COLOR = 'cyan'; | 
| 19 |  |  |  |  |  |  | our $EPANSI_SCRIPT_COLOR = 'yellow'; | 
| 20 |  |  |  |  |  |  | our $EPANSI_SUB_COLOR = 'green'; | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | our $VERSION = 0.03; | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | # Pretty print of backtrace. | 
| 25 |  |  |  |  |  |  | sub err_bt_pretty { | 
| 26 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 27 | 0 |  |  |  |  |  | my @ret; | 
| 28 | 0 |  |  |  |  |  | my $l_ar = _lenghts(@errors); | 
| 29 | 0 |  |  |  |  |  | foreach my $error_hr (@errors) { | 
| 30 | 0 |  |  |  |  |  | push @ret, _bt_pretty_one($error_hr, $l_ar); | 
| 31 |  |  |  |  |  |  | } | 
| 32 | 0 | 0 |  |  |  |  | return wantarray ? @ret : (join "\n", @ret)."\n"; | 
| 33 |  |  |  |  |  |  | } | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | # Reverse pretty print of backtrace. | 
| 36 |  |  |  |  |  |  | sub err_bt_pretty_rev { | 
| 37 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 38 | 0 |  |  |  |  |  | my @ret; | 
| 39 | 0 |  |  |  |  |  | my $l_ar = _lenghts(@errors); | 
| 40 | 0 |  |  |  |  |  | foreach my $error_hr (reverse @errors) { | 
| 41 | 0 |  |  |  |  |  | push @ret, _bt_pretty_one($error_hr, $l_ar); | 
| 42 |  |  |  |  |  |  | } | 
| 43 | 0 | 0 |  |  |  |  | return wantarray ? @ret : (join "\n", @ret)."\n"; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | # Pretty print of classic die. | 
| 47 |  |  |  |  |  |  | sub err_die { | 
| 48 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 49 | 0 |  |  |  |  |  | my $error = join $EMPTY_STR, @{$errors[-1]->{'msg'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 50 | 0 | 0 |  |  |  |  | if ($error eq 'undef') { | 
| 51 | 0 |  |  |  |  |  | $error = 'Died'; | 
| 52 |  |  |  |  |  |  | } | 
| 53 | 0 |  |  |  |  |  | my $stack_ar = $errors[-1]->{'stack'}; | 
| 54 |  |  |  |  |  |  | my $die = color($EPANSI_ERROR_COLOR).$error. | 
| 55 |  |  |  |  |  |  | color($EPANSI_OTHER_COLOR).' at '. | 
| 56 | 0 |  |  |  |  |  | color($EPANSI_SCRIPT_COLOR).$stack_ar->[0]->{'prog'}. | 
| 57 |  |  |  |  |  |  | color($EPANSI_OTHER_COLOR).' line '. | 
| 58 |  |  |  |  |  |  | color($EPANSI_LINE_COLOR)."$stack_ar->[0]->{'line'}.". | 
| 59 |  |  |  |  |  |  | color('reset'); | 
| 60 | 0 |  |  |  |  |  | return $die; | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | # Pretty print line error. | 
| 64 |  |  |  |  |  |  | sub err_line { | 
| 65 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 66 | 0 |  |  |  |  |  | return _err_line($errors[-1]); | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | # Pretty print with errors each on one line. | 
| 70 |  |  |  |  |  |  | sub err_line_all { | 
| 71 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 72 | 0 |  |  |  |  |  | my $ret; | 
| 73 | 0 |  |  |  |  |  | foreach my $error_hr (@errors) { | 
| 74 | 0 |  |  |  |  |  | $ret .= _err_line($error_hr); | 
| 75 |  |  |  |  |  |  | } | 
| 76 | 0 |  |  |  |  |  | return $ret; | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | # Print error. | 
| 80 |  |  |  |  |  |  | sub err_print { | 
| 81 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 82 | 0 |  |  |  |  |  | my $class = _err_class($errors[-1]); | 
| 83 | 0 |  |  |  |  |  | return $class.$errors[-1]->{'msg'}->[0]; | 
| 84 |  |  |  |  |  |  | } | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | # Print error with all variables. | 
| 87 |  |  |  |  |  |  | sub err_print_var { | 
| 88 | 0 |  |  | 0 | 1 |  | my @errors = @_; | 
| 89 | 0 |  |  |  |  |  | my @msg = @{$errors[-1]->{'msg'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 90 | 0 |  |  |  |  |  | my $class = _err_class($errors[-1]); | 
| 91 | 0 |  |  |  |  |  | my @ret = ($class.color($EPANSI_ERROR_COLOR).(shift @msg).color('reset')); | 
| 92 | 0 |  |  |  |  |  | push @ret, _err_variables(@msg); | 
| 93 | 0 | 0 |  |  |  |  | return wantarray ? @ret : (join "\n", @ret)."\n"; | 
| 94 |  |  |  |  |  |  | } | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | # Pretty print one error backtrace helper. | 
| 97 |  |  |  |  |  |  | sub _bt_pretty_one { | 
| 98 | 0 |  |  | 0 |  |  | my ($error_hr, $l_ar) = @_; | 
| 99 | 0 |  |  |  |  |  | my @msg = @{$error_hr->{'msg'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 100 | 0 |  |  |  |  |  | my @ret = (color($EPANSI_OTHER_COLOR).'ERROR: '. | 
| 101 |  |  |  |  |  |  | color($EPANSI_ERROR_COLOR).(shift @msg).color('reset')); | 
| 102 | 0 |  |  |  |  |  | push @ret, _err_variables(@msg); | 
| 103 | 0 |  |  |  |  |  | foreach my $i (0 .. $#{$error_hr->{'stack'}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 104 | 0 |  |  |  |  |  | my $st = $error_hr->{'stack'}->[$i]; | 
| 105 | 0 |  |  |  |  |  | my $ret = color($EPANSI_CLASS_COLOR).$st->{'class'}.color('reset'); | 
| 106 | 0 |  |  |  |  |  | $ret .=  $SPACE x ($l_ar->[0] - length $st->{'class'}); | 
| 107 | 0 |  |  |  |  |  | $ret .=  color($EPANSI_SUB_COLOR).$st->{'sub'}.color('reset'); | 
| 108 | 0 |  |  |  |  |  | $ret .=  $SPACE x ($l_ar->[1] - length $st->{'sub'}); | 
| 109 | 0 |  |  |  |  |  | $ret .= color($EPANSI_SCRIPT_COLOR).$st->{'prog'}.color('reset'); | 
| 110 | 0 |  |  |  |  |  | $ret .=  $SPACE x ($l_ar->[2] - length $st->{'prog'}); | 
| 111 | 0 |  |  |  |  |  | $ret .=  color($EPANSI_LINE_COLOR).$st->{'line'}.color('reset'); | 
| 112 | 0 |  |  |  |  |  | push @ret, $ret; | 
| 113 |  |  |  |  |  |  | } | 
| 114 | 0 |  |  |  |  |  | return @ret; | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | # Print class if class isn't main. | 
| 118 |  |  |  |  |  |  | sub _err_class { | 
| 119 | 0 |  |  | 0 |  |  | my $error_hr = shift; | 
| 120 | 0 |  |  |  |  |  | my $class = $error_hr->{'stack'}->[0]->{'class'}; | 
| 121 | 0 | 0 |  |  |  |  | if ($class eq 'main') { | 
| 122 | 0 |  |  |  |  |  | $class = $EMPTY_STR; | 
| 123 |  |  |  |  |  |  | } | 
| 124 | 0 | 0 |  |  |  |  | if ($class) { | 
| 125 | 0 |  |  |  |  |  | $class = color($EPANSI_CLASS_COLOR).$class. | 
| 126 |  |  |  |  |  |  | color($EPANSI_OTHER_COLOR).': '.color('reset'); | 
| 127 |  |  |  |  |  |  | } | 
| 128 | 0 |  |  |  |  |  | return $class; | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | # Pretty print line error. | 
| 132 |  |  |  |  |  |  | sub _err_line { | 
| 133 | 0 |  |  | 0 |  |  | my $error_hr = shift; | 
| 134 | 0 |  |  |  |  |  | my $stack_ar = $error_hr->{'stack'}; | 
| 135 | 0 |  |  |  |  |  | my $msg = $error_hr->{'msg'}; | 
| 136 | 0 |  |  |  |  |  | my $prog = $stack_ar->[0]->{'prog'}; | 
| 137 | 0 |  |  |  |  |  | $prog =~ s/^\.\///gms; | 
| 138 | 0 |  |  |  |  |  | my $e = $msg->[0]; | 
| 139 | 0 |  |  |  |  |  | chomp $e; | 
| 140 |  |  |  |  |  |  | return color($EPANSI_OTHER_COLOR).'#Error ['.color($EPANSI_SCRIPT_COLOR).$prog. | 
| 141 | 0 |  |  |  |  |  | color($EPANSI_OTHER_COLOR).':'.color($EPANSI_LINE_COLOR).$stack_ar->[0]->{'line'}. | 
| 142 |  |  |  |  |  |  | color($EPANSI_OTHER_COLOR).'] '.color($EPANSI_ERROR_COLOR).$e.color('reset')."\n"; | 
| 143 |  |  |  |  |  |  | } | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | # Process variables. | 
| 146 |  |  |  |  |  |  | sub _err_variables { | 
| 147 | 0 |  |  | 0 |  |  | my @msg = @_; | 
| 148 | 0 |  |  |  |  |  | my @ret; | 
| 149 | 0 |  |  |  |  |  | while (@msg) { | 
| 150 | 0 |  |  |  |  |  | my $f = shift @msg; | 
| 151 | 0 |  |  |  |  |  | my $t = shift @msg; | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 0 | 0 |  |  |  |  | if (! defined $f) { | 
| 154 | 0 |  |  |  |  |  | last; | 
| 155 |  |  |  |  |  |  | } | 
| 156 | 0 |  |  |  |  |  | my $ret = $f; | 
| 157 | 0 | 0 |  |  |  |  | if (defined $t) { | 
| 158 | 0 |  |  |  |  |  | chomp $t; | 
| 159 | 0 |  |  |  |  |  | $ret .= color($EPANSI_OTHER_COLOR).': '. | 
| 160 |  |  |  |  |  |  | color($EPANSI_ERROR_COLOR).$t.color('reset'); | 
| 161 |  |  |  |  |  |  | } | 
| 162 | 0 |  |  |  |  |  | push @ret, color($EPANSI_ERROR_COLOR).$ret.color('reset'); | 
| 163 |  |  |  |  |  |  | } | 
| 164 | 0 |  |  |  |  |  | return @ret; | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | # Gets length for errors. | 
| 168 |  |  |  |  |  |  | sub _lenghts { | 
| 169 | 0 |  |  | 0 |  |  | my @errors = @_; | 
| 170 | 0 |  |  |  |  |  | my $l_ar = [0, 0, 0]; | 
| 171 | 0 |  |  |  |  |  | foreach my $error_hr (@errors) { | 
| 172 | 0 |  |  |  |  |  | foreach my $st (@{$error_hr->{'stack'}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 173 | 0 | 0 |  |  |  |  | if (length $st->{'class'} > $l_ar->[0]) { | 
| 174 | 0 |  |  |  |  |  | $l_ar->[0] = length $st->{'class'}; | 
| 175 |  |  |  |  |  |  | } | 
| 176 | 0 | 0 |  |  |  |  | if (length $st->{'sub'} > $l_ar->[1]) { | 
| 177 | 0 |  |  |  |  |  | $l_ar->[1] = length $st->{'sub'}; | 
| 178 |  |  |  |  |  |  | } | 
| 179 | 0 | 0 |  |  |  |  | if (length $st->{'prog'} > $l_ar->[2]) { | 
| 180 | 0 |  |  |  |  |  | $l_ar->[2] = length $st->{'prog'}; | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  | } | 
| 184 | 0 |  |  |  |  |  | $l_ar->[0] += 2; | 
| 185 | 0 |  |  |  |  |  | $l_ar->[1] += 2; | 
| 186 | 0 |  |  |  |  |  | $l_ar->[2] += 2; | 
| 187 | 0 |  |  |  |  |  | return $l_ar; | 
| 188 |  |  |  |  |  |  | } | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | 1; | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | __END__ |