This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate:
[perl5.git] / warnings.pl
CommitLineData
599cee73
PM
1#!/usr/bin/perl
2
252d2216 3$VERSION = '1.02_02';
b75c8c73 4
73f0cc2d
GS
5BEGIN {
6 push @INC, './lib';
7}
599cee73
PM
8use strict ;
9
10sub DEFAULT_ON () { 1 }
11sub DEFAULT_OFF () { 2 }
12
13my $tree = {
d3a7d8c7 14
0d658bf5
PM
15'all' => [ 5.008, {
16 'io' => [ 5.008, {
17 'pipe' => [ 5.008, DEFAULT_OFF],
18 'unopened' => [ 5.008, DEFAULT_OFF],
19 'closed' => [ 5.008, DEFAULT_OFF],
20 'newline' => [ 5.008, DEFAULT_OFF],
21 'exec' => [ 5.008, DEFAULT_OFF],
22 'layer' => [ 5.008, DEFAULT_OFF],
23 }],
24 'syntax' => [ 5.008, {
25 'ambiguous' => [ 5.008, DEFAULT_OFF],
26 'semicolon' => [ 5.008, DEFAULT_OFF],
27 'precedence' => [ 5.008, DEFAULT_OFF],
28 'bareword' => [ 5.008, DEFAULT_OFF],
29 'reserved' => [ 5.008, DEFAULT_OFF],
30 'digit' => [ 5.008, DEFAULT_OFF],
31 'parenthesis' => [ 5.008, DEFAULT_OFF],
32 'printf' => [ 5.008, DEFAULT_OFF],
33 'prototype' => [ 5.008, DEFAULT_OFF],
34 'qw' => [ 5.008, DEFAULT_OFF],
35 }],
36 'severe' => [ 5.008, {
37 'inplace' => [ 5.008, DEFAULT_ON],
38 'internal' => [ 5.008, DEFAULT_ON],
39 'debugging' => [ 5.008, DEFAULT_ON],
40 'malloc' => [ 5.008, DEFAULT_ON],
41 }],
42 'deprecated' => [ 5.008, DEFAULT_OFF],
43 'void' => [ 5.008, DEFAULT_OFF],
44 'recursion' => [ 5.008, DEFAULT_OFF],
45 'redefine' => [ 5.008, DEFAULT_OFF],
46 'numeric' => [ 5.008, DEFAULT_OFF],
47 'uninitialized' => [ 5.008, DEFAULT_OFF],
48 'once' => [ 5.008, DEFAULT_OFF],
49 'misc' => [ 5.008, DEFAULT_OFF],
50 'regexp' => [ 5.008, DEFAULT_OFF],
51 'glob' => [ 5.008, DEFAULT_OFF],
52 'y2k' => [ 5.008, DEFAULT_OFF],
53 'untie' => [ 5.008, DEFAULT_OFF],
54 'substr' => [ 5.008, DEFAULT_OFF],
55 'taint' => [ 5.008, DEFAULT_OFF],
56 'signal' => [ 5.008, DEFAULT_OFF],
57 'closure' => [ 5.008, DEFAULT_OFF],
58 'overflow' => [ 5.008, DEFAULT_OFF],
59 'portable' => [ 5.008, DEFAULT_OFF],
60 'utf8' => [ 5.008, DEFAULT_OFF],
61 'exiting' => [ 5.008, DEFAULT_OFF],
62 'pack' => [ 5.008, DEFAULT_OFF],
63 'unpack' => [ 5.008, DEFAULT_OFF],
38875929 64 'threads' => [ 5.008, DEFAULT_OFF],
0d658bf5
PM
65 #'default' => [ 5.008, DEFAULT_ON ],
66 }],
d3a7d8c7 67} ;
599cee73 68
599cee73
PM
69###########################################################################
70sub tab {
71 my($l, $t) = @_;
72 $t .= "\t" x ($l - (length($t) + 1) / 8);
73 $t;
74}
75
76###########################################################################
77
78my %list ;
79my %Value ;
0d658bf5
PM
80my %ValueToName ;
81my %NameToValue ;
d3a7d8c7 82my $index ;
599cee73 83
0d658bf5
PM
84my %v_list = () ;
85
86sub valueWalk
87{
88 my $tre = shift ;
89 my @list = () ;
90 my ($k, $v) ;
91
92 foreach $k (sort keys %$tre) {
93 $v = $tre->{$k};
94 die "duplicate key $k\n" if defined $list{$k} ;
95 die "Value associated with key '$k' is not an ARRAY reference"
96 if !ref $v || ref $v ne 'ARRAY' ;
97
98 my ($ver, $rest) = @{ $v } ;
99 push @{ $v_list{$ver} }, $k;
100
101 if (ref $rest)
102 { valueWalk ($rest) }
103
104 }
105
106}
107
108sub orderValues
109{
110 my $index = 0;
111 foreach my $ver ( sort { $a <=> $b } keys %v_list ) {
112 foreach my $name (@{ $v_list{$ver} } ) {
113 $ValueToName{ $index } = [ uc $name, $ver ] ;
114 $NameToValue{ uc $name } = $index ++ ;
115 }
116 }
117
118 return $index ;
119}
120
121###########################################################################
122
599cee73
PM
123sub walk
124{
125 my $tre = shift ;
126 my @list = () ;
127 my ($k, $v) ;
128
95dfd3ab
GS
129 foreach $k (sort keys %$tre) {
130 $v = $tre->{$k};
599cee73 131 die "duplicate key $k\n" if defined $list{$k} ;
0d658bf5
PM
132 #$Value{$index} = uc $k ;
133 die "Can't find key '$k'"
134 if ! defined $NameToValue{uc $k} ;
135 push @{ $list{$k} }, $NameToValue{uc $k} ;
136 die "Value associated with key '$k' is not an ARRAY reference"
137 if !ref $v || ref $v ne 'ARRAY' ;
138
139 my ($ver, $rest) = @{ $v } ;
140 if (ref $rest)
141 { push (@{ $list{$k} }, walk ($rest)) }
142
599cee73
PM
143 push @list, @{ $list{$k} } ;
144 }
145
146 return @list ;
599cee73
PM
147}
148
149###########################################################################
150
151sub mkRange
152{
153 my @a = @_ ;
154 my @out = @a ;
155 my $i ;
156
157
158 for ($i = 1 ; $i < @a; ++ $i) {
0ca4541c 159 $out[$i] = ".."
599cee73
PM
160 if $a[$i] == $a[$i - 1] + 1 && $a[$i] + 1 == $a[$i + 1] ;
161 }
162
163 my $out = join(",",@out);
164
165 $out =~ s/,(\.\.,)+/../g ;
166 return $out;
167}
168
169###########################################################################
e476b1b5
GS
170sub printTree
171{
172 my $tre = shift ;
173 my $prefix = shift ;
e476b1b5
GS
174 my ($k, $v) ;
175
176 my $max = (sort {$a <=> $b} map { length $_ } keys %$tre)[-1] ;
0d658bf5 177 my @keys = sort keys %$tre ;
e476b1b5 178
0d658bf5 179 while ($k = shift @keys) {
e476b1b5 180 $v = $tre->{$k};
0d658bf5
PM
181 die "Value associated with key '$k' is not an ARRAY reference"
182 if !ref $v || ref $v ne 'ARRAY' ;
183
184 my $offset ;
185 if ($tre ne $tree) {
186 print $prefix . "|\n" ;
187 print $prefix . "+- $k" ;
188 $offset = ' ' x ($max + 4) ;
189 }
190 else {
191 print $prefix . "$k" ;
192 $offset = ' ' x ($max + 1) ;
193 }
194
195 my ($ver, $rest) = @{ $v } ;
196 if (ref $rest)
0ca4541c 197 {
0d658bf5
PM
198 my $bar = @keys ? "|" : " ";
199 print " -" . "-" x ($max - length $k ) . "+\n" ;
200 printTree ($rest, $prefix . $bar . $offset )
e476b1b5
GS
201 }
202 else
203 { print "\n" }
204 }
205
206}
207
208###########################################################################
599cee73 209
317ea90d 210sub mkHexOct
599cee73 211{
317ea90d 212 my ($f, $max, @a) = @_ ;
599cee73
PM
213 my $mask = "\x00" x $max ;
214 my $string = "" ;
215
216 foreach (@a) {
217 vec($mask, $_, 1) = 1 ;
218 }
219
599cee73 220 foreach (unpack("C*", $mask)) {
317ea90d
MS
221 if ($f eq 'x') {
222 $string .= '\x' . sprintf("%2.2x", $_)
223 }
224 else {
225 $string .= '\\' . sprintf("%o", $_)
226 }
599cee73
PM
227 }
228 return $string ;
229}
230
317ea90d
MS
231sub mkHex
232{
233 my($max, @a) = @_;
234 return mkHexOct("x", $max, @a);
235}
236
237sub mkOct
238{
239 my($max, @a) = @_;
240 return mkHexOct("o", $max, @a);
241}
242
599cee73
PM
243###########################################################################
244
e476b1b5
GS
245if (@ARGV && $ARGV[0] eq "tree")
246{
0d658bf5 247 printTree($tree, " ") ;
e476b1b5
GS
248 exit ;
249}
599cee73 250
918426be
NC
251unlink "warnings.h";
252unlink "lib/warnings.pm";
4438c4b7 253open(WARN, ">warnings.h") || die "Can't create warnings.h: $!\n";
9ca8eaf1 254binmode WARN;
4438c4b7 255open(PM, ">lib/warnings.pm") || die "Can't create lib/warnings.pm: $!\n";
9ca8eaf1 256binmode PM;
599cee73
PM
257
258print WARN <<'EOM' ;
d8294a4d
NC
259/* -*- buffer-read-only: t -*-
260 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 261 This file is built by warnings.pl
599cee73
PM
262 Any changes made here will be lost!
263*/
264
265
0453d815
PM
266#define Off(x) ((x) / 8)
267#define Bit(x) (1 << ((x) % 8))
599cee73
PM
268#define IsSet(a, x) ((a)[Off(x)] & Bit(x))
269
0453d815 270
599cee73 271#define G_WARN_OFF 0 /* $^W == 0 */
0453d815 272#define G_WARN_ON 1 /* -w flag and $^W != 0 */
599cee73
PM
273#define G_WARN_ALL_ON 2 /* -W flag */
274#define G_WARN_ALL_OFF 4 /* -X flag */
0453d815 275#define G_WARN_ONCE 8 /* set if 'once' ever enabled */
599cee73
PM
276#define G_WARN_ALL_MASK (G_WARN_ALL_ON|G_WARN_ALL_OFF)
277
0e2d6244
SS
278#define pWARN_STD NULL
279#define pWARN_ALL (((SV*)0)+1) /* use warnings 'all' */
280#define pWARN_NONE (((SV*)0)+2) /* no warnings 'all' */
599cee73 281
d3a7d8c7
GS
282#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
283 (x) == pWARN_NONE)
910ce816
NC
284
285/* if PL_warnhook is set to this value, then warnings die */
286#define PERL_WARNHOOK_FATAL (((SV*)0) + 1)
599cee73
PM
287EOM
288
d3a7d8c7
GS
289my $offset = 0 ;
290
291$index = $offset ;
292#@{ $list{"all"} } = walk ($tree) ;
0d658bf5
PM
293valueWalk ($tree) ;
294my $index = orderValues();
599cee73 295
12bcd1a6
PM
296die <<EOM if $index > 255 ;
297Too many warnings categories -- max is 255
298 rewrite packWARN* & unpackWARN* macros
299EOM
599cee73 300
0d658bf5
PM
301walk ($tree) ;
302
599cee73
PM
303$index *= 2 ;
304my $warn_size = int($index / 8) + ($index % 8 != 0) ;
305
306my $k ;
0d658bf5
PM
307my $last_ver = 0;
308foreach $k (sort { $a <=> $b } keys %ValueToName) {
309 my ($name, $version) = @{ $ValueToName{$k} };
310 print WARN "\n/* Warnings Categories added in Perl $version */\n\n"
311 if $last_ver != $version ;
312 print WARN tab(5, "#define WARN_$name"), "$k\n" ;
313 $last_ver = $version ;
599cee73
PM
314}
315print WARN "\n" ;
316
317print WARN tab(5, '#define WARNsize'), "$warn_size\n" ;
318#print WARN tab(5, '#define WARN_ALLstring'), '"', ('\377' x $warn_size) , "\"\n" ;
319print WARN tab(5, '#define WARN_ALLstring'), '"', ('\125' x $warn_size) , "\"\n" ;
320print WARN tab(5, '#define WARN_NONEstring'), '"', ('\0' x $warn_size) , "\"\n" ;
317ea90d
MS
321my $WARN_TAINTstring = mkOct($warn_size, map $_ * 2, @{ $list{'taint'} });
322
323print WARN tab(5, '#define WARN_TAINTstring'), qq["$WARN_TAINTstring"\n] ;
599cee73
PM
324
325print WARN <<'EOM';
326
d5a71f30
GS
327#define isLEXWARN_on (PL_curcop->cop_warnings != pWARN_STD)
328#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)
329#define isWARN_ONCE (PL_dowarn & (G_WARN_ON|G_WARN_ONCE))
5e7e76a3
SP
330#define isWARN_on(c,x) (IsSet(SvPVX_const(c), 2*(x)))
331#define isWARNf_on(c,x) (IsSet(SvPVX_const(c), 2*(x)+1))
d5a71f30 332
f5e9f069
NC
333#define ckWARN(w) Perl_ckwarn(aTHX_ packWARN(w))
334#define ckWARN2(w1,w2) Perl_ckwarn(aTHX_ packWARN2(w1,w2))
335#define ckWARN3(w1,w2,w3) Perl_ckwarn(aTHX_ packWARN3(w1,w2,w3))
336#define ckWARN4(w1,w2,w3,w4) Perl_ckwarn(aTHX_ packWARN4(w1,w2,w3,w4))
337
338#define ckWARN_d(w) Perl_ckwarn_d(aTHX_ packWARN(w))
339#define ckWARN2_d(w1,w2) Perl_ckwarn_d(aTHX_ packWARN2(w1,w2))
340#define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
341#define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
12bcd1a6 342
9469442c
MB
343#define packWARN(a) (a )
344#define packWARN2(a,b) ((a) | ((b)<<8) )
345#define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
346#define packWARN4(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d) <<24))
12bcd1a6
PM
347
348#define unpackWARN1(x) ((x) & 0xFF)
349#define unpackWARN2(x) (((x) >>8) & 0xFF)
350#define unpackWARN3(x) (((x) >>16) & 0xFF)
351#define unpackWARN4(x) (((x) >>24) & 0xFF)
352
353#define ckDEAD(x) \
354 ( ! specialWARN(PL_curcop->cop_warnings) && \
355 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
356 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
357 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
358 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
359 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
360
4438c4b7 361/* end of file warnings.h */
d8294a4d 362/* ex: set ro: */
599cee73
PM
363EOM
364
365close WARN ;
366
367while (<DATA>) {
368 last if /^KEYWORDS$/ ;
369 print PM $_ ;
370}
371
d3a7d8c7
GS
372#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
373
0d658bf5 374$last_ver = 0;
fea227c9 375print PM "our %Offsets = (\n" ;
0d658bf5
PM
376foreach my $k (sort { $a <=> $b } keys %ValueToName) {
377 my ($name, $version) = @{ $ValueToName{$k} };
378 $name = lc $name;
d3a7d8c7 379 $k *= 2 ;
0d658bf5
PM
380 if ( $last_ver != $version ) {
381 print PM "\n";
382 print PM tab(4, " # Warnings Categories added in Perl $version");
383 print PM "\n\n";
384 }
385 print PM tab(4, " '$name'"), "=> $k,\n" ;
386 $last_ver = $version;
d3a7d8c7
GS
387}
388
389print PM " );\n\n" ;
390
fea227c9 391print PM "our %Bits = (\n" ;
599cee73
PM
392foreach $k (sort keys %list) {
393
394 my $v = $list{$k} ;
395 my @list = sort { $a <=> $b } @$v ;
396
0ca4541c
NIS
397 print PM tab(4, " '$k'"), '=> "',
398 # mkHex($warn_size, @list),
399 mkHex($warn_size, map $_ * 2 , @list),
599cee73
PM
400 '", # [', mkRange(@list), "]\n" ;
401}
402
403print PM " );\n\n" ;
404
fea227c9 405print PM "our %DeadBits = (\n" ;
599cee73
PM
406foreach $k (sort keys %list) {
407
408 my $v = $list{$k} ;
409 my @list = sort { $a <=> $b } @$v ;
410
0ca4541c
NIS
411 print PM tab(4, " '$k'"), '=> "',
412 # mkHex($warn_size, @list),
413 mkHex($warn_size, map $_ * 2 + 1 , @list),
599cee73
PM
414 '", # [', mkRange(@list), "]\n" ;
415}
416
417print PM " );\n\n" ;
d3a7d8c7
GS
418print PM '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
419print PM '$LAST_BIT = ' . "$index ;\n" ;
420print PM '$BYTES = ' . "$warn_size ;\n" ;
599cee73
PM
421while (<DATA>) {
422 print PM $_ ;
423}
424
d8294a4d 425print PM "# ex: set ro:\n";
599cee73
PM
426close PM ;
427
428__END__
d8294a4d 429# -*- buffer-read-only: t -*-
38875929 430# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 431# This file was created by warnings.pl
599cee73
PM
432# Any changes made here will be lost.
433#
434
4438c4b7 435package warnings;
599cee73 436
252d2216 437our $VERSION = '1.05';
b75c8c73 438
599cee73
PM
439=head1 NAME
440
4438c4b7 441warnings - Perl pragma to control optional warnings
599cee73
PM
442
443=head1 SYNOPSIS
444
4438c4b7
JH
445 use warnings;
446 no warnings;
599cee73 447
4438c4b7
JH
448 use warnings "all";
449 no warnings "all";
599cee73 450
d3a7d8c7
GS
451 use warnings::register;
452 if (warnings::enabled()) {
453 warnings::warn("some warning");
454 }
455
456 if (warnings::enabled("void")) {
e476b1b5
GS
457 warnings::warn("void", "some warning");
458 }
459
7e6d00f8
PM
460 if (warnings::enabled($object)) {
461 warnings::warn($object, "some warning");
462 }
463
721f911b
PM
464 warnings::warnif("some warning");
465 warnings::warnif("void", "some warning");
466 warnings::warnif($object, "some warning");
7e6d00f8 467
599cee73
PM
468=head1 DESCRIPTION
469
0e0a3cd3
JH
470The C<warnings> pragma is a replacement for the command line flag C<-w>,
471but the pragma is limited to the enclosing block, while the flag is global.
472See L<perllexwarn> for more information.
473
0453d815
PM
474If no import list is supplied, all possible warnings are either enabled
475or disabled.
599cee73 476
0ca4541c 477A number of functions are provided to assist module authors.
e476b1b5
GS
478
479=over 4
480
d3a7d8c7
GS
481=item use warnings::register
482
7e6d00f8
PM
483Creates a new warnings category with the same name as the package where
484the call to the pragma is used.
485
486=item warnings::enabled()
487
488Use the warnings category with the same name as the current package.
489
490Return TRUE if that warnings category is enabled in the calling module.
491Otherwise returns FALSE.
492
493=item warnings::enabled($category)
494
495Return TRUE if the warnings category, C<$category>, is enabled in the
496calling module.
497Otherwise returns FALSE.
498
499=item warnings::enabled($object)
500
501Use the name of the class for the object reference, C<$object>, as the
502warnings category.
503
504Return TRUE if that warnings category is enabled in the first scope
505where the object is used.
506Otherwise returns FALSE.
507
508=item warnings::warn($message)
509
510Print C<$message> to STDERR.
511
512Use the warnings category with the same name as the current package.
513
514If that warnings category has been set to "FATAL" in the calling module
515then die. Otherwise return.
516
517=item warnings::warn($category, $message)
518
519Print C<$message> to STDERR.
520
521If the warnings category, C<$category>, has been set to "FATAL" in the
522calling module then die. Otherwise return.
d3a7d8c7 523
7e6d00f8 524=item warnings::warn($object, $message)
e476b1b5 525
7e6d00f8 526Print C<$message> to STDERR.
e476b1b5 527
7e6d00f8
PM
528Use the name of the class for the object reference, C<$object>, as the
529warnings category.
e476b1b5 530
7e6d00f8
PM
531If that warnings category has been set to "FATAL" in the scope where C<$object>
532is first used then die. Otherwise return.
599cee73 533
e476b1b5 534
7e6d00f8
PM
535=item warnings::warnif($message)
536
537Equivalent to:
538
539 if (warnings::enabled())
540 { warnings::warn($message) }
541
542=item warnings::warnif($category, $message)
543
544Equivalent to:
545
546 if (warnings::enabled($category))
547 { warnings::warn($category, $message) }
548
549=item warnings::warnif($object, $message)
550
551Equivalent to:
552
553 if (warnings::enabled($object))
554 { warnings::warn($object, $message) }
d3a7d8c7 555
e476b1b5
GS
556=back
557
749f83fa 558See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73
PM
559
560=cut
561
4315de2b 562use Carp ();
599cee73
PM
563
564KEYWORDS
565
d3a7d8c7
GS
566$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
567
c3186b65
PM
568sub Croaker
569{
d06e5290 570 require Carp::Heavy; # this initializes %CarpInternal
c3186b65 571 delete $Carp::CarpInternal{'warnings'};
4315de2b 572 Carp::croak(@_);
c3186b65
PM
573}
574
6e9af7e4
PM
575sub bits
576{
577 # called from B::Deparse.pm
578
579 push @_, 'all' unless @_;
580
581 my $mask;
599cee73
PM
582 my $catmask ;
583 my $fatal = 0 ;
6e9af7e4
PM
584 my $no_fatal = 0 ;
585
586 foreach my $word ( @_ ) {
587 if ($word eq 'FATAL') {
327afb7f 588 $fatal = 1;
6e9af7e4
PM
589 $no_fatal = 0;
590 }
591 elsif ($word eq 'NONFATAL') {
592 $fatal = 0;
593 $no_fatal = 1;
327afb7f 594 }
d3a7d8c7
GS
595 elsif ($catmask = $Bits{$word}) {
596 $mask |= $catmask ;
597 $mask |= $DeadBits{$word} if $fatal ;
6e9af7e4 598 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
599cee73 599 }
d3a7d8c7 600 else
c3186b65 601 { Croaker("Unknown warnings category '$word'")}
599cee73
PM
602 }
603
604 return $mask ;
605}
606
6e9af7e4
PM
607sub import
608{
599cee73 609 shift;
6e9af7e4
PM
610
611 my $catmask ;
612 my $fatal = 0 ;
613 my $no_fatal = 0 ;
614
f1f33818 615 my $mask = ${^WARNING_BITS} ;
6e9af7e4 616
f1f33818
PM
617 if (vec($mask, $Offsets{'all'}, 1)) {
618 $mask |= $Bits{'all'} ;
619 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
620 }
6e9af7e4
PM
621
622 push @_, 'all' unless @_;
623
624 foreach my $word ( @_ ) {
625 if ($word eq 'FATAL') {
626 $fatal = 1;
627 $no_fatal = 0;
628 }
629 elsif ($word eq 'NONFATAL') {
630 $fatal = 0;
631 $no_fatal = 1;
632 }
633 elsif ($catmask = $Bits{$word}) {
634 $mask |= $catmask ;
635 $mask |= $DeadBits{$word} if $fatal ;
636 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
637 }
638 else
639 { Croaker("Unknown warnings category '$word'")}
640 }
641
642 ${^WARNING_BITS} = $mask ;
599cee73
PM
643}
644
6e9af7e4
PM
645sub unimport
646{
599cee73 647 shift;
6e9af7e4
PM
648
649 my $catmask ;
d3a7d8c7 650 my $mask = ${^WARNING_BITS} ;
6e9af7e4 651
d3a7d8c7 652 if (vec($mask, $Offsets{'all'}, 1)) {
f1f33818 653 $mask |= $Bits{'all'} ;
d3a7d8c7
GS
654 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
655 }
6e9af7e4
PM
656
657 push @_, 'all' unless @_;
658
659 foreach my $word ( @_ ) {
660 if ($word eq 'FATAL') {
661 next;
662 }
663 elsif ($catmask = $Bits{$word}) {
664 $mask &= ~($catmask | $DeadBits{$word} | $All);
665 }
666 else
667 { Croaker("Unknown warnings category '$word'")}
668 }
669
670 ${^WARNING_BITS} = $mask ;
599cee73
PM
671}
672
7661b143
NC
673my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
674
7e6d00f8 675sub __chk
599cee73 676{
d3a7d8c7
GS
677 my $category ;
678 my $offset ;
7e6d00f8 679 my $isobj = 0 ;
d3a7d8c7
GS
680
681 if (@_) {
682 # check the category supplied.
683 $category = shift ;
7661b143
NC
684 if (my $type = ref $category) {
685 Croaker("not an object")
686 if exists $builtin_type{$type};
687 $category = $type;
7e6d00f8
PM
688 $isobj = 1 ;
689 }
d3a7d8c7 690 $offset = $Offsets{$category};
c3186b65 691 Croaker("Unknown warnings category '$category'")
d3a7d8c7
GS
692 unless defined $offset;
693 }
694 else {
0ca4541c 695 $category = (caller(1))[0] ;
d3a7d8c7 696 $offset = $Offsets{$category};
c3186b65 697 Croaker("package '$category' not registered for warnings")
d3a7d8c7
GS
698 unless defined $offset ;
699 }
700
0ca4541c 701 my $this_pkg = (caller(1))[0] ;
7e6d00f8
PM
702 my $i = 2 ;
703 my $pkg ;
704
705 if ($isobj) {
706 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
707 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
708 }
709 $i -= 2 ;
710 }
711 else {
712 for ($i = 2 ; $pkg = (caller($i))[0] ; ++ $i) {
713 last if $pkg ne $this_pkg ;
714 }
0ca4541c 715 $i = 2
7e6d00f8
PM
716 if !$pkg || $pkg eq $this_pkg ;
717 }
718
0ca4541c 719 my $callers_bitmask = (caller($i))[9] ;
7e6d00f8
PM
720 return ($callers_bitmask, $offset, $i) ;
721}
722
723sub enabled
724{
c3186b65 725 Croaker("Usage: warnings::enabled([category])")
7e6d00f8
PM
726 unless @_ == 1 || @_ == 0 ;
727
728 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
729
730 return 0 unless defined $callers_bitmask ;
d3a7d8c7
GS
731 return vec($callers_bitmask, $offset, 1) ||
732 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73
PM
733}
734
d3a7d8c7 735
e476b1b5
GS
736sub warn
737{
c3186b65 738 Croaker("Usage: warnings::warn([category,] 'message')")
d3a7d8c7 739 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 740
7e6d00f8
PM
741 my $message = pop ;
742 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
4315de2b 743 Carp::croak($message)
d3a7d8c7
GS
744 if vec($callers_bitmask, $offset+1, 1) ||
745 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
4315de2b 746 Carp::carp($message) ;
e476b1b5
GS
747}
748
7e6d00f8
PM
749sub warnif
750{
c3186b65 751 Croaker("Usage: warnings::warnif([category,] 'message')")
7e6d00f8
PM
752 unless @_ == 2 || @_ == 1 ;
753
754 my $message = pop ;
755 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
7e6d00f8 756
0ca4541c 757 return
7e6d00f8
PM
758 unless defined $callers_bitmask &&
759 (vec($callers_bitmask, $offset, 1) ||
760 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
761
4315de2b 762 Carp::croak($message)
7e6d00f8
PM
763 if vec($callers_bitmask, $offset+1, 1) ||
764 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
765
4315de2b 766 Carp::carp($message) ;
7e6d00f8 767}
0d658bf5 768
599cee73 7691;