Subversion Repositories DevTools

Rev

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