File Coverage

blib/lib/gerr.pm
Criterion Covered Total %
statement 65 107 60.7
branch 14 42 33.3
condition 6 13 46.1
subroutine 8 10 80.0
pod 4 4 100.0
total 97 176 55.1


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             ################################################################################
3              
4             ############################################################################
5             # #
6             # Eureka Error System v1.1.7 #
7             # (C) 2020 OnEhIppY, Domero #
8             # ALL RIGHTS RESERVED #
9             # #
10             ############################################################################
11              
12             ################################################################################
13              
14             package gerr;
15              
16 1     1   118681 use strict;
  1         1  
  1         26  
17 1     1   3 use warnings;
  1         4  
  1         35  
18 1     1   3 use Exporter;
  1         1  
  1         81  
19              
20             our $VERSION = '1.1.7';
21             our @ISA = qw(Exporter);
22             our @EXPORT = qw(error Warn Die);
23             our @EXPORT_OK = qw(trace);
24              
25             ################################################################################
26              
27 1     1   421 use utf8; # Enable UTF-8 support
  1         194  
  1         6  
28              
29             sub error {
30 1     1 1 200255 my @msg = @_;
31 1         3 my $return = 0;
32 1         19 my $type = "FATAL ERROR";
33 1         3 my $size = 80 - 2;
34 1         2 my $trace = 2;
35 1         3 my @lines;
36              
37 1         4 while (scalar(@msg)) {
38 4 50       26 if (!defined $msg[0]) {
    100          
    100          
    50          
    100          
39 0         0 shift(@msg);
40             }
41             elsif ($msg[0] =~ /^return=(.+)$/s) {
42 1         3 $return = $1;
43 1         4 shift(@msg);
44             }
45             elsif ($msg[0] =~ /^type=(.+)$/s) {
46 1         3 $type = $1;
47 1         3 shift(@msg);
48             }
49             elsif ($msg[0] =~ /^size=(.+)$/s) {
50 0         0 $size = $1;
51 0         0 shift(@msg);
52             }
53             elsif ($msg[0] =~ /^trace=(.+)$/s) {
54 1         3 $trace = $1;
55 1         2 shift(@msg);
56             }
57             else {
58 1         6 push @lines, split(/\n/, shift(@msg));
59             }
60             }
61              
62 1         3 $type = " $type ";
63 1         3 my $tsize = length("$type");
64 1         3 push @lines, "";
65              
66 1         3 my $ls = ($size >> 1) - ($tsize >> 1);
67 1         3 my $rs = $size - ($size >> 1) - ($tsize >> 1) - 1;
68 1         12 my $tit = " " . ("#" x $ls) . $type . ("#" x $rs) . "\n";
69 1         4 my $str = "\n$tit\n";
70              
71 1         3 foreach my $line (@lines) {
72 2         8 while (length($line) > 0) {
73 1         8 $str .= " # ";
74 1 50       4 if (length($line) > $size) {
75 0         0 $str .= substr($line, 0, $size - 6) . "..." . " #\n";
76 0         0 $line = "..." . substr($line, $size - 6);
77             } else {
78 1 50       9 $str .= $line . (length(" " x ($size - length($line) - 3)) > 0 ? (" " x ($size - length($line) - 3)) : '') . " #\n";
79 1         3 $line = "";
80             }
81             }
82             }
83              
84 1         30 $str .= trace($trace,$size); # Include stack trace if enabled
85              
86             # Only exit if not in an eval block
87 1 0 33     5 if (!$return && !$^S) {
88 0         0 $| = 1; # Autoflush STDERR
89 0         0 binmode STDERR, ":encoding(UTF-8)"; # Set UTF-8 encoding for STDERR
90 0         0 print STDERR $str;
91 0         0 exit 1;
92             }
93              
94 1         5 return $str;
95             }
96              
97             ################################################################################
98              
99             sub trace {
100 2   50 2 1 1921 my $depth = $_[0] || 1;
101 2   100     11 my $size = $_[1] || 80-2;
102 2         4 my @out = ();
103              
104 2   66     14 while ($depth > 0 && $depth < 20) {
105 2         9 my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash) = caller($depth);
106            
107 2 50       6 if (!$package) {
108 2         8 $depth = 0;
109             } else {
110 0 0 0     0 push @out, [$line, "$package($filename)", "Calling $subroutine" . ($hasargs ? "@DB::args" : ""), ($subroutine eq '(eval)' && $evaltext ? "[$evaltext]" : "")];
    0          
111 0         0 $depth++;
112             }
113             }
114              
115 2         4 @out = reverse @out;
116              
117 2 50       6 if (@out) {
118 0         0 for my $i (0 .. $#out) {
119 0 0       0 my $dept = "# " . (" " x $i) . ($i > 0 ? "`[" : "-[");
120 0         0 my ($ln, $pk, $cl, $ev) = @{$out[$i]};
  0         0  
121 0         0 my $ll = (60 - length($dept . $cl));
122 0         0 my $rr = (6 - length($ln));
123 0 0       0 $out[$i] = "$dept $cl" . (" " x ($ll > 0 ? $ll : 0)) . " at line: " . (" " x ($rr > 0 ? $rr : 0)) . "$ln : $pk" . ($ev ? "\n$ev" : "");
    0          
    0          
124             }
125             }
126              
127 2         4 my $type = " Trace Stack ";
128 2         5 my $tsize = length("$type");
129 2         5 my $ls = ($size >> 1) - ($tsize >> 1);
130 2         5 my $rs = $size - ($size >> 1) - ($tsize >> 1) - 1;
131 2         9 my $tit = " " . ("#" x $ls) . $type . ("#" x $rs) . "\n";
132 2         27 return "$tit\n".join("\n", @out)."\n" . ("#" x $size) . "\n";
133             }
134              
135             ################################################################################
136              
137             sub Warn {
138 0     0 1 0 my ($message) = @_;
139 0         0 my $file = (caller)[1];
140 0         0 my $line = (caller)[2];
141 0         0 my $formatted_message = error("$message at $file line $line.", "return=1", "type=Warning", "trace=3");
142 0 0       0 if (ref($SIG{__WARN__}) eq 'CODE') {
143 0         0 $SIG{__WARN__}->($formatted_message);
144             } else {
145 0         0 binmode STDERR, ":encoding(UTF-8)"; # Set UTF-8 encoding for STDERR
146 0         0 print STDERR $formatted_message;
147             }
148 0         0 return $formatted_message;
149             }
150              
151             ################################################################################
152              
153             sub Die {
154 0     0 1 0 my ($message) = @_;
155 0         0 my $file = (caller)[1];
156 0         0 my $line = (caller)[2];
157 0         0 my $formatted_message = error("$message at $file line $line.", "return=1", "type=Fatal", "trace=3");
158 0 0       0 if (ref($SIG{__DIE__}) eq 'CODE') {
159 0         0 $SIG{__DIE__}->($formatted_message);
160             } else {
161 0         0 binmode STDERR, ":encoding(UTF-8)"; # Set UTF-8 encoding for STDERR
162 0         0 print STDERR $formatted_message;
163             }
164 0 0       0 exit 1 unless $^S; # Only exit if not in an eval block
165 0         0 return $formatted_message;
166             }
167              
168             ################################################################################
169              
170             sub import {
171 1     1   7 my ($class, @args) = @_;
172              
173             # Handle import arguments
174 1 50       6 if (grep { $_ eq ':control' } @args) {
  0         0  
175             # Override global warn and die
176 1     1   1014 no strict 'refs'; # Allow modifying symbolic references
  1         2  
  1         121  
177 0         0 *CORE::GLOBAL::warn = \&Warn;
178 0         0 *CORE::GLOBAL::die = \&Die;
179             }
180              
181             # Export default functions
182 1         105 $class->export_to_level(1, $class, @EXPORT);
183              
184             # Conditionally export functions based on import arguments
185 1 50       13 if (grep { $_ eq ':control' } @args) {
  0            
186 0           $class->export_to_level(1, $class, @EXPORT_OK);
187             }
188             }
189              
190             1;
191              
192             ################################################################################
193             # EOF gerr.pm (C) 2020 Domero