| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
### |
|
2
|
|
|
|
|
|
|
### Copyright (c) 2007 - 2025 Curtis Leach. All rights reserved. |
|
3
|
|
|
|
|
|
|
### |
|
4
|
|
|
|
|
|
|
### Based on the Fred Fish DBUG macros in C/C++. |
|
5
|
|
|
|
|
|
|
### This Algorithm is in the public domain! |
|
6
|
|
|
|
|
|
|
### |
|
7
|
|
|
|
|
|
|
### Module: Fred::Fish::DBUG::ON |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Fred::Fish::DBUG::ON - Fred Fish Live library for Perl |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use Fred::Fish::DBUG qw / ON /; |
|
16
|
|
|
|
|
|
|
or |
|
17
|
|
|
|
|
|
|
require Fred::Fish::DBUG; |
|
18
|
|
|
|
|
|
|
Fred::Fish::DBUG->import (qw / ON /); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Depreciated way. |
|
21
|
|
|
|
|
|
|
use Fred::Fish::DBUG::ON; |
|
22
|
|
|
|
|
|
|
or |
|
23
|
|
|
|
|
|
|
require Fred::Fish::DBUG::ON; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
F is a pure Perl implementation of the C/C++ Fred Fish |
|
28
|
|
|
|
|
|
|
macro libraries. While in C/C++ this library is implemented mostly via macros, |
|
29
|
|
|
|
|
|
|
in Perl this library is implemented using true function calls. It has also |
|
30
|
|
|
|
|
|
|
been slightly modified to address Perlish features over C/C++ ones. This can |
|
31
|
|
|
|
|
|
|
make using some features a bit strange compared to C/C++. But the basic |
|
32
|
|
|
|
|
|
|
concepts are the same. |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Using this module directly has been depreciated. You should be using |
|
35
|
|
|
|
|
|
|
L instead. The list of functions listed below are a subset |
|
36
|
|
|
|
|
|
|
of what's available there. It also provides a lot of other usefull information |
|
37
|
|
|
|
|
|
|
not repeated here. |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=over 4 |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=cut |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
package Fred::Fish::DBUG::ON; |
|
46
|
|
|
|
|
|
|
|
|
47
|
43
|
|
|
43
|
|
450911
|
use strict; |
|
|
43
|
|
|
|
|
81
|
|
|
|
43
|
|
|
|
|
1670
|
|
|
48
|
43
|
|
|
43
|
|
222
|
use warnings; |
|
|
43
|
|
|
|
|
74
|
|
|
|
43
|
|
|
|
|
2475
|
|
|
49
|
|
|
|
|
|
|
|
|
50
|
43
|
|
|
43
|
|
229
|
use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION ); |
|
|
43
|
|
|
|
|
75
|
|
|
|
43
|
|
|
|
|
3479
|
|
|
51
|
43
|
|
|
43
|
|
382
|
use Exporter; |
|
|
43
|
|
|
|
|
157
|
|
|
|
43
|
|
|
|
|
2497
|
|
|
52
|
|
|
|
|
|
|
|
|
53
|
43
|
|
|
43
|
|
21198
|
use Perl::OSType ':all'; |
|
|
43
|
|
|
|
|
24099
|
|
|
|
43
|
|
|
|
|
6975
|
|
|
54
|
43
|
|
|
43
|
|
19936
|
use FileHandle; |
|
|
43
|
|
|
|
|
497694
|
|
|
|
43
|
|
|
|
|
273
|
|
|
55
|
43
|
|
|
43
|
|
16455
|
use File::Basename; |
|
|
43
|
|
|
|
|
90
|
|
|
|
43
|
|
|
|
|
4251
|
|
|
56
|
43
|
|
|
43
|
|
306
|
use Cwd 'abs_path'; |
|
|
43
|
|
|
|
|
96
|
|
|
|
43
|
|
|
|
|
2942
|
|
|
57
|
43
|
|
|
43
|
|
280
|
use Config qw( %Config ); |
|
|
43
|
|
|
|
|
80
|
|
|
|
43
|
|
|
|
|
1997
|
|
|
58
|
43
|
|
|
43
|
|
17731
|
use Sub::Identify 'sub_fullname'; |
|
|
43
|
|
|
|
|
45008
|
|
|
|
43
|
|
|
|
|
7981
|
|
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
$VERSION = "2.10"; |
|
61
|
|
|
|
|
|
|
@ISA = qw( Exporter ); |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------ |
|
64
|
|
|
|
|
|
|
# The special var @EXPORT contains the list of functions and constants exposed |
|
65
|
|
|
|
|
|
|
# to the users of this module. The breakdown is as follows: |
|
66
|
|
|
|
|
|
|
# 1) The 1st section is a list of exposed functions that a user may call. |
|
67
|
|
|
|
|
|
|
# They mostly follow the Fred Fish standards! |
|
68
|
|
|
|
|
|
|
# 2) The remaining sections are exposed constants that can be passed as values |
|
69
|
|
|
|
|
|
|
# to exposed functions. They can also be used to test some return values. |
|
70
|
|
|
|
|
|
|
# See the POD for more details! |
|
71
|
|
|
|
|
|
|
# |
|
72
|
|
|
|
|
|
|
# Function names that are in lower case will never be exposed! They are not for |
|
73
|
|
|
|
|
|
|
# the general public and risk breaking your code between releases if used! |
|
74
|
|
|
|
|
|
|
# Those that begin with underscores (_) are for internal use only to centralize |
|
75
|
|
|
|
|
|
|
# common tasks. |
|
76
|
|
|
|
|
|
|
# The others were written to help the t/*.t programs validate that this module |
|
77
|
|
|
|
|
|
|
# worked as advertised. Exposing them would just polute Perl's name space. |
|
78
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------ |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
@EXPORT = qw( DBUG_PUSH DBUG_POP |
|
82
|
|
|
|
|
|
|
DBUG_ENTER_FUNC DBUG_ENTER_BLOCK DBUG_PRINT |
|
83
|
|
|
|
|
|
|
DBUG_RETURN DBUG_ARRAY_RETURN |
|
84
|
|
|
|
|
|
|
DBUG_VOID_RETURN DBUG_RETURN_SPECIAL |
|
85
|
|
|
|
|
|
|
DBUG_LEAVE DBUG_CATCH DBUG_PAUSE |
|
86
|
|
|
|
|
|
|
DBUG_MASK DBUG_MASK_NEXT_FUNC_CALL |
|
87
|
|
|
|
|
|
|
DBUG_FILTER DBUG_SET_FILTER_COLOR |
|
88
|
|
|
|
|
|
|
DBUG_CUSTOM_FILTER DBUG_CUSTOM_FILTER_OFF |
|
89
|
|
|
|
|
|
|
DBUG_ACTIVE DBUG_EXECUTE |
|
90
|
|
|
|
|
|
|
DBUG_FILE_NAME DBUG_FILE_HANDLE DBUG_ASSERT |
|
91
|
|
|
|
|
|
|
DBUG_MODULE_LIST |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
DBUG_SPECIAL_ARRAYREF DBUG_SPECIAL_COUNT |
|
94
|
|
|
|
|
|
|
DBUG_SPECIAL_LAST |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
DBUG_FILTER_LEVEL_FUNC DBUG_FILTER_LEVEL_ARGS |
|
97
|
|
|
|
|
|
|
DBUG_FILTER_LEVEL_ERROR DBUG_FILTER_LEVEL_STD |
|
98
|
|
|
|
|
|
|
DBUG_FILTER_LEVEL_WARN |
|
99
|
|
|
|
|
|
|
DBUG_FILTER_LEVEL_DEBUG DBUG_FILTER_LEVEL_INFO |
|
100
|
|
|
|
|
|
|
DBUG_FILTER_LEVEL_OTHER DBUG_FILTER_LEVEL_INTERNAL |
|
101
|
|
|
|
|
|
|
); |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
@EXPORT_OK = qw( ); |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# NOTE: OFF.pm inherits all exposed functions and constants exported here. |
|
106
|
|
|
|
|
|
|
# So if you add a new function, consider if it needs to be a stub in |
|
107
|
|
|
|
|
|
|
# OFF.pm. Otherwise it's automatically available in OFF.pm. Done this |
|
108
|
|
|
|
|
|
|
# way to keep this module and OFF.pm compatible. |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Constants for use by DBUG_RETURN_SPECIAL () ... |
|
111
|
43
|
|
|
43
|
|
373
|
use constant DBUG_SPECIAL_ARRAYREF => "_-"x40 . "_"; # A long random string ... |
|
|
43
|
|
|
|
|
95
|
|
|
|
43
|
|
|
|
|
5809
|
|
|
112
|
43
|
|
|
43
|
|
262
|
use constant DBUG_SPECIAL_COUNT => "-_"x40 . "-"; # A long random string ... |
|
|
43
|
|
|
|
|
108
|
|
|
|
43
|
|
|
|
|
2974
|
|
|
113
|
43
|
|
|
43
|
|
252
|
use constant DBUG_SPECIAL_LAST => "-="x40 . "="; # A long random string ... |
|
|
43
|
|
|
|
|
84
|
|
|
|
43
|
|
|
|
|
3075
|
|
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# An array for convering the DBUG_FILTER_LEVEL_... constants into stings ... |
|
116
|
|
|
|
|
|
|
my @dbug_levels; |
|
117
|
|
|
|
|
|
|
my @dbug_custom_levels; |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# For filtering what get's written to fish ... (never use level 0) |
|
120
|
43
|
|
|
43
|
|
309
|
use constant DBUG_FILTER_LEVEL_FUNC => 1; # Most restrictive. |
|
|
43
|
|
|
|
|
121
|
|
|
|
43
|
|
|
|
|
2509
|
|
|
121
|
43
|
|
|
43
|
|
330
|
use constant DBUG_FILTER_LEVEL_ARGS => 2; |
|
|
43
|
|
|
|
|
161
|
|
|
|
43
|
|
|
|
|
2204
|
|
|
122
|
43
|
|
|
43
|
|
366
|
use constant DBUG_FILTER_LEVEL_ERROR => 3; |
|
|
43
|
|
|
|
|
86
|
|
|
|
43
|
|
|
|
|
2376
|
|
|
123
|
43
|
|
|
43
|
|
224
|
use constant DBUG_FILTER_LEVEL_STD => 4; |
|
|
43
|
|
|
|
|
88
|
|
|
|
43
|
|
|
|
|
2141
|
|
|
124
|
43
|
|
|
43
|
|
202
|
use constant DBUG_FILTER_LEVEL_WARN => 5; |
|
|
43
|
|
|
|
|
91
|
|
|
|
43
|
|
|
|
|
3343
|
|
|
125
|
43
|
|
|
43
|
|
243
|
use constant DBUG_FILTER_LEVEL_DEBUG => 6; |
|
|
43
|
|
|
|
|
85
|
|
|
|
43
|
|
|
|
|
2100
|
|
|
126
|
43
|
|
|
43
|
|
210
|
use constant DBUG_FILTER_LEVEL_INFO => 7; |
|
|
43
|
|
|
|
|
90
|
|
|
|
43
|
|
|
|
|
2031
|
|
|
127
|
43
|
|
|
43
|
|
211
|
use constant DBUG_FILTER_LEVEL_OTHER => 8; # Least restrictive. |
|
|
43
|
|
|
|
|
103
|
|
|
|
43
|
|
|
|
|
1952
|
|
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Used for debugging this module. |
|
130
|
43
|
|
|
43
|
|
276
|
use constant DBUG_FILTER_LEVEL_INTERNAL => 99; |
|
|
43
|
|
|
|
|
97
|
|
|
|
43
|
|
|
|
|
2367
|
|
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# So can easily add new levels and not have to worry about changing other code! |
|
133
|
43
|
|
|
43
|
|
267
|
use constant DBUG_FILTER_LEVEL_MIN => DBUG_FILTER_LEVEL_FUNC; |
|
|
43
|
|
|
|
|
147
|
|
|
|
43
|
|
|
|
|
2196
|
|
|
134
|
43
|
|
|
43
|
|
245
|
use constant DBUG_FILTER_LEVEL_MAX => DBUG_FILTER_LEVEL_OTHER; |
|
|
43
|
|
|
|
|
97
|
|
|
|
43
|
|
|
|
|
2122
|
|
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# Names the unamed main function for the trace ... |
|
137
|
43
|
|
|
43
|
|
454
|
use constant MAIN_FUNC_NAME => "main-prog"; |
|
|
43
|
|
|
|
|
334
|
|
|
|
43
|
|
|
|
|
2167
|
|
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# Value to use when masking sensitive data in fish ... |
|
140
|
43
|
|
|
43
|
|
224
|
use constant MASKING_VALUE => "<******>"; |
|
|
43
|
|
|
|
|
77
|
|
|
|
43
|
|
|
|
|
2142
|
|
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Value to use when making undefined values printable in fish ... |
|
143
|
43
|
|
|
43
|
|
494
|
use constant UNDEF_VALUE => ""; |
|
|
43
|
|
|
|
|
98
|
|
|
|
43
|
|
|
|
|
23706
|
|
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# This hash variable holds all the global variables used by this module. |
|
146
|
|
|
|
|
|
|
my %dbug_global_vars; # The current fish frame ... |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $threads_possible; # Boolean flag telling if threads are supported. |
|
149
|
|
|
|
|
|
|
my $fork_possible; # Boolean flag telling if forks are supported. |
|
150
|
|
|
|
|
|
|
my $color_supported; # Boolean flag telling if Term::ANSIColor is avaailable. |
|
151
|
|
|
|
|
|
|
my @color_list; |
|
152
|
|
|
|
|
|
|
my $color_clear; |
|
153
|
|
|
|
|
|
|
my $time_hires_flag; # Boolean flag telling if Time::HiRes is supported! |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# Holds the version of Perl & OS ... |
|
156
|
|
|
|
|
|
|
my $dbug_log_msg; |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# So we can one day support multiple fish frames |
|
159
|
|
|
|
|
|
|
sub _init_frame |
|
160
|
|
|
|
|
|
|
{ |
|
161
|
80
|
|
|
80
|
|
183
|
my $frame_ref = shift; # A hash reference ... |
|
162
|
80
|
|
|
|
|
190
|
my $old_stack = shift; # An array of hash reference ... |
|
163
|
|
|
|
|
|
|
|
|
164
|
80
|
|
|
|
|
238
|
$frame_ref->{can_close} = 0; # OK to close the file handle. |
|
165
|
80
|
|
|
|
|
215
|
$frame_ref->{fh} = undef; # Fish's file handle. |
|
166
|
80
|
|
|
|
|
240
|
$frame_ref->{file} = ""; # The full absolute path to fish file. |
|
167
|
80
|
|
|
|
|
267
|
$frame_ref->{who_called} = 0; # Print func/file/line of caller. |
|
168
|
80
|
|
|
|
|
156
|
$frame_ref->{no_end} = 0; # Turn off fish tracing for END blocks! |
|
169
|
80
|
|
|
|
|
215
|
$frame_ref->{on} = 0; # Is Fish currently turned on or off. |
|
170
|
80
|
|
|
|
|
183
|
$frame_ref->{pause} = 0; # Is Fish is currently paused? |
|
171
|
80
|
|
|
|
|
208
|
$frame_ref->{multi} = 0; # Will we write the PID-TID or PID/xx pair to Fish? |
|
172
|
80
|
|
|
|
|
164
|
$frame_ref->{limit} = 0; # Will we limit which thread to write to Fish? |
|
173
|
80
|
|
|
|
|
161
|
$frame_ref->{screen} = 0; # Fish is writing to your screen. |
|
174
|
80
|
|
|
|
|
227
|
$frame_ref->{strip} = 0; # Will fish strip the module part of func namee? |
|
175
|
80
|
|
|
|
|
191
|
$frame_ref->{delay} = 0.0; # Will we delay after each write to fish? |
|
176
|
80
|
|
|
|
|
182
|
$frame_ref->{elapsed} = 0; # Will we track elapsed time in your code? |
|
177
|
80
|
|
|
|
|
163
|
$frame_ref->{keep} = 0; # Will we toss the logs on success? (keep on failure) |
|
178
|
80
|
|
|
|
|
142
|
$frame_ref->{no_addresses} = 0; # Will we supress unique addresses for references? |
|
179
|
80
|
|
|
|
|
183
|
$frame_ref->{dbug_leave_called} = 0; # Tells if DBUG_LEAVE() was called or not. |
|
180
|
80
|
|
|
|
|
149
|
$frame_ref->{allow_utf8} = 0; # Will we support UTF8 chars to fish? |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# Used when forking a sub-process (not separate threads!) |
|
183
|
80
|
|
|
|
|
590
|
$frame_ref->{PID} = $$; # The process PID. |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# Tell's how many return values by DBUG_RETURN() were to be masked. |
|
186
|
|
|
|
|
|
|
# Only non-zero if DBUG_MASK() was called! |
|
187
|
|
|
|
|
|
|
# You will always get the same results even if the return values |
|
188
|
|
|
|
|
|
|
# weren't printed to fish. |
|
189
|
|
|
|
|
|
|
# For DBUG_VOID_RETURN() it will always be zero! |
|
190
|
80
|
|
|
|
|
169
|
$frame_ref->{mask_return_count} = 0; |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# The filtering tags ... |
|
193
|
80
|
|
|
|
|
213
|
$frame_ref->{filter} = DBUG_FILTER_LEVEL_MAX; |
|
194
|
80
|
|
|
|
|
215
|
$dbug_global_vars{pkg_lvl} = DBUG_FILTER_LEVEL_INTERNAL; |
|
195
|
80
|
|
|
|
|
252
|
$frame_ref->{filter_style} = 1; # Standard filtering enabled ... |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# What to call the unnamed main function block in your code ... |
|
198
|
80
|
|
|
|
|
260
|
$frame_ref->{main} = MAIN_FUNC_NAME; |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
# Tells what functions are currently on the stack ... |
|
201
|
80
|
100
|
|
|
|
304
|
if ( $old_stack ) { |
|
202
|
37
|
|
|
|
|
147
|
$frame_ref->{functions} = $old_stack; |
|
203
|
|
|
|
|
|
|
} else { |
|
204
|
43
|
|
|
|
|
833
|
my @funcs; # Will be an array of hashes ... |
|
205
|
43
|
|
|
|
|
167
|
$frame_ref->{functions} = \@funcs; |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Flag tells if the exit status was printed in DBUG_LEAVE(). |
|
209
|
80
|
|
|
|
|
2322
|
$frame_ref->{printed_exit_status} = 0; |
|
210
|
|
|
|
|
|
|
|
|
211
|
80
|
|
|
|
|
208
|
return; |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# -------------------------------- |
|
215
|
|
|
|
|
|
|
# This BEGIN block handles the initialization of the DBUG frame logic. |
|
216
|
|
|
|
|
|
|
# It can only call DBUG functions appearing before this function is defined! |
|
217
|
|
|
|
|
|
|
# All BEGIN blocks are automatically executed when this module is 1st soruced |
|
218
|
|
|
|
|
|
|
# in via 'use' or 'require'! |
|
219
|
|
|
|
|
|
|
# -------------------------------- |
|
220
|
|
|
|
|
|
|
BEGIN |
|
221
|
|
|
|
|
|
|
{ |
|
222
|
43
|
|
|
43
|
|
248
|
_init_frame ( \%dbug_global_vars, undef ); |
|
223
|
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
# The array to convert the constant values into something human readable! |
|
225
|
43
|
|
|
|
|
97
|
$dbug_levels[DBUG_FILTER_LEVEL_FUNC] = "DBUG_FILTER_LEVEL_FUNC"; |
|
226
|
43
|
|
|
|
|
128
|
$dbug_levels[DBUG_FILTER_LEVEL_ARGS] = "DBUG_FILTER_LEVEL_ARGS"; |
|
227
|
43
|
|
|
|
|
175
|
$dbug_levels[DBUG_FILTER_LEVEL_ERROR] = "DBUG_FILTER_LEVEL_ERROR"; |
|
228
|
43
|
|
|
|
|
2361
|
$dbug_levels[DBUG_FILTER_LEVEL_STD] = "DBUG_FILTER_LEVEL_STD"; |
|
229
|
43
|
|
|
|
|
133
|
$dbug_levels[DBUG_FILTER_LEVEL_WARN] = "DBUG_FILTER_LEVEL_WARN"; |
|
230
|
43
|
|
|
|
|
85
|
$dbug_levels[DBUG_FILTER_LEVEL_DEBUG] = "DBUG_FILTER_LEVEL_DEBUG"; |
|
231
|
43
|
|
|
|
|
124
|
$dbug_levels[DBUG_FILTER_LEVEL_INFO] = "DBUG_FILTER_LEVEL_INFO"; |
|
232
|
43
|
|
|
|
|
133
|
$dbug_levels[DBUG_FILTER_LEVEL_OTHER] = "DBUG_FILTER_LEVEL_OTHER"; |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# The odd ball undocumented filter level. |
|
235
|
43
|
|
|
|
|
166
|
$dbug_levels[DBUG_FILTER_LEVEL_INTERNAL] = "DBUG_FILTER_LEVEL_INTERNAL"; |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
# The custom levels are all off by default! |
|
238
|
|
|
|
|
|
|
# $dbug_custom_levels[...] = 0; |
|
239
|
|
|
|
|
|
|
|
|
240
|
43
|
|
|
|
|
8527
|
return; |
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
# -------------------------------- |
|
244
|
|
|
|
|
|
|
# This BEGIN block detects if Perl supports threads. |
|
245
|
|
|
|
|
|
|
# So that we can detect which thread we're in for logging purposes! |
|
246
|
|
|
|
|
|
|
# Tests came from Test2::Util ... |
|
247
|
|
|
|
|
|
|
# -------------------------------- |
|
248
|
|
|
|
|
|
|
BEGIN |
|
249
|
|
|
|
|
|
|
{ |
|
250
|
43
|
|
|
43
|
|
157
|
$threads_possible = 0; # Threads are not supporteed ... |
|
251
|
|
|
|
|
|
|
|
|
252
|
43
|
50
|
33
|
|
|
8475
|
if ( $] >= 5.008001 && $Config{useithreads} ) { |
|
253
|
|
|
|
|
|
|
# Threads are broken on Perl 5.10.0 built with gcc 4.8+ |
|
254
|
0
|
|
|
|
|
0
|
my $broken = 0; |
|
255
|
0
|
0
|
0
|
|
|
0
|
if ($] == 5.010000 && $Config{ccname} eq 'gcc' && $Config{gccversion}) { |
|
|
|
|
0
|
|
|
|
|
|
256
|
0
|
|
|
|
|
0
|
my @parts = split /\./, $Config{gccversion}; |
|
257
|
0
|
0
|
0
|
|
|
0
|
$broken = 1 if ($parts[0] > 4 || ($parts[0] == 4 && $parts[1] >= 8)); |
|
|
|
|
0
|
|
|
|
|
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
|
|
260
|
0
|
0
|
|
|
|
0
|
unless ( $broken ) { |
|
261
|
0
|
|
|
|
|
0
|
eval { |
|
262
|
0
|
|
|
|
|
0
|
require threads; |
|
263
|
0
|
|
|
|
|
0
|
threads->import (); |
|
264
|
0
|
|
|
|
|
0
|
$threads_possible = 1; # Threads are supporteed after all ... |
|
265
|
|
|
|
|
|
|
}; |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
} # Ends if Perl > v5.8.1 && compiled with threads. |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# -------------------------------- |
|
272
|
|
|
|
|
|
|
# This BEGIN block detects if Perl supports forking. |
|
273
|
|
|
|
|
|
|
# So that we can detect which child process we're in for logging purposes! |
|
274
|
|
|
|
|
|
|
# Tests came from Test2::Util ... |
|
275
|
|
|
|
|
|
|
# -------------------------------- |
|
276
|
|
|
|
|
|
|
BEGIN |
|
277
|
|
|
|
|
|
|
{ |
|
278
|
43
|
|
|
43
|
|
175
|
$fork_possible = 1; # Assuming fork is supporteed ... |
|
279
|
|
|
|
|
|
|
|
|
280
|
43
|
50
|
|
|
|
28646
|
unless ( $Config{d_fork} ) { |
|
281
|
0
|
0
|
0
|
|
|
0
|
$fork_possible = 0 unless ($^O eq 'MSWin32' || $^O eq 'NetWare'); |
|
282
|
0
|
0
|
|
|
|
0
|
$fork_possible = 0 if ( $threads_possible == 0 ); |
|
283
|
0
|
0
|
|
|
|
0
|
$fork_possible = 0 unless ($Config{ccflags} =~ m/-DPERL_IMPLICIT_SYS/); |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# -------------------------------- |
|
288
|
|
|
|
|
|
|
# Tells if the optional Term::ANSIColor module is installed! |
|
289
|
|
|
|
|
|
|
# Done this way so that color is an optional feature. |
|
290
|
|
|
|
|
|
|
# -------------------------------- |
|
291
|
|
|
|
|
|
|
BEGIN |
|
292
|
|
|
|
|
|
|
{ |
|
293
|
43
|
|
|
43
|
|
175
|
$color_supported = 0; # Assume color isn't supported! |
|
294
|
|
|
|
|
|
|
|
|
295
|
43
|
|
|
|
|
132
|
eval { |
|
296
|
43
|
50
|
|
|
|
253
|
if ( $^O eq "MSWin32" ) { |
|
297
|
|
|
|
|
|
|
# Windows needs this module for Term::ANSIColor to work. |
|
298
|
0
|
|
|
|
|
0
|
require Win32::Console::ANSI; |
|
299
|
0
|
|
|
|
|
0
|
Win32::Console::ANSI->import (); |
|
300
|
|
|
|
|
|
|
} |
|
301
|
|
|
|
|
|
|
|
|
302
|
43
|
|
|
|
|
36058
|
require Term::ANSIColor; |
|
303
|
43
|
|
|
|
|
510187
|
Term::ANSIColor->import (); |
|
304
|
|
|
|
|
|
|
|
|
305
|
43
|
|
|
|
|
3698
|
$color_supported = 1; |
|
306
|
|
|
|
|
|
|
}; |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# -------------------------------- |
|
310
|
|
|
|
|
|
|
# Tells if the HiRes timer is available ... |
|
311
|
|
|
|
|
|
|
# Overrides the core time() & sleep() functions if available. |
|
312
|
|
|
|
|
|
|
# -------------------------------- |
|
313
|
|
|
|
|
|
|
BEGIN |
|
314
|
|
|
|
|
|
|
{ |
|
315
|
43
|
|
|
43
|
|
144
|
$time_hires_flag = 0; # Assume the HiRes timer isn't supported! |
|
316
|
|
|
|
|
|
|
|
|
317
|
43
|
|
|
|
|
88
|
eval { |
|
318
|
43
|
|
|
|
|
345
|
require Time::HiRes; |
|
319
|
43
|
|
|
|
|
327
|
Time::HiRes->import ( qw(time sleep) ); |
|
320
|
43
|
|
|
|
|
14318
|
$time_hires_flag = 1; |
|
321
|
|
|
|
|
|
|
}; |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
# -------------------------------- |
|
325
|
|
|
|
|
|
|
# Builds the string for CPAN support ... |
|
326
|
|
|
|
|
|
|
# -------------------------------- |
|
327
|
|
|
|
|
|
|
BEGIN |
|
328
|
|
|
|
|
|
|
{ |
|
329
|
43
|
|
|
43
|
|
749
|
my $pv = sprintf ("%s [%vd]", $], $^V); # The version of perl! |
|
330
|
43
|
|
|
|
|
368
|
my $flvr = os_type (); |
|
331
|
|
|
|
|
|
|
|
|
332
|
43
|
|
|
|
|
743
|
$dbug_log_msg = "Perl: $pv, OS: $^O, Flavor: $flvr\n"; |
|
333
|
43
|
50
|
|
|
|
262
|
$dbug_log_msg .= "Threads: " . ($threads_possible ? "Supported" : "Unsupported") . "\n"; |
|
334
|
43
|
50
|
|
|
|
197
|
$dbug_log_msg .= "Forking: " . ($fork_possible ? "Supported" : "Unsupported") . "\n"; |
|
335
|
43
|
50
|
|
|
|
128
|
$dbug_log_msg .= "Color: " . ($color_supported ? "Supported" : "Unsupported") . "\n"; |
|
336
|
43
|
50
|
|
|
|
159
|
$dbug_log_msg .= "HiRes: " . ($time_hires_flag ? "Supported" : "Unsupported") . "\n"; |
|
337
|
43
|
|
|
|
|
205
|
$dbug_log_msg .= "Program: $0\n"; |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
# Assume not running via a "make test" variant ... |
|
340
|
43
|
|
|
|
|
95
|
my $make_test_flag = 0; |
|
341
|
|
|
|
|
|
|
|
|
342
|
43
|
50
|
|
|
|
200
|
if ( $ENV{PERL_DL_NONLAZY} ) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
343
|
43
|
|
|
|
|
89
|
$make_test_flag = 1; # Detects "make test" on Unix like systems ... |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
} elsif ( $ENV{PERL_USE_UNSAFE_INC} ) { |
|
346
|
0
|
|
|
|
|
0
|
$make_test_flag = 1; # Detects "gmake test" on Windows (Strawberry Perl) ... |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
} elsif ( $ENV{HARNESS_ACTIVE} ) { |
|
349
|
0
|
|
|
|
|
0
|
$make_test_flag = 1; # Detects "prove -vl t/*.t" ... |
|
350
|
|
|
|
|
|
|
} |
|
351
|
|
|
|
|
|
|
|
|
352
|
43
|
50
|
|
|
|
152
|
if ( $make_test_flag ) { |
|
353
|
43
|
|
|
|
|
175223
|
$dbug_log_msg .= "Run during a \"make test\" run.\n"; |
|
354
|
|
|
|
|
|
|
} |
|
355
|
|
|
|
|
|
|
} |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
# -------------------------------- |
|
359
|
|
|
|
|
|
|
# END is automatically called when this module goes out of scope! |
|
360
|
|
|
|
|
|
|
# -------------------------------- |
|
361
|
|
|
|
|
|
|
END |
|
362
|
|
|
|
|
|
|
{ |
|
363
|
|
|
|
|
|
|
# Only happens if you call exit() directly, die due to an |
|
364
|
|
|
|
|
|
|
# untrapped signal, or just return from your main program. |
|
365
|
|
|
|
|
|
|
# If this happens the code never gets the chance to clean |
|
366
|
|
|
|
|
|
|
# up properly. So doing it now! |
|
367
|
43
|
100
|
|
43
|
|
421
|
unless ( $dbug_global_vars{dbug_leave_called} ) { |
|
368
|
2
|
|
|
|
|
7
|
_dbug_leave_cleanup (); |
|
369
|
|
|
|
|
|
|
} |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# Clear the function stack of all remaining entries ... |
|
372
|
43
|
|
|
|
|
223
|
while ( pop (@{$dbug_global_vars{functions}}) ) { } |
|
|
43
|
|
|
|
|
269
|
|
|
373
|
|
|
|
|
|
|
|
|
374
|
43
|
|
|
|
|
266
|
DBUG_ENTER_FUNC (@_); |
|
375
|
|
|
|
|
|
|
|
|
376
|
43
|
|
|
|
|
253
|
_dbug_print_pkg_tag ( DBUG_FILTER_LEVEL_INFO, |
|
377
|
|
|
|
|
|
|
"So Long, and Thanks for All the Fish!" ); |
|
378
|
|
|
|
|
|
|
|
|
379
|
43
|
100
|
|
|
|
278
|
unless ( $dbug_global_vars{printed_exit_status} ) { |
|
380
|
6
|
|
|
|
|
43
|
_dbug_print_pkg_tag ( DBUG_FILTER_LEVEL_INFO, |
|
381
|
|
|
|
|
|
|
"Exit Status (%d)", $? ); |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
|
|
384
|
43
|
|
|
|
|
246
|
DBUG_VOID_RETURN (); |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
# ------------------------------------------------ |
|
387
|
|
|
|
|
|
|
# Implements: keep => 1 or keep => \&test(). |
|
388
|
|
|
|
|
|
|
# ------------------------------------------------ |
|
389
|
43
|
|
|
|
|
90
|
my $toss_the_file; |
|
390
|
43
|
0
|
33
|
|
|
260
|
if ( $dbug_global_vars{keep} && $dbug_global_vars{file} ) { |
|
391
|
0
|
|
|
|
|
0
|
my $keep = ($? != 0); |
|
392
|
0
|
0
|
|
|
|
0
|
if ( ref ($dbug_global_vars{keep}) eq "CODE" ) { |
|
393
|
0
|
|
|
|
|
0
|
$keep = $dbug_global_vars{keep}->($?); |
|
394
|
|
|
|
|
|
|
} |
|
395
|
0
|
0
|
|
|
|
0
|
$toss_the_file = $dbug_global_vars{file} unless ( $keep ); |
|
396
|
|
|
|
|
|
|
} |
|
397
|
|
|
|
|
|
|
|
|
398
|
43
|
|
|
|
|
130
|
$dbug_global_vars{on} = 0; # Turn fish off. |
|
399
|
|
|
|
|
|
|
|
|
400
|
43
|
100
|
|
|
|
229
|
if ( $dbug_global_vars{can_close} ) { |
|
401
|
36
|
|
|
|
|
128
|
my $dbug_fh = $dbug_global_vars{fh}; |
|
402
|
36
|
|
|
|
|
848
|
close ( $dbug_fh ); |
|
403
|
|
|
|
|
|
|
} |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# Finishes: keep => ?. |
|
406
|
43
|
50
|
|
|
|
2224
|
unlink ( $toss_the_file ) if ( $toss_the_file ); |
|
407
|
|
|
|
|
|
|
} |
|
408
|
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
# -------------------------------- |
|
411
|
|
|
|
|
|
|
# Tells if you are in the required thread/process ... |
|
412
|
|
|
|
|
|
|
# Returns: |
|
413
|
|
|
|
|
|
|
# 1 - You are in the correct thread |
|
414
|
|
|
|
|
|
|
# 0 - You are in the wrong thread. |
|
415
|
|
|
|
|
|
|
# -------------------------------- |
|
416
|
|
|
|
|
|
|
sub _limit_thread_check |
|
417
|
|
|
|
|
|
|
{ |
|
418
|
18211
|
50
|
|
18211
|
|
70147
|
return (1) unless ( $dbug_global_vars{limit} ); |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
# Which thread/process are we in ... |
|
421
|
0
|
|
|
|
|
0
|
my $parent = 0; |
|
422
|
0
|
0
|
|
|
|
0
|
if ( $dbug_global_vars{PID} == $$ ) { |
|
423
|
0
|
0
|
|
|
|
0
|
my $tid = ( $threads_possible ) ? threads->tid () : 0; |
|
424
|
0
|
0
|
|
|
|
0
|
$parent = 1 if ( $tid == 0 ); |
|
425
|
|
|
|
|
|
|
} |
|
426
|
|
|
|
|
|
|
|
|
427
|
0
|
0
|
0
|
|
|
0
|
return (1) if ( $parent == 1 && $dbug_global_vars{limit} == 1 ); |
|
428
|
0
|
0
|
0
|
|
|
0
|
return (1) if ( $parent == 0 && $dbug_global_vars{limit} == -1 ); |
|
429
|
|
|
|
|
|
|
|
|
430
|
0
|
|
|
|
|
0
|
return (0); # In the wrong thread/process ... |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
# -------------------------------- |
|
434
|
|
|
|
|
|
|
# This function handles all printing to the fish logs. |
|
435
|
|
|
|
|
|
|
# Done this way so we don't have to call "or die" all over the place or check |
|
436
|
|
|
|
|
|
|
# if fish is active all the time or not. This slows the module down slightly |
|
437
|
|
|
|
|
|
|
# when fish is turned off, but makes the coding significantly simpler. |
|
438
|
|
|
|
|
|
|
# If formatted printing is desired, just use "sprintf" & then call this method! |
|
439
|
|
|
|
|
|
|
# Returns: |
|
440
|
|
|
|
|
|
|
# 0 - Nothing written to fish |
|
441
|
|
|
|
|
|
|
# 1 - Something was written to fish |
|
442
|
|
|
|
|
|
|
# Calls die if the write fails! |
|
443
|
|
|
|
|
|
|
# -------------------------------- |
|
444
|
|
|
|
|
|
|
sub _printing |
|
445
|
|
|
|
|
|
|
{ |
|
446
|
|
|
|
|
|
|
# Fish must be active to print anything ... |
|
447
|
9155
|
100
|
|
9155
|
|
17047
|
return (0) unless ( DBUG_ACTIVE () ); |
|
448
|
|
|
|
|
|
|
|
|
449
|
8777
|
|
|
|
|
31882
|
my $dbug_fh = $dbug_global_vars{fh}; |
|
450
|
|
|
|
|
|
|
|
|
451
|
8777
|
100
|
|
|
|
17213
|
if ( defined $dbug_fh ) { |
|
452
|
8752
|
50
|
|
|
|
310943
|
print $dbug_fh @_ or |
|
453
|
|
|
|
|
|
|
die ("Can't write the mesage to the fish file! $!\n"); |
|
454
|
|
|
|
|
|
|
} else { |
|
455
|
|
|
|
|
|
|
# Open, write, close the fish file ... doesn't return on error! |
|
456
|
25
|
|
|
|
|
57
|
_dbug_auto_open_printing (@_); |
|
457
|
|
|
|
|
|
|
} |
|
458
|
|
|
|
|
|
|
|
|
459
|
8777
|
|
|
|
|
28636
|
return (1); |
|
460
|
|
|
|
|
|
|
} |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# For inserting color directives into preformatted multi-line messages ... |
|
464
|
|
|
|
|
|
|
sub _printing_with_color |
|
465
|
|
|
|
|
|
|
{ |
|
466
|
111
|
|
|
111
|
|
218
|
my $lvl = shift; |
|
467
|
|
|
|
|
|
|
|
|
468
|
111
|
|
|
|
|
364
|
my @colors = _get_filter_color ( $lvl ); |
|
469
|
111
|
50
|
|
|
|
440
|
if ( $colors[0] eq "" ) { |
|
470
|
111
|
|
|
|
|
416
|
return ( _printing ( @_ ) ); # No color asked for. |
|
471
|
|
|
|
|
|
|
} |
|
472
|
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
# Join the rest of the arguments into a single message to parse! |
|
474
|
0
|
|
|
|
|
0
|
my $msg = join ("", @_); |
|
475
|
|
|
|
|
|
|
|
|
476
|
0
|
|
|
|
|
0
|
my $term = "-_"x100 . "-"; |
|
477
|
0
|
|
|
|
|
0
|
my @lines = split ( /\n/, $msg . $term ); |
|
478
|
|
|
|
|
|
|
|
|
479
|
0
|
|
|
|
|
0
|
my ($build, $sep) = ("", ""); |
|
480
|
0
|
|
|
|
|
0
|
my $final = $lines[-1]; |
|
481
|
|
|
|
|
|
|
|
|
482
|
0
|
|
|
|
|
0
|
foreach my $ln ( @lines ) { |
|
483
|
0
|
0
|
0
|
|
|
0
|
if ( (! defined $ln) || $ln eq $term || $ln =~ m/^\s*$/ ) { |
|
|
|
0
|
0
|
|
|
|
|
|
484
|
0
|
|
|
|
|
0
|
$build .= $sep; # Blank lines have no color! |
|
485
|
|
|
|
|
|
|
} elsif ( $ln eq $final ) { |
|
486
|
0
|
|
|
|
|
0
|
$ln =~ s/${term}$//; |
|
487
|
0
|
|
|
|
|
0
|
$build .= $sep . $colors[0] . $ln . $colors[1]; |
|
488
|
|
|
|
|
|
|
} else { |
|
489
|
0
|
|
|
|
|
0
|
$build .= $sep . $colors[0] . $ln . $colors[1]; |
|
490
|
|
|
|
|
|
|
} |
|
491
|
|
|
|
|
|
|
|
|
492
|
0
|
|
|
|
|
0
|
$sep = "\n"; |
|
493
|
|
|
|
|
|
|
} |
|
494
|
|
|
|
|
|
|
|
|
495
|
0
|
|
|
|
|
0
|
return ( _printing ( $build ) ); |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
# -------------------------------- |
|
499
|
|
|
|
|
|
|
# To handle printing for the auto-open option ... (very slow!) |
|
500
|
|
|
|
|
|
|
# Only called via _printing()! Never by anyone else! |
|
501
|
|
|
|
|
|
|
# -------------------------------- |
|
502
|
|
|
|
|
|
|
sub _dbug_auto_open_printing |
|
503
|
|
|
|
|
|
|
{ |
|
504
|
25
|
|
|
25
|
|
58
|
my $f = $dbug_global_vars{file}; |
|
505
|
25
|
50
|
|
|
|
57
|
unless ($f) { |
|
506
|
0
|
|
|
|
|
0
|
die ("No fish file name available for auto-reopen to use!\n"); |
|
507
|
|
|
|
|
|
|
} |
|
508
|
25
|
50
|
|
|
|
1417
|
open (REOPEN_FISH_FILE, ">>", $f) or |
|
509
|
|
|
|
|
|
|
die ("Can't reopen the FISH file: " . basename ($f) . " $!\n"); |
|
510
|
25
|
50
|
|
|
|
100
|
if ( $dbug_global_vars{allow_utf8} ) { |
|
511
|
0
|
|
|
|
|
0
|
binmode (REOPEN_FISH_FILE, "encoding(UTF-8)"); |
|
512
|
|
|
|
|
|
|
} |
|
513
|
|
|
|
|
|
|
|
|
514
|
25
|
50
|
|
|
|
310
|
print REOPEN_FISH_FILE @_ or |
|
515
|
|
|
|
|
|
|
die ("Can't write the mesage to the reopened fish file! $!\n"); |
|
516
|
25
|
|
|
|
|
1119
|
close (REOPEN_FISH_FILE); |
|
517
|
25
|
|
|
|
|
100
|
return (1); |
|
518
|
|
|
|
|
|
|
} |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
# -------------------------------- |
|
521
|
|
|
|
|
|
|
# These 2 private functions handle indenting each line written to fish! |
|
522
|
|
|
|
|
|
|
# It builds & returns the string to use to allow the caller to |
|
523
|
|
|
|
|
|
|
# combine calls to _printing(), just in case using the auto-reopen logic, |
|
524
|
|
|
|
|
|
|
# which is slow, slow, slow, ... |
|
525
|
|
|
|
|
|
|
# Or if multiple threads are writing to fish to make the calls atomic! |
|
526
|
|
|
|
|
|
|
# -------------------------------- |
|
527
|
|
|
|
|
|
|
sub _indent_multi |
|
528
|
|
|
|
|
|
|
{ |
|
529
|
15012
|
|
100
|
15012
|
|
45873
|
my $remove = shift || 0; |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
# A no-op if option multi wasn't used ... |
|
532
|
15012
|
100
|
|
|
|
41006
|
return ( "" ) unless ( $dbug_global_vars{multi} ); |
|
533
|
|
|
|
|
|
|
|
|
534
|
935
|
|
|
|
|
5550
|
my ($tid, $fid, $ind_str) = (-1, -1, ""); |
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
# Gives preference to logging threads over forks ... |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# Logging Threads ... |
|
539
|
935
|
50
|
|
|
|
3292
|
$tid = threads->tid () if ( $threads_possible ); |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# Logging Forks ... |
|
542
|
935
|
50
|
|
|
|
2084
|
if ( $fork_possible ) { |
|
543
|
935
|
100
|
|
|
|
6131
|
if ( $dbug_global_vars{PID} == $$ ) { |
|
544
|
611
|
50
|
|
|
|
1637
|
$fid = 0 if ( $tid == -1 ); |
|
545
|
|
|
|
|
|
|
} else { |
|
546
|
324
|
|
|
|
|
1409
|
my $id = ( abs ($$) % 100 ); |
|
547
|
324
|
50
|
|
|
|
990
|
$fid = ($id == 0) ? 100 : $id; |
|
548
|
324
|
50
|
|
|
|
980
|
$tid = -1 if ( $tid == 0 ); |
|
549
|
|
|
|
|
|
|
} |
|
550
|
|
|
|
|
|
|
} |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
# Build the line's prefix ... |
|
553
|
935
|
50
|
33
|
|
|
3526
|
if ( $tid != -1 && $fid != -1 ) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
# Both threads and forks ... |
|
555
|
0
|
|
|
|
|
0
|
$ind_str .= sprintf ( "%d/%02d-%d", $$, $fid, $tid ); |
|
556
|
|
|
|
|
|
|
} elsif ( $tid != -1 ) { |
|
557
|
|
|
|
|
|
|
# Threads only ... |
|
558
|
0
|
|
|
|
|
0
|
$ind_str .= sprintf ( "%d-%d", $$, $tid ); |
|
559
|
|
|
|
|
|
|
} elsif ( $fid != -1 ) { |
|
560
|
|
|
|
|
|
|
# Forks only ... |
|
561
|
935
|
|
|
|
|
5130
|
$ind_str .= sprintf ( "%d/%02d", $$, $fid ); |
|
562
|
|
|
|
|
|
|
} else { |
|
563
|
|
|
|
|
|
|
# Neither threads nor forks are supported ... |
|
564
|
0
|
|
|
|
|
0
|
$ind_str = $$; |
|
565
|
|
|
|
|
|
|
} |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
# Easier to not add it than remove it ... |
|
568
|
935
|
100
|
|
|
|
2465
|
$ind_str .= ":: " if ( $remove == 0 ); |
|
569
|
|
|
|
|
|
|
|
|
570
|
935
|
|
|
|
|
3046
|
return ( $ind_str ); |
|
571
|
|
|
|
|
|
|
} |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
# Determines how deep to indent each row ... |
|
575
|
|
|
|
|
|
|
sub _indent |
|
576
|
|
|
|
|
|
|
{ |
|
577
|
9006
|
|
50
|
9006
|
|
22446
|
my $label = shift || ""; |
|
578
|
|
|
|
|
|
|
|
|
579
|
9006
|
|
|
|
|
20163
|
my $ind_str = _indent_multi (); |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
# Building the indenting string ... "| | | | | ..." |
|
582
|
9006
|
|
|
|
|
14818
|
my $cnt = @{$dbug_global_vars{functions}}; |
|
|
9006
|
|
|
|
|
18061
|
|
|
583
|
9006
|
|
|
|
|
25854
|
$ind_str .= "| "x$cnt . $label; |
|
584
|
|
|
|
|
|
|
|
|
585
|
9006
|
|
|
|
|
23584
|
return ($ind_str); |
|
586
|
|
|
|
|
|
|
} |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
# ============================================================== |
|
590
|
|
|
|
|
|
|
# A helper function ... |
|
591
|
|
|
|
|
|
|
# Returns the number of evals on the stack + an array refernce containing |
|
592
|
|
|
|
|
|
|
# the line number each eval appears on. |
|
593
|
|
|
|
|
|
|
sub _eval_depth |
|
594
|
|
|
|
|
|
|
{ |
|
595
|
10805
|
|
50
|
10805
|
|
24902
|
my $base = shift || 0; # The caller() index to the code that called DBUG_... |
|
596
|
|
|
|
|
|
|
|
|
597
|
10805
|
|
|
|
|
17960
|
my @eval_lines; |
|
598
|
|
|
|
|
|
|
|
|
599
|
10805
|
|
|
|
|
16656
|
my $eval_lvl = 0; |
|
600
|
10805
|
|
|
|
|
64339
|
my ($c2, $ln2) = (caller ($base + $eval_lvl))[3,2]; |
|
601
|
10805
|
|
|
|
|
30709
|
while ( defined $c2 ) { |
|
602
|
52375
|
100
|
|
|
|
97753
|
if ( $c2 eq "(eval)" ) { |
|
603
|
5607
|
|
|
|
|
10175
|
++$eval_lvl; # Just count how deep in eval's we are! |
|
604
|
5607
|
|
|
|
|
11455
|
push (@eval_lines, $ln2); |
|
605
|
|
|
|
|
|
|
} else { |
|
606
|
46768
|
|
|
|
|
67454
|
++$base; # Wasn't an eval! |
|
607
|
|
|
|
|
|
|
} |
|
608
|
52375
|
|
|
|
|
208032
|
($c2, $ln2) = (caller ($base + $eval_lvl))[3,2]; |
|
609
|
|
|
|
|
|
|
} |
|
610
|
|
|
|
|
|
|
|
|
611
|
10805
|
50
|
|
|
|
36258
|
return ( wantarray ? ( $eval_lvl, \@eval_lines) : $eval_lvl ); |
|
612
|
|
|
|
|
|
|
} |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
# ============================================================== |
|
616
|
|
|
|
|
|
|
# A helper function for elapsed time ... |
|
617
|
|
|
|
|
|
|
sub _dbug_elapsed_time |
|
618
|
|
|
|
|
|
|
{ |
|
619
|
786
|
|
|
786
|
|
2245
|
my $start_clock = shift; |
|
620
|
|
|
|
|
|
|
|
|
621
|
786
|
100
|
|
|
|
4748
|
return ("") unless ( $dbug_global_vars{elapsed} ); |
|
622
|
14
|
50
|
|
|
|
34
|
return ("") unless ( defined $start_clock ); |
|
623
|
|
|
|
|
|
|
|
|
624
|
14
|
|
|
|
|
54
|
my $elapsed_time = time () - $start_clock; |
|
625
|
|
|
|
|
|
|
|
|
626
|
14
|
|
|
|
|
40
|
my $msg; |
|
627
|
14
|
50
|
|
|
|
31
|
if ( $time_hires_flag ) { |
|
628
|
14
|
|
|
|
|
146
|
$msg = sprintf (" -- Elapsed time: %0.6f second(s)", $elapsed_time); |
|
629
|
|
|
|
|
|
|
} else { |
|
630
|
0
|
|
|
|
|
0
|
$msg = sprintf (" -- Elapsed time: %d second(s)", $elapsed_time); |
|
631
|
|
|
|
|
|
|
} |
|
632
|
|
|
|
|
|
|
|
|
633
|
14
|
|
|
|
|
46
|
return ( $msg ); |
|
634
|
|
|
|
|
|
|
} |
|
635
|
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# ============================================================== |
|
637
|
|
|
|
|
|
|
# A helper function ... |
|
638
|
|
|
|
|
|
|
# This will never return a Fred::Fish::DBUG::ON funtion as the caller! |
|
639
|
|
|
|
|
|
|
# It will return who called the DBUG function instead! |
|
640
|
|
|
|
|
|
|
# So sometimes the caller looks a bit indirect! |
|
641
|
|
|
|
|
|
|
# Returns: " -- caller at file line 1234" |
|
642
|
|
|
|
|
|
|
# or: "caller at file line 1234" |
|
643
|
|
|
|
|
|
|
sub _dbug_called_by |
|
644
|
|
|
|
|
|
|
{ |
|
645
|
|
|
|
|
|
|
# Uncomment next 2 lines to demonstrate potential problem with t/*.t progs... |
|
646
|
|
|
|
|
|
|
# _dbug_auto_fix_eval_exception (); |
|
647
|
|
|
|
|
|
|
# _printing ("XXXX: Inside of _dbug_called_by(", join (", ", @_), ")\n"); |
|
648
|
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
# Only happens if called by any of the t/*.t program hacks as an object! |
|
650
|
447
|
100
|
66
|
447
|
|
2059
|
shift if ( defined $_[0] && $_[0] eq __PACKAGE__ ); |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
# The real arguments ... |
|
653
|
447
|
|
100
|
|
|
1240
|
my $no_prefix_flg = shift || 0; |
|
654
|
447
|
|
100
|
|
|
1388
|
my $dbug_enter_flg = shift || 0; # Called by DBUG_ENTER_FUNC() ? |
|
655
|
447
|
|
100
|
|
|
1333
|
my $anon_flag = shift || 0; # Ignored unless $dbug_enter_flg is true. |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
|
|
658
|
447
|
|
|
|
|
724
|
my $eval_caller = '(eval)'; |
|
659
|
447
|
|
|
|
|
708
|
my $pkg = __PACKAGE__ . '::'; |
|
660
|
447
|
|
|
|
|
2707
|
$pkg =~ s/::ON::$/::/; |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
# Start with who called me ... |
|
663
|
447
|
|
|
|
|
1103
|
my ($ind_by, $ind_call) = (1, 0); |
|
664
|
|
|
|
|
|
|
|
|
665
|
447
|
|
66
|
|
|
2870
|
my $by = (caller($ind_by))[3] || $dbug_global_vars{main}; |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
# Find caller of the 1st Fred::Fish::DBUG::ON entry point ... |
|
668
|
447
|
|
100
|
|
|
3937
|
while ( $by =~ m/^${pkg}/ || $by eq $eval_caller ) { |
|
669
|
952
|
100
|
|
|
|
3474
|
$ind_call = $ind_by if ( $by =~ m/^${pkg}/ ); |
|
670
|
952
|
|
66
|
|
|
6881
|
$by = (caller(++$ind_by))[3] || $dbug_global_vars{main}; |
|
671
|
|
|
|
|
|
|
} |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# Get the line number of where the calling function was called. |
|
674
|
|
|
|
|
|
|
# Only happens when called by DBUG_ENTER_FUNC() & it asked for it. |
|
675
|
|
|
|
|
|
|
# Will never return as the caller another DBUG function! |
|
676
|
447
|
100
|
66
|
|
|
1308
|
if ( $dbug_enter_flg && $by ne $dbug_global_vars{main} ) { |
|
677
|
55
|
|
|
|
|
88
|
$by = $pkg; # So I'll skip over the current function! |
|
678
|
|
|
|
|
|
|
|
|
679
|
55
|
|
100
|
|
|
249
|
while ( $by =~ m/^${pkg}/ || $by eq $eval_caller ) { |
|
680
|
96
|
100
|
|
|
|
311
|
$ind_call = $ind_by if ( $by =~ m/^${pkg}/ ); |
|
681
|
|
|
|
|
|
|
# ++$ind_call if ( $by ne $eval_caller ); |
|
682
|
96
|
|
66
|
|
|
586
|
$by = (caller(++$ind_by))[3] || $dbug_global_vars{main}; |
|
683
|
|
|
|
|
|
|
} |
|
684
|
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
# HACK: If called in a try/catch/finally block ... |
|
686
|
|
|
|
|
|
|
# Then was called with wrong arguments to this function! |
|
687
|
|
|
|
|
|
|
# So ask caller to try again with $dbug_enter_flg set to 0! |
|
688
|
55
|
100
|
|
|
|
103
|
if ( $anon_flag ) { |
|
689
|
2
|
50
|
|
|
|
6
|
return ("") if ( $by eq "Try::Tiny::try" ); |
|
690
|
2
|
50
|
|
|
|
4
|
return ("") if ( $by eq "Try::Tiny::ScopeGuard::DESTROY" ); |
|
691
|
2
|
50
|
|
|
|
4
|
return ("") if ( $by eq "Error::subs::try" ); |
|
692
|
|
|
|
|
|
|
} |
|
693
|
|
|
|
|
|
|
} |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
# Get file & line number ... |
|
696
|
447
|
|
|
|
|
1641
|
my @c = (caller($ind_call))[1,2]; |
|
697
|
|
|
|
|
|
|
|
|
698
|
447
|
100
|
|
|
|
1279
|
my $prefix = ($no_prefix_flg) ? "" : " -- "; |
|
699
|
447
|
|
|
|
|
756
|
my $line; |
|
700
|
447
|
50
|
|
|
|
1054
|
if ( $#c == -1 ) { |
|
701
|
0
|
|
|
|
|
0
|
$line = sprintf ("%s%s at ? line ?", $prefix, $by); # Can we fix? |
|
702
|
|
|
|
|
|
|
} else { |
|
703
|
447
|
|
|
|
|
1858
|
$line = sprintf ("%s%s at %s line %d", $prefix, $by, @c); |
|
704
|
|
|
|
|
|
|
} |
|
705
|
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
# (${ind_by} > ${ind_call}) is always true! Never equal! |
|
707
|
|
|
|
|
|
|
# $line .= " IDX: ${ind_by}, ${ind_call}"; |
|
708
|
|
|
|
|
|
|
|
|
709
|
447
|
|
|
|
|
1734
|
return ( $line ); |
|
710
|
|
|
|
|
|
|
} |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
# ============================================================== |
|
713
|
|
|
|
|
|
|
# Allows for a quick and dirty way to cheat this module without |
|
714
|
|
|
|
|
|
|
# giving you access to the underlying module configuration |
|
715
|
|
|
|
|
|
|
# variable %dbug_global_vars. |
|
716
|
|
|
|
|
|
|
# It tells which key(s) to temporarily override before calling |
|
717
|
|
|
|
|
|
|
# the requested function without having to worry about the |
|
718
|
|
|
|
|
|
|
# scope of the change. |
|
719
|
|
|
|
|
|
|
# Since not exposed, you don't have access to it by default and |
|
720
|
|
|
|
|
|
|
# can remain undocumentded in the POD. |
|
721
|
|
|
|
|
|
|
# For use by my helper modules and t/*.t programs only! |
|
722
|
|
|
|
|
|
|
# Also use internally by the Signal handling & TIE routines! |
|
723
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
724
|
|
|
|
|
|
|
# Usage: $res = Fred::Fish::DBUG::ON::_dbug_hack ( %opts, $func, @args); |
|
725
|
|
|
|
|
|
|
sub _dbug_hack |
|
726
|
|
|
|
|
|
|
{ |
|
727
|
894
|
|
|
894
|
|
1787
|
my $key = shift; |
|
728
|
894
|
|
|
|
|
1694
|
my $val = shift; |
|
729
|
894
|
|
|
|
|
1716
|
my $func = shift; # May be start of another key/val pair instead! |
|
730
|
|
|
|
|
|
|
# my @args = @_; |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
# Usage error ... no hash key provided. |
|
733
|
894
|
50
|
|
|
|
2371
|
rturn (undef) unless ( $key ); |
|
734
|
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# If undef, don't change the value ... |
|
736
|
894
|
100
|
|
|
|
2337
|
$val = $dbug_global_vars{$key} unless ( defined $val ); |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# ERROR: Can only replace with the same data type ... |
|
739
|
894
|
50
|
|
|
|
3031
|
return (undef) if ( ref ($val) ne ref ($dbug_global_vars{$key}) ); |
|
740
|
|
|
|
|
|
|
|
|
741
|
894
|
|
|
|
|
2348
|
local $dbug_global_vars{$key} = $val; |
|
742
|
|
|
|
|
|
|
|
|
743
|
894
|
100
|
66
|
|
|
4006
|
if ( $func && ref ($func) eq "CODE" ) { |
|
744
|
655
|
|
|
|
|
2118
|
return ( $func->( @_ ) ); |
|
745
|
|
|
|
|
|
|
} |
|
746
|
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
# Recursively add the next key/value pair ... |
|
748
|
239
|
|
|
|
|
719
|
return ( _dbug_hack ($func, @_) ); |
|
749
|
|
|
|
|
|
|
} |
|
750
|
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
752
|
|
|
|
|
|
|
# Get the requested entry in the global hash ... |
|
753
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
754
|
|
|
|
|
|
|
sub _get_global_var |
|
755
|
|
|
|
|
|
|
{ |
|
756
|
481
|
|
|
481
|
|
897
|
my $key = shift; |
|
757
|
481
|
|
|
|
|
2610
|
return ( $dbug_global_vars{$key} ); |
|
758
|
|
|
|
|
|
|
} |
|
759
|
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
761
|
|
|
|
|
|
|
# Permanently set the requested entry in the global hash ... |
|
762
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
763
|
|
|
|
|
|
|
sub _set_global_var |
|
764
|
|
|
|
|
|
|
{ |
|
765
|
292
|
|
|
292
|
|
558
|
my $key = shift; |
|
766
|
292
|
|
|
|
|
479
|
my $val = shift; |
|
767
|
292
|
|
|
|
|
612
|
$dbug_global_vars{$key} = $val; |
|
768
|
292
|
|
|
|
|
709
|
return; |
|
769
|
|
|
|
|
|
|
} |
|
770
|
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------ |
|
772
|
|
|
|
|
|
|
# DBUG Code |
|
773
|
|
|
|
|
|
|
# |
|
774
|
|
|
|
|
|
|
# I have tried to keep the functions in a meaningfull order, to make it |
|
775
|
|
|
|
|
|
|
# easier to learn how to use this module. |
|
776
|
|
|
|
|
|
|
# |
|
777
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------ |
|
778
|
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
=item DBUG_PUSH ( [$file [, %opts]] ) |
|
780
|
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
Calling this function turns logging on so that all future DBUG B calls are |
|
782
|
|
|
|
|
|
|
written to the requested file. Failure to call this function results in nothing |
|
783
|
|
|
|
|
|
|
being written to the B logs. Currently there is no way to turn B |
|
784
|
|
|
|
|
|
|
back off again except by aborting the program. But there are ways to turn |
|
785
|
|
|
|
|
|
|
some of the logging off. |
|
786
|
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
You are expected to provide a filename to write the fish logs to. If |
|
788
|
|
|
|
|
|
|
that file already exists, this function will recreate the B file and |
|
789
|
|
|
|
|
|
|
write as its first log message that this happened. By default, the B |
|
790
|
|
|
|
|
|
|
log's file permissions allow anyone to read the log file no matter the current |
|
791
|
|
|
|
|
|
|
I settings. |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
But if you fail to provide a filename, B will instead be written to |
|
794
|
|
|
|
|
|
|
I. You may also use an open file handle or I reference instead |
|
795
|
|
|
|
|
|
|
of a filename and B would be written there instead. |
|
796
|
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
The options hash may be passed by either reference or value. Either way works. |
|
798
|
|
|
|
|
|
|
Most options are ignored unless you also gave it a filename to open. |
|
799
|
|
|
|
|
|
|
Most option's value is a flag telling if it's turned on (1) or off (0), and |
|
800
|
|
|
|
|
|
|
most options default to off unless otherwise specified. The valid options are: |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=over 4 |
|
803
|
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
B - Open an old B log in append mode instead of creating a new |
|
805
|
|
|
|
|
|
|
one. |
|
806
|
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
B - Turn autoflush on/off. By default it's turned on! |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
B - Turn auto-open on/off. Causes each call to a B function to |
|
810
|
|
|
|
|
|
|
auto-reopen the B log, write out its message, and then close the B |
|
811
|
|
|
|
|
|
|
file again. |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
B - If set, treat as if I was never called! (IE: Fish is off.) |
|
814
|
|
|
|
|
|
|
It overrides all other options. |
|
815
|
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
B - See I for more details. |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
B - Suppress the B logging for the Perl B blocks. |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
B - Adds I to the end of the enter function |
|
821
|
|
|
|
|
|
|
block. So you can locate the code making the call. Also added to the end of |
|
822
|
|
|
|
|
|
|
I messages. |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
B - Turns on/off writing process ownership info to the start of each line |
|
825
|
|
|
|
|
|
|
of the B log. For multi-thread programs this is B-B. |
|
826
|
|
|
|
|
|
|
Ex: 252345-0 is the main process && 252345-4 is the 4th thread spawned by the |
|
827
|
|
|
|
|
|
|
process. But if it's a forked process it would be B/B<2-digits>. |
|
828
|
|
|
|
|
|
|
Ex: 252345/00 is the main process. And 536435/35 is one of its forked child |
|
829
|
|
|
|
|
|
|
processes. There are no sequential ids for forked processes, nor is the 2-digit |
|
830
|
|
|
|
|
|
|
code guaranteed to be unique. |
|
831
|
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
B - If your program is multi-threaded or muli-process, use this option to |
|
833
|
|
|
|
|
|
|
limit what gets written to B. B<1> - Limit B to the parent process. |
|
834
|
|
|
|
|
|
|
B<0> - Write everything (default). B<-1> - Limit B to the child processes. |
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
B - Override the default B file permissions. Default is B<0644>. |
|
837
|
|
|
|
|
|
|
It ignores the current I settings! |
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
B - Normally the 1st call to I is after the call to |
|
840
|
|
|
|
|
|
|
I, but set to B if you've already called it. But you will lose |
|
841
|
|
|
|
|
|
|
printing the function arguments if you do it this way. |
|
842
|
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
B - Strip off the module name for I and the various |
|
844
|
|
|
|
|
|
|
return methods. So I becomes I in B. |
|
845
|
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
B - Number of seconds to sleep after calling I in your code. |
|
847
|
|
|
|
|
|
|
The delay only happens if the write to B actually happens. |
|
848
|
|
|
|
|
|
|
If I is installed you can sleep for fractions of a second. But if |
|
849
|
|
|
|
|
|
|
it isn't installed your time will be truncated. IE: 0.5 becomes 0. |
|
850
|
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
B - Prints the elapsed time inside the function once any DBUG return |
|
852
|
|
|
|
|
|
|
function is called. If I is installed it tracks to fractions of a |
|
853
|
|
|
|
|
|
|
second. Otherwise it's whole seconds only. |
|
854
|
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
B - (1/0/code ref) - (1) Keep your B log only if your program exits |
|
856
|
|
|
|
|
|
|
with a non-zero exit status. (0) Always keep your B log (default). |
|
857
|
|
|
|
|
|
|
Otherwise it calls your function with the exit status as it's single argument. |
|
858
|
|
|
|
|
|
|
It's expected to return B<1> to keep the B log or B<0> to toss it. This |
|
859
|
|
|
|
|
|
|
code ref is only called if there is a B log to potentially remove. |
|
860
|
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
B - (1/0) - (0) Default, print variable reference addresses like |
|
862
|
|
|
|
|
|
|
S which change between runs. (1) Suppress addresses so shows |
|
863
|
|
|
|
|
|
|
up like S so it's easier to compare fish files between runs. Only |
|
864
|
|
|
|
|
|
|
works for arguments and return values. |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
B - Writes to B in UTF-8 mode. Use if you get warnings |
|
867
|
|
|
|
|
|
|
about writing S<'Wide character in print'> to B. |
|
868
|
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=back |
|
870
|
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=cut |
|
872
|
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
# ============================================================== |
|
874
|
|
|
|
|
|
|
sub DBUG_PUSH |
|
875
|
|
|
|
|
|
|
{ |
|
876
|
38
|
|
|
38
|
1
|
2599
|
my $file = shift; |
|
877
|
38
|
50
|
|
|
|
324
|
my $opts = (ref ($_[0]) eq "HASH") ? $_[0] : {@_}; |
|
878
|
|
|
|
|
|
|
|
|
879
|
38
|
50
|
|
|
|
220
|
if ( $dbug_global_vars{on} ) { |
|
880
|
0
|
|
|
|
|
0
|
warn "You may not call DBUG_PUSH() more than once!\n"; |
|
881
|
0
|
|
|
|
|
0
|
return; |
|
882
|
|
|
|
|
|
|
} |
|
883
|
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
# Check if eval needs rebalancing ... |
|
885
|
38
|
|
|
|
|
198
|
_dbug_auto_fix_eval_exception (); |
|
886
|
|
|
|
|
|
|
|
|
887
|
38
|
100
|
|
|
|
142
|
if ( $opts->{off} ) { |
|
888
|
|
|
|
|
|
|
# warn "You disabled fish, no fish logs are kept!\n"; |
|
889
|
1
|
|
|
|
|
2
|
return; |
|
890
|
|
|
|
|
|
|
} |
|
891
|
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
# DBUG_SET_FILTER_COLOR ( DBUG_FILTER_LEVEL_INTERNAL, "green" ); |
|
893
|
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
# Set all flags to a default value ... |
|
895
|
37
|
|
|
|
|
80
|
my @lst = @{$dbug_global_vars{functions}}; |
|
|
37
|
|
|
|
|
111
|
|
|
896
|
37
|
|
|
|
|
216
|
_init_frame ( \%dbug_global_vars, \@lst ); |
|
897
|
|
|
|
|
|
|
|
|
898
|
37
|
100
|
|
|
|
275
|
$dbug_global_vars{no_end} = 1 if ( $opts->{kill_end_trace} ); |
|
899
|
37
|
100
|
|
|
|
176
|
$dbug_global_vars{who_called} = 1 if ( $opts->{who_called} ); |
|
900
|
37
|
100
|
|
|
|
239
|
$dbug_global_vars{multi} = 1 if ( $opts->{multi} ); |
|
901
|
37
|
50
|
|
|
|
207
|
$dbug_global_vars{strip} = 1 if ( $opts->{strip} ); |
|
902
|
37
|
100
|
|
|
|
152
|
$dbug_global_vars{elapsed} = 1 if ( $opts->{elapsed} ); |
|
903
|
37
|
50
|
|
|
|
174
|
$dbug_global_vars{no_addresses} = 1 if ( $opts->{no_addresses} ); |
|
904
|
37
|
100
|
|
|
|
223
|
$dbug_global_vars{allow_utf8} = 1 if ( $opts->{allow_utf8} ); |
|
905
|
|
|
|
|
|
|
|
|
906
|
37
|
50
|
|
|
|
178
|
if ( $opts->{keep} ) { |
|
907
|
0
|
0
|
|
|
|
0
|
if ( ref ($opts->{keep}) eq "CODE" ) { |
|
908
|
0
|
|
|
|
|
0
|
$dbug_global_vars{keep} = $opts->{keep}; |
|
909
|
|
|
|
|
|
|
} else { |
|
910
|
0
|
|
|
|
|
0
|
$dbug_global_vars{keep} = 1; |
|
911
|
|
|
|
|
|
|
} |
|
912
|
|
|
|
|
|
|
} |
|
913
|
|
|
|
|
|
|
|
|
914
|
37
|
50
|
|
|
|
183
|
if ( $opts->{limit} ) { |
|
915
|
0
|
0
|
|
|
|
0
|
$dbug_global_vars{limit} = ( $opts->{limit} > 0 ) ? 1 : -1; |
|
916
|
|
|
|
|
|
|
} |
|
917
|
|
|
|
|
|
|
|
|
918
|
37
|
100
|
66
|
|
|
420
|
if ( $opts->{delay} && $opts->{delay} =~ m/(^\d+$)|(\d+\.\d+$)/ ) { |
|
|
|
50
|
|
|
|
|
|
|
919
|
1
|
|
|
|
|
4
|
$dbug_global_vars{delay} = $opts->{delay}; |
|
920
|
1
|
50
|
|
|
|
4
|
unless ( $time_hires_flag ) { |
|
921
|
0
|
0
|
|
|
|
0
|
if ( $dbug_global_vars{delay} =~ s/[.]\d+$// ) { |
|
922
|
|
|
|
|
|
|
warn ( "Time::HiRes isn't installed. Truncating delay to ", |
|
923
|
0
|
|
|
|
|
0
|
$dbug_global_vars{delay}, ".\n" ); |
|
924
|
|
|
|
|
|
|
} |
|
925
|
|
|
|
|
|
|
} |
|
926
|
|
|
|
|
|
|
} elsif ( $opts->{delay} ) { |
|
927
|
0
|
|
|
|
|
0
|
warn ( "Option 'delay' isn't numeric, so the delay request is ignored!\n" ); |
|
928
|
|
|
|
|
|
|
} |
|
929
|
|
|
|
|
|
|
|
|
930
|
37
|
|
|
|
|
259
|
DBUG_FILTER ($opts->{filter}); |
|
931
|
|
|
|
|
|
|
|
|
932
|
37
|
50
|
|
|
|
158
|
$file = \*STDERR unless ( defined $file ); |
|
933
|
|
|
|
|
|
|
|
|
934
|
37
|
50
|
|
|
|
156
|
if ( ref ($file) eq "GLOB" ) { |
|
935
|
0
|
0
|
0
|
|
|
0
|
if ( $file == \*STDERR || $file == \*STDOUT ) { |
|
936
|
0
|
|
|
|
|
0
|
$dbug_global_vars{screen} = 1; |
|
937
|
|
|
|
|
|
|
} |
|
938
|
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
# Enable writing to the open file handle by fish ... |
|
940
|
0
|
|
|
|
|
0
|
$dbug_global_vars{on} = 1; |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
# Provided an open file handle to write to ... |
|
943
|
0
|
|
|
|
|
0
|
$dbug_global_vars{fh} = $file; |
|
944
|
0
|
|
|
|
|
0
|
return; |
|
945
|
|
|
|
|
|
|
} |
|
946
|
|
|
|
|
|
|
|
|
947
|
37
|
50
|
|
|
|
151
|
if ( ref ($file) ne "" ) { |
|
948
|
0
|
|
|
|
|
0
|
die ("Unknown reference for a filename: " . ref($file) . "\n"); |
|
949
|
|
|
|
|
|
|
} |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
# Trim leading/trailing spaces from the file name. |
|
952
|
37
|
|
|
|
|
178
|
$file =~ s/^\s+//; |
|
953
|
37
|
|
|
|
|
128
|
$file =~ s/\s+$//; |
|
954
|
37
|
50
|
|
|
|
124
|
die ("The filename can't be all spaces!\n") if ( $file eq "" ); |
|
955
|
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
# Now let's acutally open up the file ... if we were given a name ... |
|
957
|
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
# Don't need to remember this option ... |
|
959
|
37
|
|
|
|
|
79
|
my $flush = 1; |
|
960
|
37
|
50
|
33
|
|
|
192
|
if ( exists $opts->{autoflush} && ! $opts->{autoflush} ) { |
|
961
|
0
|
|
|
|
|
0
|
$flush = 0; |
|
962
|
|
|
|
|
|
|
} |
|
963
|
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
# Get the old fish log file's age ... |
|
965
|
37
|
|
|
|
|
162
|
my ($age, $overwritten, $type, $mode) = (0, 0, "day(s)", ">"); |
|
966
|
37
|
50
|
|
|
|
2690
|
if ( -f $file ) { |
|
967
|
0
|
|
|
|
|
0
|
$age = -M _; |
|
968
|
0
|
0
|
|
|
|
0
|
if ( $age < 1 ) { |
|
969
|
0
|
|
|
|
|
0
|
$age *= 24; $type = "hour(s)"; |
|
|
0
|
|
|
|
|
0
|
|
|
970
|
0
|
0
|
|
|
|
0
|
if ( $age < 1 ) { |
|
971
|
0
|
|
|
|
|
0
|
$age *= 60; $type = "minute(s)"; |
|
|
0
|
|
|
|
|
0
|
|
|
972
|
0
|
0
|
|
|
|
0
|
if ( $age < 1 ) { |
|
973
|
0
|
|
|
|
|
0
|
$age *= 60; $type = "second(s)"; |
|
|
0
|
|
|
|
|
0
|
|
|
974
|
|
|
|
|
|
|
} |
|
975
|
|
|
|
|
|
|
} |
|
976
|
|
|
|
|
|
|
} |
|
977
|
|
|
|
|
|
|
|
|
978
|
0
|
0
|
|
|
|
0
|
if ( $opts->{append} ) { |
|
979
|
0
|
|
|
|
|
0
|
$mode = ">>"; |
|
980
|
|
|
|
|
|
|
} else { |
|
981
|
0
|
|
|
|
|
0
|
$overwritten = 1; |
|
982
|
0
|
|
|
|
|
0
|
unlink ( $file ); |
|
983
|
|
|
|
|
|
|
} |
|
984
|
|
|
|
|
|
|
} |
|
985
|
|
|
|
|
|
|
|
|
986
|
37
|
50
|
|
|
|
7305
|
open ( FISH_FILE, $mode, $file ) or |
|
987
|
|
|
|
|
|
|
die ("Can't open the fish file for writing: $file ($!)\n"); |
|
988
|
37
|
50
|
|
|
|
1132
|
FISH_FILE->autoflush (1) if ( $flush ); |
|
989
|
37
|
100
|
|
|
|
2608
|
if ( $dbug_global_vars{allow_utf8} ) { |
|
990
|
1
|
|
|
1
|
|
24
|
binmode (FISH_FILE, "encoding(UTF-8)"); |
|
|
1
|
|
|
|
|
636
|
|
|
|
1
|
|
|
|
|
13
|
|
|
|
1
|
|
|
|
|
33
|
|
|
991
|
|
|
|
|
|
|
} |
|
992
|
37
|
|
|
|
|
15785
|
$dbug_global_vars{fh} = \*FISH_FILE; |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
# If we're going to auto-open/close the file, we need to always have |
|
995
|
|
|
|
|
|
|
# a full absolute path name to the file instead of a relatve file name! |
|
996
|
|
|
|
|
|
|
# Just in case the program changes directories on us! |
|
997
|
|
|
|
|
|
|
# On Windows, this file must always exists for this to work! |
|
998
|
37
|
|
|
|
|
1777
|
$dbug_global_vars{file} = abs_path ($file); |
|
999
|
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
# Allow writing to the fish log ... |
|
1001
|
|
|
|
|
|
|
# Must set only after the fish log has been opened! |
|
1002
|
37
|
|
|
|
|
120
|
$dbug_global_vars{on} = 1; |
|
1003
|
|
|
|
|
|
|
|
|
1004
|
37
|
50
|
|
|
|
331
|
if ( $overwritten ) { |
|
|
|
50
|
|
|
|
|
|
|
1005
|
0
|
|
|
|
|
0
|
my $fmt = " *** Overwrote a previous fish file of the same name. ***\n" |
|
1006
|
|
|
|
|
|
|
. " *** Previous file was last written to %0.3f %s ago. ***\n\n"; |
|
1007
|
0
|
|
|
|
|
0
|
_printing_with_color ( DBUG_FILTER_LEVEL_INTERNAL, |
|
1008
|
|
|
|
|
|
|
sprintf ( $fmt, $age, $type ) ); |
|
1009
|
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
} elsif ( $mode eq ">>" ) { |
|
1011
|
0
|
0
|
|
|
|
0
|
my $id = $dbug_global_vars{multi} ? _indent_multi (1) : $$; |
|
1012
|
|
|
|
|
|
|
|
|
1013
|
0
|
|
|
|
|
0
|
my $msg = "\n" . "="x70 . |
|
1014
|
|
|
|
|
|
|
"\n*** Appending to a pre-existing fish log. PID ($id)\n"; |
|
1015
|
0
|
|
|
|
|
0
|
$msg .= sprintf ("*** The log was last written to %0.3f %s ago.\n", $age, $type); |
|
1016
|
0
|
|
|
|
|
0
|
$msg .= "="x70 . "\n\n"; |
|
1017
|
0
|
|
|
|
|
0
|
_printing_with_color ( DBUG_FILTER_LEVEL_INTERNAL, $msg ); |
|
1018
|
|
|
|
|
|
|
} |
|
1019
|
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
# Print out the CPAN support info to FISH ... |
|
1021
|
37
|
|
|
|
|
348
|
_printing_with_color ( DBUG_FILTER_LEVEL_INTERNAL, |
|
1022
|
|
|
|
|
|
|
sprintf ("%s %s\n", __PACKAGE__, $VERSION) ); |
|
1023
|
37
|
|
|
|
|
143
|
_printing_with_color ( DBUG_FILTER_LEVEL_INTERNAL, $dbug_log_msg ); |
|
1024
|
37
|
|
|
|
|
154
|
_printing "\n"; |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
# ------------------------------------------------------------------ |
|
1027
|
|
|
|
|
|
|
# Tells what options were selected for generating the fish file ... |
|
1028
|
|
|
|
|
|
|
# ------------------------------------------------------------------ |
|
1029
|
37
|
|
|
|
|
90
|
my $opts_prefix = "DBUG_PUSH Options: "; |
|
1030
|
37
|
|
|
|
|
181
|
my ($opts_str, $sep) = ("", ""); |
|
1031
|
37
|
|
|
|
|
227
|
foreach my $k ( sort keys %{$opts} ) { |
|
|
37
|
|
|
|
|
261
|
|
|
1032
|
62
|
|
|
|
|
131
|
my $str; |
|
1033
|
62
|
50
|
33
|
|
|
307
|
if ( $k eq "chmod" && defined $opts->{chmod} ) { |
|
1034
|
0
|
|
|
|
|
0
|
$str = sprintf ("%s => 0%o", $k, $opts->{$k}); |
|
1035
|
|
|
|
|
|
|
} else { |
|
1036
|
62
|
|
|
|
|
236
|
$str = sprintf ("%s => %s", $k, $opts->{$k}); |
|
1037
|
|
|
|
|
|
|
} |
|
1038
|
62
|
|
|
|
|
179
|
$opts_str .= ${sep} . ${str}; |
|
1039
|
62
|
|
|
|
|
186
|
$sep = ", "; |
|
1040
|
|
|
|
|
|
|
} |
|
1041
|
37
|
100
|
|
|
|
192
|
if ( $opts_str eq "" ) { |
|
1042
|
4
|
|
|
|
|
12
|
$opts_str = ${opts_prefix} . "\n\n"; |
|
1043
|
|
|
|
|
|
|
} else { |
|
1044
|
33
|
|
|
|
|
99
|
$opts_str = ${opts_prefix} . ${opts_str} . "\n\n"; |
|
1045
|
|
|
|
|
|
|
} |
|
1046
|
37
|
|
|
|
|
256
|
_printing_with_color ( DBUG_FILTER_LEVEL_INTERNAL, _indent ($opts_str) ); |
|
1047
|
|
|
|
|
|
|
# ------------------------------------------------------------------ |
|
1048
|
|
|
|
|
|
|
|
|
1049
|
37
|
50
|
|
|
|
185
|
if ( defined $opts->{chmod} ) { |
|
1050
|
0
|
|
|
|
|
0
|
chmod (oct ($opts->{chmod}), $file); |
|
1051
|
|
|
|
|
|
|
} else { |
|
1052
|
37
|
|
|
|
|
1661
|
chmod (0644, $file); # So it's always -rw-r--r--. |
|
1053
|
|
|
|
|
|
|
} |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
37
|
100
|
|
|
|
228
|
if ( $opts->{autoopen} ) { |
|
1056
|
1
|
|
|
|
|
12
|
close (FISH_FILE); |
|
1057
|
1
|
|
|
|
|
4
|
$dbug_global_vars{fh} = undef; |
|
1058
|
|
|
|
|
|
|
} else { |
|
1059
|
36
|
|
|
|
|
119
|
$dbug_global_vars{can_close} = 1; |
|
1060
|
|
|
|
|
|
|
} |
|
1061
|
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
# Check if we have to print the previous function declaration ... |
|
1063
|
|
|
|
|
|
|
# We've lost the arguments if this option was used! |
|
1064
|
|
|
|
|
|
|
# We've also lost the start time if asked for! |
|
1065
|
37
|
50
|
33
|
|
|
280
|
if ( $opts->{before} && $#lst != -1 ) { |
|
1066
|
0
|
|
|
|
|
0
|
my $block = pop ( @{$dbug_global_vars{functions}} ); |
|
|
0
|
|
|
|
|
0
|
|
|
1067
|
0
|
|
|
|
|
0
|
my $func = $block->{NAME}; |
|
1068
|
0
|
|
|
|
|
0
|
my $line = $block->{LINE}; |
|
1069
|
0
|
|
|
|
|
0
|
_printing ( $block->{COLOR1}, _indent (">${func}${line}"), $block->{COLOR2}, "\n"); |
|
1070
|
0
|
|
|
|
|
0
|
push ( @{$dbug_global_vars{functions}}, $block ); |
|
|
0
|
|
|
|
|
0
|
|
|
1071
|
|
|
|
|
|
|
} |
|
1072
|
|
|
|
|
|
|
|
|
1073
|
37
|
|
|
|
|
276
|
return; |
|
1074
|
|
|
|
|
|
|
} |
|
1075
|
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
=item DBUG_POP ( ) |
|
1078
|
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
Not yet implemented. |
|
1080
|
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
=cut |
|
1082
|
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
# ============================================================== |
|
1084
|
|
|
|
|
|
|
sub DBUG_POP |
|
1085
|
|
|
|
|
|
|
{ |
|
1086
|
0
|
|
|
0
|
1
|
0
|
warn "DBUG_POP() is currently a NO-OP!\n"; |
|
1087
|
|
|
|
|
|
|
} |
|
1088
|
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
=item DBUG_ENTER_FUNC ( [@arguments] ) |
|
1091
|
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
Its expected to be called whenever you enter a function. You pass all the |
|
1093
|
|
|
|
|
|
|
arguments from the calling function to this one (B<@_>). It automatically |
|
1094
|
|
|
|
|
|
|
knows the calling function without having to be told what it is. |
|
1095
|
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
To keep things in the B logs balanced, it expects you to call one of the |
|
1097
|
|
|
|
|
|
|
I variant methods when exiting your function! |
|
1098
|
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
This function also works when called inside named blocks such as B blocks |
|
1100
|
|
|
|
|
|
|
or even try/catch blocks. |
|
1101
|
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
It returns the name of the calling function. In rare cases this name can be |
|
1103
|
|
|
|
|
|
|
useful. |
|
1104
|
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
See I should you need to mask any arguments! |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
=cut |
|
1108
|
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
# ============================================================== |
|
1110
|
|
|
|
|
|
|
sub DBUG_ENTER_FUNC |
|
1111
|
|
|
|
|
|
|
{ |
|
1112
|
|
|
|
|
|
|
# Who called this function ... |
|
1113
|
1027
|
|
66
|
1027
|
1
|
7940711
|
my $func = (caller (1))[3] || $dbug_global_vars{main}; |
|
1114
|
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
# Check if eval needs rebalancing ... |
|
1116
|
1027
|
|
|
|
|
5780
|
_dbug_auto_fix_eval_exception (); |
|
1117
|
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
# Count how deep in eval blocks we are so DBUG_CATCH can work! |
|
1119
|
1027
|
|
|
|
|
2416
|
my ($eval_cnt, $eval_lns) = _eval_depth (1); |
|
1120
|
1027
|
|
|
|
|
2027
|
my $eval_flg = 0; |
|
1121
|
1027
|
100
|
|
|
|
2575
|
if ( $func eq "(eval)" ) { |
|
1122
|
35
|
|
|
|
|
133
|
$func .=" [${eval_cnt}, " . $eval_lns->[0] . "]"; |
|
1123
|
35
|
|
|
|
|
87
|
$eval_flg = 1; |
|
1124
|
|
|
|
|
|
|
} |
|
1125
|
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
# This special function traps calls to undefined functions. |
|
1127
|
|
|
|
|
|
|
# So we want to know what the user was really calling by |
|
1128
|
|
|
|
|
|
|
# referencing the special variable named after the function! |
|
1129
|
1027
|
100
|
|
|
|
3893
|
if ( $func =~ m/::AUTOLOAD$/ ) { |
|
1130
|
43
|
|
|
43
|
|
447
|
no strict; # So can indirectly access the variable as a ref. |
|
|
43
|
|
|
|
|
105
|
|
|
|
43
|
|
|
|
|
405945
|
|
|
1131
|
8
|
|
|
|
|
9
|
my $aka = ${$func}; |
|
|
8
|
|
|
|
|
23
|
|
|
1132
|
8
|
50
|
33
|
|
|
26
|
$aka = $1 if ( $dbug_global_vars{strip} && $aka =~ m/::([^:]+)$/ ); |
|
1133
|
8
|
|
|
|
|
17
|
$func .= " "; |
|
1134
|
|
|
|
|
|
|
} |
|
1135
|
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
# Do we need to know who called ${func} at this time ??? |
|
1137
|
1027
|
|
|
|
|
2414
|
my $line=""; |
|
1138
|
1027
|
100
|
100
|
|
|
3407
|
if ( $dbug_global_vars{who_called} && $func ne $dbug_global_vars{main} ) { |
|
1139
|
|
|
|
|
|
|
# Special functions where there are no valid callers ... |
|
1140
|
71
|
100
|
66
|
|
|
837
|
if ( $eval_flg || $func =~ m/::END$/ || $func =~ m/::BEGIN$/ || |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
$func =~ m/::UNITCHECK$/ || $func =~ m/::CHECK$/ || $func =~ m/::INIT$/ || |
|
1142
|
|
|
|
|
|
|
$func =~ m/::DESTROY$/ ) { |
|
1143
|
15
|
|
|
|
|
35
|
$line = _dbug_called_by (0, 0, 0); |
|
1144
|
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
# When Try::Tiny renames the __ANON__ function to ... "YourModule::xxx {...}" |
|
1146
|
|
|
|
|
|
|
# It doesn't always do this ... |
|
1147
|
|
|
|
|
|
|
} elsif ( $func =~ m/::try [{][.]{3}[}]\s*$/ || |
|
1148
|
|
|
|
|
|
|
$func =~ m/::catch [{][.]{3}[}]\s*$/ || |
|
1149
|
|
|
|
|
|
|
$func =~ m/::finally [{][.]{3}[}]\s*$/ ) { |
|
1150
|
3
|
|
|
|
|
6
|
$line = _dbug_called_by (0, 0, 0); |
|
1151
|
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
# Want who called the logged function, not who called DBUG_ENTER_FUNC ... |
|
1153
|
|
|
|
|
|
|
} else { |
|
1154
|
53
|
|
|
|
|
98
|
my $may_be_a_try_catch_finally_event = ( $func =~ m/::__ANON__$/ ); |
|
1155
|
53
|
|
|
|
|
102
|
$line = _dbug_called_by (0, 1, $may_be_a_try_catch_finally_event); |
|
1156
|
53
|
50
|
|
|
|
115
|
$line = _dbug_called_by (0, 0, 0) unless ( $line ); |
|
1157
|
|
|
|
|
|
|
} |
|
1158
|
|
|
|
|
|
|
} |
|
1159
|
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
# Put a blank line before all END blocks ... |
|
1161
|
1027
|
100
|
|
|
|
4035
|
my $skip = ( $func =~ m/::END$/ ) ? "\n" : ""; |
|
1162
|
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
# Strip off any module info from the calling function's name? |
|
1164
|
1027
|
50
|
33
|
|
|
3192
|
$func = $1 if ( $dbug_global_vars{strip} && $func =~ m/::([^:]+)$/ ); |
|
1165
|
|
|
|
|
|
|
|
|
1166
|
1027
|
|
|
|
|
3343
|
my @colors = _get_filter_color (DBUG_FILTER_LEVEL_FUNC); |
|
1167
|
1027
|
100
|
|
|
|
2617
|
if ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
1168
|
948
|
|
|
|
|
3909
|
_printing ( $skip, $colors[0], _indent (">${func}${line}"), $colors[1], "\n"); |
|
1169
|
|
|
|
|
|
|
} |
|
1170
|
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
my %block = ( NAME => $func, |
|
1172
|
|
|
|
|
|
|
PAUSED => $dbug_global_vars{pause}, |
|
1173
|
1027
|
|
|
|
|
12340
|
EVAL => $eval_cnt, |
|
1174
|
|
|
|
|
|
|
EVAL_LN => $eval_lns->[0], |
|
1175
|
|
|
|
|
|
|
LINE => $line, |
|
1176
|
|
|
|
|
|
|
FUNC => 1, |
|
1177
|
|
|
|
|
|
|
COLOR1 => $colors[0], |
|
1178
|
|
|
|
|
|
|
COLOR2 => $colors[1] ); |
|
1179
|
1027
|
100
|
|
|
|
3066
|
$block{TIME} = time () if ( $dbug_global_vars{elapsed} ); |
|
1180
|
1027
|
100
|
|
|
|
2628
|
$block{MULTI} = _indent_multi (1) if ( $dbug_global_vars{multi} ); |
|
1181
|
|
|
|
|
|
|
|
|
1182
|
1027
|
|
|
|
|
1971
|
push ( @{$dbug_global_vars{functions}}, \%block ); |
|
|
1027
|
|
|
|
|
2836
|
|
|
1183
|
|
|
|
|
|
|
|
|
1184
|
1027
|
|
|
|
|
3741
|
_dbug_args ( @_ ); |
|
1185
|
|
|
|
|
|
|
|
|
1186
|
1027
|
|
|
|
|
4812
|
return ( $func ); |
|
1187
|
|
|
|
|
|
|
} |
|
1188
|
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
# Helper method to DBUG_ENTER_FUNC & DBUG_ENTER_BLOCK! |
|
1191
|
|
|
|
|
|
|
# Called almost as frequently as DBUG_PRINT ... |
|
1192
|
|
|
|
|
|
|
sub _dbug_args |
|
1193
|
|
|
|
|
|
|
{ |
|
1194
|
2017
|
|
|
2017
|
|
5028
|
my @args = @_; |
|
1195
|
|
|
|
|
|
|
|
|
1196
|
2017
|
|
|
|
|
4509
|
$dbug_global_vars{mask_last_argument_count} = 0; |
|
1197
|
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
# If nothing to write to fish ... |
|
1199
|
2017
|
100
|
|
|
|
5767
|
if ( $#args == -1 ) { |
|
|
|
100
|
|
|
|
|
|
|
1200
|
1369
|
|
|
|
|
2604
|
delete $dbug_global_vars{mask_func_call}; |
|
1201
|
1369
|
|
|
|
|
2873
|
return; |
|
1202
|
|
|
|
|
|
|
} elsif ( DBUG_EXECUTE ("args") == 0 ) { |
|
1203
|
104
|
50
|
|
|
|
303
|
if ( exists $dbug_global_vars{mask_func_call} ) { |
|
1204
|
0
|
|
|
|
|
0
|
$dbug_global_vars{mask_last_argument_count} = -1; |
|
1205
|
0
|
|
|
|
|
0
|
delete $dbug_global_vars{mask_func_call}; |
|
1206
|
|
|
|
|
|
|
} |
|
1207
|
104
|
|
|
|
|
224
|
return; |
|
1208
|
|
|
|
|
|
|
} |
|
1209
|
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
# Optionally mask your function arguments ... |
|
1211
|
544
|
100
|
|
|
|
3106
|
if ( exists $dbug_global_vars{mask_func_call} ) { |
|
1212
|
7
|
|
|
|
|
18
|
my $mask = $dbug_global_vars{mask_func_call}; |
|
1213
|
7
|
100
|
|
|
|
27
|
if ( $mask->{ALL} ) { |
|
1214
|
1
|
|
|
|
|
5
|
foreach (0..$#args) { |
|
1215
|
4
|
|
|
|
|
8
|
$args[$_] = MASKING_VALUE; |
|
1216
|
4
|
|
|
|
|
8
|
++$dbug_global_vars{mask_last_argument_count}; |
|
1217
|
|
|
|
|
|
|
} |
|
1218
|
|
|
|
|
|
|
} |
|
1219
|
7
|
100
|
|
|
|
26
|
if ( $mask->{ARRAY} ) { |
|
1220
|
4
|
|
|
|
|
11
|
foreach ( @{$mask->{ARRAY}} ) { |
|
|
4
|
|
|
|
|
17
|
|
|
1221
|
9
|
100
|
|
|
|
31
|
if ( $_ <= $#args ) { |
|
1222
|
5
|
|
|
|
|
33
|
$args[$_] = MASKING_VALUE; |
|
1223
|
5
|
|
|
|
|
16
|
++$dbug_global_vars{mask_last_argument_count}; |
|
1224
|
|
|
|
|
|
|
} |
|
1225
|
|
|
|
|
|
|
} |
|
1226
|
|
|
|
|
|
|
} |
|
1227
|
7
|
100
|
|
|
|
30
|
if ( $mask->{HASH} ) { |
|
1228
|
2
|
|
|
|
|
6
|
my $mask_flag = 0; |
|
1229
|
2
|
|
|
|
|
10
|
foreach (0..$#args) { |
|
1230
|
18
|
100
|
|
|
|
37
|
if ( $mask_flag ) { |
|
1231
|
3
|
|
|
|
|
126
|
$args[$_] = MASKING_VALUE; |
|
1232
|
3
|
|
|
|
|
10
|
$mask_flag = 0; |
|
1233
|
3
|
|
|
|
|
9
|
++$dbug_global_vars{mask_last_argument_count}; |
|
1234
|
|
|
|
|
|
|
} else { |
|
1235
|
15
|
|
|
|
|
33
|
my $k = lc ($args[$_]); # All keys are in lower case. |
|
1236
|
15
|
100
|
|
|
|
42
|
$mask_flag = 1 if ( exists $mask->{HASH}->{$k} ); |
|
1237
|
|
|
|
|
|
|
} |
|
1238
|
|
|
|
|
|
|
} |
|
1239
|
|
|
|
|
|
|
} |
|
1240
|
7
|
|
|
|
|
34
|
delete $dbug_global_vars{mask_func_call}; |
|
1241
|
|
|
|
|
|
|
} |
|
1242
|
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
# Convert any code refs into it's function name ... |
|
1244
|
544
|
|
|
|
|
2335
|
foreach (0..$#args) { |
|
1245
|
1272
|
100
|
|
|
|
4229
|
if ( ref ( $args[$_] ) eq "CODE" ) { |
|
1246
|
84
|
|
|
|
|
994
|
my $f = sub_fullname ( $args[$_] ); |
|
1247
|
84
|
50
|
33
|
|
|
1419
|
$f = $1 if ( $dbug_global_vars{strip} && $f =~ m/::([^:]+)$/ ); |
|
1248
|
84
|
|
|
|
|
297
|
$args[$_] = '\&' . $f; |
|
1249
|
|
|
|
|
|
|
} |
|
1250
|
|
|
|
|
|
|
} |
|
1251
|
|
|
|
|
|
|
|
|
1252
|
544
|
50
|
|
|
|
1595
|
if ( $dbug_global_vars{no_addresses} ) { |
|
1253
|
0
|
|
|
|
|
0
|
my $i = 0; |
|
1254
|
0
|
|
|
|
|
0
|
foreach (0..$#args) { |
|
1255
|
0
|
0
|
|
|
|
0
|
if ( ref ( $args[$_] ) ne "" ) { |
|
1256
|
0
|
|
|
|
|
0
|
$args[$_] = sprintf ("%s(%03d)", ref ( $args[$_] ), ++$i); |
|
1257
|
|
|
|
|
|
|
} |
|
1258
|
|
|
|
|
|
|
} |
|
1259
|
|
|
|
|
|
|
} |
|
1260
|
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
# Now format the arugment list you need to print out ... |
|
1262
|
544
|
|
|
|
|
1740
|
my ($sep, $msg) = ("", ""); |
|
1263
|
544
|
|
|
|
|
1366
|
foreach (0..$#args) { |
|
1264
|
1272
|
50
|
|
|
|
3212
|
my $val = (defined $args[$_]) ? $args[$_] : UNDEF_VALUE; |
|
1265
|
|
|
|
|
|
|
|
|
1266
|
1272
|
|
|
|
|
3988
|
$msg .= $sep . "[${val}]"; |
|
1267
|
1272
|
|
|
|
|
2629
|
$sep = ", "; |
|
1268
|
|
|
|
|
|
|
} |
|
1269
|
|
|
|
|
|
|
|
|
1270
|
544
|
|
|
|
|
1882
|
_dbug_print_no_delay_or_caller ("args", $msg); |
|
1271
|
|
|
|
|
|
|
|
|
1272
|
544
|
|
|
|
|
1572
|
return; |
|
1273
|
|
|
|
|
|
|
} |
|
1274
|
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
=item DBUG_ENTER_BLOCK ( $name[, @arguments] ) |
|
1277
|
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
Similar to I except that it deals with I blocks of |
|
1279
|
|
|
|
|
|
|
code. Or if you wish to call a particular function a different name in the |
|
1280
|
|
|
|
|
|
|
B logs. |
|
1281
|
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
It usually expects you to call I when the block goes out of |
|
1283
|
|
|
|
|
|
|
scope to keep the B logs balanced. But nothing prevents you from using |
|
1284
|
|
|
|
|
|
|
one of the other return variants instead. |
|
1285
|
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
It returns the name of the code block you used. In rare cases this name can |
|
1287
|
|
|
|
|
|
|
be useful. |
|
1288
|
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
=cut |
|
1290
|
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
# ============================================================== |
|
1292
|
|
|
|
|
|
|
sub DBUG_ENTER_BLOCK |
|
1293
|
|
|
|
|
|
|
{ |
|
1294
|
990
|
|
|
990
|
1
|
176162
|
my $block_name = shift; |
|
1295
|
|
|
|
|
|
|
|
|
1296
|
990
|
50
|
|
|
|
2547
|
$block_name = "[undef]" unless ( defined $block_name ); |
|
1297
|
|
|
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
# Strip off any module info from the passed block name? |
|
1299
|
990
|
50
|
33
|
|
|
2996
|
$block_name = $1 if ( $dbug_global_vars{strip} && $block_name =~ m/::([^:]+)$/ ); |
|
1300
|
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
# Determine if the caller info is needed at this point. |
|
1302
|
990
|
|
|
|
|
1852
|
my $line=""; |
|
1303
|
990
|
100
|
|
|
|
2362
|
if ( $dbug_global_vars{who_called} ) { |
|
1304
|
7
|
|
|
|
|
12
|
$line = _dbug_called_by (0); |
|
1305
|
|
|
|
|
|
|
} |
|
1306
|
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
# Check if eval needs rebalancing ... |
|
1308
|
990
|
|
|
|
|
2832
|
_dbug_auto_fix_eval_exception (); |
|
1309
|
|
|
|
|
|
|
|
|
1310
|
990
|
|
|
|
|
2703
|
my @colors = _get_filter_color (DBUG_FILTER_LEVEL_FUNC); |
|
1311
|
990
|
100
|
|
|
|
2293
|
if ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
1312
|
317
|
|
|
|
|
1293
|
_printing ( $colors[0], _indent (">>${block_name}${line}"), $colors[1], "\n"); |
|
1313
|
|
|
|
|
|
|
} |
|
1314
|
|
|
|
|
|
|
|
|
1315
|
990
|
|
|
|
|
2664
|
my ($eval_dp, $eval_lns) = _eval_depth (1); |
|
1316
|
|
|
|
|
|
|
my %block = ( NAME => $block_name, |
|
1317
|
|
|
|
|
|
|
PAUSED => $dbug_global_vars{pause}, |
|
1318
|
990
|
|
|
|
|
10029
|
EVAL => $eval_dp, |
|
1319
|
|
|
|
|
|
|
EVAL_LN => $eval_lns->[0], |
|
1320
|
|
|
|
|
|
|
LINE => $line, |
|
1321
|
|
|
|
|
|
|
FUNC => 0, |
|
1322
|
|
|
|
|
|
|
COLOR1 => $colors[0], |
|
1323
|
|
|
|
|
|
|
COLOR2 => $colors[1] ); |
|
1324
|
990
|
50
|
|
|
|
2827
|
$block{TIME} = time () if ( $dbug_global_vars{elapsed} ); |
|
1325
|
990
|
50
|
|
|
|
2602
|
$block{MULTI} = _indent_multi (1) if ( $dbug_global_vars{multi} ); |
|
1326
|
|
|
|
|
|
|
|
|
1327
|
990
|
|
|
|
|
1841
|
push ( @{$dbug_global_vars{functions}}, \%block ); |
|
|
990
|
|
|
|
|
2926
|
|
|
1328
|
|
|
|
|
|
|
|
|
1329
|
990
|
|
|
|
|
3294
|
_dbug_args ( @_ ); |
|
1330
|
|
|
|
|
|
|
|
|
1331
|
990
|
|
|
|
|
4461
|
return ( $block_name ); |
|
1332
|
|
|
|
|
|
|
} |
|
1333
|
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
=item DBUG_PRINT ( $tag, $fmt [, $val1 [, $val2 [, ...]]] ) |
|
1336
|
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
This function writes the requested message to the active B log. |
|
1338
|
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
The B<$tag> argument is a text identifier that will be used to 'tag' the line |
|
1340
|
|
|
|
|
|
|
being printed out and enforce any requested filtering and/or coloring. |
|
1341
|
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
The remaining arguments are the same as what's passed to L if given a |
|
1343
|
|
|
|
|
|
|
B<$fmt> and one or more values. But if no values are given then it's treated |
|
1344
|
|
|
|
|
|
|
as a regular call to L. |
|
1345
|
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
If the formatted message should be terminated by multiple B<\n>, then it will |
|
1347
|
|
|
|
|
|
|
be truncated to a single B<\n>. All trailing whitespace on each line will be |
|
1348
|
|
|
|
|
|
|
removed as well. |
|
1349
|
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
It returns the formatted message written to fish and it will always end in |
|
1351
|
|
|
|
|
|
|
B<\n>. This message doesn't include the I<$tag> or the optional caller info |
|
1352
|
|
|
|
|
|
|
if the I option was used by B. |
|
1353
|
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
This message is returned even if fish is currently turned off! |
|
1355
|
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
B: If this request resulted in a write to B, and you asked for a |
|
1357
|
|
|
|
|
|
|
B in I, this function will sleep the requested number of |
|
1358
|
|
|
|
|
|
|
seconds before returning control to you. If no write, then no delay! |
|
1359
|
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
=cut |
|
1361
|
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
# ============================================================== |
|
1363
|
|
|
|
|
|
|
# Determine the current filter level from the tag's value ... |
|
1364
|
|
|
|
|
|
|
sub _filter_lvl |
|
1365
|
|
|
|
|
|
|
{ |
|
1366
|
15604
|
|
50
|
15604
|
|
36887
|
my $tag = shift || ""; # The keyword/tag passed to DBUG_PRINT! |
|
1367
|
|
|
|
|
|
|
# or _filter_on() or DBUG_EXECUTE() ... |
|
1368
|
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
# Not recomended: But someone always tries it ... |
|
1370
|
|
|
|
|
|
|
# If you used one of the DBUG_FILTER_LEVEL_... constants instead |
|
1371
|
|
|
|
|
|
|
# of a string in your DBUG_PRINT($tag,...) call. |
|
1372
|
|
|
|
|
|
|
# So if valid just return it as the level selected! |
|
1373
|
|
|
|
|
|
|
# Also greatly helped with Custom Filtering to allow this. |
|
1374
|
15604
|
100
|
66
|
|
|
93269
|
if ( $tag =~ m/^\d+$/ && defined $dbug_levels[$tag] ) { |
|
1375
|
2964
|
50
|
|
|
|
10890
|
return ( wantarray ? ($tag, $tag) : $tag ); |
|
1376
|
|
|
|
|
|
|
} |
|
1377
|
|
|
|
|
|
|
|
|
1378
|
12640
|
|
|
|
|
25715
|
my $utag = uc ( $tag ); # The tag in upper case! |
|
1379
|
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
# Assume this level until proven otherwise ... |
|
1381
|
12640
|
|
|
|
|
18957
|
my $fltr_lvl = DBUG_FILTER_LEVEL_OTHER; # Filtering ... |
|
1382
|
12640
|
|
|
|
|
18507
|
my $clr_lvl = $fltr_lvl; # Coloring ... |
|
1383
|
|
|
|
|
|
|
|
|
1384
|
12640
|
|
|
|
|
19671
|
my $pkg = __PACKAGE__; |
|
1385
|
|
|
|
|
|
|
|
|
1386
|
12640
|
100
|
100
|
|
|
134134
|
if ( $tag eq "args" ) { |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1387
|
1636
|
|
|
|
|
3252
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_ARGS; |
|
1388
|
|
|
|
|
|
|
} elsif ( $utag eq "ERROR" ) { |
|
1389
|
704
|
|
|
|
|
1149
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_ERROR; |
|
1390
|
|
|
|
|
|
|
} elsif ( $utag eq "STDOUT" || $utag eq "STDERR") { |
|
1391
|
20
|
|
|
|
|
39
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_STD; |
|
1392
|
|
|
|
|
|
|
} elsif ( $utag eq "WARN" || $utag eq "WARNING" ) { |
|
1393
|
144
|
|
|
|
|
295
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_WARN; |
|
1394
|
|
|
|
|
|
|
} elsif ( $utag eq "DEBUG" || $utag eq "DBUG" ) { |
|
1395
|
136
|
|
|
|
|
245
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_DEBUG; |
|
1396
|
|
|
|
|
|
|
} elsif ( $utag eq "INFO" ) { |
|
1397
|
206
|
|
|
|
|
683
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_INFO; |
|
1398
|
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
# The 3 different ways to specify internal levels ... |
|
1400
|
|
|
|
|
|
|
} elsif ( $utag eq "INTERNAL" ) { |
|
1401
|
0
|
|
|
|
|
0
|
$fltr_lvl = $clr_lvl = DBUG_FILTER_LEVEL_INTERNAL; |
|
1402
|
|
|
|
|
|
|
} elsif ( $tag eq __PACKAGE__ ) { |
|
1403
|
698
|
|
50
|
|
|
2019
|
$fltr_lvl = $dbug_global_vars{pkg_lvl} || DBUG_FILTER_LEVEL_INTERNAL; |
|
1404
|
698
|
|
|
|
|
1216
|
$clr_lvl = DBUG_FILTER_LEVEL_INTERNAL; |
|
1405
|
|
|
|
|
|
|
} elsif ( $tag =~ m/^${pkg}::/ ) { |
|
1406
|
202
|
|
50
|
|
|
585
|
$fltr_lvl = $dbug_global_vars{pkg_lvl} || DBUG_FILTER_LEVEL_INTERNAL; |
|
1407
|
202
|
|
|
|
|
321
|
$clr_lvl = DBUG_FILTER_LEVEL_INTERNAL; |
|
1408
|
|
|
|
|
|
|
} |
|
1409
|
|
|
|
|
|
|
|
|
1410
|
12640
|
100
|
|
|
|
38661
|
return ( wantarray ? ($fltr_lvl, $clr_lvl) : $fltr_lvl ); |
|
1411
|
|
|
|
|
|
|
} |
|
1412
|
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
# ============================================================== |
|
1414
|
|
|
|
|
|
|
# Does the filter rule say it's OK to print things? |
|
1415
|
|
|
|
|
|
|
# Based on the keyword/tag value ($_[0]) ... |
|
1416
|
|
|
|
|
|
|
# Or the DBUG_FILTER_LEVEL_... constants ... |
|
1417
|
|
|
|
|
|
|
sub _filter_on |
|
1418
|
|
|
|
|
|
|
{ |
|
1419
|
9846
|
|
|
9846
|
|
23275
|
my $lvl = _filter_lvl ( $_[0] ); |
|
1420
|
|
|
|
|
|
|
|
|
1421
|
9846
|
50
|
|
|
|
23228
|
if ( $dbug_global_vars{filter_style} >= 0 ) { |
|
1422
|
9846
|
|
|
|
|
36321
|
return ( $lvl <= $dbug_global_vars{filter} ); # Standard filtering ... |
|
1423
|
|
|
|
|
|
|
} else { |
|
1424
|
0
|
|
|
|
|
0
|
return ( $dbug_custom_levels[$lvl] ); # Custom filtering ... |
|
1425
|
|
|
|
|
|
|
} |
|
1426
|
|
|
|
|
|
|
} |
|
1427
|
|
|
|
|
|
|
|
|
1428
|
|
|
|
|
|
|
# ============================================================== |
|
1429
|
|
|
|
|
|
|
# So can always call DBUG_PRINT internally without any delays or caller info ... |
|
1430
|
|
|
|
|
|
|
sub _dbug_print_no_delay_or_caller |
|
1431
|
|
|
|
|
|
|
{ |
|
1432
|
2107
|
|
|
2107
|
|
6329
|
local $dbug_global_vars{delay} = 0; # Don't delay on this call ... |
|
1433
|
2107
|
|
|
|
|
4355
|
local $dbug_global_vars{who_called} = 0; # Don't add caller info ... |
|
1434
|
2107
|
|
|
|
|
5131
|
return DBUG_PRINT (@_); |
|
1435
|
|
|
|
|
|
|
} |
|
1436
|
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
# ============================================================== |
|
1438
|
|
|
|
|
|
|
# So can print with tag PACKAGE with custom internal levels ... |
|
1439
|
|
|
|
|
|
|
sub _dbug_print_pkg_tag |
|
1440
|
|
|
|
|
|
|
{ |
|
1441
|
508
|
|
|
508
|
|
988
|
my $level = shift; # if undef, don't change the level! |
|
1442
|
|
|
|
|
|
|
|
|
1443
|
508
|
50
|
|
|
|
1786
|
$level = $dbug_global_vars{pkg_lvl} unless ( $level ); |
|
1444
|
|
|
|
|
|
|
|
|
1445
|
508
|
|
|
|
|
1706
|
local $dbug_global_vars{pkg_lvl} = $level; |
|
1446
|
|
|
|
|
|
|
|
|
1447
|
508
|
|
|
|
|
985
|
my $pkg = __PACKAGE__; |
|
1448
|
508
|
100
|
66
|
|
|
3284
|
if ( $_[0] && $_[0] =~ m/^::[^:]/ ) { |
|
1449
|
105
|
|
|
|
|
322
|
$pkg .= shift; |
|
1450
|
|
|
|
|
|
|
} |
|
1451
|
|
|
|
|
|
|
|
|
1452
|
508
|
|
|
|
|
1403
|
return ( _dbug_print_no_delay_or_caller ( $pkg, @_ ) ); |
|
1453
|
|
|
|
|
|
|
} |
|
1454
|
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
# ============================================================== |
|
1456
|
|
|
|
|
|
|
# Make as efficient as possible since this is the most frequently called method! |
|
1457
|
|
|
|
|
|
|
# And usually the return value is tossed! |
|
1458
|
|
|
|
|
|
|
# ------------------------------------------------------------------ |
|
1459
|
|
|
|
|
|
|
sub DBUG_PRINT |
|
1460
|
|
|
|
|
|
|
{ |
|
1461
|
6759
|
|
|
6759
|
1
|
30990591
|
my ($keyword, $fmt, @values) = @_; |
|
1462
|
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
# Check if untrapped eval needs rebalancing ... |
|
1464
|
6759
|
|
|
|
|
19231
|
_dbug_auto_fix_eval_exception (); |
|
1465
|
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
# If undef, the caller wasn't interested in any return value! |
|
1467
|
6759
|
|
|
|
|
11470
|
my $want_return = wantarray; # Or could have used: (caller(0))[5] instead; |
|
1468
|
|
|
|
|
|
|
|
|
1469
|
6759
|
|
|
|
|
15318
|
my $fish_on = DBUG_EXECUTE ( $keyword ); |
|
1470
|
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
# ------------------------------------------------------------------- |
|
1472
|
|
|
|
|
|
|
# A no-op if fish isn't turned on & you don't want the return value! |
|
1473
|
|
|
|
|
|
|
# Very, very common! |
|
1474
|
|
|
|
|
|
|
# ------------------------------------------------------------------- |
|
1475
|
6759
|
100
|
|
|
|
15073
|
unless ( defined $want_return ) { |
|
1476
|
6739
|
100
|
|
|
|
14813
|
unless ( $fish_on ) { |
|
1477
|
997
|
|
|
|
|
3523
|
return (undef); # Not interested in the return value ... |
|
1478
|
|
|
|
|
|
|
} |
|
1479
|
|
|
|
|
|
|
} |
|
1480
|
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1482
|
|
|
|
|
|
|
# Build the message that we want to print out. |
|
1483
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1484
|
|
|
|
|
|
|
# Also converts any CODE references encountered. |
|
1485
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1486
|
5762
|
|
|
|
|
8740
|
my $msg; |
|
1487
|
5762
|
50
|
|
|
|
15662
|
if ( ! defined $fmt ) { |
|
|
|
100
|
|
|
|
|
|
|
1488
|
0
|
|
|
|
|
0
|
$msg = ""; |
|
1489
|
|
|
|
|
|
|
} elsif ( $#values == -1 ) { |
|
1490
|
3243
|
|
|
|
|
5376
|
$msg = $fmt; |
|
1491
|
3243
|
50
|
|
|
|
7325
|
if ( ref ($fmt) eq "CODE" ) { |
|
1492
|
0
|
|
|
|
|
0
|
my $f = sub_fullname ($fmt); |
|
1493
|
0
|
0
|
0
|
|
|
0
|
$f = $1 if ( $dbug_global_vars{strip} && $f =~ m/::([^:]+)$/ ); |
|
1494
|
0
|
|
|
|
|
0
|
$msg = '\&' . $f; |
|
1495
|
|
|
|
|
|
|
} |
|
1496
|
|
|
|
|
|
|
} else { |
|
1497
|
|
|
|
|
|
|
# Get rid of undef warnings & CODE references for sprintf() ... |
|
1498
|
2519
|
|
|
|
|
5669
|
foreach (@values) { |
|
1499
|
8444
|
50
|
|
|
|
17367
|
$_ = "" unless ( defined $_ ); |
|
1500
|
8444
|
100
|
|
|
|
19410
|
if ( ref ($_) eq "CODE" ) { |
|
1501
|
4
|
|
|
|
|
21
|
my $f = sub_fullname ($_); |
|
1502
|
4
|
50
|
33
|
|
|
46
|
$f = $1 if ( $dbug_global_vars{strip} && $f =~ m/::([^:]+)$/ ); |
|
1503
|
4
|
|
|
|
|
14
|
$_ = '\&' . $f; |
|
1504
|
|
|
|
|
|
|
} |
|
1505
|
|
|
|
|
|
|
} |
|
1506
|
2519
|
|
|
|
|
11509
|
$msg = sprintf ( $fmt, @values ); |
|
1507
|
|
|
|
|
|
|
} |
|
1508
|
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1510
|
|
|
|
|
|
|
# Split the resulting message into multiple lines ... |
|
1511
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1512
|
5762
|
|
|
|
|
22674
|
my @lines = split ( /[^\S\n]*\n/, $msg ); # Split on "\n" & trim! |
|
1513
|
5762
|
100
|
|
|
|
14166
|
push (@lines, "") if ( $#lines == -1 ); # Must have at least one line! |
|
1514
|
|
|
|
|
|
|
|
|
1515
|
5762
|
100
|
|
|
|
11186
|
if ( defined $want_return ) { |
|
1516
|
20
|
|
|
|
|
72
|
$msg = join ( "\n", @lines ) . "\n"; # Put back together trimmed! |
|
1517
|
|
|
|
|
|
|
} else { |
|
1518
|
5742
|
|
|
|
|
10357
|
$msg = undef; # The message wasn't wanted! |
|
1519
|
|
|
|
|
|
|
} |
|
1520
|
|
|
|
|
|
|
|
|
1521
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1522
|
|
|
|
|
|
|
# Only do this complex work if fish is turned on ... |
|
1523
|
|
|
|
|
|
|
# --------------------------------------------------------- |
|
1524
|
5762
|
100
|
|
|
|
11614
|
if ( $fish_on ) { |
|
1525
|
5758
|
|
|
|
|
18762
|
my $sep = _indent ("${keyword}: "); |
|
1526
|
5758
|
|
|
|
|
12668
|
my $len = length ($sep) - 2; # Doesn't count the trailing ": ". |
|
1527
|
|
|
|
|
|
|
|
|
1528
|
5758
|
|
|
|
|
9946
|
my $help_str = _indent_multi (); |
|
1529
|
5758
|
|
|
|
|
10451
|
$len = $len - length ($help_str); |
|
1530
|
|
|
|
|
|
|
|
|
1531
|
5758
|
|
|
|
|
11759
|
my ($level, $color_lvl) = _filter_lvl ($keyword); |
|
1532
|
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
# Check if the caller info needs to be retuned as part of $msg ... |
|
1534
|
5758
|
100
|
|
|
|
15454
|
if ( $dbug_global_vars{who_called} ) { |
|
1535
|
101
|
|
|
|
|
197
|
my $ln = _dbug_called_by (1); |
|
1536
|
|
|
|
|
|
|
# unshift (@lines, $ln); # Put before the message. |
|
1537
|
101
|
|
|
|
|
200
|
push (@lines, $ln); # Put after the message. |
|
1538
|
|
|
|
|
|
|
} |
|
1539
|
|
|
|
|
|
|
|
|
1540
|
5758
|
100
|
|
|
|
13103
|
if ( $dbug_global_vars{delay} ) { |
|
1541
|
22
|
50
|
|
|
|
100
|
if ( $time_hires_flag ) { |
|
1542
|
22
|
|
|
|
|
215
|
push (@lines, sprintf ("Sleeping %0.6f second(s)", $dbug_global_vars{delay})); |
|
1543
|
|
|
|
|
|
|
} else { |
|
1544
|
0
|
|
|
|
|
0
|
push (@lines, sprintf ("Sleeping %d second(s)", $dbug_global_vars{delay})); |
|
1545
|
|
|
|
|
|
|
} |
|
1546
|
|
|
|
|
|
|
} |
|
1547
|
|
|
|
|
|
|
|
|
1548
|
5758
|
|
|
|
|
12569
|
my @colors = _get_filter_color ( $color_lvl ); |
|
1549
|
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
# Indent each line of the message ... (note: \s includes \n!) |
|
1551
|
5758
|
|
|
|
|
17599
|
my ($output, $spaces) = ("", ${help_str} . " "x${len} . ": "); |
|
1552
|
5758
|
|
|
|
|
12104
|
foreach my $row (@lines) { |
|
1553
|
6230
|
|
|
|
|
12502
|
$output .= $colors[0] . ${sep} . $row . $colors[1] . "\n"; |
|
1554
|
6230
|
|
|
|
|
12603
|
$sep = $spaces; |
|
1555
|
|
|
|
|
|
|
} |
|
1556
|
5758
|
|
|
|
|
12566
|
my $flg = _printing ($output); |
|
1557
|
|
|
|
|
|
|
|
|
1558
|
5758
|
100
|
66
|
|
|
32511
|
if ( $flg && $dbug_global_vars{delay} ) { |
|
1559
|
22
|
|
|
|
|
33034078
|
sleep ( $dbug_global_vars{delay} ); |
|
1560
|
|
|
|
|
|
|
} |
|
1561
|
|
|
|
|
|
|
} |
|
1562
|
|
|
|
|
|
|
|
|
1563
|
5762
|
|
|
|
|
27142
|
return ( $msg ); # Returns what was printed out to the fish file. |
|
1564
|
|
|
|
|
|
|
} |
|
1565
|
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
|
|
1567
|
|
|
|
|
|
|
=item DBUG_RETURN ( ... ) |
|
1568
|
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
It takes the parameter(s) passed as arguments and uses them as the return |
|
1570
|
|
|
|
|
|
|
values to the calling function similar to how perl's return command works. |
|
1571
|
|
|
|
|
|
|
Except that it also writes what is being returned to B. Since this is a |
|
1572
|
|
|
|
|
|
|
function, care should be taken if called from the middle of your function's |
|
1573
|
|
|
|
|
|
|
code. In that case use the syntax: |
|
1574
|
|
|
|
|
|
|
S<"return DBUG_RETURN( value1 [, value2 [, ...]] );">. |
|
1575
|
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
It uses Perl's B feature to determine what to print to B and |
|
1577
|
|
|
|
|
|
|
return to the calling function. IE scalar mode (only the 1st value) or list |
|
1578
|
|
|
|
|
|
|
mode (all the values in the list). Which is not quite what many perl developers |
|
1579
|
|
|
|
|
|
|
might expect. |
|
1580
|
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
EX: return (wantarray ? (value1, value2, ...) : value1); |
|
1582
|
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
If I was called, it will mask the appropriate return value(s) |
|
1584
|
|
|
|
|
|
|
as: B******E>>. |
|
1585
|
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
=cut |
|
1587
|
|
|
|
|
|
|
|
|
1588
|
|
|
|
|
|
|
# ============================================================== |
|
1589
|
|
|
|
|
|
|
# Tells which return values are to be masked ... |
|
1590
|
|
|
|
|
|
|
# The index to the values to mask are returned as keys to a hash. |
|
1591
|
|
|
|
|
|
|
sub _dbug_mask_expect |
|
1592
|
|
|
|
|
|
|
{ |
|
1593
|
388
|
|
|
388
|
|
735
|
my $func = shift; # The return func block hash ref. |
|
1594
|
388
|
|
|
|
|
685
|
my $max = shift; # The count of return values. (-1 is no args) |
|
1595
|
388
|
|
|
|
|
619
|
my $args = shift; # A reference to the list of args to DBUG_RETURN. |
|
1596
|
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
# Did we decide to mask specific values by offset ?? |
|
1598
|
388
|
100
|
|
|
|
1247
|
my %mask = %{$func->{AMASK}} if ( exists $func->{AMASK} ); |
|
|
27
|
|
|
|
|
135
|
|
|
1599
|
388
|
|
|
|
|
897
|
my $all = $mask{-1}; # Did we say mask everything returned??? |
|
1600
|
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
# Did we decide to mask specific hash values ?? |
|
1602
|
|
|
|
|
|
|
# If so, get the offset to that hash key's value! |
|
1603
|
388
|
100
|
|
|
|
990
|
unless ( $all ) { |
|
1604
|
386
|
100
|
66
|
|
|
1297
|
if ( exists $func->{HMASK} && $max > 0 ) { |
|
1605
|
1
|
50
|
|
|
|
9
|
my $idx = (($max % 2) == 0) ? 1 : 0; |
|
1606
|
1
|
|
|
|
|
5
|
while ( $idx <= $max ) { |
|
1607
|
4
|
|
|
|
|
7
|
my $key = $args->[$idx]; # The key to check for |
|
1608
|
4
|
|
|
|
|
6
|
my $iv = $idx + 1; # It's value |
|
1609
|
4
|
|
|
|
|
7
|
$idx += 2; # Skip to the next key |
|
1610
|
|
|
|
|
|
|
|
|
1611
|
4
|
50
|
|
|
|
8
|
next unless ( defined $key ); |
|
1612
|
4
|
100
|
|
|
|
29
|
next unless ( exists $func->{HMASK}->{$key} ); |
|
1613
|
2
|
|
|
|
|
8
|
$mask{$iv} = 1; # Mark this key's value as maskable! |
|
1614
|
|
|
|
|
|
|
} |
|
1615
|
|
|
|
|
|
|
} |
|
1616
|
|
|
|
|
|
|
} |
|
1617
|
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
# Now count how many of the return values would be masked ... |
|
1619
|
388
|
|
|
|
|
702
|
my $cnt = 0; |
|
1620
|
388
|
|
|
|
|
1130
|
foreach (0..$max) { |
|
1621
|
952
|
100
|
100
|
|
|
4597
|
++$cnt if ( $all || $mask{$_} ); |
|
1622
|
|
|
|
|
|
|
} |
|
1623
|
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
# The keys to this hash are it's offsets! |
|
1625
|
388
|
|
|
|
|
1442
|
return ($cnt, %mask); |
|
1626
|
|
|
|
|
|
|
} |
|
1627
|
|
|
|
|
|
|
|
|
1628
|
|
|
|
|
|
|
# ============================================================== |
|
1629
|
|
|
|
|
|
|
sub DBUG_RETURN |
|
1630
|
|
|
|
|
|
|
{ |
|
1631
|
413
|
|
|
413
|
1
|
49968
|
my @args = @_; |
|
1632
|
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
# Check if untrapped eval needs rebalancing ... |
|
1634
|
413
|
|
|
|
|
1345
|
_dbug_auto_fix_eval_exception (); |
|
1635
|
|
|
|
|
|
|
|
|
1636
|
|
|
|
|
|
|
# Pop off the function being returned ... |
|
1637
|
413
|
|
|
|
|
911
|
my $block = pop ( @{$dbug_global_vars{functions}} ); |
|
|
413
|
|
|
|
|
1012
|
|
|
1638
|
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
# Will this turn pause off ??? |
|
1640
|
413
|
100
|
|
|
|
1232
|
unless ( $block->{PAUSED} ) { |
|
1641
|
408
|
|
|
|
|
981
|
$dbug_global_vars{pause} = 0; # Yes! |
|
1642
|
|
|
|
|
|
|
} |
|
1643
|
|
|
|
|
|
|
|
|
1644
|
|
|
|
|
|
|
# How many of the return values are to be masked in fish ... |
|
1645
|
413
|
|
|
|
|
791
|
$dbug_global_vars{mask_return_count} = 0; # Actual count |
|
1646
|
413
|
|
|
|
|
679
|
my %mask; |
|
1647
|
|
|
|
|
|
|
|
|
1648
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1649
|
|
|
|
|
|
|
# If undef, the caller wasn't interested in looking at any return values! |
|
1650
|
|
|
|
|
|
|
# Assume that its planing on doing a normal "return" later on and you just |
|
1651
|
|
|
|
|
|
|
# wanted to see what the expected return values are in fish. |
|
1652
|
|
|
|
|
|
|
# But DBUG_RETURN() will still return undef to the caller in this case! |
|
1653
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1654
|
|
|
|
|
|
|
# See t/15-return_simple.t for examples of this type of return. |
|
1655
|
|
|
|
|
|
|
# It's too difficult to explain otherwise. |
|
1656
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1657
|
413
|
|
|
|
|
785
|
my $fish_return = wantarray; # Or could have used: (caller(0))[5] instead. |
|
1658
|
|
|
|
|
|
|
|
|
1659
|
413
|
100
|
|
|
|
1208
|
unless ( defined $fish_return ) { |
|
1660
|
85
|
|
|
|
|
164
|
my $func; |
|
1661
|
85
|
|
|
|
|
14184
|
my $called_by_special = __PACKAGE__ . "::DBUG_RETURN_SPECIAL"; |
|
1662
|
85
|
|
|
|
|
161
|
my $called_by_special2 = __PACKAGE__ . "::DBUG_ARRAY_RETURN"; |
|
1663
|
85
|
|
|
|
|
352
|
($func, $fish_return) = (caller(1))[3,5]; |
|
1664
|
85
|
100
|
66
|
|
|
661
|
$fish_return = (caller(2))[5] if ( defined $func && ($func eq $called_by_special || $func eq $called_by_special2) ); |
|
|
|
|
33
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
} |
|
1666
|
|
|
|
|
|
|
|
|
1667
|
|
|
|
|
|
|
# Take a shortcut if fish is currently disabled ... |
|
1668
|
413
|
100
|
|
|
|
1326
|
unless ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
1669
|
21
|
50
|
33
|
|
|
128
|
my $unknown = ( exists $block->{AMASK} || exists $block->{HMASK} ) ? -1 : 0; |
|
1670
|
21
|
100
|
|
|
|
70
|
if ( ! defined $fish_return ) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1671
|
16
|
|
|
|
|
87
|
return ( undef ); # Return value is being ignored! |
|
1672
|
|
|
|
|
|
|
} elsif ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_ARGS ) ) { |
|
1673
|
|
|
|
|
|
|
; # Can't quit now, we have return values to print out! |
|
1674
|
|
|
|
|
|
|
} elsif ( $fish_return ) { |
|
1675
|
4
|
|
|
|
|
9
|
$dbug_global_vars{mask_return_count} = $unknown; |
|
1676
|
4
|
|
|
|
|
31
|
return ( @args ); # Array context ... |
|
1677
|
|
|
|
|
|
|
} else { |
|
1678
|
1
|
|
|
|
|
3
|
$dbug_global_vars{mask_return_count} = $unknown; |
|
1679
|
1
|
|
|
|
|
14
|
return ( $args[0] ); # Scalar context ... |
|
1680
|
|
|
|
|
|
|
} |
|
1681
|
|
|
|
|
|
|
} |
|
1682
|
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
# From here on down we know we know we'll write something to fish ... |
|
1684
|
|
|
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
# How many of the arguments do we expect to mask when we print them out ... |
|
1686
|
392
|
|
|
|
|
786
|
my $max = $#args; |
|
1687
|
392
|
100
|
|
|
|
983
|
if ($max != -1) { |
|
1688
|
388
|
100
|
|
|
|
931
|
$max = ($fish_return ? $#args : 0); |
|
1689
|
388
|
|
|
|
|
1633
|
($dbug_global_vars{mask_return_count}, %mask) = |
|
1690
|
|
|
|
|
|
|
_dbug_mask_expect ($block, $max, \@args); |
|
1691
|
|
|
|
|
|
|
} |
|
1692
|
|
|
|
|
|
|
|
|
1693
|
392
|
|
|
|
|
1028
|
my @colors = _get_filter_color (DBUG_FILTER_LEVEL_ARGS); |
|
1694
|
|
|
|
|
|
|
|
|
1695
|
392
|
|
|
|
|
1065
|
my $func = $block->{NAME}; |
|
1696
|
392
|
100
|
|
|
|
1310
|
my $lbl = ( $block->{FUNC} ) ? "<" : "<<"; |
|
1697
|
392
|
|
|
|
|
1014
|
my $ret = $block->{COLOR1}; |
|
1698
|
392
|
|
|
|
|
1584
|
$ret .= _indent ("${lbl}${func} - return ("); |
|
1699
|
392
|
|
|
|
|
1393
|
$ret .= $block->{COLOR2} . $colors[0]; |
|
1700
|
|
|
|
|
|
|
|
|
1701
|
392
|
100
|
66
|
|
|
955
|
unless ( _filter_on ( DBUG_FILTER_LEVEL_ARGS ) ) { |
|
1702
|
4
|
|
|
|
|
27
|
$ret .= "?"; # Don't print the return value(s) to fish ... |
|
1703
|
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
# Do we have any return values to print to fish ??? |
|
1705
|
|
|
|
|
|
|
} elsif ( $max != -1 && defined $fish_return ) { |
|
1706
|
|
|
|
|
|
|
my $all = $mask{-1}; # Did we request to mask all return values ??? |
|
1707
|
|
|
|
|
|
|
|
|
1708
|
|
|
|
|
|
|
# Now let's build the return value list to print to fish ... |
|
1709
|
|
|
|
|
|
|
my $sep = ""; |
|
1710
|
|
|
|
|
|
|
my $cnt = 0; # Count return values masked. |
|
1711
|
|
|
|
|
|
|
my $i = 500; # Count reference addresses dereferenced. |
|
1712
|
|
|
|
|
|
|
|
|
1713
|
|
|
|
|
|
|
foreach (0..$max) { |
|
1714
|
|
|
|
|
|
|
my $val; |
|
1715
|
|
|
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
if ( $all || $mask{$_} ) { |
|
1717
|
|
|
|
|
|
|
$val = MASKING_VALUE; # Let's mask it ... |
|
1718
|
|
|
|
|
|
|
++$cnt; # Count it! |
|
1719
|
|
|
|
|
|
|
} elsif ( ! defined $args[$_] ) { |
|
1720
|
|
|
|
|
|
|
$val = UNDEF_VALUE; |
|
1721
|
|
|
|
|
|
|
} elsif ( ref ($args[$_]) eq "CODE" ) { |
|
1722
|
|
|
|
|
|
|
my $f = sub_fullname ( $args[$_] ); |
|
1723
|
|
|
|
|
|
|
$f = $1 if ( $dbug_global_vars{strip} && $f =~ m/::([^:]+)$/ ); |
|
1724
|
|
|
|
|
|
|
$val = '\&' . $f; |
|
1725
|
|
|
|
|
|
|
} elsif ( $dbug_global_vars{no_addresses} && ref ($args[$_]) ne "" ) { |
|
1726
|
|
|
|
|
|
|
$val = sprintf ("%s(%03d)", ref ($args[$_]), ++$i); |
|
1727
|
|
|
|
|
|
|
} else { |
|
1728
|
|
|
|
|
|
|
$val = $args[$_]; |
|
1729
|
|
|
|
|
|
|
} |
|
1730
|
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
$ret .= $sep . "[" . $val . "]"; |
|
1732
|
|
|
|
|
|
|
$sep = ", "; |
|
1733
|
|
|
|
|
|
|
} |
|
1734
|
|
|
|
|
|
|
|
|
1735
|
|
|
|
|
|
|
# Should never happen ... |
|
1736
|
|
|
|
|
|
|
if ( $cnt != $dbug_global_vars{mask_return_count} ) { |
|
1737
|
|
|
|
|
|
|
_dbug_print_pkg_tag ( DBUG_FILTER_LEVEL_INFO, |
|
1738
|
|
|
|
|
|
|
"Expected %d masked return values and found %d.", |
|
1739
|
|
|
|
|
|
|
$dbug_global_vars{mask_return_count}, $cnt ); |
|
1740
|
|
|
|
|
|
|
$dbug_global_vars{mask_return_count} = $cnt; |
|
1741
|
|
|
|
|
|
|
} |
|
1742
|
|
|
|
|
|
|
} |
|
1743
|
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
# Finishing up all paths ... |
|
1745
|
392
|
|
|
|
|
941
|
$ret .= $colors[1] . $block->{COLOR1} . ")"; |
|
1746
|
392
|
100
|
|
|
|
1143
|
$ret .= _dbug_elapsed_time ($block->{TIME}) if ( $dbug_global_vars{elapsed} ); |
|
1747
|
392
|
|
|
|
|
843
|
$ret .= $block->{COLOR2} . "\n"; |
|
1748
|
|
|
|
|
|
|
|
|
1749
|
392
|
|
|
|
|
1344
|
_printing ($ret); |
|
1750
|
|
|
|
|
|
|
|
|
1751
|
392
|
100
|
|
|
|
1206
|
if ( $fish_return ) { |
|
|
|
100
|
|
|
|
|
|
|
1752
|
204
|
|
|
|
|
2561
|
return ( @args ); # Array context ... |
|
1753
|
|
|
|
|
|
|
} elsif ( defined $fish_return ) { |
|
1754
|
137
|
|
|
|
|
2064
|
return ( $args[0] ); # Scalar context ... |
|
1755
|
|
|
|
|
|
|
} else { |
|
1756
|
51
|
|
|
|
|
452
|
return ( undef ); # Return value is being ignored! |
|
1757
|
|
|
|
|
|
|
} |
|
1758
|
|
|
|
|
|
|
} |
|
1759
|
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
=item DBUG_ARRAY_RETURN ( @args ) |
|
1762
|
|
|
|
|
|
|
|
|
1763
|
|
|
|
|
|
|
A variant of S<"DBUG_RETURN()"> that behaves the same as perl does natively when |
|
1764
|
|
|
|
|
|
|
returning a list to a scalar. IE it returns the # of elements in the @args |
|
1765
|
|
|
|
|
|
|
array. |
|
1766
|
|
|
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
It always assumes @args is a list, even when provided a single scalar value. |
|
1768
|
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
=cut |
|
1770
|
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
# ============================================================== |
|
1772
|
|
|
|
|
|
|
sub DBUG_ARRAY_RETURN |
|
1773
|
|
|
|
|
|
|
{ |
|
1774
|
20
|
|
|
20
|
1
|
235
|
my @args = @_; |
|
1775
|
|
|
|
|
|
|
|
|
1776
|
20
|
100
|
|
|
|
47
|
unless ( defined wantarray ) { |
|
1777
|
8
|
|
|
|
|
104
|
return DBUG_VOID_RETURN (); |
|
1778
|
|
|
|
|
|
|
} |
|
1779
|
|
|
|
|
|
|
|
|
1780
|
12
|
100
|
|
|
|
27
|
if ( wantarray ) { |
|
1781
|
8
|
|
|
|
|
21
|
return DBUG_RETURN ( @args ); |
|
1782
|
|
|
|
|
|
|
} |
|
1783
|
|
|
|
|
|
|
|
|
1784
|
4
|
|
|
|
|
8
|
my $cnt = @args; # The number of elements in the array. |
|
1785
|
4
|
|
|
|
|
12
|
return DBUG_RETURN ( $cnt ) |
|
1786
|
|
|
|
|
|
|
} |
|
1787
|
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
|
|
1789
|
|
|
|
|
|
|
=item DBUG_VOID_RETURN ( ) |
|
1790
|
|
|
|
|
|
|
|
|
1791
|
|
|
|
|
|
|
Terminates the current block of B code. It doesn't return any value back |
|
1792
|
|
|
|
|
|
|
to the calling function. |
|
1793
|
|
|
|
|
|
|
|
|
1794
|
|
|
|
|
|
|
=cut |
|
1795
|
|
|
|
|
|
|
|
|
1796
|
|
|
|
|
|
|
# ============================================================== |
|
1797
|
|
|
|
|
|
|
sub DBUG_VOID_RETURN |
|
1798
|
|
|
|
|
|
|
{ |
|
1799
|
|
|
|
|
|
|
# Check if untrapped eval needs rebalancing ... |
|
1800
|
723
|
|
|
723
|
1
|
3685529
|
_dbug_auto_fix_eval_exception (); |
|
1801
|
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
# Pop off the function being returned ... |
|
1803
|
723
|
|
|
|
|
1140
|
my $block = pop ( @{$dbug_global_vars{functions}} ); |
|
|
723
|
|
|
|
|
2551
|
|
|
1804
|
|
|
|
|
|
|
|
|
1805
|
723
|
100
|
|
|
|
2301
|
unless ( $block->{PAUSED} ) { |
|
1806
|
649
|
|
|
|
|
1343
|
$dbug_global_vars{pause} = 0; |
|
1807
|
|
|
|
|
|
|
|
|
1808
|
649
|
100
|
|
|
|
1511
|
if ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
1809
|
628
|
|
|
|
|
1766
|
my $func = $block->{NAME}; |
|
1810
|
628
|
100
|
|
|
|
1650
|
my $lbl = ( $block->{FUNC} ) ? "<" : "<<"; |
|
1811
|
|
|
|
|
|
|
_printing ( $block->{COLOR1}, _indent ("${lbl}${func} ()"), |
|
1812
|
|
|
|
|
|
|
_dbug_elapsed_time ($block->{TIME}), |
|
1813
|
628
|
|
|
|
|
2520
|
$block->{COLOR2}, "\n" ); |
|
1814
|
|
|
|
|
|
|
} |
|
1815
|
|
|
|
|
|
|
} |
|
1816
|
|
|
|
|
|
|
|
|
1817
|
|
|
|
|
|
|
# No return values can ever be masked here! |
|
1818
|
723
|
|
|
|
|
2774
|
$dbug_global_vars{mask_return_count} = 0; |
|
1819
|
|
|
|
|
|
|
|
|
1820
|
723
|
|
|
|
|
124980
|
return (undef); # Undef just in case someone looks! |
|
1821
|
|
|
|
|
|
|
} |
|
1822
|
|
|
|
|
|
|
|
|
1823
|
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
=item DBUG_RETURN_SPECIAL ( $scalar, @array ) |
|
1825
|
|
|
|
|
|
|
|
|
1826
|
|
|
|
|
|
|
This I variant allows you to differentiate between what to return |
|
1827
|
|
|
|
|
|
|
when your function is called in a scalar context vs an array context vs void |
|
1828
|
|
|
|
|
|
|
context. |
|
1829
|
|
|
|
|
|
|
|
|
1830
|
|
|
|
|
|
|
If called in an array context, the return value is equivalent to |
|
1831
|
|
|
|
|
|
|
S.> |
|
1832
|
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
If called in a scalar context, the return value is equivalent to |
|
1834
|
|
|
|
|
|
|
S.> With a few special case exceptions. |
|
1835
|
|
|
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
=over |
|
1837
|
|
|
|
|
|
|
|
|
1838
|
|
|
|
|
|
|
Special case # 1: If I<$scalar> is set to the predefined constant value |
|
1839
|
|
|
|
|
|
|
B, it returns the equivalent to |
|
1840
|
|
|
|
|
|
|
S.> Feel free to modify the contents of the referenced |
|
1841
|
|
|
|
|
|
|
array, it can't hurt anything. It's a copy. |
|
1842
|
|
|
|
|
|
|
|
|
1843
|
|
|
|
|
|
|
Special case # 2: If I<$scalar> is set to the predefined constant value |
|
1844
|
|
|
|
|
|
|
B, it returns the equivalent to |
|
1845
|
|
|
|
|
|
|
S,> the number of elements in the array. |
|
1846
|
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
Special case # 3: If I<$scalar> is set to the predefined constant value |
|
1848
|
|
|
|
|
|
|
B, it returns the equivalent to |
|
1849
|
|
|
|
|
|
|
S,> the last element in the array. |
|
1850
|
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
Special case # 4: If I<$scalar> is a CODE ref, it returns the equivalent to |
|
1852
|
|
|
|
|
|
|
S(@array)))>.> |
|
1853
|
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
=back |
|
1855
|
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
If called in a void context, the return value is equivalent to |
|
1857
|
|
|
|
|
|
|
S.> But in some cases it will print additional |
|
1858
|
|
|
|
|
|
|
information to B. But it will B call the CODE reference |
|
1859
|
|
|
|
|
|
|
when called in void context. |
|
1860
|
|
|
|
|
|
|
|
|
1861
|
|
|
|
|
|
|
=cut |
|
1862
|
|
|
|
|
|
|
|
|
1863
|
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
# ============================================================== |
|
1865
|
|
|
|
|
|
|
# Must always call DBUG_RETURN() or DBUG_VOID_RETURN () |
|
1866
|
|
|
|
|
|
|
# to handle all the bookkeeping! |
|
1867
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
1868
|
|
|
|
|
|
|
sub DBUG_RETURN_SPECIAL |
|
1869
|
|
|
|
|
|
|
{ |
|
1870
|
79
|
|
|
79
|
1
|
556
|
my $scalar = shift; # Just take the scalar of the stack ... |
|
1871
|
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
# Caller is asking for an array of values ... |
|
1873
|
79
|
100
|
|
|
|
183
|
if ( wantarray ) { |
|
1874
|
33
|
|
|
|
|
91
|
return DBUG_RETURN ( @_ ); |
|
1875
|
|
|
|
|
|
|
} |
|
1876
|
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
# Check if we have to monkey with the return value masking ... |
|
1878
|
46
|
|
|
|
|
69
|
my $last_masked = 0; |
|
1879
|
46
|
|
|
|
|
75
|
my %new_mask; |
|
1880
|
46
|
100
|
100
|
|
|
215
|
if ( $scalar eq DBUG_SPECIAL_LAST && exists $dbug_global_vars{functions}->[-1]->{AMASK} ) { |
|
1881
|
4
|
|
|
|
|
12
|
my $msk = $dbug_global_vars{functions}->[-1]->{AMASK}; |
|
1882
|
4
|
100
|
|
|
|
18
|
if ( $msk->{$#_ + 0} ) { |
|
|
|
50
|
|
|
|
|
|
|
1883
|
2
|
|
|
|
|
5
|
$new_mask{0} = 1; |
|
1884
|
2
|
|
|
|
|
5
|
$last_masked = 1; |
|
1885
|
|
|
|
|
|
|
} elsif ( $msk->{0} ) { |
|
1886
|
2
|
|
|
|
|
5
|
$last_masked = 1; |
|
1887
|
|
|
|
|
|
|
} |
|
1888
|
|
|
|
|
|
|
} |
|
1889
|
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1891
|
|
|
|
|
|
|
# If undef, the caller wasn't interested in looking at any return values! |
|
1892
|
|
|
|
|
|
|
# Assume that its planing on doing a normal "return" later on and you just |
|
1893
|
|
|
|
|
|
|
# wanted to see what the expected return values are in fish. |
|
1894
|
|
|
|
|
|
|
# But DBUG_RETURN_SPECIAL() will still return undef to the caller no |
|
1895
|
|
|
|
|
|
|
# matter what's written to fish in this case! |
|
1896
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1897
|
|
|
|
|
|
|
# See "t/16-return_special_scalar_join.t" for examples of this type of |
|
1898
|
|
|
|
|
|
|
# return. It's just too difficult to explain otherwise. |
|
1899
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1900
|
|
|
|
|
|
|
# return_test_1 () - Shows the expected way to use this function. |
|
1901
|
|
|
|
|
|
|
# return_test_2 () - Shows the problem way on why this code is complex. |
|
1902
|
|
|
|
|
|
|
# I don't recommend you use DBUG_RETURN_SPECIAL() this 2nd way. |
|
1903
|
|
|
|
|
|
|
# deep_test_1 () - Shows how your intuition may be wrong! |
|
1904
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1905
|
46
|
100
|
|
|
|
112
|
unless ( defined wantarray ) { |
|
1906
|
31
|
|
|
|
|
152
|
my $parent_wantarray = (caller(1))[5]; |
|
1907
|
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
# If called like return_test_1 () ... (expected way) |
|
1909
|
31
|
100
|
|
|
|
137
|
return DBUG_VOID_RETURN () unless ( defined $parent_wantarray ); |
|
1910
|
|
|
|
|
|
|
|
|
1911
|
|
|
|
|
|
|
# If called like return_test_2 () ... (problem way) |
|
1912
|
12
|
100
|
|
|
|
54
|
return DBUG_RETURN ( @_ ) if ( $parent_wantarray ); |
|
1913
|
|
|
|
|
|
|
|
|
1914
|
|
|
|
|
|
|
# Not doing the CODE ref conversion on purpose! Since not saving any |
|
1915
|
|
|
|
|
|
|
# return value we want to avoid any potenial side affects due to |
|
1916
|
|
|
|
|
|
|
# calling the CODE ref function. |
|
1917
|
4
|
50
|
|
|
|
15
|
if ( defined $scalar ) { |
|
1918
|
4
|
100
|
|
|
|
25
|
if ( $scalar eq DBUG_SPECIAL_ARRAYREF ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1919
|
1
|
|
|
|
|
4
|
$scalar = \@_; |
|
1920
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_COUNT ) { |
|
1921
|
1
|
|
|
|
|
3
|
$scalar = scalar (@_); |
|
1922
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_LAST ) { |
|
1923
|
1
|
|
|
|
|
3
|
$scalar = $_[-1]; |
|
1924
|
|
|
|
|
|
|
} |
|
1925
|
|
|
|
|
|
|
} |
|
1926
|
|
|
|
|
|
|
|
|
1927
|
4
|
50
|
|
|
|
14
|
if ( $last_masked ) { |
|
1928
|
0
|
|
|
|
|
0
|
local $dbug_global_vars{functions}->[-1]->{AMASK}; |
|
1929
|
0
|
|
|
|
|
0
|
$dbug_global_vars{functions}->[-1]->{AMASK} = \%new_mask; |
|
1930
|
0
|
|
|
|
|
0
|
return DBUG_RETURN ( $scalar ); |
|
1931
|
|
|
|
|
|
|
} else { |
|
1932
|
4
|
|
|
|
|
14
|
return DBUG_RETURN ( $scalar ); |
|
1933
|
|
|
|
|
|
|
} |
|
1934
|
|
|
|
|
|
|
} |
|
1935
|
|
|
|
|
|
|
|
|
1936
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1937
|
|
|
|
|
|
|
# If you get here, you want a scalar value returned ... |
|
1938
|
|
|
|
|
|
|
# Was it one of the special case values??? |
|
1939
|
|
|
|
|
|
|
# ------------------------------------------------------------------------ |
|
1940
|
15
|
50
|
|
|
|
50
|
if ( defined $scalar ) { |
|
1941
|
15
|
100
|
66
|
|
|
96
|
if ( ref ($scalar) eq "CODE" ) { |
|
|
|
100
|
33
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1942
|
5
|
|
|
|
|
13
|
my $res = $scalar->( @_ ); |
|
1943
|
5
|
|
|
|
|
15
|
return DBUG_RETURN ( $res ); |
|
1944
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_ARRAYREF ) { |
|
1945
|
3
|
|
|
|
|
15
|
my @args = @_; |
|
1946
|
3
|
|
|
|
|
126
|
return DBUG_RETURN ( \@args ); |
|
1947
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_COUNT ) { |
|
1948
|
3
|
|
|
|
|
11
|
return DBUG_RETURN ( scalar (@_) ); |
|
1949
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_LAST && ! $last_masked ) { |
|
1950
|
2
|
|
|
|
|
9
|
return DBUG_RETURN ( $_[-1] ); |
|
1951
|
|
|
|
|
|
|
} elsif ( $scalar eq DBUG_SPECIAL_LAST && $last_masked ) { |
|
1952
|
2
|
|
|
|
|
8
|
local $dbug_global_vars{functions}->[-1]->{AMASK}; |
|
1953
|
2
|
|
|
|
|
6
|
$dbug_global_vars{functions}->[-1]->{AMASK} = \%new_mask; |
|
1954
|
2
|
|
|
|
|
7
|
return DBUG_RETURN ( $_[-1] ); |
|
1955
|
|
|
|
|
|
|
} |
|
1956
|
|
|
|
|
|
|
} |
|
1957
|
|
|
|
|
|
|
|
|
1958
|
|
|
|
|
|
|
# Not a special case ... returning the literal value! |
|
1959
|
0
|
|
|
|
|
0
|
DBUG_RETURN ( $scalar ); |
|
1960
|
|
|
|
|
|
|
} |
|
1961
|
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
|
|
1963
|
|
|
|
|
|
|
=item DBUG_LEAVE ( [$status] ) |
|
1964
|
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
This function terminates your program with a call to I. It expects a |
|
1966
|
|
|
|
|
|
|
numeric argument to use as the program's I<$status> code, but will default to |
|
1967
|
|
|
|
|
|
|
zero if it's missing. It is considered the final return of your program. |
|
1968
|
|
|
|
|
|
|
|
|
1969
|
|
|
|
|
|
|
Only module B and B blocks can be logged after this function is |
|
1970
|
|
|
|
|
|
|
called as Perl cleans up after itself, unless you turned this feature off with |
|
1971
|
|
|
|
|
|
|
option B when B was first enabled. |
|
1972
|
|
|
|
|
|
|
|
|
1973
|
|
|
|
|
|
|
=cut |
|
1974
|
|
|
|
|
|
|
|
|
1975
|
|
|
|
|
|
|
# ============================================================== |
|
1976
|
|
|
|
|
|
|
sub DBUG_LEAVE |
|
1977
|
|
|
|
|
|
|
{ |
|
1978
|
39
|
|
50
|
39
|
1
|
28939
|
my $status = shift || 0; |
|
1979
|
|
|
|
|
|
|
|
|
1980
|
|
|
|
|
|
|
# Check if untrapped eval needs rebalancing ... |
|
1981
|
39
|
|
|
|
|
496
|
_dbug_auto_fix_eval_exception (); |
|
1982
|
|
|
|
|
|
|
|
|
1983
|
|
|
|
|
|
|
# Pop off the function being returned ... |
|
1984
|
39
|
|
|
|
|
154
|
my $block = pop ( @{$dbug_global_vars{functions}} ); |
|
|
39
|
|
|
|
|
221
|
|
|
1985
|
|
|
|
|
|
|
|
|
1986
|
39
|
100
|
|
|
|
566
|
if ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
1987
|
37
|
|
|
|
|
152
|
my $func; |
|
1988
|
|
|
|
|
|
|
my @colors; |
|
1989
|
37
|
|
|
|
|
371
|
my $lbl = "<"; |
|
1990
|
37
|
|
|
|
|
206
|
my $elaps = ""; |
|
1991
|
37
|
50
|
|
|
|
499
|
unless ( defined $block ) { |
|
1992
|
0
|
|
|
|
|
0
|
$func = " *** Unbalanced Returns *** Potential bug in your code!"; |
|
1993
|
0
|
|
|
|
|
0
|
$colors[0] = $colors[1] = ""; |
|
1994
|
|
|
|
|
|
|
} else { |
|
1995
|
37
|
|
|
|
|
198
|
$func = $block->{NAME}; |
|
1996
|
37
|
|
|
|
|
279
|
$colors[0] = $block->{COLOR1}; |
|
1997
|
37
|
|
|
|
|
104
|
$colors[1] = $block->{COLOR2}; |
|
1998
|
37
|
100
|
|
|
|
285
|
$lbl = "<<" unless ( $block->{FUNC} ); |
|
1999
|
37
|
100
|
|
|
|
336
|
$elaps = _dbug_elapsed_time ( $block->{TIME} ) if ( $dbug_global_vars{elapsed} ); |
|
2000
|
|
|
|
|
|
|
} |
|
2001
|
|
|
|
|
|
|
|
|
2002
|
37
|
|
|
|
|
356
|
$dbug_global_vars{printed_exit_status} = _printing ( |
|
2003
|
|
|
|
|
|
|
$colors[0], _indent ("${lbl}${func}"), $elaps, $colors[1], "\n", |
|
2004
|
|
|
|
|
|
|
_indent_multi (), "exit ($status)\n\n" ); |
|
2005
|
|
|
|
|
|
|
} |
|
2006
|
|
|
|
|
|
|
|
|
2007
|
39
|
|
|
|
|
235
|
_dbug_leave_cleanup (); |
|
2008
|
|
|
|
|
|
|
|
|
2009
|
39
|
|
|
|
|
7942
|
exit ($status); # Exit the program! (This isn't trappable by eval!) |
|
2010
|
|
|
|
|
|
|
} |
|
2011
|
|
|
|
|
|
|
|
|
2012
|
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
# Broken out so I can call from END block and |
|
2014
|
|
|
|
|
|
|
# Fred::Fish::DBUG::OFF as well. |
|
2015
|
|
|
|
|
|
|
# So that we can trace all the END/DESTROY blocks cleanly ... |
|
2016
|
|
|
|
|
|
|
sub _dbug_leave_cleanup |
|
2017
|
|
|
|
|
|
|
{ |
|
2018
|
43
|
|
|
43
|
|
178
|
$dbug_global_vars{pause} = 0; |
|
2019
|
|
|
|
|
|
|
|
|
2020
|
43
|
|
|
|
|
387
|
my @empty; |
|
2021
|
43
|
|
|
|
|
133
|
@{$dbug_global_vars{functions}} = @empty; |
|
|
43
|
|
|
|
|
829
|
|
|
2022
|
|
|
|
|
|
|
|
|
2023
|
|
|
|
|
|
|
# Are we tracing the END/DESTROY blocks after all? |
|
2024
|
43
|
100
|
|
|
|
415
|
$dbug_global_vars{on} = 0 if ( $dbug_global_vars{no_end} ); |
|
2025
|
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
# So any requested caller info/line numbers are never printed out ... |
|
2027
|
43
|
|
|
|
|
149
|
$dbug_global_vars{who_called} = 0; |
|
2028
|
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
# Tells the END code DBUG_LEAVE was aleady called. |
|
2030
|
43
|
|
|
|
|
212
|
$dbug_global_vars{dbug_leave_called} = 1; |
|
2031
|
|
|
|
|
|
|
|
|
2032
|
43
|
|
|
|
|
151
|
return; |
|
2033
|
|
|
|
|
|
|
} |
|
2034
|
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
=item DBUG_CATCH ( ) |
|
2037
|
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
This function rebalances the B function trace after trapping B from |
|
2039
|
|
|
|
|
|
|
an B or B code block. |
|
2040
|
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
If using B, place this function call inside the S> section |
|
2042
|
|
|
|
|
|
|
after each B block of code. |
|
2043
|
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
If using B/B, place this function inside the B block instead. |
|
2045
|
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
But if you don't call this function, the B logs will still try to auto |
|
2047
|
|
|
|
|
|
|
rebalance itself. But you loose why this happens and it I mischaracterize |
|
2048
|
|
|
|
|
|
|
why it did so in the B logs. It implies you trapped an B or B |
|
2049
|
|
|
|
|
|
|
event. |
|
2050
|
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
So calling this function is in most cases optional. One of the few times it |
|
2052
|
|
|
|
|
|
|
could be considered required is if you used the B option to |
|
2053
|
|
|
|
|
|
|
I. In that case failure to immediately call it could affect your |
|
2054
|
|
|
|
|
|
|
timings when the rebalancing gets deferred until the next DBUG call. |
|
2055
|
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
=cut |
|
2057
|
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
# ============================================================== |
|
2059
|
|
|
|
|
|
|
sub DBUG_CATCH |
|
2060
|
|
|
|
|
|
|
{ |
|
2061
|
|
|
|
|
|
|
# No matter what, when called don't disable rebalancing the stack! |
|
2062
|
151
|
|
|
151
|
1
|
3062
|
local $dbug_global_vars{skip_eval_fix} = 0; |
|
2063
|
|
|
|
|
|
|
|
|
2064
|
151
|
|
|
|
|
499
|
_dbug_auto_fix_eval_exception (1); |
|
2065
|
|
|
|
|
|
|
|
|
2066
|
151
|
|
|
|
|
611
|
return; |
|
2067
|
|
|
|
|
|
|
} |
|
2068
|
|
|
|
|
|
|
|
|
2069
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
2070
|
|
|
|
|
|
|
# Auto-handles dynamic DBUG_CATCH logic ... It's a real mess! |
|
2071
|
|
|
|
|
|
|
# This was the reason keys EVAL_LN & MULTI were added to the function block ... |
|
2072
|
|
|
|
|
|
|
# Called whenever anything writes to the fish logs ... |
|
2073
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
2074
|
|
|
|
|
|
|
# Works since "eval" is in Perl's stack trace and I can easily detect from the |
|
2075
|
|
|
|
|
|
|
# fish stack if we're still in the same eval block of code. |
|
2076
|
|
|
|
|
|
|
# It works for "try" since it eventually puts an "eval" onto the stack itself. |
|
2077
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
2078
|
|
|
|
|
|
|
# Doesn't work for perl -we '...' scripts since everything is a 1 liner! |
|
2079
|
|
|
|
|
|
|
# -------------------------------------------------------------- |
|
2080
|
|
|
|
|
|
|
# Too bad we can't auto-balance other usage issues with this module. |
|
2081
|
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
sub _dbug_auto_fix_eval_exception |
|
2083
|
|
|
|
|
|
|
{ |
|
2084
|
10140
|
|
100
|
10140
|
|
37617
|
my $from_dbug_catch_flag = shift || 0; |
|
2085
|
|
|
|
|
|
|
|
|
2086
|
10140
|
100
|
|
|
|
26043
|
return if ( $dbug_global_vars{skip_eval_fix} ); |
|
2087
|
|
|
|
|
|
|
|
|
2088
|
8788
|
|
|
|
|
22296
|
my ($eval_cnt, $eval_lns) = _eval_depth (2); |
|
2089
|
|
|
|
|
|
|
|
|
2090
|
8788
|
|
|
|
|
14475
|
my @list = @{$dbug_global_vars{functions}}; |
|
|
8788
|
|
|
|
|
23889
|
|
|
2091
|
|
|
|
|
|
|
|
|
2092
|
8788
|
100
|
|
|
|
20207
|
my $pop_msg = $from_dbug_catch_flag |
|
2093
|
|
|
|
|
|
|
? " *** Caught eval/try trap and popped the fish stack! ***" |
|
2094
|
|
|
|
|
|
|
: " *** Auto-balancing the fish stack again after leaving an eval/try block! ***"; |
|
2095
|
|
|
|
|
|
|
|
|
2096
|
8788
|
|
|
|
|
18810
|
foreach my $b ( reverse @list ) { |
|
2097
|
8618
|
100
|
|
|
|
24480
|
last if ( $b->{EVAL} < $eval_cnt ); |
|
2098
|
8331
|
100
|
100
|
|
|
41176
|
last if ( $eval_cnt == 0 && $b->{EVAL} == 0 ); |
|
2099
|
|
|
|
|
|
|
|
|
2100
|
|
|
|
|
|
|
# Don't pop items owned by another thread/PID ... |
|
2101
|
1613
|
50
|
66
|
|
|
4801
|
last if ( exists $b->{MULTI} && $b->{MULTI} ne _indent_multi (1) ); |
|
2102
|
|
|
|
|
|
|
|
|
2103
|
|
|
|
|
|
|
# Checking if in the same eval block. May have to add a filename |
|
2104
|
|
|
|
|
|
|
# comparision to this logic in the future. |
|
2105
|
|
|
|
|
|
|
# IE two evals with the same depth & line numbers from different files. |
|
2106
|
1613
|
100
|
|
|
|
4132
|
if ( $b->{EVAL} == $eval_cnt ) { |
|
2107
|
1400
|
100
|
|
|
|
4287
|
last if ( $b->{EVAL_LN} == $eval_lns->[0] ); |
|
2108
|
3
|
|
|
|
|
7
|
--$eval_cnt; |
|
2109
|
3
|
|
|
|
|
4
|
shift ( @{$eval_lns} ); |
|
|
3
|
|
|
|
|
7
|
|
|
2110
|
|
|
|
|
|
|
} |
|
2111
|
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
# Now lets pop off the bypassed return calls ... |
|
2113
|
216
|
|
|
|
|
378
|
pop ( @{$dbug_global_vars{functions}} ); |
|
|
216
|
|
|
|
|
499
|
|
|
2114
|
|
|
|
|
|
|
|
|
2115
|
216
|
100
|
|
|
|
658
|
unless ( $b->{PAUSED} ) { |
|
2116
|
152
|
|
|
|
|
356
|
$dbug_global_vars{pause} = 0; |
|
2117
|
|
|
|
|
|
|
|
|
2118
|
152
|
50
|
|
|
|
472
|
if ( DBUG_EXECUTE ( DBUG_FILTER_LEVEL_FUNC ) ) { |
|
2119
|
152
|
|
|
|
|
348
|
my $func = $b->{NAME}; |
|
2120
|
152
|
100
|
|
|
|
421
|
my $lbl = ( $b->{FUNC} ) ? "<" : "<<"; |
|
2121
|
152
|
|
|
|
|
628
|
my $elaps = _dbug_elapsed_time ($b->{TIME}); |
|
2122
|
152
|
|
|
|
|
682
|
_printing $b->{COLOR1}, _indent ("${lbl}${func}"), $pop_msg, $elaps, $b->{COLOR2}, "\n"; |
|
2123
|
|
|
|
|
|
|
} |
|
2124
|
|
|
|
|
|
|
} |
|
2125
|
|
|
|
|
|
|
} |
|
2126
|
|
|
|
|
|
|
|
|
2127
|
8788
|
|
|
|
|
22448
|
return; |
|
2128
|
|
|
|
|
|
|
} |
|
2129
|
|
|
|
|
|
|
|
|
2130
|
|
|
|
|
|
|
|
|
2131
|
|
|
|
|
|
|
=item DBUG_PAUSE ( ) |
|
2132
|
|
|
|
|
|
|
|
|
2133
|
|
|
|
|
|
|
Temporarily turns B off until the pause request goes out of scope. This |
|
2134
|
|
|
|
|
|
|
allows you to conditionally disable B for particularly verbose blocks of |
|
2135
|
|
|
|
|
|
|
code or any other reason you choose. |
|
2136
|
|
|
|
|
|
|
|
|
2137
|
|
|
|
|
|
|
The scope of the pause is defined as the previous call to a I |
|
2138
|
|
|
|
|
|
|
function variant and it's coresponding call to a I variant. |
|
2139
|
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
While the pause is active, calling it again does nothing. |
|
2141
|
|
|
|
|
|
|
|
|
2142
|
|
|
|
|
|
|
=cut |
|
2143
|
|
|
|
|
|
|
|
|
2144
|
|
|
|
|
|
|
# ============================================================== |
|
2145
|
|
|
|
|
|
|
sub DBUG_PAUSE |
|
2146
|
|
|
|
|
|
|
{ |
|
2147
|
45
|
100
|
|
45
|
1
|
303
|
return if ( $dbug_global_vars{pause} ); |
|
2148
|
|
|
|
|
|
|
|
|
2149
|
43
|
|
|
|
|
137
|
_dbug_print_pkg_tag ( DBUG_FILTER_LEVEL_INFO, |
|
2150
|
|
|
|
|
|
|
"PAUSE: Fish has been paused! In %s", |
|
2151
|
|
|
|
|
|
|
_dbug_called_by (1) ); |
|
2152
|
|
|
|
|
|
|
|
|
2153
|
43
|
|
|
|
|
100
|
$dbug_global_vars{pause} = 1; |
|
2154
|
|
|
|
|
|
|
|
|
2155
|
43
|
|
|
|
|
158
|
return; |
|
2156
|
|
|
|
|
|
|
} |
|
2157
|
|
|
|
|
|
|
|
|
2158
|
|
|
|
|
|
|
|
|
2159
|
|
|
|
|
|
|
=item DBUG_MASK ( @offsets ) |
|
2160
|
|
|
|
|
|
|
|
|
2161
|
|
|
|
|
|
|
Sometimes the return value(s) returned by I and/or it's variants |
|
2162
|
|
|
|
|
|
|
contain sensitive data that you wouldn't want to see recorded in a B file. |
|
2163
|
|
|
|
|
|
|
Such as user names and passwords. So we need a way to mask these values without |
|
2164
|
|
|
|
|
|
|
the programmer having to jump through too many hoops to do so. |
|
2165
|
|
|
|
|
|
|
|
|
2166
|
|
|
|
|
|
|
So this function tells the I call that goes with the most recent |
|
2167
|
|
|
|
|
|
|
I variant which of its return values to mask. So if you have |
|
2168
|
|
|
|
|
|
|
multiple exit points to the current function, this one call handles the masking |
|
2169
|
|
|
|
|
|
|
for them all. |
|
2170
|
|
|
|
|
|
|
|
|
2171
|
|
|
|
|
|
|
The I<@offsets> array consists of 1 or more integers representing the offset to |
|
2172
|
|
|
|
|
|
|
expected return values. Or the special case of B<-1> to say mask all return |
|
2173
|
|
|
|
|
|
|
values. |
|
2174
|
|
|
|
|
|
|
|
|
2175
|
|
|
|
|
|
|
So I would cause I to mask the 1st and 3rd elements |
|
2176
|
|
|
|
|
|
|
being returned. |
|
2177
|
|
|
|
|
|
|
|
|
2178
|
|
|
|
|
|
|
If you pass a non-numeric value, it will assume that the return value is a hash |
|
2179
|
|
|
|
|
|
|
and that you are providing a hash key who's value needs to be masked. |
|
2180
|
|
|
|
|
|
|
|
|
2181
|
|
|
|
|
|
|
So if you say I, it might return |
|
2182
|
|
|
|
|
|
|
B*****E], [ONE], [1]>>. And since there is no key "THREE" |
|
2183
|
|
|
|
|
|
|
in your hash, nothing was masked for it. And as you can see, we only mask the |
|
2184
|
|
|
|
|
|
|
value, not the key itself! The key is case sensitive, so "two" wouldn't have |
|
2185
|
|
|
|
|
|
|
matched anything. Also remember that the order of the keys returned is random, |
|
2186
|
|
|
|
|
|
|
so pure numeric offsets wouldn't give you the desired results. |
|
2187
|
|
|
|
|
|
|
|
|
2188
|
|
|
|
|
|
|
We could have combined both examples with I. |
|
2189
|
|
|
|
|
|
|
|
|
2190
|
|
|
|
|
|
|
=cut |
|
2191
|
|
|
|
|
|
|
|
|
2192
|
|
|
|
|
|
|
# ============================================================== |
|
2193
|
|
|
|
|
|
|
sub DBUG_MASK |
|
2194
|
|
|
|
|
|
|
{ |
|
2195
|
42
|
|
|
42
|
1
|
327
|
my @lst = sort (@_); # So the list of offsets are in predictable order. |
|
2196
|
|
|
|
|
|
|
|
|
2197
|
42
|
100
|
|
|
|
201
|
return if ( $#lst == -1 ); |
|
2198
|
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
|
|
2200
|
|
|
|
|
|
|
# Silently drop any invalid masking offset. |
|
2201
|
34
|
|
|
|
|
124
|
my (%amask, %hmask); |
|
2202
|
34
|
|
|
|
|
105
|
my ($acnt, $hcnt) = (0, 0); |
|
2203
|
34
|
|
|
|
|
78
|
foreach my $idx (@lst) { |
|
2204
|
61
|
50
|
|
|
|
159
|
next unless ( defined $idx ); |
|
2205
|
61
|
50
|
|
|
|
273
|
next if ( $idx =~ m/^\s*$/ ); |
|
2206
|
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
# if non-numeric ... assume it's a hash key to match. |
|
2208
|
61
|
100
|
|
|
|
320
|
unless ( $idx =~ m/^-?\d+$/ ) { |
|
2209
|
3
|
|
|
|
|
9
|
$hmask{$idx} = 1; |
|
2210
|
3
|
|
|
|
|
4
|
++$hcnt; |
|
2211
|
3
|
|
|
|
|
6
|
next; |
|
2212
|
|
|
|
|
|
|
} |
|
2213
|
|
|
|
|
|
|
|
|
2214
|
58
|
|
|
|
|
98
|
++$acnt; |
|
2215
|
58
|
100
|
|
|
|
167
|
if ( $idx <= -1 ) { |
|
2216
|
2
|
|
|
|
|
8
|
$amask{-1} = 1; |
|
2217
|
2
|
|
|
|
|
4
|
$hcnt = 0; |
|
2218
|
2
|
|
|
|
|
6
|
last; |
|
2219
|
|
|
|
|
|
|
} |
|
2220
|
|
|
|
|
|
|
|
|
2221
|
56
|
|
|
|
|
190
|
$amask{$idx + 0} = 1; # The +0 removes leading 0's. |
|
2222
|
|
|
|
|
|
|
} |
|
2223
|
|
|
|
|
|
|
|
|
2224
|
|
|
|
|
|
|
# Updates the most recent ENTER block ... |
|
2225
|
34
|
100
|
|
|
|
84
|
if ( $acnt > 0 ) { |
|
2226
|
33
|
|
|
|
|
158
|
$dbug_global_vars{functions}->[-1]->{AMASK} = \%amask; |
|
2227
|
|
|
|
|
|
|
} else { |
|
2228
|
1
|
|
|
|
|
3
|
delete $dbug_global_vars{functions}->[-1]->{AMASK}; |
|
2229
|
|
|
|
|
|
|
} |
|
2230
|
34
|
100
|
|
|
|
83
|
if ( $hcnt > 0 ) { |
|
2231
|
1
|
|
|
|
|
4
|
$dbug_global_vars{functions}->[-1]->{HMASK} = \%hmask; |
|
2232
|
|
|
|
|
|
|
} else { |
|
2233
|
33
|
|
|
|
|
95
|
delete $dbug_global_vars{functions}->[-1]->{HMASK}; |
|
2234
|
|
|
|
|
|
|
} |
|
2235
|
|
|
|
|
|
|
|
|
2236
|
34
|
|
|
|
|
140
|
return; |
|
2237
|
|
|
|
|
|
|
} |
|
2238
|
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
|
|
2240
|
|
|
|
|
|
|
=item DBUG_MASK_NEXT_FUNC_CALL ( @offsets ) |
|
2241
|
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
Sometimes some arguments passed to I contain sensitive data |
|
2243
|
|
|
|
|
|
|
that you wouldn't want to see recorded in a B file. Such as user names |
|
2244
|
|
|
|
|
|
|
and passwords. So we need a way to mask these values without the programmer |
|
2245
|
|
|
|
|
|
|
having to jump through too many hoops to do so. |
|
2246
|
|
|
|
|
|
|
|
|
2247
|
|
|
|
|
|
|
So this function tells the next I or I call |
|
2248
|
|
|
|
|
|
|
which arguments are sensitive. If you call it multiple times before the next |
|
2249
|
|
|
|
|
|
|
time the enter function is called it will only remember the last time called! |
|
2250
|
|
|
|
|
|
|
|
|
2251
|
|
|
|
|
|
|
The I<@offsets> array consists of 1 or more integers representing the offset to |
|
2252
|
|
|
|
|
|
|
expected arguments. Or the special case of B<-1> to say mask all arguments |
|
2253
|
|
|
|
|
|
|
passed. Any other negative value will be ignored. |
|
2254
|
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
But should any offset be non-numeric, it assumes one of the arguments was a |
|
2256
|
|
|
|
|
|
|
hash I with that string as it's key. And so it will mask the |
|
2257
|
|
|
|
|
|
|
next value after it if the key exists. Needed since the order of hash keys is |
|
2258
|
|
|
|
|
|
|
random. Also in this case the hash key is case insensitive. So "abc" and "ABC" |
|
2259
|
|
|
|
|
|
|
represent the same hash key. |
|
2260
|
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
So I would cause I |
|
2262
|
|
|
|
|
|
|
to mask the 1st and 3rd elements passed to it as well as the next argument |
|
2263
|
|
|
|
|
|
|
after the "password" key. |
|
2264
|
|
|
|
|
|
|
|
|
2265
|
|
|
|
|
|
|
Any invalid offset value will be silently ignored. |
|
2266
|
|
|
|
|
|
|
|
|
2267
|
|
|
|
|
|
|
=cut |
|
2268
|
|
|
|
|
|
|
|
|
2269
|
|
|
|
|
|
|
# ============================================================== |
|
2270
|
|
|
|
|
|
|
sub DBUG_MASK_NEXT_FUNC_CALL |
|
2271
|
|
|
|
|
|
|
{ |
|
2272
|
11
|
|
|
11
|
1
|
92
|
my @args = @_; |
|
2273
|
|
|
|
|
|
|
|
|
2274
|
11
|
|
|
|
|
29
|
delete $dbug_global_vars{mask_func_call}; |
|
2275
|
|
|
|
|
|
|
|
|
2276
|
11
|
50
|
|
|
|
34
|
return if ( $#args == -1 ); |
|
2277
|
|
|
|
|
|
|
|
|
2278
|
11
|
|
|
|
|
25
|
my (@offsets, %mask); |
|
2279
|
11
|
|
|
|
|
32
|
my ($acnt, $hcnt, $all) = (0, 0, 0); |
|
2280
|
|
|
|
|
|
|
|
|
2281
|
11
|
|
|
|
|
64
|
foreach my $idx (@args) { |
|
2282
|
16
|
50
|
|
|
|
47
|
next unless ( defined $idx ); |
|
2283
|
16
|
50
|
|
|
|
84
|
next if ( $idx =~ m/^\s*$/ ); |
|
2284
|
|
|
|
|
|
|
|
|
2285
|
16
|
100
|
|
|
|
90
|
if ( $idx =~ m/^-\d+$/ ) { |
|
|
|
100
|
|
|
|
|
|
|
2286
|
4
|
50
|
|
|
|
14
|
if ( $idx == -1 ) { |
|
2287
|
4
|
|
|
|
|
9
|
$acnt = $hcnt = 0; |
|
2288
|
4
|
|
|
|
|
8
|
$all = 1; |
|
2289
|
4
|
|
|
|
|
12
|
last; |
|
2290
|
|
|
|
|
|
|
} |
|
2291
|
|
|
|
|
|
|
|
|
2292
|
|
|
|
|
|
|
} elsif ( $idx =~ m/^\d+$/ ) { |
|
2293
|
9
|
|
|
|
|
26
|
push (@offsets, $idx); |
|
2294
|
9
|
|
|
|
|
19
|
++$acnt; |
|
2295
|
|
|
|
|
|
|
|
|
2296
|
|
|
|
|
|
|
} else { |
|
2297
|
3
|
|
|
|
|
17
|
$mask{lc($idx)} = 1; # Make case insensitive. |
|
2298
|
3
|
|
|
|
|
12
|
++$hcnt; |
|
2299
|
|
|
|
|
|
|
} |
|
2300
|
|
|
|
|
|
|
} |
|
2301
|
|
|
|
|
|
|
|
|
2302
|
|
|
|
|
|
|
# Register that the next call to DBUG_ENTER_FUNC() should mask it's values! |
|
2303
|
11
|
50
|
|
|
|
51
|
if ( ($acnt + $hcnt + $all) > 0 ) { |
|
2304
|
11
|
|
|
|
|
22
|
my %mask_it; |
|
2305
|
|
|
|
|
|
|
|
|
2306
|
11
|
|
|
|
|
33
|
$mask_it{ALL} = $all; |
|
2307
|
11
|
100
|
|
|
|
50
|
$mask_it{HASH} = \%mask if ( $hcnt > 0 ); |
|
2308
|
|
|
|
|
|
|
|
|
2309
|
11
|
100
|
|
|
|
30
|
if ( $acnt > 0 ) { |
|
2310
|
4
|
|
|
|
|
32
|
@offsets = sort (@offsets); |
|
2311
|
4
|
|
|
|
|
16
|
$mask_it{ARRAY} = \@offsets; |
|
2312
|
|
|
|
|
|
|
} |
|
2313
|
|
|
|
|
|
|
|
|
2314
|
11
|
|
|
|
|
32
|
$dbug_global_vars{mask_func_call} = \%mask_it; |
|
2315
|
|
|
|
|
|
|
} |
|
2316
|
|
|
|
|
|
|
|
|
2317
|
11
|
|
|
|
|
71
|
return; |
|
2318
|
|
|
|
|
|
|
} |
|
2319
|
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
|
|
2321
|
|
|
|
|
|
|
=item DBUG_FILTER ( [$level] ) |
|
2322
|
|
|
|
|
|
|
|
|
2323
|
|
|
|
|
|
|
This function allows you to filter out unwanted messages being written to |
|
2324
|
|
|
|
|
|
|
B. This is controlled by the value of I<$level> being passed to |
|
2325
|
|
|
|
|
|
|
this method. If you never call this method, by default you'll get |
|
2326
|
|
|
|
|
|
|
everything. |
|
2327
|
|
|
|
|
|
|
|
|
2328
|
|
|
|
|
|
|
If you call it with no I<$level> provided, the current level will remain |
|
2329
|
|
|
|
|
|
|
unchanged! |
|
2330
|
|
|
|
|
|
|
|
|
2331
|
|
|
|
|
|
|
It returns up to two values: (old_level, new_level) |
|
2332
|
|
|
|
|
|
|
|
|
2333
|
|
|
|
|
|
|
The old_level may be -1 if it was previously using custom filtering. |
|
2334
|
|
|
|
|
|
|
|
|
2335
|
|
|
|
|
|
|
The valid levels are defined by the following exposed constants: |
|
2336
|
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
=over 4 |
|
2338
|
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
B - Just the function entry and exit points. |
|
2340
|
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
B - Add on the function arguments & return values. |
|
2342
|
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
B - Add on DBUG_PRINT calls with ERROR as their tag. |
|
2344
|
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
B - Add on trapped writes to STDOUT & STDERR. |
|
2346
|
|
|
|
|
|
|
|
|
2347
|
|
|
|
|
|
|
B - Add on DBUG_PRINT calls with WARN or WARNING as |
|
2348
|
|
|
|
|
|
|
their tag. |
|
2349
|
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
B - Add on DBUG_PRINT calls with DEBUG or DBUG as |
|
2351
|
|
|
|
|
|
|
their tag. |
|
2352
|
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
B - Add on DBUG_PRINT calls with INFO as their tag. |
|
2354
|
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
B - Include everything! (default) |
|
2356
|
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
B - Include Fred::Fish::DBUG diagnostics. |
|
2358
|
|
|
|
|
|
|
|
|
2359
|
|
|
|
|
|
|
=back |
|
2360
|
|
|
|
|
|
|
|
|
2361
|
|
|
|
|
|
|
=cut |
|
2362
|
|
|
|
|
|
|
|
|
2363
|
|
|
|
|
|
|
# ============================================================== |
|
2364
|
|
|
|
|
|
|
sub DBUG_FILTER |
|
2365
|
|
|
|
|
|
|
{ |
|
2366
|
84
|
|
|
84
|
1
|
377
|
my $level = shift; |
|
2367
|
|
|
|
|
|
|
|
|
2368
|
84
|
|
|
|
|
150
|
my $old_lvl; |
|
2369
|
84
|
50
|
|
|
|
276
|
if ( $dbug_global_vars{filter_style} == 1 ) { |
|
2370
|
84
|
|
50
|
|
|
329
|
$old_lvl = $dbug_global_vars{filter} || DBUG_FILTER_LEVEL_MAX; |
|
2371
|
|
|
|
|
|
|
} else { |
|
2372
|
0
|
|
|
|
|
0
|
$old_lvl = -1; # Currently using custom filtering ... |
|
2373
|
|
|
|
|
|
|
} |
|
2374
|
84
|
|
|
|
|
242
|
my $new_lvl = $old_lvl; |
|
2375
|
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
# Only update the level if it's valid ... |
|
2377
|
84
|
100
|
66
|
|
|
567
|
if ( $level && $level =~ m/^\d+$/ ) { |
|
2378
|
39
|
100
|
66
|
|
|
267
|
if (DBUG_FILTER_LEVEL_MIN <= $level && $level <= DBUG_FILTER_LEVEL_MAX) { |
|
|
|
50
|
|
|
|
|
|
|
2379
|
32
|
|
|
|
|
90
|
$new_lvl = $dbug_global_vars{filter} = $level; |
|
2380
|
|
|
|
|
|
|
} elsif ( $level == DBUG_FILTER_LEVEL_INTERNAL ) { |
|
2381
|
7
|
|
|
|
|
27
|
$new_lvl = $dbug_global_vars{filter} = $level; |
|
2382
|
|
|
|
|
|
|
} |
|
2383
|
|
|
|
|
|
|
|
|
2384
|
39
|
100
|
|
|
|
195
|
if ( $old_lvl != $new_lvl ) { |
|
2385
|
38
|
50
|
33
|
|
|
262
|
my $old = ($old_lvl == -1) ? "Custom Level" : ($dbug_levels[$old_lvl] || $old_lvl); |
|
2386
|
38
|
|
33
|
|
|
208
|
my $new = $dbug_levels[$new_lvl] || $new_lvl; |
|
2387
|
38
|
100
|
|
|
|
153
|
my $direction = ($old_lvl > $new_lvl) ? "down to" : "up to"; |
|
2388
|
|
|
|
|
|
|
|
|
2389
|
|
|
|
|
|
|
# Standard Style ... |
|
2390
|
38
|
|
|
|
|
100
|
$dbug_global_vars{filter_style} = 1; |
|
2391
|
|
|
|
|
|
|
|
|
2392
|
|
|
|
|
|
|
# Determine index to whom to say was our caller. |
|
2393
|
38
|
|
100
|
|
|
227
|
my $c = (caller(1))[3] || ""; |
|
2394
|
|
|
|
|
|
|
|
|
2395
|
38
|
|
|
|
|
148
|
_dbug_print_pkg_tag ( DBUG_FILTER_LEVEL_MIN, |
|
2396
|
|
|
|
|
|
|
"The fish filtering level was changed from\n%s %s %s\n%s", |
|
2397
|
|
|
|
|
|
|
$old, $direction, $new, _dbug_called_by (1) ); |
|
2398
|
|
|
|
|
|
|
} |
|
2399
|
|
|
|
|
|
|
} |
|
2400
|
|
|
|
|
|
|
|
|
2401
|
84
|
50
|
|
|
|
402
|
return ( wantarray ? ( $old_lvl, $new_lvl ) : $old_lvl ); |
|
2402
|
|
|
|
|
|
|
} |
|
2403
|
|
|
|
|
|
|
|
|
2404
|
|
|
|
|
|
|
|
|
2405
|
|
|
|
|
|
|
=item DBUG_CUSTOM_FILTER ( @levels ) |
|
2406
|
|
|
|
|
|
|
|
|
2407
|
|
|
|
|
|
|
This function allows you to customize which filter level(s) should appear in |
|
2408
|
|
|
|
|
|
|
your B logs. You can pick and choose from any of the levels defined by |
|
2409
|
|
|
|
|
|
|
I. If you provide an invalid level, it will be silently ignored. |
|
2410
|
|
|
|
|
|
|
Any level not listed will no longer appear in B. |
|
2411
|
|
|
|
|
|
|
|
|
2412
|
|
|
|
|
|
|
=cut |
|
2413
|
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
# ============================================================== |
|
2415
|
|
|
|
|
|
|
sub DBUG_CUSTOM_FILTER |
|
2416
|
|
|
|
|
|
|
{ |
|
2417
|
|
|
|
|
|
|
# Convert this list of arguments into a hash of valid levels ... |
|
2418
|
0
|
|
|
0
|
1
|
0
|
my %levels; |
|
2419
|
0
|
|
|
|
|
0
|
foreach my $lvl (@_) { |
|
2420
|
0
|
0
|
0
|
|
|
0
|
next unless ( defined $lvl && $lvl =~ m/^\d+$/ ); |
|
2421
|
|
|
|
|
|
|
|
|
2422
|
0
|
0
|
0
|
|
|
0
|
if (DBUG_FILTER_LEVEL_MIN <= $lvl || $lvl <= DBUG_FILTER_LEVEL_MAX) { |
|
|
|
0
|
|
|
|
|
|
|
2423
|
0
|
|
|
|
|
0
|
$levels{$lvl + 0} = 1; |
|
2424
|
|
|
|
|
|
|
} elsif ( $lvl == DBUG_FILTER_LEVEL_INTERNAL ) { |
|
2425
|
0
|
|
|
|
|
0
|
$levels{DBUG_FILTER_LEVEL_INTERNAL} = 1; |
|
2426
|
|
|
|
|
|
|
} |
|
2427
|
|
|
|
|
|
|
} |
|
2428
|
|
|
|
|
|
|
|
|
2429
|
0
|
|
|
|
|
0
|
my ( $msg, $sep, $plvl ) = ( "", "", DBUG_FILTER_LEVEL_MIN ); |
|
2430
|
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
# Now lets turn on/off the individual filter levels ... |
|
2432
|
0
|
|
|
|
|
0
|
foreach (DBUG_FILTER_LEVEL_MIN..DBUG_FILTER_LEVEL_MAX, DBUG_FILTER_LEVEL_INTERNAL) { |
|
2433
|
0
|
0
|
|
|
|
0
|
$dbug_custom_levels[$_] = ( $levels{$_} ) ? 1 : 0; |
|
2434
|
0
|
0
|
|
|
|
0
|
if ( $dbug_custom_levels[$_] ) { |
|
2435
|
0
|
|
|
|
|
0
|
$msg .= ${sep} . $dbug_levels[$_]; |
|
2436
|
0
|
0
|
|
|
|
0
|
$plvl = $_ if ( $sep eq "" ); |
|
2437
|
0
|
|
|
|
|
0
|
$sep = ", "; |
|
2438
|
|
|
|
|
|
|
} |
|
2439
|
|
|
|
|
|
|
} |
|
2440
|
|
|
|
|
|
|
|
|
2441
|
|
|
|
|
|
|
# Custom Style ... |
|
2442
|
0
|
|
|
|
|
0
|
$dbug_global_vars{filter_style} = -1; |
|
2443
|
|
|
|
|
|
|
|
|
2444
|
|
|
|
|
|
|
# What if called by the inverse function? |
|
2445
|
0
|
|
0
|
|
|
0
|
my $c = (caller(1))[3] || ""; |
|
2446
|
0
|
0
|
|
|
|
0
|
return if ( $c eq __PACKAGE__ . "::DBUG_CUSTOM_FILTER_OFF" ); |
|
2447
|
|
|
|
|
|
|
|
|
2448
|
0
|
|
|
|
|
0
|
_dbug_print_pkg_tag ( $plvl, "The filtering level was changed to custom level(s): %s", $msg ); |
|
2449
|
|
|
|
|
|
|
|
|
2450
|
0
|
|
|
|
|
0
|
return; |
|
2451
|
|
|
|
|
|
|
} |
|
2452
|
|
|
|
|
|
|
|
|
2453
|
|
|
|
|
|
|
|
|
2454
|
|
|
|
|
|
|
=item DBUG_CUSTOM_FILTER_OFF ( @levels ) |
|
2455
|
|
|
|
|
|
|
|
|
2456
|
|
|
|
|
|
|
This function is the reverse of I. Instead of specifying |
|
2457
|
|
|
|
|
|
|
the filter levels you wish to see, you specify the list of levels you don't |
|
2458
|
|
|
|
|
|
|
want to see. Sometimes it's just easier to list what you don't want to see |
|
2459
|
|
|
|
|
|
|
in B. |
|
2460
|
|
|
|
|
|
|
|
|
2461
|
|
|
|
|
|
|
=cut |
|
2462
|
|
|
|
|
|
|
|
|
2463
|
|
|
|
|
|
|
# ============================================================== |
|
2464
|
|
|
|
|
|
|
sub DBUG_CUSTOM_FILTER_OFF |
|
2465
|
|
|
|
|
|
|
{ |
|
2466
|
0
|
|
|
0
|
1
|
0
|
DBUG_CUSTOM_FILTER ( @_ ); # Set to custom filter levels ... |
|
2467
|
|
|
|
|
|
|
|
|
2468
|
0
|
|
|
|
|
0
|
my ( $msg, $sep, $plvl ) = ( "", "", DBUG_FILTER_LEVEL_MIN ); |
|
2469
|
|
|
|
|
|
|
|
|
2470
|
|
|
|
|
|
|
# Now lets invert the on/off settings of the individual filter levels ... |
|
2471
|
0
|
|
|
|
|
0
|
foreach (DBUG_FILTER_LEVEL_MIN..DBUG_FILTER_LEVEL_MAX, DBUG_FILTER_LEVEL_INTERNAL) { |
|
2472
|
0
|
0
|
|
|
|
0
|
$dbug_custom_levels[$_] = ( $dbug_custom_levels[$_] ) ? 0 : 1; |
|
2473
|
|
|
|
|
|
|
|
|
2474
|
0
|
0
|
|
|
|
0
|
if ( $dbug_custom_levels[$_] ) { |
|
2475
|
0
|
|
|
|
|
0
|
$msg .= ${sep} . $dbug_levels[$_]; |
|
2476
|
0
|
0
|
|
|
|
0
|
$plvl = $_ if ( $sep eq "" ); |
|
2477
|
0
|
|
|
|
|
0
|
$sep = ", "; |
|
2478
|
|
|
|
|
|
|
} |
|
2479
|
|
|
|
|
|
|
} |
|
2480
|
|
|
|
|
|
|
|
|
2481
|
0
|
|
|
|
|
0
|
_dbug_print_pkg_tag ( $plvl, "The filtering level was changed to custom level(s): %s", $msg ); |
|
2482
|
|
|
|
|
|
|
|
|
2483
|
0
|
|
|
|
|
0
|
return; |
|
2484
|
|
|
|
|
|
|
} |
|
2485
|
|
|
|
|
|
|
|
|
2486
|
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
=item DBUG_SET_FILTER_COLOR ( $level [, @color_attr] ) |
|
2488
|
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
This method allows you to control what I to use when printing to the |
|
2490
|
|
|
|
|
|
|
B logs for each filter I. Each I may use different |
|
2491
|
|
|
|
|
|
|
I or repeat the same I between I. |
|
2492
|
|
|
|
|
|
|
|
|
2493
|
|
|
|
|
|
|
See I above to see what the valid levels are. |
|
2494
|
|
|
|
|
|
|
|
|
2495
|
|
|
|
|
|
|
See L for what I strings are available. But I |
|
2496
|
|
|
|
|
|
|
or the empty string means to use no I information. (default) You may |
|
2497
|
|
|
|
|
|
|
use strings like ("red on_yellow") or ("red", "on_yellow") or even use the color |
|
2498
|
|
|
|
|
|
|
constants (RED, ON_YELLOW). |
|
2499
|
|
|
|
|
|
|
|
|
2500
|
|
|
|
|
|
|
If L is not installed, this method does nothing. If you set |
|
2501
|
|
|
|
|
|
|
I<$ENV{ANSI_COLORS_DISABLED}> to a non-zero value it will disable your I |
|
2502
|
|
|
|
|
|
|
choice as well. |
|
2503
|
|
|
|
|
|
|
|
|
2504
|
|
|
|
|
|
|
Returns B<1> if the color request was accepted, else B<0>. |
|
2505
|
|
|
|
|
|
|
|
|
2506
|
|
|
|
|
|
|
=cut |
|
2507
|
|
|
|
|
|
|
|
|
2508
|
|
|
|
|
|
|
# ============================================================== |
|
2509
|
|
|
|
|
|
|
sub DBUG_SET_FILTER_COLOR |
|
2510
|
|
|
|
|
|
|
{ |
|
2511
|
21
|
|
|
21
|
1
|
494070
|
my $level = shift; # Always non-zero ... |
|
2512
|
21
|
|
|
|
|
89
|
my @color_attr = @_; # List of color attributs. |
|
2513
|
|
|
|
|
|
|
|
|
2514
|
|
|
|
|
|
|
# If color not supported ... |
|
2515
|
21
|
50
|
|
|
|
70
|
return (0) if ( $color_supported == 0 ); |
|
2516
|
|
|
|
|
|
|
|
|
2517
|
21
|
|
|
|
|
48
|
my $valid_level = 0; |
|
2518
|
21
|
50
|
33
|
|
|
203
|
if ( $level && $level =~ m/^\d+$/ ) { |
|
2519
|
21
|
100
|
66
|
|
|
139
|
if ( (DBUG_FILTER_LEVEL_MIN <= $level && $level <= DBUG_FILTER_LEVEL_MAX) || |
|
|
|
|
100
|
|
|
|
|
|
2520
|
|
|
|
|
|
|
($level == DBUG_FILTER_LEVEL_INTERNAL) ) { |
|
2521
|
19
|
|
|
|
|
35
|
$valid_level = 1; |
|
2522
|
|
|
|
|
|
|
} |
|
2523
|
|
|
|
|
|
|
} |
|
2524
|
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
# Merge all the color attributes into a single escape sequence string ... |
|
2526
|
21
|
|
|
|
|
45
|
my $color_str = ""; |
|
2527
|
21
|
100
|
|
|
|
63
|
if ( $valid_level ) { |
|
2528
|
19
|
|
|
|
|
192
|
local $ENV{ANSI_COLORS_DISABLED} = 0; # Enable colors! |
|
2529
|
19
|
|
|
|
|
92
|
local $SIG{__DIE__} = ""; # Disable any die customization ... |
|
2530
|
|
|
|
|
|
|
|
|
2531
|
19
|
|
|
|
|
44
|
foreach my $cm ( @color_attr ) { |
|
2532
|
47
|
50
|
|
|
|
117
|
next unless (defined $cm); |
|
2533
|
47
|
50
|
|
|
|
185
|
next if ( $cm =~m/^\s*$/ ); |
|
2534
|
47
|
|
|
|
|
107
|
eval { |
|
2535
|
|
|
|
|
|
|
# Throws an exception if not a valid color string such as "red", |
|
2536
|
|
|
|
|
|
|
# "red on_yellow", or "bold red on_yellow". |
|
2537
|
47
|
|
|
|
|
171
|
my $str = color ($cm); # Convert to an escape sequence ... |
|
2538
|
26
|
|
|
|
|
773
|
$color_str .= $str; |
|
2539
|
|
|
|
|
|
|
# print STDERR "Valid Color String '$cm'\n"; |
|
2540
|
|
|
|
|
|
|
}; |
|
2541
|
47
|
100
|
|
|
|
4249
|
if ( $@ ) { |
|
2542
|
21
|
|
|
|
|
43
|
eval { |
|
2543
|
|
|
|
|
|
|
# Throws exception if color value wasn't from a color macro! |
|
2544
|
|
|
|
|
|
|
# Ex: use Term::ANSIColor qw(:constants); $color = RED; |
|
2545
|
|
|
|
|
|
|
# Not all color macro values are escape sequences ... |
|
2546
|
21
|
|
|
|
|
70
|
my @str = Term::ANSIColor::uncolor ($cm); |
|
2547
|
21
|
|
|
|
|
1025
|
foreach my $s ( @str ) { |
|
2548
|
21
|
|
|
|
|
62
|
$color_str .= color ($s); # Makes sure always an escape sequence ... |
|
2549
|
|
|
|
|
|
|
} |
|
2550
|
|
|
|
|
|
|
# print STDERR "Valid Color Macro(s): '", join (", ", @str), "'\n"; |
|
2551
|
|
|
|
|
|
|
}; |
|
2552
|
21
|
50
|
|
|
|
757
|
if ( $@ ) { |
|
2553
|
0
|
|
|
|
|
0
|
warn ("Invalid color string '$cm'.\nColor request reset to no colors for level $dbug_levels[$level]!\n"); |
|
2554
|
0
|
|
|
|
|
0
|
$color_str = ""; |
|
2555
|
0
|
|
|
|
|
0
|
last; |
|
2556
|
|
|
|
|
|
|
} |
|
2557
|
|
|
|
|
|
|
} |
|
2558
|
|
|
|
|
|
|
} |
|
2559
|
|
|
|
|
|
|
} |
|
2560
|
|
|
|
|
|
|
|
|
2561
|
|
|
|
|
|
|
# Save the results ... |
|
2562
|
21
|
100
|
|
|
|
175
|
if ( $valid_level ) { |
|
2563
|
19
|
50
|
|
|
|
57
|
if ( $color_str ) { |
|
2564
|
19
|
|
|
|
|
122
|
local $ENV{ANSI_COLORS_DISABLED} = 0; # Enable colors! |
|
2565
|
19
|
|
|
|
|
56
|
$color_list[$level] = $color_str; # Get the escape sequence for this color. |
|
2566
|
19
|
|
|
|
|
84
|
$color_clear = color ("clear"); # Back to defaults. |
|
2567
|
|
|
|
|
|
|
} else { |
|
2568
|
0
|
|
|
|
|
0
|
delete ( $color_list[$level] ); |
|
2569
|
|
|
|
|
|
|
} |
|
2570
|
|
|
|
|
|
|
} |
|
2571
|
|
|
|
|
|
|
|
|
2572
|
21
|
|
|
|
|
691
|
return ( $valid_level ); |
|
2573
|
|
|
|
|
|
|
} |
|
2574
|
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
|
|
2576
|
|
|
|
|
|
|
# ============================================================== |
|
2577
|
|
|
|
|
|
|
# Get the colors to use for the current filter level. |
|
2578
|
|
|
|
|
|
|
sub _get_filter_color |
|
2579
|
|
|
|
|
|
|
{ |
|
2580
|
8376
|
|
|
8376
|
|
14082
|
my $level = shift; |
|
2581
|
|
|
|
|
|
|
|
|
2582
|
8376
|
50
|
|
|
|
18564
|
return ("", "") if ( $color_supported == 0 ); |
|
2583
|
8376
|
100
|
|
|
|
23394
|
return ("", "") if ( $ENV{ANSI_COLORS_DISABLED} ); |
|
2584
|
8220
|
100
|
|
|
|
28841
|
return ("", "") unless ( defined $color_list[$level] ); |
|
2585
|
|
|
|
|
|
|
|
|
2586
|
183
|
|
|
|
|
650
|
return ( $color_list[$level], $color_clear ); |
|
2587
|
|
|
|
|
|
|
} |
|
2588
|
|
|
|
|
|
|
|
|
2589
|
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
=item DBUG_ACTIVE ( ) |
|
2591
|
|
|
|
|
|
|
|
|
2592
|
|
|
|
|
|
|
This function tells you if B is currently turned on or not. |
|
2593
|
|
|
|
|
|
|
|
|
2594
|
|
|
|
|
|
|
It will return B<0> if I was never called, called with |
|
2595
|
|
|
|
|
|
|
S 1>>, or if I is currently in effect. It ignores |
|
2596
|
|
|
|
|
|
|
any filter request. |
|
2597
|
|
|
|
|
|
|
|
|
2598
|
|
|
|
|
|
|
It will return B<1> if B is currently writing to a file. |
|
2599
|
|
|
|
|
|
|
|
|
2600
|
|
|
|
|
|
|
It will return B<-1> if B is currently writing to your screen via |
|
2601
|
|
|
|
|
|
|
B or B. |
|
2602
|
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
=cut |
|
2604
|
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
# ============================================================== |
|
2606
|
|
|
|
|
|
|
sub DBUG_ACTIVE |
|
2607
|
|
|
|
|
|
|
{ |
|
2608
|
20321
|
|
|
20321
|
1
|
31777
|
my $active = 0; # Assume not currently active ... |
|
2609
|
|
|
|
|
|
|
|
|
2610
|
20321
|
100
|
100
|
|
|
93510
|
if ( $dbug_global_vars{on} && (! $dbug_global_vars{pause}) && |
|
|
|
|
66
|
|
|
|
|
|
2611
|
|
|
|
|
|
|
_limit_thread_check () ) { |
|
2612
|
18211
|
50
|
|
|
|
37906
|
$active = ($dbug_global_vars{screen}) ? -1 : 1; |
|
2613
|
|
|
|
|
|
|
} |
|
2614
|
|
|
|
|
|
|
|
|
2615
|
20321
|
|
|
|
|
42579
|
return ( $active ); |
|
2616
|
|
|
|
|
|
|
} |
|
2617
|
|
|
|
|
|
|
|
|
2618
|
|
|
|
|
|
|
|
|
2619
|
|
|
|
|
|
|
=item DBUG_EXECUTE ( $tag ) |
|
2620
|
|
|
|
|
|
|
|
|
2621
|
|
|
|
|
|
|
This boolean function helps determine if a call to I using this |
|
2622
|
|
|
|
|
|
|
I<$tag> would actually result in the print request being written to B |
|
2623
|
|
|
|
|
|
|
or not. |
|
2624
|
|
|
|
|
|
|
|
|
2625
|
|
|
|
|
|
|
It returns B<1> if the I would write it to B and B<0> if for |
|
2626
|
|
|
|
|
|
|
any reason it wouldn't write to B. It returns B<-1> if B is |
|
2627
|
|
|
|
|
|
|
currently writing to your screena via B or B. |
|
2628
|
|
|
|
|
|
|
|
|
2629
|
|
|
|
|
|
|
Reasons for returning B<0> would be: Fish was turned off, pause was turned on, |
|
2630
|
|
|
|
|
|
|
or you set your B filtering level too low. |
|
2631
|
|
|
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
This way you can write conditional code based on what's being written to fish! |
|
2633
|
|
|
|
|
|
|
|
|
2634
|
|
|
|
|
|
|
=cut |
|
2635
|
|
|
|
|
|
|
|
|
2636
|
|
|
|
|
|
|
# ============================================================== |
|
2637
|
|
|
|
|
|
|
sub DBUG_EXECUTE |
|
2638
|
|
|
|
|
|
|
{ |
|
2639
|
11074
|
|
|
11074
|
1
|
20184
|
my $tag = shift; |
|
2640
|
|
|
|
|
|
|
|
|
2641
|
|
|
|
|
|
|
# Is fish active ? |
|
2642
|
11074
|
|
|
|
|
23126
|
my $active = DBUG_ACTIVE (); # -1, 0, 1 |
|
2643
|
|
|
|
|
|
|
|
|
2644
|
|
|
|
|
|
|
# Return if inactive ... |
|
2645
|
11074
|
100
|
|
|
|
26436
|
return (0) unless ( $active ); |
|
2646
|
|
|
|
|
|
|
|
|
2647
|
|
|
|
|
|
|
# Are we filtering the results out of fish ??? |
|
2648
|
9356
|
100
|
|
|
|
20691
|
return (0) unless ( _filter_on ( $tag ) ); |
|
2649
|
|
|
|
|
|
|
|
|
2650
|
8888
|
|
|
|
|
20480
|
return ($active); # This tag would be written to fish! |
|
2651
|
|
|
|
|
|
|
} |
|
2652
|
|
|
|
|
|
|
|
|
2653
|
|
|
|
|
|
|
|
|
2654
|
|
|
|
|
|
|
=item DBUG_FILE_NAME ( ) |
|
2655
|
|
|
|
|
|
|
|
|
2656
|
|
|
|
|
|
|
Returns the full absolute file name to the B log created by I. |
|
2657
|
|
|
|
|
|
|
If I was passed an open file handle, then the file name is unknown |
|
2658
|
|
|
|
|
|
|
and the empty string is returned! |
|
2659
|
|
|
|
|
|
|
|
|
2660
|
|
|
|
|
|
|
=cut |
|
2661
|
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
# ============================================================== |
|
2663
|
|
|
|
|
|
|
sub DBUG_FILE_NAME |
|
2664
|
|
|
|
|
|
|
{ |
|
2665
|
46
|
|
|
46
|
1
|
430
|
return ( $dbug_global_vars{file} ); |
|
2666
|
|
|
|
|
|
|
} |
|
2667
|
|
|
|
|
|
|
|
|
2668
|
|
|
|
|
|
|
|
|
2669
|
|
|
|
|
|
|
=item DBUG_FILE_HANDLE ( ) |
|
2670
|
|
|
|
|
|
|
|
|
2671
|
|
|
|
|
|
|
Returns the file handle to the open I file created by I. If |
|
2672
|
|
|
|
|
|
|
I wasn't called, or called using I, then it returns |
|
2673
|
|
|
|
|
|
|
I instead. |
|
2674
|
|
|
|
|
|
|
|
|
2675
|
|
|
|
|
|
|
=cut; |
|
2676
|
|
|
|
|
|
|
|
|
2677
|
|
|
|
|
|
|
# ============================================================== |
|
2678
|
|
|
|
|
|
|
sub DBUG_FILE_HANDLE |
|
2679
|
|
|
|
|
|
|
{ |
|
2680
|
0
|
|
|
0
|
1
|
0
|
return ( $dbug_global_vars{fh} ); # The open file handle written to ... |
|
2681
|
|
|
|
|
|
|
} |
|
2682
|
|
|
|
|
|
|
|
|
2683
|
|
|
|
|
|
|
|
|
2684
|
|
|
|
|
|
|
=item DBUG_ASSERT ( $expression [, $always_on [, $msg]] ) |
|
2685
|
|
|
|
|
|
|
|
|
2686
|
|
|
|
|
|
|
This function works similar to the C/C++ I function except that it |
|
2687
|
|
|
|
|
|
|
can't tell you what the boolean expression was. |
|
2688
|
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
This I is usually turned off when B isn't currently active. |
|
2690
|
|
|
|
|
|
|
But you may enable it even when B is turned off by setting the |
|
2691
|
|
|
|
|
|
|
I<$always_on> flag to true. |
|
2692
|
|
|
|
|
|
|
|
|
2693
|
|
|
|
|
|
|
If the I<$expression> is true, no action is taken and nothing is written |
|
2694
|
|
|
|
|
|
|
to B. |
|
2695
|
|
|
|
|
|
|
|
|
2696
|
|
|
|
|
|
|
But if the I<$expression> is false, it will log the event to B and then |
|
2697
|
|
|
|
|
|
|
exit your program with a status code of B<14>. Meaning this exit can't be |
|
2698
|
|
|
|
|
|
|
trapped by I or I/I blocks. |
|
2699
|
|
|
|
|
|
|
|
|
2700
|
|
|
|
|
|
|
If you provide the optional I<$msg>, it will print out that message as well |
|
2701
|
|
|
|
|
|
|
after the assert statement. |
|
2702
|
|
|
|
|
|
|
|
|
2703
|
|
|
|
|
|
|
These messages will be written to both B and B. |
|
2704
|
|
|
|
|
|
|
|
|
2705
|
|
|
|
|
|
|
=cut |
|
2706
|
|
|
|
|
|
|
|
|
2707
|
|
|
|
|
|
|
# ============================================================== |
|
2708
|
|
|
|
|
|
|
sub DBUG_ASSERT |
|
2709
|
|
|
|
|
|
|
{ |
|
2710
|
0
|
|
|
0
|
1
|
0
|
my $bool_expr = shift; |
|
2711
|
0
|
0
|
|
|
|
0
|
return if ( $bool_expr ); # The assertion is true ... (noop) |
|
2712
|
|
|
|
|
|
|
|
|
2713
|
0
|
|
|
|
|
0
|
my $always_on = shift; |
|
2714
|
0
|
|
|
|
|
0
|
my $msg = shift; |
|
2715
|
|
|
|
|
|
|
|
|
2716
|
0
|
|
|
|
|
0
|
my $asserted = 0; # Assume it can't be triggered ... |
|
2717
|
|
|
|
|
|
|
|
|
2718
|
|
|
|
|
|
|
# Checks if the assert was triggered. |
|
2719
|
0
|
0
|
|
|
|
0
|
if ( $always_on ) { |
|
|
|
0
|
|
|
|
|
|
|
2720
|
0
|
|
|
|
|
0
|
$asserted = 1; # Always assert ... |
|
2721
|
|
|
|
|
|
|
} elsif ( DBUG_ACTIVE () ) { |
|
2722
|
0
|
|
|
|
|
0
|
$asserted = 1; # Only when Fish is turned on ... |
|
2723
|
|
|
|
|
|
|
} |
|
2724
|
|
|
|
|
|
|
|
|
2725
|
0
|
0
|
|
|
|
0
|
if ( $asserted ) { |
|
2726
|
0
|
|
|
|
|
0
|
my $str = _dbug_called_by (1); # Where the assertion was made. |
|
2727
|
0
|
|
|
|
|
0
|
$str = "Assertion Violation: " . $str; |
|
2728
|
|
|
|
|
|
|
|
|
2729
|
0
|
|
|
|
|
0
|
my $level = DBUG_FILTER_LEVEL_ERROR; |
|
2730
|
|
|
|
|
|
|
|
|
2731
|
0
|
0
|
0
|
|
|
0
|
unless ( $dbug_global_vars{screen} && _filter_on ( $level ) ) { |
|
2732
|
0
|
|
|
|
|
0
|
print STDERR "\n", $str, "\n"; |
|
2733
|
0
|
0
|
|
|
|
0
|
print STDERR $msg, "\n" if ( $msg ); |
|
2734
|
0
|
|
|
|
|
0
|
print STDERR "\n"; |
|
2735
|
|
|
|
|
|
|
} |
|
2736
|
|
|
|
|
|
|
|
|
2737
|
0
|
|
|
|
|
0
|
_dbug_print_pkg_tag ( $level, "ASSERT: %s", $str ); |
|
2738
|
0
|
0
|
|
|
|
0
|
_dbug_print_pkg_tag ( $level, "ASSERT: %s", $msg ) if ( $msg ); |
|
2739
|
0
|
|
|
|
|
0
|
DBUG_LEAVE (14); |
|
2740
|
|
|
|
|
|
|
} |
|
2741
|
|
|
|
|
|
|
|
|
2742
|
0
|
|
|
|
|
0
|
return; |
|
2743
|
|
|
|
|
|
|
} |
|
2744
|
|
|
|
|
|
|
|
|
2745
|
|
|
|
|
|
|
|
|
2746
|
|
|
|
|
|
|
=item DBUG_MODULE_LIST ( ) |
|
2747
|
|
|
|
|
|
|
|
|
2748
|
|
|
|
|
|
|
This optional method writes to B all modules used by your program. It |
|
2749
|
|
|
|
|
|
|
provides the module version as well as where the module was installed. Very |
|
2750
|
|
|
|
|
|
|
useful when you are trying to see what's different between different installs |
|
2751
|
|
|
|
|
|
|
of perl or when you need to open a CPAN ticket. |
|
2752
|
|
|
|
|
|
|
|
|
2753
|
|
|
|
|
|
|
=cut |
|
2754
|
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
sub DBUG_MODULE_LIST |
|
2756
|
|
|
|
|
|
|
{ |
|
2757
|
7
|
|
|
7
|
1
|
27
|
my ($max1, $max2) = (0, 0); # (label len, version len) |
|
2758
|
7
|
|
|
|
|
16
|
my %vers; |
|
2759
|
|
|
|
|
|
|
my %mod; |
|
2760
|
|
|
|
|
|
|
|
|
2761
|
|
|
|
|
|
|
# Get the formatting data & version info. |
|
2762
|
7
|
|
|
|
|
995
|
foreach ( sort keys %INC ) { |
|
2763
|
1029
|
|
|
|
|
1668
|
my $len = length ($_); |
|
2764
|
1029
|
100
|
|
|
|
2047
|
$max1 = $len if ( $len > $max1 ); |
|
2765
|
|
|
|
|
|
|
|
|
2766
|
|
|
|
|
|
|
# Get the module name ... |
|
2767
|
1029
|
|
|
|
|
1681
|
my $module = $_; |
|
2768
|
1029
|
|
|
|
|
4142
|
$module =~ s#[\\/]#::#g; |
|
2769
|
1029
|
|
|
|
|
3140
|
$module =~ s/[.]pm$//i; |
|
2770
|
|
|
|
|
|
|
|
|
2771
|
|
|
|
|
|
|
# Determine the module's version ... |
|
2772
|
1029
|
|
|
|
|
1780
|
my $ver = "(Unknown)"; |
|
2773
|
1029
|
|
|
|
|
1626
|
eval { |
|
2774
|
1029
|
|
|
|
|
2857
|
local $SIG{__DIE__} = undef; # Just in case already trapped. |
|
2775
|
1029
|
|
|
|
|
12478
|
my $tmp = ${module}->VERSION (); |
|
2776
|
1029
|
100
|
|
|
|
4102
|
$ver = $tmp if ( $tmp ); |
|
2777
|
|
|
|
|
|
|
}; |
|
2778
|
|
|
|
|
|
|
|
|
2779
|
|
|
|
|
|
|
# Save the version info ... |
|
2780
|
1029
|
|
|
|
|
1473
|
$len = length ($ver); |
|
2781
|
1029
|
100
|
|
|
|
1934
|
$max2 = $len if ( $len > $max2 ); |
|
2782
|
1029
|
|
|
|
|
2539
|
$vers{$_} = $ver; |
|
2783
|
|
|
|
|
|
|
|
|
2784
|
|
|
|
|
|
|
# Save the module info ... |
|
2785
|
1029
|
|
|
|
|
1969
|
$mod{$_} = $module; |
|
2786
|
1029
|
|
|
|
|
1528
|
$len = length ($module); |
|
2787
|
1029
|
50
|
|
|
|
2502
|
$max1 = $len if ( $len > $max1 ); |
|
2788
|
|
|
|
|
|
|
} |
|
2789
|
|
|
|
|
|
|
|
|
2790
|
7
|
|
|
|
|
157
|
_dbug_print_no_delay_or_caller ( "INFO", "The Module List ..." ); |
|
2791
|
|
|
|
|
|
|
|
|
2792
|
|
|
|
|
|
|
# Now print out the results ... |
|
2793
|
7
|
|
|
|
|
746
|
foreach ( sort keys %INC ) { |
|
2794
|
|
|
|
|
|
|
_dbug_print_no_delay_or_caller ( "MODULE", "%*s ==> %*s ==> %s", |
|
2795
|
1029
|
|
|
|
|
4132
|
$max1, $mod{$_}, $max2, $vers{$_}, $INC{$_} ); |
|
2796
|
|
|
|
|
|
|
} |
|
2797
|
|
|
|
|
|
|
|
|
2798
|
7
|
|
|
|
|
795
|
return; |
|
2799
|
|
|
|
|
|
|
} |
|
2800
|
|
|
|
|
|
|
|
|
2801
|
|
|
|
|
|
|
|
|
2802
|
|
|
|
|
|
|
# Converts the reqeuested code ref or function string into a code ref/name pair. |
|
2803
|
|
|
|
|
|
|
# Used by both the Signal & TIE extensions for low level work! |
|
2804
|
|
|
|
|
|
|
sub _get_func_info |
|
2805
|
|
|
|
|
|
|
{ |
|
2806
|
92
|
|
|
92
|
|
209
|
my $callback = shift; # A String or a CODE ref ... |
|
2807
|
92
|
|
|
|
|
186
|
my $msg = shift; # A label to use when printing warnings. |
|
2808
|
|
|
|
|
|
|
|
|
2809
|
92
|
|
|
|
|
189
|
my ( $code, $func ); # The return values ... |
|
2810
|
|
|
|
|
|
|
|
|
2811
|
92
|
50
|
|
|
|
302
|
if ( $callback ) { |
|
2812
|
92
|
|
|
|
|
234
|
my $pkg_name = __PACKAGE__ . "::"; |
|
2813
|
92
|
|
|
|
|
585
|
$pkg_name =~ s/:ON::$/:/; |
|
2814
|
92
|
|
|
|
|
219
|
my $use_warn = 1; |
|
2815
|
|
|
|
|
|
|
|
|
2816
|
92
|
100
|
|
|
|
539
|
if ( ref ($callback) eq "CODE" ) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
2817
|
|
|
|
|
|
|
# Can't detect if there was typo in the given func name of the CODE ref |
|
2818
|
71
|
|
|
|
|
163
|
$code = $callback; # Already a code referencd. |
|
2819
|
71
|
|
|
|
|
350
|
$func = sub_fullname ($callback); # Get it's name ... or _ANNON_ |
|
2820
|
|
|
|
|
|
|
|
|
2821
|
71
|
50
|
|
|
|
1885
|
if ( $func =~ m/^${pkg_name}/ ) { |
|
2822
|
0
|
|
|
|
|
0
|
warn ("You may not ${msg} a member of the FISH package!\n", |
|
2823
|
|
|
|
|
|
|
' ==> ' . $func . "\n"); |
|
2824
|
0
|
|
|
|
|
0
|
$code = $func = undef; |
|
2825
|
0
|
|
|
|
|
0
|
$use_warn = 0; |
|
2826
|
|
|
|
|
|
|
} |
|
2827
|
|
|
|
|
|
|
|
|
2828
|
|
|
|
|
|
|
# May not self-reference something in this module ... |
|
2829
|
|
|
|
|
|
|
} elsif ( $callback =~ m/^${pkg_name}/ ) { |
|
2830
|
0
|
|
|
|
|
0
|
warn ("You may not ${msg} a member of the FISH package!\n", |
|
2831
|
|
|
|
|
|
|
' ==> ' . $callback . "\n"); |
|
2832
|
0
|
|
|
|
|
0
|
$use_warn = 0; |
|
2833
|
|
|
|
|
|
|
|
|
2834
|
|
|
|
|
|
|
# Provided a fully qualified function name as a string ... |
|
2835
|
|
|
|
|
|
|
} elsif ( $callback =~ m/^(.+)::([^:]+)$/ ) { |
|
2836
|
2
|
|
|
|
|
12
|
my ($pkg, $name) = ($1, $2); |
|
2837
|
2
|
50
|
|
|
|
21
|
if ( $pkg->can ($name) ) { |
|
2838
|
2
|
|
|
|
|
9
|
$code = $pkg->can ($name); # Convert name into code ref. |
|
2839
|
2
|
|
|
|
|
7
|
$func = $callback; |
|
2840
|
|
|
|
|
|
|
} |
|
2841
|
|
|
|
|
|
|
|
|
2842
|
|
|
|
|
|
|
# Provided a partially qualified function name as a string ... |
|
2843
|
|
|
|
|
|
|
# Done by figuring out who called the original DBUG method! |
|
2844
|
|
|
|
|
|
|
} else { |
|
2845
|
19
|
|
|
|
|
49
|
my $call_ind = 1; |
|
2846
|
19
|
|
50
|
|
|
176
|
my $called_by = (caller ($call_ind))[3] || ""; |
|
2847
|
19
|
|
66
|
|
|
244
|
while ( $called_by =~ m/^${pkg_name}/ || $called_by eq "(eval)" ) { |
|
2848
|
57
|
|
100
|
|
|
464
|
$called_by = (caller (++$call_ind))[3] || ""; |
|
2849
|
|
|
|
|
|
|
} |
|
2850
|
|
|
|
|
|
|
|
|
2851
|
|
|
|
|
|
|
# Get the package name of the caller ... |
|
2852
|
19
|
100
|
66
|
|
|
120
|
if ( $called_by && $called_by =~ m/^(.+)::([^:]+)$/ ) { |
|
2853
|
5
|
|
|
|
|
32
|
my ($pkg, $name) = ($1, $2); |
|
2854
|
5
|
50
|
|
|
|
67
|
if ( $pkg->can ($callback) ) { |
|
2855
|
5
|
|
|
|
|
50
|
$code = $pkg->can ($callback); # Convert name into code ref. |
|
2856
|
5
|
|
|
|
|
15
|
$func = $callback; |
|
2857
|
|
|
|
|
|
|
} |
|
2858
|
|
|
|
|
|
|
} |
|
2859
|
|
|
|
|
|
|
|
|
2860
|
|
|
|
|
|
|
# If not from the caller's package ... |
|
2861
|
19
|
100
|
|
|
|
62
|
unless ( $func ) { |
|
2862
|
14
|
|
|
|
|
179
|
my $tmp = "main"->can ($callback); |
|
2863
|
14
|
50
|
|
|
|
60
|
if ( $tmp ) { |
|
2864
|
14
|
|
|
|
|
26
|
$code = $tmp; |
|
2865
|
14
|
|
|
|
|
40
|
$func = "main::" . $callback; |
|
2866
|
|
|
|
|
|
|
} |
|
2867
|
|
|
|
|
|
|
} |
|
2868
|
|
|
|
|
|
|
} |
|
2869
|
|
|
|
|
|
|
|
|
2870
|
92
|
50
|
33
|
|
|
663
|
if ( $use_warn && ! $func ) { |
|
2871
|
0
|
|
|
|
|
0
|
warn ("No such ${msg} function! ($callback)\n"); |
|
2872
|
|
|
|
|
|
|
} |
|
2873
|
|
|
|
|
|
|
} |
|
2874
|
|
|
|
|
|
|
|
|
2875
|
92
|
100
|
|
|
|
613
|
return ( wantarray ? ( $code, $func ) : $code ); |
|
2876
|
|
|
|
|
|
|
} |
|
2877
|
|
|
|
|
|
|
|
|
2878
|
|
|
|
|
|
|
# ============================================================================== |
|
2879
|
|
|
|
|
|
|
# Start of Helper methods designed to help test out this module's functionality. |
|
2880
|
|
|
|
|
|
|
# ============================================================================== |
|
2881
|
|
|
|
|
|
|
|
|
2882
|
|
|
|
|
|
|
# ============================================================== |
|
2883
|
|
|
|
|
|
|
# Not exposed on purpose, so they don't polute the naming space! |
|
2884
|
|
|
|
|
|
|
# Or have people trying to use them! |
|
2885
|
|
|
|
|
|
|
# ============================================================== |
|
2886
|
|
|
|
|
|
|
# Undocumented helper functions exclusively for use by the "t/*.t" programs via |
|
2887
|
|
|
|
|
|
|
# the t/off/helper1234.pm helper module. |
|
2888
|
|
|
|
|
|
|
# Not intended for use by anyone else. |
|
2889
|
|
|
|
|
|
|
# So subject to change without notice! |
|
2890
|
|
|
|
|
|
|
# They are used to help these test programs validate that this module is working |
|
2891
|
|
|
|
|
|
|
# as expected without having to manually examine the fish logs for everything!! |
|
2892
|
|
|
|
|
|
|
# But despite everything, some manual checks will always be needed! |
|
2893
|
|
|
|
|
|
|
# ============================================================== |
|
2894
|
|
|
|
|
|
|
# Most of these functions in Fred::Fish::DBUG:OFF are broken and do not |
|
2895
|
|
|
|
|
|
|
# work there unless you lie and use the $hint arguments! So it's another |
|
2896
|
|
|
|
|
|
|
# reason not to use them in yor own code base! |
|
2897
|
|
|
|
|
|
|
# In fact many of these functions in this module are broken as well if fish was |
|
2898
|
|
|
|
|
|
|
# turned off or paused when the measured event happened. |
|
2899
|
|
|
|
|
|
|
# ============================================================== |
|
2900
|
|
|
|
|
|
|
# NOTE: Be carefull how they are called in the t/*.t programs. If called |
|
2901
|
|
|
|
|
|
|
# the wrong way the HINT parameter won't be handled properly when |
|
2902
|
|
|
|
|
|
|
# you swap over to the OFF.pm module! The $hint arguments are |
|
2903
|
|
|
|
|
|
|
# ignored here! |
|
2904
|
|
|
|
|
|
|
# ============================================================== |
|
2905
|
|
|
|
|
|
|
# The current FISH function on the fish stack ... |
|
2906
|
|
|
|
|
|
|
sub dbug_func_name |
|
2907
|
|
|
|
|
|
|
{ |
|
2908
|
68
|
|
|
68
|
0
|
144
|
my $hint = shift; # Only used in OFF.pm ... |
|
2909
|
68
|
|
|
|
|
332
|
return ( $dbug_global_vars{functions}->[-1]->{NAME} ); |
|
2910
|
|
|
|
|
|
|
} |
|
2911
|
|
|
|
|
|
|
|
|
2912
|
|
|
|
|
|
|
# Number of fish functions on the stack |
|
2913
|
|
|
|
|
|
|
# This one is used internally as well. |
|
2914
|
|
|
|
|
|
|
sub dbug_level |
|
2915
|
|
|
|
|
|
|
{ |
|
2916
|
384
|
|
|
384
|
0
|
787
|
my $hint = shift; # Only used in OFF.pm ... |
|
2917
|
384
|
|
|
|
|
683
|
my $cnt = @{$dbug_global_vars{functions}}; |
|
|
384
|
|
|
|
|
1063
|
|
|
2918
|
384
|
|
|
|
|
1679
|
return ( $cnt ); |
|
2919
|
|
|
|
|
|
|
} |
|
2920
|
|
|
|
|
|
|
|
|
2921
|
|
|
|
|
|
|
# This value is set via the calls to DBUG_RETURN() / DBUG_VOID_RETURN() / |
|
2922
|
|
|
|
|
|
|
# DBUG_RETURN_SPECIAL(). |
|
2923
|
|
|
|
|
|
|
# It can only be non-zero if DBUG_MASK() was called 1st and only for |
|
2924
|
|
|
|
|
|
|
# DBUG_RETURN(). If fish is turned off it will be -1. Otherwise |
|
2925
|
|
|
|
|
|
|
# it will be a count of the masked values in fish! |
|
2926
|
|
|
|
|
|
|
# In all other situations it will return zero! |
|
2927
|
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
sub dbug_mask_return_counts |
|
2929
|
|
|
|
|
|
|
{ |
|
2930
|
9
|
|
|
9
|
0
|
14
|
my $hint = shift; # Only used in OFF.pm ... |
|
2931
|
9
|
|
|
|
|
22
|
my $cnt = $dbug_global_vars{mask_return_count}; |
|
2932
|
9
|
50
|
33
|
|
|
33
|
$cnt = $hint if ( $cnt == -1 && defined $hint ); # If unknown ... |
|
2933
|
9
|
|
|
|
|
33
|
return ( $cnt ); |
|
2934
|
|
|
|
|
|
|
} |
|
2935
|
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
# This value is set via the last call to DBUG_ENTER_FUNC() / DBUG_ENTER_BLOCK() |
|
2937
|
|
|
|
|
|
|
# when it prints it's masked arguments to fish. If the write to fish doesn't |
|
2938
|
|
|
|
|
|
|
# happen the count will be -1! |
|
2939
|
|
|
|
|
|
|
# To decide what needs to be masked, you must call DBUG_MASK_NEXT_FUNC_CALL() 1st! |
|
2940
|
|
|
|
|
|
|
# Otherwise it will always be zero! |
|
2941
|
|
|
|
|
|
|
|
|
2942
|
|
|
|
|
|
|
sub dbug_mask_argument_counts |
|
2943
|
|
|
|
|
|
|
{ |
|
2944
|
17
|
|
|
17
|
0
|
31
|
my $hint = shift; # Only used in OFF.pm ... |
|
2945
|
17
|
|
|
|
|
61
|
my $cnt = $dbug_global_vars{mask_last_argument_count}; |
|
2946
|
17
|
50
|
33
|
|
|
78
|
$cnt = $hint if ( $cnt == -1 && defined $hint ); # If unknown ... |
|
2947
|
17
|
|
|
|
|
67
|
return ( $cnt ); |
|
2948
|
|
|
|
|
|
|
} |
|
2949
|
|
|
|
|
|
|
|
|
2950
|
|
|
|
|
|
|
# These 4 actually work in Fred::Fish::DBUG::OFF as well! |
|
2951
|
|
|
|
|
|
|
sub dbug_threads_supported |
|
2952
|
|
|
|
|
|
|
{ |
|
2953
|
1
|
|
|
1
|
0
|
8
|
return ( $threads_possible ); |
|
2954
|
|
|
|
|
|
|
} |
|
2955
|
|
|
|
|
|
|
|
|
2956
|
|
|
|
|
|
|
sub dbug_fork_supported |
|
2957
|
|
|
|
|
|
|
{ |
|
2958
|
15
|
|
|
15
|
0
|
64
|
return ( $fork_possible ); |
|
2959
|
|
|
|
|
|
|
} |
|
2960
|
|
|
|
|
|
|
|
|
2961
|
|
|
|
|
|
|
sub dbug_time_hires_supported |
|
2962
|
|
|
|
|
|
|
{ |
|
2963
|
2
|
|
|
2
|
0
|
12
|
return ( $time_hires_flag ); |
|
2964
|
|
|
|
|
|
|
} |
|
2965
|
|
|
|
|
|
|
|
|
2966
|
|
|
|
|
|
|
sub dbug_get_frame_value |
|
2967
|
|
|
|
|
|
|
{ |
|
2968
|
0
|
|
|
0
|
0
|
0
|
my $key = shift; |
|
2969
|
|
|
|
|
|
|
|
|
2970
|
0
|
|
|
|
|
0
|
my $value; |
|
2971
|
|
|
|
|
|
|
|
|
2972
|
0
|
0
|
0
|
|
|
0
|
if ( $dbug_global_vars{on} && exists $dbug_global_vars{$key} ) { |
|
2973
|
0
|
|
|
|
|
0
|
$value = $dbug_global_vars{$key}; |
|
2974
|
|
|
|
|
|
|
} |
|
2975
|
|
|
|
|
|
|
|
|
2976
|
0
|
|
|
|
|
0
|
return ( $value ); |
|
2977
|
|
|
|
|
|
|
} |
|
2978
|
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
=back |
|
2980
|
|
|
|
|
|
|
|
|
2981
|
|
|
|
|
|
|
=head1 CREDITS |
|
2982
|
|
|
|
|
|
|
|
|
2983
|
|
|
|
|
|
|
To Fred Fish for developing the basic algorithm and putting it into the |
|
2984
|
|
|
|
|
|
|
public domain! Any bugs in its implementation are purely my fault. |
|
2985
|
|
|
|
|
|
|
|
|
2986
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
2987
|
|
|
|
|
|
|
|
|
2988
|
|
|
|
|
|
|
L The controling module which you should be using instead |
|
2989
|
|
|
|
|
|
|
of this one. |
|
2990
|
|
|
|
|
|
|
|
|
2991
|
|
|
|
|
|
|
L The stub version of the ON module. |
|
2992
|
|
|
|
|
|
|
|
|
2993
|
|
|
|
|
|
|
L - Allows you to trap and log STDOUT/STDERR to B. |
|
2994
|
|
|
|
|
|
|
|
|
2995
|
|
|
|
|
|
|
L - Allows you to trap and log signals to B. |
|
2996
|
|
|
|
|
|
|
|
|
2997
|
|
|
|
|
|
|
L - Allows you to implement action |
|
2998
|
|
|
|
|
|
|
DBUG_SIG_ACTION_LOG for B. Really dangerous to use. Will break most |
|
2999
|
|
|
|
|
|
|
code bases. |
|
3000
|
|
|
|
|
|
|
|
|
3001
|
|
|
|
|
|
|
L - A L wrapper to redirect test results to |
|
3002
|
|
|
|
|
|
|
B. |
|
3003
|
|
|
|
|
|
|
|
|
3004
|
|
|
|
|
|
|
L - Sample code demonstrating using DBUG module. |
|
3005
|
|
|
|
|
|
|
|
|
3006
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
3007
|
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
Copyright (c) 2007 - 2025 Curtis Leach. All rights reserved. |
|
3009
|
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
This program is free software. You can redistribute it and/or modify it |
|
3011
|
|
|
|
|
|
|
under the same terms as Perl itself. |
|
3012
|
|
|
|
|
|
|
|
|
3013
|
|
|
|
|
|
|
=cut |
|
3014
|
|
|
|
|
|
|
|
|
3015
|
|
|
|
|
|
|
# ============================================================ |
|
3016
|
|
|
|
|
|
|
#required if module is included w/ require command; |
|
3017
|
|
|
|
|
|
|
1; |
|
3018
|
|
|
|
|
|
|
|