| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Devel::Carp; | 
| 2 |  |  |  |  |  |  | $VERSION = '0.04'; | 
| 3 |  |  |  |  |  |  |  | 
| 4 |  |  |  |  |  |  | # Avoid loading Carp if it wasn't already loaded. | 
| 5 |  |  |  |  |  |  | $INC{'Carp.pm'} = $INC{'Devel/Carp.pm'}; | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | package Carp; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 NAME | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | carp    - warn of errors (from perspective of caller) | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | cluck   - warn of errors with stack backtrace | 
| 14 |  |  |  |  |  |  | (not exported by default) | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | croak   - die of errors (from perspective of caller) | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | confess - die of errors with stack backtrace | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | use Carp; | 
| 23 |  |  |  |  |  |  | croak "We're outta here!"; | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | use Carp qw(cluck); | 
| 26 |  |  |  |  |  |  | cluck "This is how we got here!"; | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | The Carp routines are useful in your own modules because | 
| 31 |  |  |  |  |  |  | they act like die() or warn(), but report where the error | 
| 32 |  |  |  |  |  |  | was in the code they were called from.  Thus if you have a | 
| 33 |  |  |  |  |  |  | routine Foo() that has a carp() in it, then the carp() | 
| 34 |  |  |  |  |  |  | will report the error as occurring where Foo() was called, | 
| 35 |  |  |  |  |  |  | not where carp() was called. | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =head2 Forcing a Stack Trace | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | As a debugging aid, you can force Carp to treat a croak as a confess | 
| 40 |  |  |  |  |  |  | and a carp as a cluck across I modules. In other words, force a | 
| 41 |  |  |  |  |  |  | detailed stack trace to be given.  This can be very helpful when trying | 
| 42 |  |  |  |  |  |  | to understand why, or from where, a warning or error is being generated. | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | This feature is enabled by 'importing' the non-existant symbol | 
| 45 |  |  |  |  |  |  | 'verbose'. You would typically enable it by saying | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | perl -MCarp=verbose script.pl | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | or by including the string C in the L | 
| 50 |  |  |  |  |  |  | environment variable. | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | =cut | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | # Comments added by Andy Wardley  09-Apr-98, based on an | 
| 55 |  |  |  |  |  |  | # _almost_ complete understanding of the package.  Corrections and | 
| 56 |  |  |  |  |  |  | # comments are welcome. | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | # The $CarpLevel variable can be set to "strip off" extra caller levels for | 
| 59 |  |  |  |  |  |  | # those times when Carp calls are buried inside other functions.  The | 
| 60 |  |  |  |  |  |  | # $Max(EvalLen|(Arg(Len|Nums)) variables are used to specify how the eval | 
| 61 |  |  |  |  |  |  | # text and function arguments should be formatted when printed. | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | $CarpLevel = 0;		# How many extra package levels to skip on carp. | 
| 64 |  |  |  |  |  |  | $MaxEvalLen = 0;	# How much eval '...text...' to show. 0 = all. | 
| 65 |  |  |  |  |  |  | $MaxArgLen = 64;        # How much of each argument to print. 0 = all. | 
| 66 |  |  |  |  |  |  | $MaxArgNums = 8;        # How many arguments to print. 0 = all. | 
| 67 |  |  |  |  |  |  | $Verbose = 0;		# If true then make shortmess call longmess instead | 
| 68 |  |  |  |  |  |  | $MaxRecursion = 2; | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | require Exporter; | 
| 71 |  |  |  |  |  |  | @ISA = ('Exporter'); | 
| 72 |  |  |  |  |  |  | @EXPORT = qw(confess croak carp); | 
| 73 |  |  |  |  |  |  | @EXPORT_OK = qw(cluck verbose); | 
| 74 |  |  |  |  |  |  | @EXPORT_FAIL = qw(verbose);	# hook to enable verbose mode | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | local $SIG{__WARN__} = sub { | 
| 77 |  |  |  |  |  |  | # Carp was probably loaded already so we need to silence | 
| 78 |  |  |  |  |  |  | # the "Subroutine %s redefined" warning. | 
| 79 |  |  |  |  |  |  | return if $_[0] =~ /redefined/; | 
| 80 |  |  |  |  |  |  | warn $_[0]; | 
| 81 |  |  |  |  |  |  | }; | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | # if the caller specifies verbose usage ("perl -MCarp=verbose script.pl") | 
| 84 |  |  |  |  |  |  | # then the following method will be called by the Exporter which knows | 
| 85 |  |  |  |  |  |  | # to do this thanks to @EXPORT_FAIL, above.  $_[1] will contain the word | 
| 86 |  |  |  |  |  |  | # 'verbose'. | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | *export_fail = sub { | 
| 89 | 0 |  |  | 0 |  | 0 | shift; | 
| 90 | 0 | 0 |  |  |  | 0 | $Verbose = shift if $_[0] eq 'verbose'; | 
| 91 | 0 |  |  |  |  | 0 | return @_; | 
| 92 |  |  |  |  |  |  | }; | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | # longmess() crawls all the way up the stack reporting on all the function | 
| 96 |  |  |  |  |  |  | # calls made.  The error string, $error, is originally constructed from the | 
| 97 |  |  |  |  |  |  | # arguments passed into longmess() via confess(), cluck() or shortmess(). | 
| 98 |  |  |  |  |  |  | # This gets appended with the stack trace messages which are generated for | 
| 99 |  |  |  |  |  |  | # each function call on the stack. | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | my $in_carp=0; | 
| 102 |  |  |  |  |  |  | *longmess = sub { | 
| 103 | 18 | 100 |  | 18 |  | 33 | if ($in_carp >= $MaxRecursion) { | 
| 104 |  |  |  |  |  |  | #--$in_carp; # ?? | 
| 105 | 11 |  |  |  |  | 33 | return "DIED\n" | 
| 106 |  |  |  |  |  |  | } | 
| 107 | 7 |  |  |  |  | 6 | ++$in_carp; | 
| 108 | 7 |  |  |  |  | 8 | my $error; | 
| 109 | 7 |  |  |  |  | 9 | eval { $error = join '', @_ }; | 
|  | 7 |  |  |  |  | 13 |  | 
| 110 | 7 | 100 |  |  |  | 18 | if ($@) { | 
| 111 | 2 |  |  |  |  | 7 | $@ =~ s/\n$//; | 
| 112 | 2 |  |  |  |  | 5 | $error = "<$@>"; | 
| 113 |  |  |  |  |  |  | } | 
| 114 | 7 |  |  |  |  | 8 | my $mess = ""; | 
| 115 | 7 |  |  |  |  | 10 | my $i = 1 + $CarpLevel; | 
| 116 | 7 |  |  |  |  | 4 | my ($pack,$file,$line,$sub,$hargs,$eval,$require); | 
| 117 | 0 |  |  |  |  | 0 | my (@a); | 
| 118 |  |  |  |  |  |  | # | 
| 119 |  |  |  |  |  |  | # crawl up the stack.... | 
| 120 |  |  |  |  |  |  | # | 
| 121 | 7 |  |  |  |  | 11 | while (do { { package DB; @a = caller($i++) } } ) { | 
|  | 32 |  |  |  |  | 31 |  | 
|  | 32 |  |  |  |  | 216 |  | 
| 122 |  |  |  |  |  |  | # get copies of the variables returned from caller() | 
| 123 | 25 |  |  |  |  | 90 | ($pack,$file,$line,$sub,$hargs,undef,$eval,$require) = @a; | 
| 124 |  |  |  |  |  |  | # | 
| 125 |  |  |  |  |  |  | # if the $error error string is newline terminated then it | 
| 126 |  |  |  |  |  |  | # is copied into $mess.  Otherwise, $mess gets set (at the end of | 
| 127 |  |  |  |  |  |  | # the 'else {' section below) to one of two things.  The first time | 
| 128 |  |  |  |  |  |  | # through, it is set to the "$error at $file line $line" message. | 
| 129 |  |  |  |  |  |  | # $error is then set to 'called' which triggers subsequent loop | 
| 130 |  |  |  |  |  |  | # iterations to append $sub to $mess before appending the "$error | 
| 131 |  |  |  |  |  |  | # at $file line $line" which now actually reads "called at $file line | 
| 132 |  |  |  |  |  |  | # $line".  Thus, the stack trace message is constructed: | 
| 133 |  |  |  |  |  |  | # | 
| 134 |  |  |  |  |  |  | #        first time: $mess  = $error at $file line $line | 
| 135 |  |  |  |  |  |  | #  subsequent times: $mess .= $sub $error at $file line $line | 
| 136 |  |  |  |  |  |  | #                                  ^^^^^^ | 
| 137 |  |  |  |  |  |  | #                                 "called" | 
| 138 | 25 | 50 |  |  |  | 45 | if ($error =~ m/\n$/) { | 
| 139 | 0 |  |  |  |  | 0 | $mess .= $error; | 
| 140 |  |  |  |  |  |  | } else { | 
| 141 |  |  |  |  |  |  | # Build a string, $sub, which names the sub-routine called. | 
| 142 |  |  |  |  |  |  | # This may also be "require ...", "eval '...' or "eval {...}" | 
| 143 | 25 | 50 |  |  |  | 58 | if (defined $eval) { | 
|  |  | 100 |  |  |  |  |  | 
| 144 | 0 | 0 |  |  |  | 0 | if ($require) { | 
| 145 | 0 |  |  |  |  | 0 | $sub = "require $eval"; | 
| 146 |  |  |  |  |  |  | } else { | 
| 147 | 0 |  |  |  |  | 0 | $eval =~ s/([\\\'])/\\$1/g; | 
| 148 | 0 | 0 | 0 |  |  | 0 | if ($MaxEvalLen && length($eval) > $MaxEvalLen) { | 
| 149 | 0 |  |  |  |  | 0 | substr($eval,$MaxEvalLen) = '...'; | 
| 150 |  |  |  |  |  |  | } | 
| 151 | 0 |  |  |  |  | 0 | $sub = "eval '$eval'"; | 
| 152 |  |  |  |  |  |  | } | 
| 153 |  |  |  |  |  |  | } elsif ($sub eq '(eval)') { | 
| 154 | 4 |  |  |  |  | 5 | $sub = 'eval {...}'; | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  | # if there are any arguments in the sub-routine call, format | 
| 157 |  |  |  |  |  |  | # them according to the format variables defined earlier in | 
| 158 |  |  |  |  |  |  | # this file and join them onto the $sub sub-routine string | 
| 159 | 25 | 100 |  |  |  | 40 | if ($hargs) { | 
| 160 |  |  |  |  |  |  | # we may trash some of the args so we take a copy | 
| 161 | 21 |  |  |  |  | 49 | @a = @DB::args;	# must get local copy of args | 
| 162 |  |  |  |  |  |  | # don't print any more than $MaxArgNums | 
| 163 | 21 | 50 | 33 |  |  | 82 | if ($MaxArgNums and @a > $MaxArgNums) { | 
| 164 |  |  |  |  |  |  | # cap the length of $#a and set the last element to '...' | 
| 165 | 0 |  |  |  |  | 0 | $#a = $MaxArgNums; | 
| 166 | 0 |  |  |  |  | 0 | $a[$#a] = "..."; | 
| 167 |  |  |  |  |  |  | } | 
| 168 | 21 |  |  |  |  | 28 | for (@a) { | 
| 169 | 36 |  |  |  |  | 36 | eval { | 
| 170 |  |  |  |  |  |  | # set args to the string "undef" if undefined | 
| 171 | 36 | 100 |  |  |  | 64 | $_ = "undef", return unless defined $_; | 
| 172 | 32 | 100 |  |  |  | 44 | if (ref $_) { | 
| 173 |  |  |  |  |  |  | # dunno what this is for... | 
| 174 | 14 |  |  |  |  | 90 | $_ .= ''; | 
| 175 | 0 |  |  |  |  | 0 | s/'/\\'/g; | 
| 176 |  |  |  |  |  |  | } | 
| 177 |  |  |  |  |  |  | else { | 
| 178 | 18 |  |  |  |  | 24 | s/'/\\'/g; | 
| 179 |  |  |  |  |  |  | # terminate the string early with '...' if too long | 
| 180 | 18 | 50 | 33 |  |  | 73 | substr($_,$MaxArgLen) = '...' | 
| 181 |  |  |  |  |  |  | if $MaxArgLen and $MaxArgLen < length; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  | # 'quote' arg unless it looks like a number | 
| 184 | 18 | 50 |  |  |  | 63 | $_ = "'$_'" unless /^-?[\d.]+$/; | 
| 185 |  |  |  |  |  |  | # print high-end chars as 'M-' or '^' | 
| 186 | 18 |  |  |  |  | 24 | s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg; | 
|  | 0 |  |  |  |  | 0 |  | 
| 187 | 18 |  |  |  |  | 24 | s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg; | 
|  | 0 |  |  |  |  | 0 |  | 
| 188 |  |  |  |  |  |  | }; | 
| 189 | 36 | 100 |  |  |  | 80 | if ($@) { | 
| 190 | 14 |  |  |  |  | 48 | $@ =~ s/\n$//; | 
| 191 | 14 |  |  |  |  | 40 | $_ = "<$@>"; | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  | } | 
| 194 |  |  |  |  |  |  | # append ('all', 'the', 'arguments') to the $sub string | 
| 195 | 21 |  |  |  |  | 47 | $sub .= '(' . join(', ', @a) . ')'; | 
| 196 |  |  |  |  |  |  | } | 
| 197 |  |  |  |  |  |  | # here's where the error message, $mess, gets constructed | 
| 198 | 25 | 100 |  |  |  | 65 | $mess .= "\t$sub " if $error eq "called"; | 
| 199 | 25 |  |  |  |  | 55 | $mess .= "$error at $file line $line\n"; | 
| 200 |  |  |  |  |  |  | } | 
| 201 |  |  |  |  |  |  | # we don't need to print the actual error message again so we can | 
| 202 |  |  |  |  |  |  | # change this to "called" so that the string "$error at $file line | 
| 203 |  |  |  |  |  |  | # $line" makes sense as "called at $file line $line". | 
| 204 | 25 |  |  |  |  | 30 | $error = "called"; | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  | # this kludge circumvents die's incorrect handling of NUL | 
| 207 | 7 |  | 33 |  |  | 14 | my $msg = \($mess || $error); | 
| 208 | 7 |  |  |  |  | 21 | $$msg =~ tr/\0//d; | 
| 209 | 7 |  |  |  |  | 7 | --$in_carp; | 
| 210 | 7 |  |  |  |  | 42 | $$msg; | 
| 211 |  |  |  |  |  |  | }; | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  |  | 
| 214 |  |  |  |  |  |  | # shortmess() is called by carp() and croak() to skip all the way up to | 
| 215 |  |  |  |  |  |  | # the top-level caller's package and report the error from there.  confess() | 
| 216 |  |  |  |  |  |  | # and cluck() generate a full stack trace so they call longmess() to | 
| 217 |  |  |  |  |  |  | # generate that.  In verbose mode shortmess() calls longmess() so | 
| 218 |  |  |  |  |  |  | # you always get a stack trace | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | *shortmess = sub {	# Short-circuit &longmess if called via multiple packages | 
| 221 | 2 | 50 |  | 2 |  | 6 | goto &longmess if $Verbose; | 
| 222 | 2 | 50 |  |  |  | 5 | if ($in_carp >= $MaxRecursion) { | 
| 223 |  |  |  |  |  |  | #--$in_carp; # ?? | 
| 224 | 0 |  |  |  |  | 0 | return "DIED\n" | 
| 225 |  |  |  |  |  |  | } | 
| 226 | 2 |  |  |  |  | 3 | ++$in_carp; | 
| 227 | 2 |  |  |  |  | 2 | my $error; | 
| 228 | 2 |  |  |  |  | 3 | eval { $error = join '', @_ }; | 
|  | 2 |  |  |  |  | 80 |  | 
| 229 | 2 | 50 |  |  |  | 14 | if ($@) { | 
| 230 | 2 |  |  |  |  | 8 | $@ =~ s/\n$//; | 
| 231 | 2 |  |  |  |  | 6 | $error = "<$@>"; | 
| 232 |  |  |  |  |  |  | } | 
| 233 | 2 |  |  |  |  | 9 | my ($prevpack) = caller(1); | 
| 234 | 2 |  |  |  |  | 4 | my $extra = $CarpLevel; | 
| 235 | 2 |  |  |  |  | 2 | my $i = 2; | 
| 236 | 2 |  |  |  |  | 3 | my ($pack,$file,$line); | 
| 237 |  |  |  |  |  |  | # when reporting an error, we want to report it from the context of the | 
| 238 |  |  |  |  |  |  | # calling package.  So what is the calling package?  Within a module, | 
| 239 |  |  |  |  |  |  | # there may be many calls between methods and perhaps between sub-classes | 
| 240 |  |  |  |  |  |  | # and super-classes, but the user isn't interested in what happens | 
| 241 |  |  |  |  |  |  | # inside the package.  We start by building a hash array which keeps | 
| 242 |  |  |  |  |  |  | # track of all the packages to which the calling package belongs.  We | 
| 243 |  |  |  |  |  |  | # do this by examining its @ISA variable.  Any call from a base class | 
| 244 |  |  |  |  |  |  | # method (one of our caller's @ISA packages) can be ignored | 
| 245 | 2 |  |  |  |  | 6 | my %isa = ($prevpack,1); | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | # merge all the caller's @ISA packages into %isa. | 
| 248 | 0 |  |  |  |  | 0 | @isa{@{"${prevpack}::ISA"}} = () | 
|  | 2 |  |  |  |  | 12 |  | 
| 249 | 2 | 50 |  |  |  | 6 | if(defined @{"${prevpack}::ISA"}); | 
| 250 |  |  |  |  |  |  |  | 
| 251 |  |  |  |  |  |  | # now we crawl up the calling stack and look at all the packages in | 
| 252 |  |  |  |  |  |  | # there.  For each package, we look to see if it has an @ISA and then | 
| 253 |  |  |  |  |  |  | # we see if our caller features in that list.  That would imply that | 
| 254 |  |  |  |  |  |  | # our caller is a derived class of that package and its calls can also | 
| 255 |  |  |  |  |  |  | # be ignored | 
| 256 | 2 |  |  |  |  | 8 | while (($pack,$file,$line) = caller($i++)) { | 
| 257 | 0 | 0 |  |  |  | 0 | if(defined @{$pack . "::ISA"}) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 258 | 0 |  |  |  |  | 0 | my @i = @{$pack . "::ISA"}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 259 | 0 |  |  |  |  | 0 | my %i; | 
| 260 | 0 |  |  |  |  | 0 | @i{@i} = (); | 
| 261 |  |  |  |  |  |  | # merge any relevant packages into %isa | 
| 262 | 0 | 0 | 0 |  |  | 0 | @isa{@i,$pack} = () | 
| 263 |  |  |  |  |  |  | if(exists $i{$prevpack} || exists $isa{$pack}); | 
| 264 |  |  |  |  |  |  | } | 
| 265 |  |  |  |  |  |  |  | 
| 266 |  |  |  |  |  |  | # and here's where we do the ignoring... if the package in | 
| 267 |  |  |  |  |  |  | # question is one of our caller's base or derived packages then | 
| 268 |  |  |  |  |  |  | # we can ignore it (skip it) and go onto the next (but note that | 
| 269 |  |  |  |  |  |  | # the continue { } block below gets called every time) | 
| 270 |  |  |  |  |  |  | next | 
| 271 | 0 | 0 |  |  |  | 0 | if(exists $isa{$pack}); | 
| 272 |  |  |  |  |  |  |  | 
| 273 |  |  |  |  |  |  | # Hey!  We've found a package that isn't one of our caller's | 
| 274 |  |  |  |  |  |  | # clan....but wait, $extra refers to the number of 'extra' levels | 
| 275 |  |  |  |  |  |  | # we should skip up.  If $extra > 0 then this is a false alarm. | 
| 276 |  |  |  |  |  |  | # We must merge the package into the %isa hash (so we can ignore it | 
| 277 |  |  |  |  |  |  | # if it pops up again), decrement $extra, and continue. | 
| 278 | 0 | 0 |  |  |  | 0 | if ($extra-- > 0) { | 
| 279 | 0 |  |  |  |  | 0 | %isa = ($pack,1); | 
| 280 | 0 |  |  |  |  | 0 | @isa{@{$pack . "::ISA"}} = () | 
|  | 0 |  |  |  |  | 0 |  | 
| 281 | 0 | 0 |  |  |  | 0 | if(defined @{$pack . "::ISA"}); | 
| 282 |  |  |  |  |  |  | } | 
| 283 |  |  |  |  |  |  | else { | 
| 284 |  |  |  |  |  |  | # OK!  We've got a candidate package.  Time to construct the | 
| 285 |  |  |  |  |  |  | # relevant error message and return it.   die() doesn't like | 
| 286 |  |  |  |  |  |  | # to be given NUL characters (which $msg may contain) so we | 
| 287 |  |  |  |  |  |  | # remove them first. | 
| 288 | 0 |  |  |  |  | 0 | (my $msg = "$error at $file line $line\n") =~ tr/\0//d; | 
| 289 | 0 |  |  |  |  | 0 | --$in_carp; | 
| 290 | 0 |  |  |  |  | 0 | return $msg; | 
| 291 |  |  |  |  |  |  | } | 
| 292 |  |  |  |  |  |  | } | 
| 293 |  |  |  |  |  |  | continue { | 
| 294 | 0 |  |  |  |  | 0 | $prevpack = $pack; | 
| 295 |  |  |  |  |  |  | } | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | # uh-oh!  It looks like we crawled all the way up the stack and | 
| 298 |  |  |  |  |  |  | # never found a candidate package.  Oh well, let's call longmess | 
| 299 |  |  |  |  |  |  | # to generate a full stack trace.  We use the magical form of 'goto' | 
| 300 |  |  |  |  |  |  | # so that this shortmess() function doesn't appear on the stack | 
| 301 |  |  |  |  |  |  | # to further confuse longmess() about it's calling package. | 
| 302 | 2 |  |  |  |  | 2 | --$in_carp; | 
| 303 | 2 |  |  |  |  | 8 | goto &longmess; | 
| 304 |  |  |  |  |  |  | }; | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | # the following four functions call longmess() or shortmess() depending on | 
| 308 |  |  |  |  |  |  | # whether they should generate a full stack trace (confess() and cluck()) | 
| 309 |  |  |  |  |  |  | # or simply report the caller's package (croak() and carp()), respectively. | 
| 310 |  |  |  |  |  |  | # confess() and croak() die, carp() and cluck() warn. | 
| 311 |  |  |  |  |  |  |  | 
| 312 | 0 |  |  | 0 |  | 0 | *croak   = sub { die  shortmess(@_) }; | 
| 313 | 15 |  |  | 15 |  | 52 | *confess = sub { die  longmess( @_) }; | 
| 314 | 2 |  |  | 2 |  | 123 | *carp    = sub { warn shortmess(@_) }; | 
| 315 | 1 |  |  | 1 |  | 80 | *cluck   = sub { warn longmess( @_) }; | 
| 316 |  |  |  |  |  |  |  | 
| 317 |  |  |  |  |  |  | 1; |