Subversion Repositories DevTools

Rev

Rev 7323 | Details | Compare with Previous | Last modification | View Log | RSS feed

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