| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
########################################################### |
|
2
|
|
|
|
|
|
|
# A Perl package for showing/modifying JPEG (meta)data. # |
|
3
|
|
|
|
|
|
|
# Copyright (C) 2004,2005,2006 Stefano Bettelli # |
|
4
|
|
|
|
|
|
|
# See the COPYING and LICENSE files for license terms. # |
|
5
|
|
|
|
|
|
|
########################################################### |
|
6
|
|
|
|
|
|
|
package Image::MetaData::JPEG::Backtrace; |
|
7
|
16
|
|
|
16
|
|
65
|
use strict; |
|
|
16
|
|
|
|
|
17
|
|
|
|
16
|
|
|
|
|
574
|
|
|
8
|
16
|
|
|
16
|
|
56
|
use warnings; |
|
|
16
|
|
|
|
|
21
|
|
|
|
16
|
|
|
|
|
7658
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
########################################################### |
|
11
|
|
|
|
|
|
|
# The following variables belong to the JPEG package. # |
|
12
|
|
|
|
|
|
|
# They are used as global switches for selecting # |
|
13
|
|
|
|
|
|
|
# backtrace verbosity in various situations: # |
|
14
|
|
|
|
|
|
|
# $show_warnings --> if false, warnings should be muted # |
|
15
|
|
|
|
|
|
|
########################################################### |
|
16
|
|
|
|
|
|
|
{ package Image::MetaData::JPEG; |
|
17
|
|
|
|
|
|
|
our $show_warnings = 1; } |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
########################################################### |
|
20
|
|
|
|
|
|
|
# This is a private customisable function for creating an # |
|
21
|
|
|
|
|
|
|
# error (or warning) message with the current stack trace # |
|
22
|
|
|
|
|
|
|
# attached. It uses additional information returned by # |
|
23
|
|
|
|
|
|
|
# the built-in Perl function 'caller' when it is called # |
|
24
|
|
|
|
|
|
|
# from within the 'DB' package (is this dangerous?). # |
|
25
|
|
|
|
|
|
|
# ------------------------------------------------------- # |
|
26
|
|
|
|
|
|
|
# To be used by JPEG, JPEG::Segment, JPEG::Record ... # |
|
27
|
|
|
|
|
|
|
########################################################### |
|
28
|
|
|
|
|
|
|
sub backtrace { |
|
29
|
86
|
|
|
86
|
0
|
115
|
my ($message, $preamble, $obj, $prefix) = @_; |
|
30
|
|
|
|
|
|
|
# a private function for formatting a line number and a file name |
|
31
|
86
|
|
|
595
|
|
346
|
my $format = sub { " [at line $_[0] in $_[1]]" }; |
|
|
595
|
|
|
|
|
2539
|
|
|
32
|
|
|
|
|
|
|
# get a textual representation of the object |
|
33
|
86
|
50
|
|
|
|
241
|
my $objstring = defined $obj ? "$obj" : ''; |
|
34
|
|
|
|
|
|
|
# get the prefix in the package name (before the last ::); |
|
35
|
|
|
|
|
|
|
# this variable can be overridden by the caller |
|
36
|
86
|
50
|
|
|
|
720
|
($prefix = $objstring) =~ s/^(.*)::[^:]*$/$1/ unless $prefix; |
|
37
|
|
|
|
|
|
|
# write the user preamble (e.g., 'Error' or 'Warning') as well as |
|
38
|
|
|
|
|
|
|
# the object's textual representation at the beginning of the output |
|
39
|
86
|
|
|
|
|
237
|
my @stacktrace = ("$preamble [obj $objstring]"); |
|
40
|
|
|
|
|
|
|
# we assume that this function is called by a "warn" or "die" |
|
41
|
|
|
|
|
|
|
# method of some package, so it does not make sense to have |
|
42
|
|
|
|
|
|
|
# less than two stack frames here. |
|
43
|
86
|
50
|
|
|
|
224
|
die "Error in backtrace: cannot backtrace!" unless caller(1); |
|
44
|
|
|
|
|
|
|
# detect where this function was called from (the function name is |
|
45
|
|
|
|
|
|
|
# not important, maybe "warn" or "die"); use this info to format a |
|
46
|
|
|
|
|
|
|
# "0-th" frame with the error message instead of the subroutine name |
|
47
|
86
|
|
|
|
|
496
|
my (undef, $filename, $line) = caller(1); |
|
48
|
86
|
|
|
|
|
250
|
push @stacktrace, "0: --> \"$message\"" . &$format($line, $filename); |
|
49
|
|
|
|
|
|
|
# loop over all frames with depth larger than one |
|
50
|
86
|
|
|
|
|
246
|
for (my $depth = 2; caller($depth); ++$depth) { |
|
51
|
|
|
|
|
|
|
# get information about this stack frame from the built-in Perl |
|
52
|
|
|
|
|
|
|
# function 'caller'; we need to call it from within the DB package |
|
53
|
|
|
|
|
|
|
# to access the list of arguments later (in @DB::args). |
|
54
|
509
|
|
|
|
|
415
|
my @info = eval { package DB; caller(1+$depth) }; |
|
|
509
|
|
|
|
|
2423
|
|
|
55
|
509
|
|
|
|
|
848
|
my @arguments = @DB::args; |
|
56
|
|
|
|
|
|
|
# create a string with a representation of the argument values; |
|
57
|
|
|
|
|
|
|
# undefined values are rendered as 'undef', non-numeric values |
|
58
|
|
|
|
|
|
|
# become strings, non-printable characters are translated. |
|
59
|
509
|
100
|
|
|
|
535
|
for (@arguments) { $_ = 'undef' unless defined; |
|
|
1311
|
|
|
|
|
1910
|
|
|
60
|
1311
|
|
|
|
|
1513
|
s/[\000-\037\177-\377]/sprintf "\\%02x",ord($&)/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
61
|
1311
|
100
|
100
|
|
|
7954
|
s/^(.*)$/'$1'/ unless /^-?\d+\.?\d*$/ || /undef/; } |
|
62
|
509
|
|
|
|
|
799
|
my $args = join ', ', @arguments; |
|
63
|
|
|
|
|
|
|
# extract subroutine names, line numbers and file names |
|
64
|
509
|
|
|
|
|
674
|
my (undef, $filename, $line, $subroutine) = @info; |
|
65
|
|
|
|
|
|
|
# detect the case of an eval statement |
|
66
|
509
|
100
|
|
|
|
713
|
my $iseval = $subroutine eq '(eval)' ? 1 : undef; |
|
67
|
|
|
|
|
|
|
# create a line for this stack frame; this contains the subroutine |
|
68
|
|
|
|
|
|
|
# name and its argument values (exception made for eval statements, |
|
69
|
|
|
|
|
|
|
# where the arguments are meaningless) plus the call location. |
|
70
|
509
|
100
|
|
|
|
1419
|
push @stacktrace, ($depth-1) . ": " . |
|
71
|
|
|
|
|
|
|
($iseval ? '(eval statement)' : "$subroutine($args)") . |
|
72
|
|
|
|
|
|
|
&$format($line, $filename); } |
|
73
|
|
|
|
|
|
|
# rework the object representation for inclusion in a regex |
|
74
|
86
|
|
|
|
|
379
|
$objstring =~ s/([\(\)])/\\$1/g; |
|
75
|
|
|
|
|
|
|
# replace $this with 'self' and take out the package prefix |
|
76
|
|
|
|
|
|
|
# (try not to touch the first line, though). |
|
77
|
86
|
|
|
|
|
120
|
for (@stacktrace) { s/'$objstring'/self/g; |
|
|
681
|
|
|
|
|
2421
|
|
|
78
|
681
|
100
|
|
|
|
2406
|
s/$prefix:{2}//g unless /\[obj .*\]/; } |
|
79
|
|
|
|
|
|
|
# returne all lines joined into one "\n"-separated string + bars |
|
80
|
86
|
|
|
|
|
1271
|
return join "\n", ('='x78, @stacktrace, '='x78, ''); |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# successful package load |
|
84
|
|
|
|
|
|
|
1; |