Subversion Repositories DevTools

Rev

Rev 7320 | Rev 7323 | 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 = '';
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
#
487
# Description     : Display a warnign or an error based onthe first argument
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
 
504
#-------------------------------------------------------------------------------
227 dpurdie 505
# Function        : Question
506
#
507
# Description     : Display a Question message
508
#                   These cannot be disabled
509
#
510
# Inputs          : An array of strings to display
511
#
512
sub Question
513
{
514
    _Message '(Q)', @_;
515
    STDERR->flush;              # Force output to be displayed
516
    STDOUT->flush;              # Force output to be displayed
517
}
518
 
519
#-------------------------------------------------------------------------------
261 dpurdie 520
# Function        : Fatal
521
#
522
# Description     : Display a multi line fatal message
523
#                   This will cause the program to exit.
524
#
525
#                   Similar to Error(), except
526
#                       Display a (F) prefix
527
#                       Alters the exit code to "2"
528
#                       Will terminate program execution.
529
#                       Will not honor delayed exit configuration.
530
#
531
#                   Fatal is to be used to indicate to consumer processes that
532
#                   the error is a function of the infrastructure and cannot be
533
#                   corrected by a user. ie:
534
#                       clearcase is not available
535
#                           Not just a bad user parameter
536
#                       dpkg_archive is not available
537
#                       release manager database is not available
538
#
539
#                   Intended to be used by build deamons to determine if building
540
#                   should continue, or if the entire build process should be
541
#                   terminated.
542
#
543
# Inputs          : An array of strings to display
544
#
545
# Returns         : May not return
546
#
547
sub Fatal
548
{
549
    _Message '(F)', @_;
550
    $ScmErrorCount++;
551
    $ScmExitCode = 2;
552
    ErrorDoExit() unless ( $ScmDelayExit );
553
}
554
 
555
#-------------------------------------------------------------------------------
227 dpurdie 556
# Function        : Error
557
#
261 dpurdie 558
# Description     : Display a multi line error message
227 dpurdie 559
#                   This may cause the program to exit, or the user may have
560
#                   configured the package to accumulate error messages
561
#
562
#                   This could be used to generate multiple error messages
563
#                   while parsing a file, and then terminate program execution at
564
#                   the end of the phase.
565
#
566
# Inputs          : An array of strings to display
2429 dpurdie 567
#                   First entry May be an exist code of the form
568
#                       ExitCode=nnn
227 dpurdie 569
#
570
# Returns         : May not return
571
#
572
 
573
sub Error
574
{
2429 dpurdie 575
    if ( $_[0] =~ m~^ExitCode=(\d+)$~i )
576
    {
577
        $ScmExitCode = $1 || 1;
578
        shift @_;
579
    }
227 dpurdie 580
    _Message '(E)', @_;
581
    $ScmErrorCount++;
7322 dpurdie 582
#    DebugTraceBack();
227 dpurdie 583
    ErrorDoExit() unless ( $ScmDelayExit );
584
}
585
 
586
#-------------------------------------------------------------------------------
587
# Function        : ReportError
588
#
589
# Description     : Like Error, but the error exit is delayed
590
#
591
# Inputs          : An array of strings to display
592
#
593
sub ReportError
594
{
595
    _Message '(E)', @_;
596
    $ScmErrorCount++;
597
}
598
 
599
#-------------------------------------------------------------------------------
600
# Function        : ErrorDoExit
601
#
602
# Description     : Will terminate the program if delayed error messages
603
#                   have been seen.
604
#
605
# Inputs          : None
606
#
607
# Returns         : Will return if no errors have been reported
608
#
609
 
610
sub ErrorDoExit
611
{
612
    if ( $ScmErrorCount )
613
    {
5109 dpurdie 614
        # If capturing, then force the captured messages to be displayed
615
        DumpCapture();
616
 
227 dpurdie 617
        #
618
        #   Prevent recusion.
619
        #   Kill error processing while doing error exit processing
620
        #
621
        if ( my $func = $ScmOnExit )
622
        {
623
            $ScmOnExit = undef;
283 dpurdie 624
            &$func( $ScmExitCode );
227 dpurdie 625
        }
261 dpurdie 626
        exit $ScmExitCode;
227 dpurdie 627
    }
628
}
629
 
630
#-------------------------------------------------------------------------------
263 dpurdie 631
# Function        : ArgsToString
632
#
633
# Description     : Convert an array of arguments to a string
634
#                   Main purpose is to allow Debug and Verbose
635
#                   calls to pass undef values without causing warnings
7322 dpurdie 636
#                   
637
#                   Put all args on one line, unless '++' is encountered
638
#                   This will force one arg per line mode
263 dpurdie 639
#
640
# Inputs          : REF to a list of scalar values
641
#                   Passing a REF is faster
642
#
7322 dpurdie 643
# Returns         : A string. May be empty, but will be defined
263 dpurdie 644
#
645
sub ArgsToString
646
{
7322 dpurdie 647
    my @result;
648
    my $mode;
649
    foreach ( @{$_[0]} ) {
650
        my $item = defined($_) ? $_ : '\'undef\'';
651
        if ( $item eq '++' ) {
652
            @result = join (' ', @result);
653
            $mode = 1;
654
        } else {
655
            push @result, $item;
656
        }
657
    }
263 dpurdie 658
 
7322 dpurdie 659
    unless ($mode) {
660
        @result = join (' ', @result);
661
    }
662
 
663
    push @result, '' unless @result;
664
    return @result;
263 dpurdie 665
}
666
 
667
#-------------------------------------------------------------------------------
668
# Function        : Verbose0
669
#                   Verbose
227 dpurdie 670
#                   Verbose2
671
#                   Verbose3
672
#
673
# Description     : Various levels of progress reporting
674
#                   By default none are displayed
675
#
676
# Inputs          : A single line string
7322 dpurdie 677
#                   Multi-line output is supported after arg that is '++'
263 dpurdie 678
#                   Arguments will be processed such that undef is handled well
227 dpurdie 679
#
263 dpurdie 680
sub Verbose0
681
{
682
    _Message '------', ArgsToString (\@_);
683
}
227 dpurdie 684
sub Verbose
685
{
263 dpurdie 686
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose);
227 dpurdie 687
}
688
 
689
sub Verbose2
690
{
263 dpurdie 691
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose >= 2);
227 dpurdie 692
}
693
 
694
sub Verbose3
695
{
263 dpurdie 696
    _Message '(V)', ArgsToString (\@_) if ($::ScmVerbose >= 3);
227 dpurdie 697
}
698
 
699
sub IsVerbose
700
{
701
    my( $level) = @_;
702
    return $::ScmVerbose >= $level;
703
}
704
 
705
#-------------------------------------------------------------------------------
706
# Function        : Debug
707
#                   Debug0
708
#                   Debug1
709
#                   Debug2
710
#                   Debug3
711
#
712
# Description     : Various levels of debug reporting
713
#                   By default none are displayed
714
#
715
# Inputs          : A single line string
7322 dpurdie 716
#                   Multi-line output is supported after arg that is '++'
263 dpurdie 717
#                   Arguments will be processed such that undef is handled well
227 dpurdie 718
#
719
sub Debug0
720
{
263 dpurdie 721
    _Message '------', ArgsToString (\@_);
227 dpurdie 722
}
723
 
724
sub Debug
725
{
263 dpurdie 726
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 1 ) ;
227 dpurdie 727
}
728
 
729
 
730
sub Debug2
731
{
263 dpurdie 732
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 2) ;
227 dpurdie 733
}
734
 
735
 
736
sub Debug3
737
{
263 dpurdie 738
    _Message '(D)', ArgsToString (\@_) if ($::ScmDebug >= 3) ;
227 dpurdie 739
}
740
 
741
sub IsDebug
742
{
743
    my( $level) = @_;
744
    return $::ScmDebug >= $level;
745
}
746
 
747
#-------------------------------------------------------------------------------
5109 dpurdie 748
# Function        : StartCapture 
749
#
750
# Description     : Start capturing non-debug non-verbose messages 
751
#
752
# Inputs          : mode    - True: Start 
753
#
754
# Returns         : 
755
#
756
sub StartCapture
757
{
758
    my ($mode) = @_;
759
    $capturing = $mode;
760
}
761
 
762
#-------------------------------------------------------------------------------
763
# Function        : DumpCapture 
764
#
765
# Description     : Dump the captured output
766
#
767
# Inputs          : None
768
#
769
# Returns         : Nothing
770
#
771
sub DumpCapture
772
{
773
    foreach my $line ( @captured) {
774
        print $line;
775
    }
776
    @captured = ();
777
    $capturing = 0;
778
}
779
 
780
#-------------------------------------------------------------------------------
227 dpurdie 781
# Function        : DebugDumpData
782
#
783
# Description     : Dump a data structure
784
#
785
# Inputs          : $name           - A name to give the structure
786
#                   @refp           - An array of references
787
#
788
# Returns         :
789
#
790
sub DebugDumpData
791
{
792
    my ($name, @refp) = @_;
793
 
794
    my $ii = 0;
4085 dpurdie 795
    $Data::Dumper::Sortkeys = 1;
227 dpurdie 796
    foreach  ( @refp )
797
    {
798
        print Data::Dumper->Dump ( [$_], ["*[Arg:$ii] $name" ]);
799
        $ii++
800
    }
801
}
802
 
803
#-------------------------------------------------------------------------------
231 dpurdie 804
# Function        : DebugTraceBack
805
#
806
# Description     : Display the call stack
807
#
808
# Inputs          : $tag
809
#
810
# Returns         : Nothing
811
#
812
sub DebugTraceBack
813
{
814
    my ($tag) = @_;
815
    $tag = 'TraceBack' unless ( $tag );
816
 
817
    #
818
    #   Limit the stack stace.
819
    #   It can't go on forever
820
    #
821
    foreach my $ii ( 0 .. 20 )
822
    {
823
         my ($package, $filename, $line) = caller($ii);
824
         last unless ( $package );
825
         print "$tag: $ii: $package, $filename, $line\n";
826
    }
827
}
828
 
829
#-------------------------------------------------------------------------------
227 dpurdie 830
# Function        : DebugPush
831
#
832
# Description     : Save the current debug level and then use a new name and
833
#                   debug level for future reporting
834
#
279 dpurdie 835
#                   Provided for backward compatability
836
#                   Preferred solution is ErrorReConfig
837
#
838
# Inputs          : $name       - New program name
227 dpurdie 839
#                   $level      - New program debug level
840
#
841
# Returns         : Current debug level
842
#
843
 
844
my @DebugStack = ();
845
sub DebugPush
846
{
847
    my ($name, $new_level) = @_;
279 dpurdie 848
    my %args;
227 dpurdie 849
 
279 dpurdie 850
    #
851
    #   Save current state on a stack
852
    #
853
    my $estate = ErrorReConfig ();
854
    push @DebugStack, $estate;
855
 
227 dpurdie 856
    $::ScmDebug = $new_level if ( defined $new_level && $new_level );
7307 dpurdie 857
    $EPrefix =   $name        if ( defined $name && $name );
227 dpurdie 858
 
859
    return $::ScmDebug;
860
}
861
 
862
#-------------------------------------------------------------------------------
863
# Function        : DebugPop
864
#
865
# Description     : Restores the operation of the DebugPush
866
#
867
# Inputs          : None
868
#
869
sub DebugPop
870
{
279 dpurdie 871
    pop @DebugStack;
227 dpurdie 872
}
873
 
874
#-------------------------------------------------------------------------------
875
# Function        : DebugDumpPackage
876
#
877
# Description     : Dump data within the scope of a given package
878
#
879
# Inputs          : $packageName            - To dump
880
#
881
# Returns         : 
882
#
883
 
884
sub DebugDumpPackage
885
{
886
    no strict "vars";
887
    no strict "refs";
888
    my ($packageName) = @_;
889
    print "==DebugDumpPackage: $packageName =============================\n";
890
 
891
    local $Data::Dumper::Pad = "\t ";
892
    local $Data::Dumper::Maxdepth = 2;
893
    local $Data::Dumper::Indent  = 1;
894
 
895
    # We want to get access to the stash corresponding to the package name
896
 
897
    *stash = *{"${packageName}::"};  # Now %stash is the symbol table
7300 dpurdie 898
 
227 dpurdie 899
    # Iterate through the symbol table, which contains glob values
900
    # indexed by symbol names.
7300 dpurdie 901
 
902
    foreach my $varName ( sort keys %stash)
227 dpurdie 903
    {
7300 dpurdie 904
        my $globValue = $stash{$varName};
227 dpurdie 905
        print "$varName =============================\n";
906
        next if ( $varName eq 'stash' );
283 dpurdie 907
        local *alias = $globValue;
227 dpurdie 908
        if (defined ($alias)) {
909
            print Data::Dumper->Dump ( [$alias], ["*$varName" ]);
910
#            print "\t \$$varName $alias \n";
911
        } 
369 dpurdie 912
        if (@alias) {
227 dpurdie 913
            print Data::Dumper->Dump ( [\@alias], ["*$varName" ]);
914
#            print "\t \@$varName @alias \n";
915
        } 
369 dpurdie 916
        if (%alias) {
227 dpurdie 917
            print Data::Dumper->Dump ( [\%alias], ["*$varName" ]);
918
#            print "\t \%$varName ",%alias," \n";
919
        }
920
        if (defined (&alias)) {
921
#            print Data::Dumper->Dump ( [\&alias], ["*$varName" ]);
922
            print "\t \&$varName ","Code Fragment"," \n";
923
        }
924
     }
925
}
926
 
927
#
928
#
929
1;