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
9469442c 3$VERSION = '1.02_01';
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
d3a7d8c7
GS
278#define pWARN_STD Nullsv
279#define pWARN_ALL (Nullsv+1) /* use warnings 'all' */
280#define pWARN_NONE (Nullsv+2) /* no warnings 'all' */
599cee73 281
d3a7d8c7
GS
282#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
283 (x) == pWARN_NONE)
599cee73
PM
284EOM
285
d3a7d8c7
GS
286my $offset = 0 ;
287
288$index = $offset ;
289#@{ $list{"all"} } = walk ($tree) ;
0d658bf5
PM
290valueWalk ($tree) ;
291my $index = orderValues();
599cee73 292
12bcd1a6
PM
293die <<EOM if $index > 255 ;
294Too many warnings categories -- max is 255
295 rewrite packWARN* & unpackWARN* macros
296EOM
599cee73 297
0d658bf5
PM
298walk ($tree) ;
299
599cee73
PM
300$index *= 2 ;
301my $warn_size = int($index / 8) + ($index % 8 != 0) ;
302
303my $k ;
0d658bf5
PM
304my $last_ver = 0;
305foreach $k (sort { $a <=> $b } keys %ValueToName) {
306 my ($name, $version) = @{ $ValueToName{$k} };
307 print WARN "\n/* Warnings Categories added in Perl $version */\n\n"
308 if $last_ver != $version ;
309 print WARN tab(5, "#define WARN_$name"), "$k\n" ;
310 $last_ver = $version ;
599cee73
PM
311}
312print WARN "\n" ;
313
314print WARN tab(5, '#define WARNsize'), "$warn_size\n" ;
315#print WARN tab(5, '#define WARN_ALLstring'), '"', ('\377' x $warn_size) , "\"\n" ;
316print WARN tab(5, '#define WARN_ALLstring'), '"', ('\125' x $warn_size) , "\"\n" ;
317print WARN tab(5, '#define WARN_NONEstring'), '"', ('\0' x $warn_size) , "\"\n" ;
317ea90d
MS
318my $WARN_TAINTstring = mkOct($warn_size, map $_ * 2, @{ $list{'taint'} });
319
320print WARN tab(5, '#define WARN_TAINTstring'), qq["$WARN_TAINTstring"\n] ;
599cee73
PM
321
322print WARN <<'EOM';
323
d5a71f30
GS
324#define isLEXWARN_on (PL_curcop->cop_warnings != pWARN_STD)
325#define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)
326#define isWARN_ONCE (PL_dowarn & (G_WARN_ON|G_WARN_ONCE))
5e7e76a3
SP
327#define isWARN_on(c,x) (IsSet(SvPVX_const(c), 2*(x)))
328#define isWARNf_on(c,x) (IsSet(SvPVX_const(c), 2*(x)+1))
d5a71f30 329
f5e9f069
NC
330#define ckWARN(w) Perl_ckwarn(aTHX_ packWARN(w))
331#define ckWARN2(w1,w2) Perl_ckwarn(aTHX_ packWARN2(w1,w2))
332#define ckWARN3(w1,w2,w3) Perl_ckwarn(aTHX_ packWARN3(w1,w2,w3))
333#define ckWARN4(w1,w2,w3,w4) Perl_ckwarn(aTHX_ packWARN4(w1,w2,w3,w4))
334
335#define ckWARN_d(w) Perl_ckwarn_d(aTHX_ packWARN(w))
336#define ckWARN2_d(w1,w2) Perl_ckwarn_d(aTHX_ packWARN2(w1,w2))
337#define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
338#define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
12bcd1a6 339
9469442c
MB
340#define packWARN(a) (a )
341#define packWARN2(a,b) ((a) | ((b)<<8) )
342#define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
343#define packWARN4(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d) <<24))
12bcd1a6
PM
344
345#define unpackWARN1(x) ((x) & 0xFF)
346#define unpackWARN2(x) (((x) >>8) & 0xFF)
347#define unpackWARN3(x) (((x) >>16) & 0xFF)
348#define unpackWARN4(x) (((x) >>24) & 0xFF)
349
350#define ckDEAD(x) \
351 ( ! specialWARN(PL_curcop->cop_warnings) && \
352 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
353 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
354 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
355 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
356 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
357
4438c4b7 358/* end of file warnings.h */
d8294a4d 359/* ex: set ro: */
599cee73
PM
360EOM
361
362close WARN ;
363
364while (<DATA>) {
365 last if /^KEYWORDS$/ ;
366 print PM $_ ;
367}
368
d3a7d8c7
GS
369#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
370
0d658bf5 371$last_ver = 0;
fea227c9 372print PM "our %Offsets = (\n" ;
0d658bf5
PM
373foreach my $k (sort { $a <=> $b } keys %ValueToName) {
374 my ($name, $version) = @{ $ValueToName{$k} };
375 $name = lc $name;
d3a7d8c7 376 $k *= 2 ;
0d658bf5
PM
377 if ( $last_ver != $version ) {
378 print PM "\n";
379 print PM tab(4, " # Warnings Categories added in Perl $version");
380 print PM "\n\n";
381 }
382 print PM tab(4, " '$name'"), "=> $k,\n" ;
383 $last_ver = $version;
d3a7d8c7
GS
384}
385
386print PM " );\n\n" ;
387
fea227c9 388print PM "our %Bits = (\n" ;
599cee73
PM
389foreach $k (sort keys %list) {
390
391 my $v = $list{$k} ;
392 my @list = sort { $a <=> $b } @$v ;
393
0ca4541c
NIS
394 print PM tab(4, " '$k'"), '=> "',
395 # mkHex($warn_size, @list),
396 mkHex($warn_size, map $_ * 2 , @list),
599cee73
PM
397 '", # [', mkRange(@list), "]\n" ;
398}
399
400print PM " );\n\n" ;
401
fea227c9 402print PM "our %DeadBits = (\n" ;
599cee73
PM
403foreach $k (sort keys %list) {
404
405 my $v = $list{$k} ;
406 my @list = sort { $a <=> $b } @$v ;
407
0ca4541c
NIS
408 print PM tab(4, " '$k'"), '=> "',
409 # mkHex($warn_size, @list),
410 mkHex($warn_size, map $_ * 2 + 1 , @list),
599cee73
PM
411 '", # [', mkRange(@list), "]\n" ;
412}
413
414print PM " );\n\n" ;
d3a7d8c7
GS
415print PM '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
416print PM '$LAST_BIT = ' . "$index ;\n" ;
417print PM '$BYTES = ' . "$warn_size ;\n" ;
599cee73
PM
418while (<DATA>) {
419 print PM $_ ;
420}
421
d8294a4d 422print PM "# ex: set ro:\n";
599cee73
PM
423close PM ;
424
425__END__
d8294a4d 426# -*- buffer-read-only: t -*-
38875929 427# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 428# This file was created by warnings.pl
599cee73
PM
429# Any changes made here will be lost.
430#
431
4438c4b7 432package warnings;
599cee73 433
4315de2b 434our $VERSION = '1.03';
b75c8c73 435
599cee73
PM
436=head1 NAME
437
4438c4b7 438warnings - Perl pragma to control optional warnings
599cee73
PM
439
440=head1 SYNOPSIS
441
4438c4b7
JH
442 use warnings;
443 no warnings;
599cee73 444
4438c4b7
JH
445 use warnings "all";
446 no warnings "all";
599cee73 447
d3a7d8c7
GS
448 use warnings::register;
449 if (warnings::enabled()) {
450 warnings::warn("some warning");
451 }
452
453 if (warnings::enabled("void")) {
e476b1b5
GS
454 warnings::warn("void", "some warning");
455 }
456
7e6d00f8
PM
457 if (warnings::enabled($object)) {
458 warnings::warn($object, "some warning");
459 }
460
721f911b
PM
461 warnings::warnif("some warning");
462 warnings::warnif("void", "some warning");
463 warnings::warnif($object, "some warning");
7e6d00f8 464
599cee73
PM
465=head1 DESCRIPTION
466
0e0a3cd3
JH
467The C<warnings> pragma is a replacement for the command line flag C<-w>,
468but the pragma is limited to the enclosing block, while the flag is global.
469See L<perllexwarn> for more information.
470
0453d815
PM
471If no import list is supplied, all possible warnings are either enabled
472or disabled.
599cee73 473
0ca4541c 474A number of functions are provided to assist module authors.
e476b1b5
GS
475
476=over 4
477
d3a7d8c7
GS
478=item use warnings::register
479
7e6d00f8
PM
480Creates a new warnings category with the same name as the package where
481the call to the pragma is used.
482
483=item warnings::enabled()
484
485Use the warnings category with the same name as the current package.
486
487Return TRUE if that warnings category is enabled in the calling module.
488Otherwise returns FALSE.
489
490=item warnings::enabled($category)
491
492Return TRUE if the warnings category, C<$category>, is enabled in the
493calling module.
494Otherwise returns FALSE.
495
496=item warnings::enabled($object)
497
498Use the name of the class for the object reference, C<$object>, as the
499warnings category.
500
501Return TRUE if that warnings category is enabled in the first scope
502where the object is used.
503Otherwise returns FALSE.
504
505=item warnings::warn($message)
506
507Print C<$message> to STDERR.
508
509Use the warnings category with the same name as the current package.
510
511If that warnings category has been set to "FATAL" in the calling module
512then die. Otherwise return.
513
514=item warnings::warn($category, $message)
515
516Print C<$message> to STDERR.
517
518If the warnings category, C<$category>, has been set to "FATAL" in the
519calling module then die. Otherwise return.
d3a7d8c7 520
7e6d00f8 521=item warnings::warn($object, $message)
e476b1b5 522
7e6d00f8 523Print C<$message> to STDERR.
e476b1b5 524
7e6d00f8
PM
525Use the name of the class for the object reference, C<$object>, as the
526warnings category.
e476b1b5 527
7e6d00f8
PM
528If that warnings category has been set to "FATAL" in the scope where C<$object>
529is first used then die. Otherwise return.
599cee73 530
e476b1b5 531
7e6d00f8
PM
532=item warnings::warnif($message)
533
534Equivalent to:
535
536 if (warnings::enabled())
537 { warnings::warn($message) }
538
539=item warnings::warnif($category, $message)
540
541Equivalent to:
542
543 if (warnings::enabled($category))
544 { warnings::warn($category, $message) }
545
546=item warnings::warnif($object, $message)
547
548Equivalent to:
549
550 if (warnings::enabled($object))
551 { warnings::warn($object, $message) }
d3a7d8c7 552
e476b1b5
GS
553=back
554
749f83fa 555See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73
PM
556
557=cut
558
4315de2b 559use Carp ();
599cee73
PM
560
561KEYWORDS
562
d3a7d8c7
GS
563$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
564
c3186b65
PM
565sub Croaker
566{
567 delete $Carp::CarpInternal{'warnings'};
4315de2b 568 Carp::croak(@_);
c3186b65
PM
569}
570
6e9af7e4
PM
571sub bits
572{
573 # called from B::Deparse.pm
574
575 push @_, 'all' unless @_;
576
577 my $mask;
599cee73
PM
578 my $catmask ;
579 my $fatal = 0 ;
6e9af7e4
PM
580 my $no_fatal = 0 ;
581
582 foreach my $word ( @_ ) {
583 if ($word eq 'FATAL') {
327afb7f 584 $fatal = 1;
6e9af7e4
PM
585 $no_fatal = 0;
586 }
587 elsif ($word eq 'NONFATAL') {
588 $fatal = 0;
589 $no_fatal = 1;
327afb7f 590 }
d3a7d8c7
GS
591 elsif ($catmask = $Bits{$word}) {
592 $mask |= $catmask ;
593 $mask |= $DeadBits{$word} if $fatal ;
6e9af7e4 594 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
599cee73 595 }
d3a7d8c7 596 else
c3186b65 597 { Croaker("Unknown warnings category '$word'")}
599cee73
PM
598 }
599
600 return $mask ;
601}
602
6e9af7e4
PM
603sub import
604{
599cee73 605 shift;
6e9af7e4
PM
606
607 my $catmask ;
608 my $fatal = 0 ;
609 my $no_fatal = 0 ;
610
f1f33818 611 my $mask = ${^WARNING_BITS} ;
6e9af7e4 612
f1f33818
PM
613 if (vec($mask, $Offsets{'all'}, 1)) {
614 $mask |= $Bits{'all'} ;
615 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
616 }
6e9af7e4
PM
617
618 push @_, 'all' unless @_;
619
620 foreach my $word ( @_ ) {
621 if ($word eq 'FATAL') {
622 $fatal = 1;
623 $no_fatal = 0;
624 }
625 elsif ($word eq 'NONFATAL') {
626 $fatal = 0;
627 $no_fatal = 1;
628 }
629 elsif ($catmask = $Bits{$word}) {
630 $mask |= $catmask ;
631 $mask |= $DeadBits{$word} if $fatal ;
632 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
633 }
634 else
635 { Croaker("Unknown warnings category '$word'")}
636 }
637
638 ${^WARNING_BITS} = $mask ;
599cee73
PM
639}
640
6e9af7e4
PM
641sub unimport
642{
599cee73 643 shift;
6e9af7e4
PM
644
645 my $catmask ;
d3a7d8c7 646 my $mask = ${^WARNING_BITS} ;
6e9af7e4 647
d3a7d8c7 648 if (vec($mask, $Offsets{'all'}, 1)) {
f1f33818 649 $mask |= $Bits{'all'} ;
d3a7d8c7
GS
650 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
651 }
6e9af7e4
PM
652
653 push @_, 'all' unless @_;
654
655 foreach my $word ( @_ ) {
656 if ($word eq 'FATAL') {
657 next;
658 }
659 elsif ($catmask = $Bits{$word}) {
660 $mask &= ~($catmask | $DeadBits{$word} | $All);
661 }
662 else
663 { Croaker("Unknown warnings category '$word'")}
664 }
665
666 ${^WARNING_BITS} = $mask ;
599cee73
PM
667}
668
7661b143
NC
669my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
670
7e6d00f8 671sub __chk
599cee73 672{
d3a7d8c7
GS
673 my $category ;
674 my $offset ;
7e6d00f8 675 my $isobj = 0 ;
d3a7d8c7
GS
676
677 if (@_) {
678 # check the category supplied.
679 $category = shift ;
7661b143
NC
680 if (my $type = ref $category) {
681 Croaker("not an object")
682 if exists $builtin_type{$type};
683 $category = $type;
7e6d00f8
PM
684 $isobj = 1 ;
685 }
d3a7d8c7 686 $offset = $Offsets{$category};
c3186b65 687 Croaker("Unknown warnings category '$category'")
d3a7d8c7
GS
688 unless defined $offset;
689 }
690 else {
0ca4541c 691 $category = (caller(1))[0] ;
d3a7d8c7 692 $offset = $Offsets{$category};
c3186b65 693 Croaker("package '$category' not registered for warnings")
d3a7d8c7
GS
694 unless defined $offset ;
695 }
696
0ca4541c 697 my $this_pkg = (caller(1))[0] ;
7e6d00f8
PM
698 my $i = 2 ;
699 my $pkg ;
700
701 if ($isobj) {
702 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
703 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
704 }
705 $i -= 2 ;
706 }
707 else {
708 for ($i = 2 ; $pkg = (caller($i))[0] ; ++ $i) {
709 last if $pkg ne $this_pkg ;
710 }
0ca4541c 711 $i = 2
7e6d00f8
PM
712 if !$pkg || $pkg eq $this_pkg ;
713 }
714
0ca4541c 715 my $callers_bitmask = (caller($i))[9] ;
7e6d00f8
PM
716 return ($callers_bitmask, $offset, $i) ;
717}
718
719sub enabled
720{
c3186b65 721 Croaker("Usage: warnings::enabled([category])")
7e6d00f8
PM
722 unless @_ == 1 || @_ == 0 ;
723
724 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
725
726 return 0 unless defined $callers_bitmask ;
d3a7d8c7
GS
727 return vec($callers_bitmask, $offset, 1) ||
728 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73
PM
729}
730
d3a7d8c7 731
e476b1b5
GS
732sub warn
733{
c3186b65 734 Croaker("Usage: warnings::warn([category,] 'message')")
d3a7d8c7 735 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 736
7e6d00f8
PM
737 my $message = pop ;
738 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
4315de2b 739 Carp::croak($message)
d3a7d8c7
GS
740 if vec($callers_bitmask, $offset+1, 1) ||
741 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
4315de2b 742 Carp::carp($message) ;
e476b1b5
GS
743}
744
7e6d00f8
PM
745sub warnif
746{
c3186b65 747 Croaker("Usage: warnings::warnif([category,] 'message')")
7e6d00f8
PM
748 unless @_ == 2 || @_ == 1 ;
749
750 my $message = pop ;
751 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
7e6d00f8 752
0ca4541c 753 return
7e6d00f8
PM
754 unless defined $callers_bitmask &&
755 (vec($callers_bitmask, $offset, 1) ||
756 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
757
4315de2b 758 Carp::croak($message)
7e6d00f8
PM
759 if vec($callers_bitmask, $offset+1, 1) ||
760 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
761
4315de2b 762 Carp::carp($message) ;
7e6d00f8 763}
0d658bf5 764
599cee73 7651;