File Coverage

blib/lib/Fred/Fish/DBUG/OFF.pm
Criterion Covered Total %
statement 70 145 48.2
branch 14 58 24.1
condition 4 20 20.0
subroutine 19 40 47.5
pod 24 32 75.0
total 131 295 44.4


line stmt bran cond sub pod time code
1             ###
2             ### Copyright (c) 2016 - 2025 Curtis Leach. All rights reserved.
3             ###
4             ### Based on the Fred Fish DBUG macros in C/C++.
5             ### The Algorithm is in the public domain!
6             ###
7             ### Module: Fred::Fish::DBUG::OFF
8              
9             =head1 NAME
10              
11             Fred::Fish::DBUG::OFF - Fred Fish Stub library for Perl
12              
13             =head1 SYNOPSIS
14              
15             use Fred::Fish::DBUG qw / OFF /;
16             or
17             require Fred::Fish::DBUG;
18             Fred::Fish::DBUG->import (qw / OFF /);
19              
20             Depreciated way.
21             use Fred::Fish::DBUG::OFF;
22             or
23             require Fred::Fish::DBUG::OFF;
24              
25             =head1 DESCRIPTION
26              
27             F is a pure Perl implementation of the C/C++ Fred Fish
28             macro libraries when the macros are B! It's intended to be a pure
29             drop and replace to the F module so that any module that
30             is uploaded to CPAN doesn't have to have their module code writing to B
31             when used by an end user's program that also uses the F
32             module.
33              
34             Using this module directly has been depreciated. You should be using
35             F instead. See that module on how to disable B for your
36             module.
37              
38             When B has ben disabled (turned off) most of the functions are overridden
39             with stubs or do minimal work to avoid breaking your code that depend on side
40             effects. But overall this module does as little work as possible.
41              
42             The undocumented validation methods used by the B test cases don't work
43             for F. So those test scripts must detect that these
44             undocumented functions are broken and handle any checks appropriately.
45              
46             =head1 FUNCTIONS IN Fred::Fish::DBUG BUT NOT IN Fred::Fish::DBUG::OFF.
47              
48             There are several functions listed in the POD of the 1st module that doesn't
49             show up in the POD of the 2nd module.
50              
51             This was by design. All the missing functions do is automatically call the
52             corresponding function in L for you. Since this module
53             inherits the missing functions from L.
54              
55             The exposed constants falls into this category so your code won't break
56             when swapping between the two modules in the same program.
57              
58             So feel free to always reference the POD from L and/or
59             L when using any of the DBUG modules.
60              
61             =head1 SWAPPING BETWEEN FISH MODULES
62              
63             There is a fairly simple way to have B available when you run your test
64             suite and have it always disabled when an end user runs code using your module.
65             this is done via:
66              
67             use Fred::Fish::DBUG qw / on_if_set FISH /;
68              
69             This way your module will only use B if someone sets this environment
70             variable (Ex: B) before your module is sourced in. Such as in your test
71             scripts when you are debugging your code. When anyone else uses your module it
72             won't write to the B logs at all, even if they are also using the
73             B module in their code base. In most cases they are not interested in
74             seeing traces of your module.
75              
76             Another reason for doing this is that this module is significantly faster
77             when run in OFF mode than when run in the ON mode. This is true even when
78             logging is turned off. The more your module writes to B, the better the
79             performance gain.
80              
81             =head1 FUNCTIONS
82              
83             =over 4
84              
85             =cut
86              
87             package Fred::Fish::DBUG::OFF;
88              
89 5     5   125437 use strict;
  5         9  
  5         168  
90 5     5   26 use warnings;
  5         10  
  5         281  
91              
92 5     5   25 use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION );
  5         7  
  5         297  
93 5     5   19 use Exporter;
  5         11  
  5         200  
94              
95 5     5   917 use FileHandle;
  5         20891  
  5         51  
96              
97             $VERSION = "2.10";
98             @ISA = qw( Exporter );
99             @EXPORT = qw( );
100             @EXPORT_OK = qw( );
101              
102             my (@imports, @override);
103              
104             BEGIN
105             {
106             # -------------------------------------------------------------------------
107             # Put the list of methods we are overriding via the OFF module!
108             # Anything missing will just call the same method in Fred::Fish::DBUG::ON
109             # instead! (Such as all those pesky exposed constant values.)
110             # -------------------------------------------------------------------------
111 5     5   2441 @override = qw( DBUG_PUSH DBUG_POP
112             DBUG_ENTER_FUNC DBUG_ENTER_BLOCK DBUG_PRINT
113             DBUG_RETURN DBUG_ARRAY_RETURN
114             DBUG_VOID_RETURN DBUG_RETURN_SPECIAL
115             DBUG_LEAVE DBUG_CATCH DBUG_PAUSE
116             DBUG_MASK DBUG_MASK_NEXT_FUNC_CALL
117             DBUG_FILTER DBUG_SET_FILTER_COLOR
118             DBUG_CUSTOM_FILTER DBUG_CUSTOM_FILTER_OFF
119             DBUG_ACTIVE DBUG_EXECUTE
120             DBUG_FILE_NAME DBUG_FILE_HANDLE DBUG_ASSERT
121             DBUG_MODULE_LIST
122             );
123              
124 5         10 my %list;
125 5         135 @list{@override} = (1 .. scalar(@override));
126              
127             # Now load the module & only expose the remaining methods & constants.
128 5         1774 require Fred::Fish::DBUG::ON;
129 5         21 @imports = grep { ! $list{$_} } @Fred::Fish::DBUG::ON::EXPORT;
  180         307  
130 5         1053 Fred::Fish::DBUG::ON->import (@imports);
131             }
132              
133              
134             # Now finish off exporting everything initialized by the above BEGIN block ...
135             push (@EXPORT, @override); # Locally defined routines ...
136             push (@EXPORT, @imports); # From Fred::Fish::DBUG::ON ...
137              
138              
139             # These hash variables holds all the global variables used by this module.
140             my %dbug_off_global_vars; # The current fish frame ...
141             my %dbug_off_return_vars; # How DBUG_RETURN behaves for the given package.
142              
143              
144             # --------------------------------
145             BEGIN
146             {
147             # Other variables used ...
148 5     5   22 $dbug_off_global_vars{mask_return_count} = 0;
149 5         10 $dbug_off_global_vars{mask_last_argument_count} = 0;
150 5         12 $dbug_off_global_vars{mask_func_call} = 0;
151 5         9 $dbug_off_global_vars{mask_return_flag} = 0;
152 5         8861 $dbug_off_global_vars{main} = Fred::Fish::DBUG::ON::MAIN_FUNC_NAME;
153             }
154              
155              
156             # --------------------------------
157             # DBUG::OFF Code
158             #
159             # I have tried to keep the functions in in the same order as listed in
160             # Fred::Fish::DBUG::ON to make it easier to support this stub version of
161             # this module.
162             #
163             # But if I skip over a function, it will mean that I used the function
164             # from Fred::Fish::DBUG::ON instead!
165             # --------------------------------
166              
167             =item DBUG_PUSH ( [$file [, %opts]] )
168              
169             This stub does nothing since B can't be turned on by this module.
170              
171             =cut
172              
173             # ==============================================================
174             sub DBUG_PUSH
175             {
176 2     2 1 1235 return;
177             }
178              
179              
180             =item DBUG_POP ( )
181              
182             This stub does nothing since B can't be turned on for this module.
183              
184             =cut
185              
186             # ==============================================================
187             sub DBUG_POP
188             {
189 0     0 1 0 return;
190             }
191              
192              
193             =item DBUG_ENTER_FUNC ( [@arguments] )
194              
195             This stub just returns the name of the calling function. It won't honor the
196             I option in the return value.
197              
198             =cut
199              
200             # ==============================================================
201             sub DBUG_ENTER_FUNC
202             {
203 18   66 18 1 377300 my $func = (caller (1))[3] || $dbug_off_global_vars{main};
204              
205 18         74 return ( DBUG_ENTER_BLOCK ($func, @_) );
206             }
207              
208              
209             =item DBUG_ENTER_BLOCK ( $name [, @arguments] )
210              
211             This stub just returns the B<$name> passed to it. It won't honor the
212             I option in the return value.
213              
214             =cut
215              
216             # ==============================================================
217             sub DBUG_ENTER_BLOCK
218             {
219 35     35 1 144 my $block_name = shift;
220 35         75 my @args = @_;
221              
222 35 50       82 $block_name = "[undef]" unless ( defined $block_name );
223              
224             # Did we make a masking request ...
225 35 50       96 if ( $dbug_off_global_vars{mask_func_call} ) {
226 0 0       0 $dbug_off_global_vars{mask_last_argument_count} = ($#args == -1) ? 0 : -1;
227 0         0 $dbug_off_global_vars{mask_func_call} = 0;
228             } else {
229 35         62 $dbug_off_global_vars{mask_last_argument_count} = 0; # Nope!
230             }
231              
232 35         105 return ( $block_name );
233             }
234              
235              
236             =item DBUG_PRINT ( $tag, $fmt [, $val1 [, $val2 [, ...]]] )
237              
238             This function is usually a no-op unless you are examining the return value.
239             In that case it will return the formatted string the same as it does for
240             I.
241              
242             It also doesn't honor the B request from I since it will
243             never write to the B file.
244              
245             =cut
246              
247             # ==============================================================
248             # Make as efficient as possible since this is the most frequently called method!
249             # And usually the return value is tossed!
250             # ------------------------------------------------------------------
251             sub DBUG_PRINT
252             {
253             # If undef, the caller wasn't interested in any return value!
254 24 100   24 1 121 return (undef) unless ( defined wantarray );
255              
256 4         11 my ($keyword, $fmt, @values) = @_;
257              
258             # Build the message that we want to return.
259 4         6 my $msg;
260 4 50       17 if ( ! defined $fmt ) {
    100          
261 0         0 $msg = "";
262             } elsif ( $#values == -1 ) {
263 2         7 $msg = $fmt;
264             } else {
265             # Get rid of undef warnings for sprintf() ...
266 2         5 foreach (@values) {
267 2 50       10 $_ = "" unless ( defined $_ );
268             }
269 2         8 $msg = sprintf ( $fmt, @values );
270             }
271              
272 4         57 my @lines = split ( /[^\S\n]*\n/, $msg ); # Split on "\n" & trim!
273 4 50       12 push (@lines, "") if ( $#lines == -1 ); # Must have at least one line!
274 4         13 $msg = join ( "\n", @lines ) . "\n"; # Put back together trimmed!
275              
276 4         12 return ( $msg ); # Here's the requested formatted message ...
277             }
278              
279              
280             =item DBUG_RETURN ( ... )
281              
282             Returns the parameter(s) passed as arguments back to the calling function.
283             Since this is a function, care should be taken if called from the middle of
284             your function's code. In that case use the syntax:
285             S<"return DBUG_RETURN( value1 [, value2 [, ...]] );">.
286              
287             It uses Perl's B feature to determine what to return the the caller.
288             IE scalar mode (only the 1st value) or list mode (all the values in the list).
289             Which is not quite what many perl developers might expect.
290              
291             EX: return (wantarray ? (value1, value2, ...) ? value1);
292              
293             =cut
294              
295             # ==============================================================
296             sub DBUG_RETURN
297             {
298 21     21 1 9569 my @args = @_;
299              
300             # Did we request masking ...
301 21         65 my $flg = $dbug_off_global_vars{mask_return_flag};
302 21 50       68 $dbug_off_global_vars{mask_return_count} = $flg ? -1 : 0;
303 21         38 $dbug_off_global_vars{mask_return_flag} = 0;
304              
305 21 100       47 if ( wantarray ) {
306 1         8 return ( @args ); # Array context ...
307             } else {
308 20         55 return ( $args[0] ); # Scalar/void context ...
309             }
310             }
311              
312             =item DBUG_ARRAY_RETURN ( @args )
313              
314             A variant of S<"DBUG_RETURN()"> that behaves the same as perl does natively when
315             returning a list to a scalar. IE it returns the # of elements in the @args
316             array.
317              
318             It always assumes @args is a list, even when provided a single scalar value.
319              
320             =cut
321              
322             # ==============================================================
323             sub DBUG_ARRAY_RETURN
324             {
325 0     0 1 0 my @args = @_;
326              
327             # Did we request masking ...
328 0         0 my $flg = $dbug_off_global_vars{mask_return_flag};
329 0 0       0 $dbug_off_global_vars{mask_return_count} = $flg ? -1 : 0;
330 0         0 $dbug_off_global_vars{mask_return_flag} = 0;
331              
332             # I can't tell apart DBUG_ARRAY_RETURN("a") & DBUG_ARRAY_RETURN(qw/a/)
333             # so always assume 2nd example if arg count is 1.
334             # my $cnt = @args;
335              
336             # Let Perl handle the mess of returning a list or a count,
337 0         0 return ( @args );
338             }
339              
340             =item DBUG_VOID_RETURN ( )
341              
342             Just a void return stub. If called in the middle of your function, do as:
343             S<"return DBUG_VOID_RETURN();">.
344              
345             =cut
346              
347             # ==============================================================
348             sub DBUG_VOID_RETURN
349             {
350             # Nothing masked ...
351 12     12 1 83 $dbug_off_global_vars{mask_return_count} = 0;
352 12         30 $dbug_off_global_vars{mask_return_flag} = 0;
353 12         3704 return (undef); # Undef just in case someone looks!
354             }
355              
356              
357             =item DBUG_RETURN_SPECIAL ( $scalar, @array )
358              
359             This I variant allows you to differentiate between what to return
360             when your function is called in a scalar context vs an array context vs void
361             context.
362              
363             If called in an array context, the return value is equivalent to
364             S.>
365              
366             If called in a scalar context, the return value is equivalent to
367             S.> With a few special case exceptions.
368              
369             =over
370              
371             Special case # 1: If I<$scalar> is set to the predefined constant value
372             B, it returns the equivalent to
373             S.> Feel free to modify the contents of the referenced
374             array, it can't hurt anything. It's a copy.
375              
376             Special case # 2: If I<$scalar> is set to the predefined constant value
377             B, it returns the equivalent to
378             S,> the number of elements in the array.
379              
380             Special case # 3: If I<$scalar> is set to the predefined constant value
381             B, it returns the equivalent to
382             S,> the last element in the array.
383              
384             Special case # 4: If I<$scalar> is a CODE ref, it returns the equivalent to
385             S(@array)))>.>
386              
387             =back
388              
389             If called in a void context, the return value is equivalent to
390             S.>
391              
392             =cut
393              
394             sub DBUG_RETURN_SPECIAL
395             {
396 0     0 1 0 my $scalar = shift;
397              
398             # Did we request masking ...
399 0         0 my $flg = $dbug_off_global_vars{mask_return_flag};
400 0 0       0 $dbug_off_global_vars{mask_return_count} = $flg ? -1 : 0;
401 0         0 $dbug_off_global_vars{mask_return_flag} = 0;
402              
403 0 0 0     0 unless ( defined wantarray ) {
404 0         0 return ( undef );
405             } elsif ( wantarray ) {
406             return ( @_ );
407             }
408              
409             # If you get here you are returning a scalar value ...
410 0 0       0 if ( defined $scalar ) {
411 0 0       0 if ( ref ($scalar) eq "CODE" ) {
    0          
    0          
    0          
412 0         0 my $res = $scalar->( @_ );
413 0         0 return ( $res );
414             } elsif ( $scalar eq DBUG_SPECIAL_ARRAYREF ) {
415 0         0 my @args = @_;
416 0         0 return ( \@args );
417             } elsif ( $scalar eq DBUG_SPECIAL_COUNT ) {
418 0         0 return ( scalar (@_) );
419             } elsif ( $scalar eq DBUG_SPECIAL_LAST ) {
420 0         0 return ( $_[-1] );
421             }
422             }
423              
424             # Returning a literal value, not one of the exceptions ...
425 0         0 return ( $scalar );
426             }
427              
428              
429             =item DBUG_LEAVE ( [$status] )
430              
431             This function terminates your program with a call to I. It expects a
432             numeric parameter to use as the program's I<$status> code. If not provided,
433             it assumes an exit status of zero!
434              
435             =cut
436              
437             # ==============================================================
438             sub DBUG_LEAVE
439             {
440 2   50 2 1 12 my $status = shift || 0;
441              
442 2         16 Fred::Fish::DBUG::ON::_dbug_leave_cleanup ();
443              
444 2         160 exit ($status); # Exit the program! (This isn't trappable by eval!)
445             }
446              
447              
448             =item DBUG_CATCH ( )
449              
450             This stub does nothing since B can't be turned on for this module.
451              
452             =cut
453              
454             # ==============================================================
455             sub DBUG_CATCH
456             {
457 0     0 1 0 return;
458             }
459              
460             =item DBUG_PAUSE ( )
461              
462             This stub does nothing since B can't be turned on for this module.
463              
464             =cut
465              
466             # ==============================================================
467             sub DBUG_PAUSE
468             {
469 0     0 1 0 return;
470             }
471              
472              
473             =item DBUG_MASK ( @offsets )
474              
475             This stub does nothing since B can't be turned on for this module.
476              
477             =cut
478              
479             # ==============================================================
480             sub DBUG_MASK
481             {
482 0     0 1 0 $dbug_off_global_vars{mask_return_flag} = 1;
483 0         0 return;
484             }
485              
486              
487             =item DBUG_MASK_NEXT_FUNC_CALL ( @offsets )
488              
489             This stub does nothing since B can't be turned on for this module.
490              
491             =cut
492              
493             # ==============================================================
494             sub DBUG_MASK_NEXT_FUNC_CALL
495             {
496 0     0 1 0 $dbug_off_global_vars{mask_func_call} = 1;
497 0         0 return;
498             }
499              
500              
501             =item DBUG_FILTER ( $lvl )
502              
503             This stub does nothing except return the current I and
504             the passed I<$lvl>. You can't change the level while using
505             this module.
506              
507             =cut
508              
509             # ==============================================================
510             sub DBUG_FILTER
511             {
512 8     8 1 39 my $new_lvl = shift;
513              
514 8         45 my $old_lvl = Fred::Fish::DBUG::ON::DBUG_FILTER ();
515 8 50       30 return ( wantarray ? ( $old_lvl, $new_lvl ) : $old_lvl );
516             }
517              
518              
519             =item DBUG_CUSTOM_FILTER ( @levels )
520              
521             This stub does nothing since B can't be turned on for this module.
522              
523             =cut
524              
525             # ==============================================================
526             sub DBUG_CUSTOM_FILTER
527             {
528 0     0 1 0 return;
529             }
530              
531              
532             =item DBUG_CUSTOM_FILTER_OFF ( @levels )
533              
534             This stub does nothing since B can't be turned on for this module.
535              
536             =cut
537              
538             # ==============================================================
539             sub DBUG_CUSTOM_FILTER_OFF
540             {
541 0     0 1 0 return;
542             }
543              
544              
545             =item DBUG_SET_FILTER_COLOR ( $level [, $color] )
546              
547             This stub always returns B<0> since B can't be turned on for this module.
548              
549             =cut
550              
551             # ==============================================================
552             sub DBUG_SET_FILTER_COLOR
553             {
554 0     0 1 0 return (0);
555             }
556              
557              
558             =item DBUG_ACTIVE ( )
559              
560             This stub always returns B<0> since B can't be turned on for this module.
561              
562             =cut
563              
564             # ==============================================================
565             sub DBUG_ACTIVE
566             {
567 2     2 1 12 return (0); # Fish is always turned off.
568             }
569              
570              
571             =item DBUG_EXECUTE ( $tag )
572              
573             This function always returns B<0> since B can't be turned on for this
574             module.
575              
576             =cut
577              
578             # ==============================================================
579             sub DBUG_EXECUTE
580             {
581 0     0 1 0 return (0); # Fish is always turned off.
582             }
583              
584              
585             =item DBUG_FILE_NAME ( )
586              
587             Always returns the empty string since B can't be turned on for this
588             module.
589              
590             =cut
591              
592             # ==============================================================
593             sub DBUG_FILE_NAME
594             {
595 2     2 1 6 return (""); # Fish is always turned off.
596             }
597              
598              
599             =item DBUG_FILE_HANDLE ( )
600              
601             Always returns B since B is never turned on with this module.
602              
603             =cut;
604              
605             # ==============================================================
606             sub DBUG_FILE_HANDLE
607             {
608 0     0 1 0 return (undef);
609             }
610              
611              
612             =item DBUG_ASSERT ( $expression [, $always_on [, $msg]] )
613              
614             This function works similar to the C/C++ I function except that it
615             can't tell you what the boolean expression was.
616              
617             This function is a no-op unless I<$always_on> is true.
618              
619             So if the I<$expression> is false, and I<$always_on> is true, it will write to
620             B the assert message and abort your program with an exit status code of
621             B<14>. Meaning this exit can't be trapped by I.
622              
623             =cut
624              
625             # ==============================================================
626             sub DBUG_ASSERT
627             {
628 0     0 1 0 my $bool = shift;
629 0         0 my $always_on = shift;
630 0         0 my $msg = shift;
631              
632 0 0       0 return if ( $bool ); # The assertion is true ... (no-op)
633 0 0       0 return unless ( $always_on ); # If not always on ... (no-op)
634              
635             # Tell where the assertion was made!
636 0         0 my $str = "Assertion Violation: " . _dbug_called_by (1);
637              
638 0         0 print STDERR "\n", $str, "\n";
639 0 0       0 print STDERR $msg, "\n" if ( $msg );
640 0         0 print STDERR "\n";
641 0         0 DBUG_LEAVE (14);
642             }
643              
644              
645             =item DBUG_MODULE_LIST ( )
646              
647             This stub does nothing since B can't be turned on for this module.
648              
649             =cut
650              
651             # ==============================================================
652             sub DBUG_MODULE_LIST
653             {
654 2     2 1 4 return;
655             }
656              
657              
658             # ==============================================================================
659             # Start of Internal DBUG methods ...
660             # ==============================================================================
661              
662             sub _dbug_called_by
663             {
664 0     0   0 my $flg = shift;
665              
666             # Hack based on how some t/*.t programs called this function ...
667             # It's why the functions below need to take care with arguments!
668 0 0 0     0 $flg = shift if ( defined $flg && $flg eq __PACKAGE__ );
669              
670 0         0 return ( Fred::Fish::DBUG::ON::_dbug_called_by ($flg, @_) );
671             }
672              
673             # ==============================================================================
674             # Start of Helper methods designed to help test out this module's functionality.
675             # ==============================================================================
676              
677             # ==================================================================
678             # Not exposed on purpose, so they don't polute Perl's naming space!
679             # ==================================================================
680             # Undocumented helper functions exclusively for use by the "t/*.t" programs!
681             # Not intended for use by anyone else.
682             # So subject to change without notice!
683             # They are used to help them validate that this module is working as expected
684             # in these test programs!
685             # ==================================================================
686             # For the OFF module, most of them are broken and usually return invalid
687             # values ... (-1)
688             # And the t/*.t programs know this & work arround it when needed!
689             # ==================================================================
690             # So don't use them in your code! You've been warned!
691             # ==================================================================
692             # NOTE: Be carefull how they are called in the t/*.t programs. If called
693             # the wrong way the HINT parameter won't be handled properly!
694             # ==================================================================
695             # ASSUMES: That there are no fish logs open when called. So it's safe to
696             # temporarily disable trapping warnings so that custom warn methods
697             # are not called to log the warnings as unexpected and trigger failed
698             # test cases.
699             # This is not in general true when called outside the t/*.t programs.
700             # So it's another reason to not call them in your own code base!
701             # ==================================================================
702              
703             # The current FISH function on the stack ...
704             sub dbug_func_name
705             {
706 0     0 0 0 my $hint = shift;
707 0 0       0 if ( defined $hint ) {
708 0         0 local $SIG{__WARN__} = ""; # Disable so won't call the custom warn funcs in tests!
709 0         0 warn ("Using the Cheat value ($hint) to replace the unknown function name!\n");
710 0         0 return ( $hint );
711             }
712 0         0 return ( undef ); # Still unknown!
713             }
714              
715             # Number of fish functions on the stack
716             sub dbug_level
717             {
718 6     6 0 17 my $hint = shift;
719 6 50 33     19 if ( defined $hint && $hint =~ m/^\d+$/ ) {
720 0         0 local $SIG{__WARN__} = ""; # Disable so won't call the custom warn funcs in tests!
721 0         0 warn ("Using the Cheat value ($hint) to replace the unknown 'dbug_level' value!\n");
722 0         0 return ( $hint );
723             }
724 6         18 return ( -1 ); # Still unknown!
725             }
726              
727             # In Fred::Fish::DBUG::ON, it gives the number of masked return values written
728             # to fish from the last call to DBUG_RETURN() / DBUG_VOID_RETURN() /
729             # DBUG_RETURN_SPECIAL().
730              
731             # But this module doesn't collect this information for these methods. So in
732             # most caes it returns -1, telling the caller it's unknown!
733              
734             # See Fred::Fish::DBUG::ON::dbug_mask_return_counts() for more of my thinking
735             # on it.
736              
737             sub dbug_mask_return_counts
738             {
739 0     0 0   my $hint = shift;
740              
741             # Will always be 0 or -1!!!
742 0 0 0       if ( $dbug_off_global_vars{mask_return_count} == 0 ) {
    0          
743 0           return (0); # Masking wasn't used ...
744              
745             } elsif ( defined $hint && $hint =~ m/^\d+$/ ) {
746 0           local $SIG{__WARN__} = ""; # Disable so won't call the custom warn funcs in tests!
747 0           warn ("Using the Cheat value ($hint) to replace the unknown return masking count!\n");
748 0           return ( $hint );
749             }
750              
751 0           return ( -1 ); # Still unknown!
752             }
753              
754             # In Fred::Fish::DBUG::ON, it gives the number of masked arguments written to
755             # fish from the last call to DBUG_ENTER_FUNC() or DBUG_ENTER_BLOCK().
756              
757             # But this module doesn't collect this information for either ENTER function.
758             # So in many cases it returns -1, telling the caller the count is unknown!
759              
760             sub dbug_mask_argument_counts
761             {
762 0     0 0   my $hint = shift;
763              
764             # Will always be 0 or -1!!!
765 0 0 0       if ( $dbug_off_global_vars{mask_last_argument_count} == 0 ) {
    0          
766 0           return (0); # Masking wasn't used ...
767              
768             } elsif ( defined $hint && $hint =~ m/^\d+$/ ) {
769 0           local $SIG{__WARN__} = ""; # Disable so won't call the custom warn funcs in tests!
770 0           warn ("Using the Cheat value ($hint) to replace the unknown argument masking count!\n");
771 0           return ( $hint );
772             }
773              
774 0           return ( -1 ); # Still unknown!
775             }
776              
777              
778             # These 4 functions actually work as advertised!
779              
780             sub dbug_threads_supported
781             {
782 0     0 0   return ( Fred::Fish::DBUG::ON::dbug_threads_supported() );
783             }
784              
785             sub dbug_fork_supported
786             {
787 0     0 0   return ( Fred::Fish::DBUG::ON::dbug_fork_supported() );
788             }
789              
790             sub dbug_time_hires_supported
791             {
792 0     0 0   return ( Fred::Fish::DBUG::ON::dbug_time_hires_supported() );
793             }
794              
795             sub dbug_get_frame_value
796             {
797 0     0 0   return ( Fred::Fish::DBUG::ON::dbug_get_frame_value (@_) );
798             }
799              
800             # -----------------------------------------------------------------------------
801             # End of Fred::Fish::DBUG::OFF ...
802             # -----------------------------------------------------------------------------
803              
804             =back
805              
806             =head1 CREDITS
807              
808             To Fred Fish for developing the basic algorithm and putting it into the
809             public domain! Any bugs in its implementation are purely my fault.
810              
811             =head1 SEE ALSO
812              
813             L - The controling module which you should be using instead
814             of this one.
815              
816             L - The live version of the OFF module.
817              
818             L - Allows you to trap and log STDOUT/STDERR to B.
819              
820             L - Allows you to trap and log signals to B.
821              
822             L - Allows you to implement action
823             DBUG_SIG_ACTION_LOG for B. Really dangerous to use. Will break most
824             code bases.
825              
826             L - A L wrapper to redirect test results to
827             B.
828              
829             L - Sample code demonstrating using DBUG module.
830              
831              
832             =head1 COPYRIGHT
833              
834             Copyright (c) 2016 - 2025 Curtis Leach. All rights reserved.
835              
836             This program is free software; you can redistribute it and/or modify it
837             under the same terms as Perl itself.
838              
839             =cut
840              
841             # ==============================================================
842             #required if module is included w/ require command;
843             1;