|  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;  |