Subversion Repositories DevTools

Rev

Rev 6276 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
279 dpurdie 4
# Module name   : JatsError
227 dpurdie 5
# Module type   : Perl Package
279 dpurdie 6
# Compiler(s)   : Perl
227 dpurdie 7
# Environment(s): jats
8
#
9
# Description   : A Perl Package to perform error handling within JATS
10
#
11
#                 Uses global variables
12
#                       $::ScmVerbose;
13
#                       $::ScmQuiet;
14
#                       $::ScmDebug;
15
#                 For use with existing scripts
16
#
17
#......................................................................#
18
 
283 dpurdie 19
package JatsError;
20
use base qw(Exporter);
21
 
255 dpurdie 22
require 5.006_001;
227 dpurdie 23
use strict;
24
use warnings;
25
use Data::Dumper;
26
use IO::Handle;
27
 
6198 dpurdie 28
# exported package globals go here
29
#our $ScmVerbose;
30
#our $ScmDebug;
31
#our $ScmQuiet;
32
our $ScmOnExit;
33
our $ScmDelayExit;
34
our $ScmErrorCount;
35
our $ScmExitCode;
36
 
37
my $EPrefix = '';
38
my $EName = '';
39
my $EFn = '';
40
my $ElPrefix = '';
41
my $EIndent = '';
42
my $EOffset = '';
43
 
227 dpurdie 44
#-------------------------------------------------------------------------------
45
# Function        : BEGIN
46
#
47
# Description     : Standard Package Interface
48
#
49
# Inputs          :
50
#
51
# Returns         :
52
#
53
 
54
BEGIN {
283 dpurdie 55
    our ($VERSION, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
227 dpurdie 56
 
57
    # set the version for version checking
58
    $VERSION     = 1.00;
59
 
279 dpurdie 60
    @EXPORT      = qw(ErrorConfig ErrorReConfig ErrorDoExit
261 dpurdie 61
                      ReportError Fatal Error Warning
227 dpurdie 62
                      Message Message1
63
                      Information Information1
64
                      Question
263 dpurdie 65
                      Verbose0 Verbose Verbose2 Verbose3
227 dpurdie 66
                      Debug0 Debug Debug2 Debug3
67
                      IsVerbose IsDebug IsQuiet
231 dpurdie 68
                      DebugDumpData DebugDumpPackage DebugTraceBack
227 dpurdie 69
                      DebugPush DebugPop
5109 dpurdie 70
                      StartCapture
71
                      DumpCapture
227 dpurdie 72
                      );
73
 
74
    %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],
75
 
76
    # your exported package globals go here,
77
    # as well as any optionally exported functions
78
    @EXPORT_OK   = qw();
79
 
80
    #
81
    #   Ensure globals have a defined value
82
    #
263 dpurdie 83
    $::ScmVerbose = $ENV{GBE_VERBOSE} || 0  unless defined( $::ScmVerbose );
84
    $::ScmDebug = $ENV{GBE_DEBUG} || 0      unless defined( $::ScmDebug );
85
    $::ScmQuiet = 0                         unless defined( $::ScmQuiet );
227 dpurdie 86
 
6198 dpurdie 87
    $ScmErrorCount = 0;
88
    $ScmExitCode = 1;
89
 
227 dpurdie 90
    #
91
    #   Force autoflush in an attempt to limit the intermingling of
92
    #   Error and non-error output.
93
    #
94
    STDOUT->autoflush(1);
95
    STDERR->autoflush(1);
96
}
97
 
98
# non-exported package globals go here
5109 dpurdie 99
my @captured;
100
my $capturing;
279 dpurdie 101
 
227 dpurdie 102
#-------------------------------------------------------------------------------
103
# Function        : import
104
#
105
# Description     : Package import function
279 dpurdie 106
#                   This function will examine arguments provided in the
227 dpurdie 107
#                   invoking 'uses' list and will configure the package
108
#                   accordingly.
109
#
110
# Inputs          : $pack           - Name of this package
111
#                   @vars           - User Config Options
112
#                   Config Options:
113
#                       :name=xxxx
279 dpurdie 114
#                       :function=xxxx
6198 dpurdie 115
#                       :prefix=xxxx
116
#                       :indent=nn/xxx
117
#                       :offset=nn/xxx
227 dpurdie 118
#                       :quiet=xxx
119
#                       :debug=xxx
120
#                       :verbose=xxx
121
#                       :delay_exit=xxx
122
#
123
# Returns         : 
124
#
125
sub import {
126
    my $pack = shift;
127
    my @vars;
128
    my @config;
129
 
130
    #
131
    #   Extract options of the form: :name=value and pass them to the
132
    #   ErrorConfig function. All other arguments will be passed to the
133
    #
134
    foreach ( @_ )
135
    {
136
        if ( m/^:(.+)=(.+)/ ) {
137
            push @config, $1, $2;
138
        } else {
139
            push @vars, $_;
140
        }
141
    }
142
 
143
    ErrorConfig( @config )
144
        if ( @config );
145
 
146
    #
147
    #   Invoke Exporter function to handle the arguments that I don't understand
148
    #
149
    $pack->export_to_level(1, $pack , @vars);
150
}
151
 
152
#-------------------------------------------------------------------------------
153
# Function        : ErrorConfig
154
#
155
# Description     : Configure aspects of the JATS error handle
279 dpurdie 156
#                   See ErrorReConfig
227 dpurdie 157
#
158
# Inputs          : A hash of option,value pairs
159
#                   Valid options
160
#                       name        - Name to report in error
279 dpurdie 161
#                       function    - Name of enclosing function
227 dpurdie 162
#                       verbose     - vebosity level
163
#                       debug       - debug level
164
#                       on_exit     - Register on-exit function
165
#                       delay_exit  - Delay exit on error
6198 dpurdie 166
#                       prefix      - Optional prefix. First line only
167
#                       indent      - Optional. All lines (number or text)
168
#                       offset      - Optional. Extra lines (number or text)
227 dpurdie 169
#
170
# Returns         :
171
#
172
sub ErrorConfig
173
{
174
    my %args = @_;
175
 
176
    while (my($key, $value) = each %args)
177
    {
6198 dpurdie 178
        if ( $key =~ /^name/ ) {
279 dpurdie 179
            $EName = $value;
227 dpurdie 180
 
279 dpurdie 181
        } elsif ( $key =~ /^function/ ) {
182
            $EFn = ':' . $value;
183
 
6198 dpurdie 184
        } elsif ( $key =~ /^prefix/ ) {
185
            $ElPrefix = $value;
186
 
187
        } elsif ( $key =~ /^indent/ ) {
188
            my $pad = $value;
189
            if ($pad =~ m~^\d+$~) {
190
                $pad = ' ' x $value;
191
            }
192
            $EIndent = $EIndent . $pad;
193
 
194
        } elsif ( $key =~ /^offset/ ) {
195
            $EOffset = $value;
196
            if ($EOffset =~ m~^\d+$~) {
197
                $EOffset = ' ' x $value;
198
            }
199
 
227 dpurdie 200
        } elsif ( $key =~ /^debug/ ) {
279 dpurdie 201
            $::ScmDebug = $value
202
                if ( defined $value && $value > $::ScmDebug  );
227 dpurdie 203
 
204
        } elsif ( $key =~ /^verbose/ ) {
279 dpurdie 205
            $::ScmVerbose = $value
206
                if ( defined $value && $value > $::ScmVerbose  );
227 dpurdie 207
 
208
        } elsif ( $key =~ /^quiet/ ) {
209
            $::ScmQuiet = $value || 0;
210
 
211
        } elsif ( $key =~ /^on_exit/ ) {
212
            $ScmOnExit = $value;
213
 
214
        } elsif ( $key =~ /^delay_exit/ ) {
215
            $ScmDelayExit = $value;
216
 
2429 dpurdie 217
        } elsif ( $key =~ /^exitCode/i ) {
218
            $ScmExitCode = $value || 1;
219
 
227 dpurdie 220
        } else {
221
            Error("ErrorConfig, Unknown option: $key");
222
        }
223
    }
224
 
225
    #
279 dpurdie 226
    #   Calculate the prefix to all messages
227
    #   Based on Name and Function( if provided
228
    #
6198 dpurdie 229
    $EPrefix = "[$EName$EFn] " if $EName;
279 dpurdie 230
 
231
    #
227 dpurdie 232
    #   Extract program specfic debug flags from the environment
233
    #   These will be based on the reporting 'name'
234
    #       GBE_name_DEBUG
235
    #       GBE_name_VERBOSE
236
    #
279 dpurdie 237
    if ( $EName )
227 dpurdie 238
    {
239
        my ($value, $tag);
240
 
279 dpurdie 241
        $tag = "GBE_${EName}_DEBUG" ;
261 dpurdie 242
        $tag =~ s~\s+~~g;
227 dpurdie 243
        $value = $ENV{ $tag };
244
        if (defined $value)
245
        {
246
            $::ScmDebug = $value;
247
            Warning("Envar: $tag setting debug: $value");
248
        }
249
 
279 dpurdie 250
        $tag = "GBE_${EName}_VERBOSE" ;
261 dpurdie 251
        $tag =~ s~\s+~~g;
227 dpurdie 252
        $value = $ENV{ $tag };
253
        if (defined $value)
254
        {
255
            $::ScmVerbose = $value;
256
            Warning("Envar: $tag setting verbose: $value");
257
        }
258
    }
259
 
260
    #
261
    #   Sanitise quiet and verbose
262
    #   Any verboseness disables quiet
263
    #
264
    $::ScmQuiet = 0 if ( $::ScmVerbose );
265
    $::ScmQuiet = 0 if ( $::ScmDebug );
266
}
267
 
279 dpurdie 268
#-------------------------------------------------------------------------------
269
# Function        : ErrorReConfig
270
#
271
# Description     : Similar to ErrorConfig , except it is used to push and
272
#                   automatically pop the current state
273
#
274
#                   Intended to be used to control error reporting
275
#                   within a function. Let the class go out of scope
276
#                   at the end of the function.
277
#
278
#                   Not intended that the user hold and pass around the
279
#                   class ref as this may confuse all.
280
#
281
# Inputs          : As for ErrorConfig
282
#
283
# Returns         : Ref to a class
284
#                   When this goes out of scope the Error State will be
285
#                   restored.
286
#
287
sub ErrorReConfig
288
{
289
    #
290
    #   Create a small class to hold existing Error Information
291
    #   The error information will be restored when the handle returned to
292
    #   the user goes out of scope.
293
    #
294
    my $self;
227 dpurdie 295
 
6198 dpurdie 296
    $self->{EPrefix}        =  $EPrefix;
297
    $self->{ElPrefix}       =  $ElPrefix;
298
    $self->{EIndent}        =  $EIndent;
299
    $self->{EOffset}        =  $EOffset;
279 dpurdie 300
    $self->{ScmVerbose}     =  $::ScmVerbose;
301
    $self->{ScmDebug}       =  $::ScmDebug;
302
    $self->{ScmQuiet}       =  $::ScmQuiet;
303
    $self->{ScmOnExit}      =  $ScmOnExit;
304
    $self->{ScmDelayExit}   =  $ScmDelayExit;
305
    $self->{ScmErrorCount}  =  $ScmErrorCount;
306
    $self->{ScmExitCode}    =  $ScmExitCode;
307
    $self->{EName}          =  $EName;
308
    $self->{EFn}            =  $EFn;
309
 
310
    bless ($self, __PACKAGE__);
311
 
312
    #
313
    #   Invoke ErrorConfig to do the hard work
314
    #
315
    ErrorConfig (@_);
316
 
317
    #
318
    #   Return ref to stored data
319
    #
320
    return $self;
321
 
322
}
323
 
227 dpurdie 324
#-------------------------------------------------------------------------------
279 dpurdie 325
# Function        : DESTROY
326
#
6198 dpurdie 327
# Description     : Called when the handle returned by ErrorConfig goes out of
279 dpurdie 328
#                   scope.
329
#
330
#                   Restores the state of the Error Reporting information
331
#
332
# Inputs          : $self               - Created by ErrorReConfig
333
#
334
# Returns         : Nothing
335
#
336
 
337
sub DESTROY
338
{
339
    my ($self) = @_;
6198 dpurdie 340
    $EPrefix          = $self->{EPrefix};
341
    $ElPrefix         = $self->{ElPrefix};
342
    $EIndent          = $self->{EIndent};
343
    $EOffset          = $self->{EOffset};
279 dpurdie 344
    $::ScmVerbose     = $self->{ScmVerbose};
345
    $::ScmDebug       = $self->{ScmDebug};
346
    $::ScmQuiet       = $self->{ScmQuiet};
347
    $ScmOnExit        = $self->{ScmOnExit};
348
    $ScmDelayExit     = $self->{ScmDelayExit};
349
    $ScmErrorCount    = $self->{ScmErrorCount};
350
    $ScmExitCode      = $self->{ScmExitCode};
351
    $EFn              = $self->{EFn};
352
    $EName            = $self->{EName};
353
}
354
 
355
 
356
#-------------------------------------------------------------------------------
227 dpurdie 357
# Function        : Information
358
#                   Message
359
#                   Question
360
#                   Warning
361
#                   Error
362
#                   Verbose
363
#                   Debug
364
#                   _Message ( Internal use only )
365
#
366
# Description     : Error, Warning and Message routines
367
#                   These routines will display a message to the user
368
#                   with the module name.
369
#
370
#                   Multiple arguments are displayed on their own line
371
#                   with suitable spacing.
372
#
373
# Inputs          : Lines of text to display
374
#
375
# Returns         : Nothing
376
#
377
sub _Message
378
{
379
    my $tag = shift;                # First argument is a tag
380
    my $count = 0;
381
 
382
    #
383
    #   Generate the message prefix
384
    #   This will only be used on the first line
385
    #   All other lines will have a space filled prefix
386
    #
6198 dpurdie 387
    my $prefix = $EPrefix . $tag. $EIndent;
227 dpurdie 388
    #
389
    #   Kill the eol if the Question is being asked
390
    #
391
    my $eol = ( $tag =~ m/Q/ ) ? "" : "\n";
6198 dpurdie 392
    foreach my $nextline ( @_ ) {
231 dpurdie 393
        next unless ( defined $nextline );              # Ignore undefined arguments
227 dpurdie 394
        chomp( my $line = $nextline );
6198 dpurdie 395
        if ( $count == 0 ) {
396
            $line = ($ElPrefix || '') . $line;
397
 
398
        } elsif ( $count == 1 ) {
227 dpurdie 399
            my $bol = $eol ? "" : "\n";
6198 dpurdie 400
            $prefix = $bol . ' ' x length($prefix) . $EOffset;
227 dpurdie 401
        }
5109 dpurdie 402
        $count++;
227 dpurdie 403
 
6198 dpurdie 404
        if ($capturing && $tag =~ m/[MWEF]/) {
5109 dpurdie 405
            push @captured, "$prefix $line$eol" 
6198 dpurdie 406
 
407
        } else {
5109 dpurdie 408
            print "$prefix $line$eol";
409
        }
227 dpurdie 410
    }
411
}
412
 
413
#-------------------------------------------------------------------------------
414
# Function        : Information
415
#                   Information1
416
#
417
# Description     : Will display informational messages
418
#                   These are normal operational messages. These may be
419
#                   supressed through the use of QUIET options
420
#
421
# Inputs          : An array of strings to display
422
#
423
sub Information
424
{
425
    _Message '(I)', @_ unless ( $::ScmQuiet);
426
}
427
 
428
sub Information1
429
{
430
    _Message '(I)', @_ unless ( $::ScmQuiet > 1);
431
}
432
 
433
 
434
#-------------------------------------------------------------------------------
435
# Function        : Message
436
#                   Message1
437
#
438
# Description     : Same as Information, except a different prefix
439
#
440
# Inputs          : An array of strings to display
441
#
442
sub Message
443
{
444
    _Message '(M)', @_ unless ( $::ScmQuiet > 1);
445
}
446
 
447
sub Message1
448
{
449
    _Message '(M)', @_ unless ( $::ScmQuiet);
450
}
451
 
452
#-------------------------------------------------------------------------------
453
# Function        : IsQuiet
454
#
455
# Description     : Determine if an Infrmation or Message will be displayed
456
#                   May be used to reduce excessive processing that may be
457
#                   discarded
458
#
459
# Inputs          : $level      - Level to test
460
#
461
# Returns         : TRUE:       A Message at $level would be displayed
462
#
463
sub IsQuiet
464
{
465
    my( $level) = @_;
466
    return $::ScmQuiet >= $level;
467
}
468
 
469
#-------------------------------------------------------------------------------
470
# Function        : Warning
471
#
472
# Description     : Display a warning message
473
#                   These may be disabled with a high quiet level
474
#
475
# Inputs          : An array of strings to display
476
#
477
sub Warning
478
{
479
    _Message '(W)', @_ unless ( $::ScmQuiet > 2);
480
}
481
 
482
#-------------------------------------------------------------------------------
483
# Function        : Question
484
#
485
# Description     : Display a Question message
486
#                   These cannot be disabled
487
#
488
# Inputs          : An array of strings to display
489
#
490
sub Question
491
{
492
    _Message '(Q)', @_;
493
    STDERR->flush;              # Force output to be displayed
494
    STDOUT->flush;              # Force output to be displayed
495
}
496
 
497
#-------------------------------------------------------------------------------
261 dpurdie 498
# Function        : Fatal
499
#
500
# Description     : Display a multi line fatal message
501
#                   This will cause the program to exit.
502
#
503
#                   Similar to Error(), except
504
#                       Display a (F) prefix
505
#                       Alters the exit code to "2"
506
#                       Will terminate program execution.
507
#                       Will not honor delayed exit configuration.
508
#
509
#                   Fatal is to be used to indicate to consumer processes that
510
#                   the error is a function of the infrastructure and cannot be
511
#                   corrected by a user. ie:
512
#                       clearcase is not available
513
#                           Not just a bad user parameter
514
#                       dpkg_archive is not available
515
#                       release manager database is not available
516
#
517
#                   Intended to be used by build deamons to determine if building
518
#                   should continue, or if the entire build process should be
519
#                   terminated.
520
#
521
# Inputs          : An array of strings to display
522
#
523
# Returns         : May not return
524
#
525
sub Fatal
526
{
527
    _Message '(F)', @_;
528
    $ScmErrorCount++;
529
    $ScmExitCode = 2;
530
    ErrorDoExit() unless ( $ScmDelayExit );
531
}
532
 
533
#-------------------------------------------------------------------------------
227 dpurdie 534
# Function        : Error
535
#
261 dpurdie 536
# Description     : Display a multi line error message
227 dpurdie 537
#                   This may cause the program to exit, or the user may have
538
#                   configured the package to accumulate error messages
539
#
540
#                   This could be used to generate multiple error messages
541
#                   while parsing a file, and then terminate program execution at
542
#                   the end of the phase.
543
#
544
# Inputs          : An array of strings to display
2429 dpurdie 545
#                   First entry May be an exist code of the form
546
#                       ExitCode=nnn
227 dpurdie 547
#
548
# Returns         : May not return
549
#
550
 
551
sub Error
552
{
2429 dpurdie 553
    if ( $_[0] =~ m~^ExitCode=(\d+)$~i )
554
    {
555
        $ScmExitCode = $1 || 1;
556
        shift @_;
557
    }
227 dpurdie 558
    _Message '(E)', @_;
559
    $ScmErrorCount++;
6276 dpurdie 560
#    DebugTraceBack();
227 dpurdie 561
    ErrorDoExit() unless ( $ScmDelayExit );
562
}
563
 
564
#-------------------------------------------------------------------------------
565
# Function        : ReportError
566
#
567
# Description     : Like Error, but the error exit is delayed
568
#
569
# Inputs          : An array of strings to display
570
#
571
sub ReportError
572
{
573
    _Message '(E)', @_;
574
    $ScmErrorCount++;
575
}
576
 
577
#-------------------------------------------------------------------------------
578
# Function        : ErrorDoExit
579
#
580
# Description     : Will terminate the program if delayed error messages
581
#                   have been seen.
582
#
583
# Inputs          : None
584
#
585
# Returns         : Will return if no errors have been reported
586
#
587
 
588
sub ErrorDoExit
589
{
590
    if ( $ScmErrorCount )
591
    {
5109 dpurdie 592
        # If capturing, then force the captured messages to be displayed
593
        DumpCapture();
594
 
227 dpurdie 595
        #
596
        #   Prevent recusion.
597
        #   Kill error processing while doing error exit processing
598
        #
599
        if ( my $func = $ScmOnExit )
600
        {
601
            $ScmOnExit = undef;
283 dpurdie 602
            &$func( $ScmExitCode );
227 dpurdie 603
        }
261 dpurdie 604
        exit $ScmExitCode;
227 dpurdie 605
    }
606
}
607
 
608
#-------------------------------------------------------------------------------
263 dpurdie 609
# Function        : ArgsToString
610
#
611
# Description     : Convert an array of arguments to a string
612
#                   Main purpose is to allow Debug and Verbose
613
#                   calls to pass undef values without causing warnings
6504 dpurdie 614
#                   
615
#                   Put all args on one line, unless '++' is encountered
616
#                   This will force one arg per line mode
263 dpurdie 617
#
618
# Inputs          : REF to a list of scalar values
619
#                   Passing a REF is faster
620
#
6504 dpurdie 621
# Returns         : A string. May be empty, but will be defined
263 dpurdie 622
#
623
sub ArgsToString
624
{
6504 dpurdie 625
    my @result;
626
    my $mode;
627
    foreach ( @{$_[0]} ) {
628
        my $item = defined($_) ? $_ : '\'undef\'';
629
        if ( $item eq '++' ) {
630
            @result = join (' ', @result);
631
            $mode = 1;
632
        } else {
633
            push @result, $item;
634
        }
635
    }
263 dpurdie 636
 
6504 dpurdie 637
    unless ($mode) {
638
        @result = join (' ', @result);
639
    }
640
 
641
    push @result, '' unless @result;
642
    return @result;
263 dpurdie 643
}
644
 
645
#-------------------------------------------------------------------------------
646
# Function        : Verbose0
647
#                   Verbose
227 dpurdie 648
#                   Verbose2
649
#                   Verbose3
650
#
651
# Description     : Various levels of progress reporting
652
#                   By default none are displayed
653
#
654
# Inputs          : A single line string
6504 dpurdie 655
#                   Multi-line output is supported after arg that is '++'
263 dpurdie 656
#                   Arguments will be processed such that undef is handled well
227 dpurdie 657
#
263 dpurdie 658
sub Verbose0
659
{
660
    _Message '------', ArgsToString (\@_);
661
}
227 dpurdie 662
sub Verbose
663
{
263 dpurdie 664
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose);
227 dpurdie 665
}
666
 
667
sub Verbose2
668
{
263 dpurdie 669
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose >= 2);
227 dpurdie 670
}
671
 
672
sub Verbose3
673
{
263 dpurdie 674
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose >= 3);
227 dpurdie 675
}
676
 
677
sub IsVerbose
678
{
679
    my( $level) = @_;
680
    return $::ScmVerbose >= $level;
681
}
682
 
683
#-------------------------------------------------------------------------------
684
# Function        : Debug
685
#                   Debug0
686
#                   Debug1
687
#                   Debug2
688
#                   Debug3
689
#
690
# Description     : Various levels of debug reporting
691
#                   By default none are displayed
692
#
693
# Inputs          : A single line string
6504 dpurdie 694
#                   Multi-line output is supported after arg that is '++'
263 dpurdie 695
#                   Arguments will be processed such that undef is handled well
227 dpurdie 696
#
697
sub Debug0
698
{
263 dpurdie 699
    _Message '------', ArgsToString (\@_);
227 dpurdie 700
}
701
 
702
sub Debug
703
{
263 dpurdie 704
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 1 ) ;
227 dpurdie 705
}
706
 
707
 
708
sub Debug2
709
{
263 dpurdie 710
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 2) ;
227 dpurdie 711
}
712
 
713
 
714
sub Debug3
715
{
263 dpurdie 716
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 3) ;
227 dpurdie 717
}
718
 
719
sub IsDebug
720
{
721
    my( $level) = @_;
722
    return $::ScmDebug >= $level;
723
}
724
 
725
#-------------------------------------------------------------------------------
5109 dpurdie 726
# Function        : StartCapture 
727
#
728
# Description     : Start capturing non-debug non-verbose messages 
729
#
730
# Inputs          : mode    - True: Start 
731
#
732
# Returns         : 
733
#
734
sub StartCapture
735
{
736
    my ($mode) = @_;
737
    $capturing = $mode;
738
}
739
 
740
#-------------------------------------------------------------------------------
741
# Function        : DumpCapture 
742
#
743
# Description     : Dump the captured output
744
#
745
# Inputs          : None
746
#
747
# Returns         : Nothing
748
#
749
sub DumpCapture
750
{
751
    foreach my $line ( @captured) {
752
        print $line;
753
    }
754
    @captured = ();
755
    $capturing = 0;
756
}
757
 
758
#-------------------------------------------------------------------------------
227 dpurdie 759
# Function        : DebugDumpData
760
#
761
# Description     : Dump a data structure
762
#
763
# Inputs          : $name           - A name to give the structure
764
#                   @refp           - An array of references
765
#
766
# Returns         :
767
#
768
sub DebugDumpData
769
{
770
    my ($name, @refp) = @_;
771
 
772
    my $ii = 0;
4085 dpurdie 773
    $Data::Dumper::Sortkeys = 1;
227 dpurdie 774
    foreach  ( @refp )
775
    {
776
        print Data::Dumper->Dump ( [$_], ["*[Arg:$ii] $name" ]);
777
        $ii++
778
    }
779
}
780
 
781
#-------------------------------------------------------------------------------
231 dpurdie 782
# Function        : DebugTraceBack
783
#
784
# Description     : Display the call stack
785
#
786
# Inputs          : $tag
787
#
788
# Returns         : Nothing
789
#
790
sub DebugTraceBack
791
{
792
    my ($tag) = @_;
793
    $tag = 'TraceBack' unless ( $tag );
794
 
795
    #
796
    #   Limit the stack stace.
797
    #   It can't go on forever
798
    #
799
    foreach my $ii ( 0 .. 20 )
800
    {
801
         my ($package, $filename, $line) = caller($ii);
802
         last unless ( $package );
803
         print "$tag: $ii: $package, $filename, $line\n";
804
    }
805
}
806
 
807
#-------------------------------------------------------------------------------
227 dpurdie 808
# Function        : DebugPush
809
#
810
# Description     : Save the current debug level and then use a new name and
811
#                   debug level for future reporting
812
#
279 dpurdie 813
#                   Provided for backward compatability
814
#                   Preferred solution is ErrorReConfig
815
#
816
# Inputs          : $name       - New program name
227 dpurdie 817
#                   $level      - New program debug level
818
#
819
# Returns         : Current debug level
820
#
821
 
822
my @DebugStack = ();
823
sub DebugPush
824
{
825
    my ($name, $new_level) = @_;
279 dpurdie 826
    my %args;
227 dpurdie 827
 
279 dpurdie 828
    #
829
    #   Save current state on a stack
830
    #
831
    my $estate = ErrorReConfig ();
832
    push @DebugStack, $estate;
833
 
227 dpurdie 834
    $::ScmDebug = $new_level if ( defined $new_level && $new_level );
6198 dpurdie 835
    $EPrefix =   $name        if ( defined $name && $name );
227 dpurdie 836
 
837
    return $::ScmDebug;
838
}
839
 
840
#-------------------------------------------------------------------------------
841
# Function        : DebugPop
842
#
843
# Description     : Restores the operation of the DebugPush
844
#
845
# Inputs          : None
846
#
847
sub DebugPop
848
{
279 dpurdie 849
    pop @DebugStack;
227 dpurdie 850
}
851
 
852
#-------------------------------------------------------------------------------
853
# Function        : DebugDumpPackage
854
#
855
# Description     : Dump data within the scope of a given package
856
#
857
# Inputs          : $packageName            - To dump
858
#
859
# Returns         : 
860
#
861
 
862
sub DebugDumpPackage
863
{
864
    no strict "vars";
865
    no strict "refs";
866
    my ($packageName) = @_;
867
    print "==DebugDumpPackage: $packageName =============================\n";
868
 
869
    local $Data::Dumper::Pad = "\t ";
870
    local $Data::Dumper::Maxdepth = 2;
871
    local $Data::Dumper::Indent  = 1;
872
 
873
    # We want to get access to the stash corresponding to the package name
874
 
875
    *stash = *{"${packageName}::"};  # Now %stash is the symbol table
6177 dpurdie 876
 
227 dpurdie 877
    # Iterate through the symbol table, which contains glob values
878
    # indexed by symbol names.
6177 dpurdie 879
 
880
    foreach my $varName ( sort keys %stash)
227 dpurdie 881
    {
6177 dpurdie 882
        my $globValue = $stash{$varName};
227 dpurdie 883
        print "$varName =============================\n";
884
        next if ( $varName eq 'stash' );
283 dpurdie 885
        local *alias = $globValue;
227 dpurdie 886
        if (defined ($alias)) {
887
            print Data::Dumper->Dump ( [$alias], ["*$varName" ]);
888
#            print "\t \$$varName $alias \n";
889
        } 
369 dpurdie 890
        if (@alias) {
227 dpurdie 891
            print Data::Dumper->Dump ( [\@alias], ["*$varName" ]);
892
#            print "\t \@$varName @alias \n";
893
        } 
369 dpurdie 894
        if (%alias) {
227 dpurdie 895
            print Data::Dumper->Dump ( [\%alias], ["*$varName" ]);
896
#            print "\t \%$varName ",%alias," \n";
897
        }
898
        if (defined (&alias)) {
899
#            print Data::Dumper->Dump ( [\&alias], ["*$varName" ]);
900
            print "\t \&$varName ","Code Fragment"," \n";
901
        }
902
     }
903
}
904
 
905
#
906
#
907
1;