[patch@31739] ASTFLT in HiRes.t on VMS
[p5sagit/p5-mst-13.2.git] / warnings.pl
CommitLineData
599cee73 1#!/usr/bin/perl
2
98225a64 3$VERSION = '1.02_02';
b75c8c73 4
73f0cc2d 5BEGIN {
6 push @INC, './lib';
7}
599cee73 8use strict ;
9
10sub DEFAULT_ON () { 1 }
11sub DEFAULT_OFF () { 2 }
12
13my $tree = {
d3a7d8c7 14
0d658bf5 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],
0d658bf5 52 'untie' => [ 5.008, DEFAULT_OFF],
53 'substr' => [ 5.008, DEFAULT_OFF],
54 'taint' => [ 5.008, DEFAULT_OFF],
55 'signal' => [ 5.008, DEFAULT_OFF],
56 'closure' => [ 5.008, DEFAULT_OFF],
57 'overflow' => [ 5.008, DEFAULT_OFF],
58 'portable' => [ 5.008, DEFAULT_OFF],
59 'utf8' => [ 5.008, DEFAULT_OFF],
60 'exiting' => [ 5.008, DEFAULT_OFF],
61 'pack' => [ 5.008, DEFAULT_OFF],
62 'unpack' => [ 5.008, DEFAULT_OFF],
38875929 63 'threads' => [ 5.008, DEFAULT_OFF],
8fa7688f 64
0d658bf5 65 #'default' => [ 5.008, DEFAULT_ON ],
66 }],
d3a7d8c7 67} ;
599cee73 68
599cee73 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 80my %ValueToName ;
81my %NameToValue ;
d3a7d8c7 82my $index ;
599cee73 83
0d658bf5 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 123sub walk
124{
125 my $tre = shift ;
126 my @list = () ;
127 my ($k, $v) ;
128
95dfd3ab 129 foreach $k (sort keys %$tre) {
130 $v = $tre->{$k};
599cee73 131 die "duplicate key $k\n" if defined $list{$k} ;
0d658bf5 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 143 push @list, @{ $list{$k} } ;
144 }
145
146 return @list ;
599cee73 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 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 170sub printTree
171{
172 my $tre = shift ;
173 my $prefix = shift ;
e476b1b5 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 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 198 my $bar = @keys ? "|" : " ";
199 print " -" . "-" x ($max - length $k ) . "+\n" ;
200 printTree ($rest, $prefix . $bar . $offset )
e476b1b5 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 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 221 if ($f eq 'x') {
222 $string .= '\x' . sprintf("%2.2x", $_)
223 }
224 else {
225 $string .= '\\' . sprintf("%o", $_)
226 }
599cee73 227 }
228 return $string ;
229}
230
317ea90d 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 243###########################################################################
244
e476b1b5 245if (@ARGV && $ARGV[0] eq "tree")
246{
0d658bf5 247 printTree($tree, " ") ;
e476b1b5 248 exit ;
249}
599cee73 250
918426be 251unlink "warnings.h";
252unlink "lib/warnings.pm";
4438c4b7 253open(WARN, ">warnings.h") || die "Can't create warnings.h: $!\n";
dfb1454f 254binmode WARN;
4438c4b7 255open(PM, ">lib/warnings.pm") || die "Can't create lib/warnings.pm: $!\n";
dfb1454f 256binmode PM;
599cee73 257
258print WARN <<'EOM' ;
37442d52 259/* -*- buffer-read-only: t -*-
260 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 261 This file is built by warnings.pl
599cee73 262 Any changes made here will be lost!
263*/
264
265
0453d815 266#define Off(x) ((x) / 8)
267#define Bit(x) (1 << ((x) % 8))
599cee73 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 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 276#define G_WARN_ALL_MASK (G_WARN_ALL_ON|G_WARN_ALL_OFF)
277
a0714e2c 278#define pWARN_STD NULL
72dc9ed5 279#define pWARN_ALL (((STRLEN*)0)+1) /* use warnings 'all' */
280#define pWARN_NONE (((STRLEN*)0)+2) /* no warnings 'all' */
599cee73 281
d3a7d8c7 282#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
283 (x) == pWARN_NONE)
5f2d9966 284
285/* if PL_warnhook is set to this value, then warnings die */
06dcd5bf 286#define PERL_WARNHOOK_FATAL (&PL_sv_placeholder)
599cee73 287EOM
288
d3a7d8c7 289my $offset = 0 ;
290
291$index = $offset ;
292#@{ $list{"all"} } = walk ($tree) ;
0d658bf5 293valueWalk ($tree) ;
294my $index = orderValues();
599cee73 295
12bcd1a6 296die <<EOM if $index > 255 ;
297Too many warnings categories -- max is 255
298 rewrite packWARN* & unpackWARN* macros
299EOM
599cee73 300
0d658bf5 301walk ($tree) ;
302
599cee73 303$index *= 2 ;
304my $warn_size = int($index / 8) + ($index % 8 != 0) ;
305
306my $k ;
0d658bf5 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 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" ;
321
322print WARN <<'EOM';
323
d5a71f30 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))
72dc9ed5 327#define isWARN_on(c,x) (IsSet((U8 *)(c + 1), 2*(x)))
328#define isWARNf_on(c,x) (IsSet((U8 *)(c + 1), 2*(x)+1))
329
330#define DUP_WARNINGS(p) \
594cd643 331 (specialWARN(p) ? (STRLEN*)(p) \
332 : (STRLEN*)CopyD(p, PerlMemShared_malloc(sizeof(*p)+*p), sizeof(*p)+*p, \
333 char))
d5a71f30 334
f54ba1c2 335#define ckWARN(w) Perl_ckwarn(aTHX_ packWARN(w))
336#define ckWARN2(w1,w2) Perl_ckwarn(aTHX_ packWARN2(w1,w2))
337#define ckWARN3(w1,w2,w3) Perl_ckwarn(aTHX_ packWARN3(w1,w2,w3))
338#define ckWARN4(w1,w2,w3,w4) Perl_ckwarn(aTHX_ packWARN4(w1,w2,w3,w4))
339
340#define ckWARN_d(w) Perl_ckwarn_d(aTHX_ packWARN(w))
341#define ckWARN2_d(w1,w2) Perl_ckwarn_d(aTHX_ packWARN2(w1,w2))
342#define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
343#define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
12bcd1a6 344
3b9e3074 345#define packWARN(a) (a )
346#define packWARN2(a,b) ((a) | ((b)<<8) )
347#define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
348#define packWARN4(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d) <<24))
12bcd1a6 349
350#define unpackWARN1(x) ((x) & 0xFF)
351#define unpackWARN2(x) (((x) >>8) & 0xFF)
352#define unpackWARN3(x) (((x) >>16) & 0xFF)
353#define unpackWARN4(x) (((x) >>24) & 0xFF)
354
355#define ckDEAD(x) \
356 ( ! specialWARN(PL_curcop->cop_warnings) && \
357 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
358 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
359 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
360 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
361 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
362
4438c4b7 363/* end of file warnings.h */
37442d52 364/* ex: set ro: */
599cee73 365EOM
366
367close WARN ;
368
369while (<DATA>) {
370 last if /^KEYWORDS$/ ;
371 print PM $_ ;
372}
373
d3a7d8c7 374#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
375
0d658bf5 376$last_ver = 0;
53c33732 377print PM "our %Offsets = (\n" ;
0d658bf5 378foreach my $k (sort { $a <=> $b } keys %ValueToName) {
379 my ($name, $version) = @{ $ValueToName{$k} };
380 $name = lc $name;
d3a7d8c7 381 $k *= 2 ;
0d658bf5 382 if ( $last_ver != $version ) {
383 print PM "\n";
384 print PM tab(4, " # Warnings Categories added in Perl $version");
385 print PM "\n\n";
386 }
387 print PM tab(4, " '$name'"), "=> $k,\n" ;
388 $last_ver = $version;
d3a7d8c7 389}
390
391print PM " );\n\n" ;
392
53c33732 393print PM "our %Bits = (\n" ;
599cee73 394foreach $k (sort keys %list) {
395
396 my $v = $list{$k} ;
397 my @list = sort { $a <=> $b } @$v ;
398
0ca4541c 399 print PM tab(4, " '$k'"), '=> "',
400 # mkHex($warn_size, @list),
401 mkHex($warn_size, map $_ * 2 , @list),
599cee73 402 '", # [', mkRange(@list), "]\n" ;
403}
404
405print PM " );\n\n" ;
406
53c33732 407print PM "our %DeadBits = (\n" ;
599cee73 408foreach $k (sort keys %list) {
409
410 my $v = $list{$k} ;
411 my @list = sort { $a <=> $b } @$v ;
412
0ca4541c 413 print PM tab(4, " '$k'"), '=> "',
414 # mkHex($warn_size, @list),
415 mkHex($warn_size, map $_ * 2 + 1 , @list),
599cee73 416 '", # [', mkRange(@list), "]\n" ;
417}
418
419print PM " );\n\n" ;
d3a7d8c7 420print PM '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
421print PM '$LAST_BIT = ' . "$index ;\n" ;
422print PM '$BYTES = ' . "$warn_size ;\n" ;
599cee73 423while (<DATA>) {
424 print PM $_ ;
425}
426
37442d52 427print PM "# ex: set ro:\n";
599cee73 428close PM ;
429
430__END__
37442d52 431# -*- buffer-read-only: t -*-
38875929 432# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 433# This file was created by warnings.pl
599cee73 434# Any changes made here will be lost.
435#
436
4438c4b7 437package warnings;
599cee73 438
f2c3e829 439our $VERSION = '1.06';
440
441# Verify that we're called correctly so that warnings will work.
442# see also strict.pm.
443unless ( __FILE__ =~ /(^|[\/\\])\Q@{[__PACKAGE__]}\E\.pm$/ ) {
444 my (undef, $f, $l) = caller;
445 die("Incorrect use of pragma '@{[__PACKAGE__,]}' at $f line $l.\n");
446}
b75c8c73 447
599cee73 448=head1 NAME
449
4438c4b7 450warnings - Perl pragma to control optional warnings
599cee73 451
452=head1 SYNOPSIS
453
4438c4b7 454 use warnings;
455 no warnings;
599cee73 456
4438c4b7 457 use warnings "all";
458 no warnings "all";
599cee73 459
d3a7d8c7 460 use warnings::register;
461 if (warnings::enabled()) {
462 warnings::warn("some warning");
463 }
464
465 if (warnings::enabled("void")) {
e476b1b5 466 warnings::warn("void", "some warning");
467 }
468
7e6d00f8 469 if (warnings::enabled($object)) {
470 warnings::warn($object, "some warning");
471 }
472
721f911b 473 warnings::warnif("some warning");
474 warnings::warnif("void", "some warning");
475 warnings::warnif($object, "some warning");
7e6d00f8 476
599cee73 477=head1 DESCRIPTION
478
fe2e802c 479The C<warnings> pragma is a replacement for the command line flag C<-w>,
480but the pragma is limited to the enclosing block, while the flag is global.
481See L<perllexwarn> for more information.
482
0453d815 483If no import list is supplied, all possible warnings are either enabled
484or disabled.
599cee73 485
0ca4541c 486A number of functions are provided to assist module authors.
e476b1b5 487
488=over 4
489
d3a7d8c7 490=item use warnings::register
491
7e6d00f8 492Creates a new warnings category with the same name as the package where
493the call to the pragma is used.
494
495=item warnings::enabled()
496
497Use the warnings category with the same name as the current package.
498
499Return TRUE if that warnings category is enabled in the calling module.
500Otherwise returns FALSE.
501
502=item warnings::enabled($category)
503
504Return TRUE if the warnings category, C<$category>, is enabled in the
505calling module.
506Otherwise returns FALSE.
507
508=item warnings::enabled($object)
509
510Use the name of the class for the object reference, C<$object>, as the
511warnings category.
512
513Return TRUE if that warnings category is enabled in the first scope
514where the object is used.
515Otherwise returns FALSE.
516
517=item warnings::warn($message)
518
519Print C<$message> to STDERR.
520
521Use the warnings category with the same name as the current package.
522
523If that warnings category has been set to "FATAL" in the calling module
524then die. Otherwise return.
525
526=item warnings::warn($category, $message)
527
528Print C<$message> to STDERR.
529
530If the warnings category, C<$category>, has been set to "FATAL" in the
531calling module then die. Otherwise return.
d3a7d8c7 532
7e6d00f8 533=item warnings::warn($object, $message)
e476b1b5 534
7e6d00f8 535Print C<$message> to STDERR.
e476b1b5 536
7e6d00f8 537Use the name of the class for the object reference, C<$object>, as the
538warnings category.
e476b1b5 539
7e6d00f8 540If that warnings category has been set to "FATAL" in the scope where C<$object>
541is first used then die. Otherwise return.
599cee73 542
e476b1b5 543
7e6d00f8 544=item warnings::warnif($message)
545
546Equivalent to:
547
548 if (warnings::enabled())
549 { warnings::warn($message) }
550
551=item warnings::warnif($category, $message)
552
553Equivalent to:
554
555 if (warnings::enabled($category))
556 { warnings::warn($category, $message) }
557
558=item warnings::warnif($object, $message)
559
560Equivalent to:
561
562 if (warnings::enabled($object))
563 { warnings::warn($object, $message) }
d3a7d8c7 564
e476b1b5 565=back
566
749f83fa 567See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73 568
569=cut
570
599cee73 571KEYWORDS
572
d3a7d8c7 573$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
574
c3186b65 575sub Croaker
576{
29ddba3b 577 require Carp::Heavy; # this initializes %CarpInternal
dbab294c 578 local $Carp::CarpInternal{'warnings'};
c3186b65 579 delete $Carp::CarpInternal{'warnings'};
8becbb3b 580 Carp::croak(@_);
c3186b65 581}
582
6e9af7e4 583sub bits
584{
585 # called from B::Deparse.pm
586
587 push @_, 'all' unless @_;
588
589 my $mask;
599cee73 590 my $catmask ;
591 my $fatal = 0 ;
6e9af7e4 592 my $no_fatal = 0 ;
593
594 foreach my $word ( @_ ) {
595 if ($word eq 'FATAL') {
327afb7f 596 $fatal = 1;
6e9af7e4 597 $no_fatal = 0;
598 }
599 elsif ($word eq 'NONFATAL') {
600 $fatal = 0;
601 $no_fatal = 1;
327afb7f 602 }
d3a7d8c7 603 elsif ($catmask = $Bits{$word}) {
604 $mask |= $catmask ;
605 $mask |= $DeadBits{$word} if $fatal ;
6e9af7e4 606 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
599cee73 607 }
d3a7d8c7 608 else
c3186b65 609 { Croaker("Unknown warnings category '$word'")}
599cee73 610 }
611
612 return $mask ;
613}
614
6e9af7e4 615sub import
616{
599cee73 617 shift;
6e9af7e4 618
619 my $catmask ;
620 my $fatal = 0 ;
621 my $no_fatal = 0 ;
622
f1f33818 623 my $mask = ${^WARNING_BITS} ;
6e9af7e4 624
f1f33818 625 if (vec($mask, $Offsets{'all'}, 1)) {
626 $mask |= $Bits{'all'} ;
627 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
628 }
6e9af7e4 629
630 push @_, 'all' unless @_;
631
632 foreach my $word ( @_ ) {
633 if ($word eq 'FATAL') {
634 $fatal = 1;
635 $no_fatal = 0;
636 }
637 elsif ($word eq 'NONFATAL') {
638 $fatal = 0;
639 $no_fatal = 1;
640 }
641 elsif ($catmask = $Bits{$word}) {
642 $mask |= $catmask ;
643 $mask |= $DeadBits{$word} if $fatal ;
644 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
645 }
646 else
647 { Croaker("Unknown warnings category '$word'")}
648 }
649
650 ${^WARNING_BITS} = $mask ;
599cee73 651}
652
6e9af7e4 653sub unimport
654{
599cee73 655 shift;
6e9af7e4 656
657 my $catmask ;
d3a7d8c7 658 my $mask = ${^WARNING_BITS} ;
6e9af7e4 659
d3a7d8c7 660 if (vec($mask, $Offsets{'all'}, 1)) {
f1f33818 661 $mask |= $Bits{'all'} ;
d3a7d8c7 662 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
663 }
6e9af7e4 664
665 push @_, 'all' unless @_;
666
667 foreach my $word ( @_ ) {
668 if ($word eq 'FATAL') {
669 next;
670 }
671 elsif ($catmask = $Bits{$word}) {
672 $mask &= ~($catmask | $DeadBits{$word} | $All);
673 }
674 else
675 { Croaker("Unknown warnings category '$word'")}
676 }
677
678 ${^WARNING_BITS} = $mask ;
599cee73 679}
680
9df0f64f 681my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
682
7e6d00f8 683sub __chk
599cee73 684{
d3a7d8c7 685 my $category ;
686 my $offset ;
7e6d00f8 687 my $isobj = 0 ;
d3a7d8c7 688
689 if (@_) {
690 # check the category supplied.
691 $category = shift ;
9df0f64f 692 if (my $type = ref $category) {
693 Croaker("not an object")
694 if exists $builtin_type{$type};
695 $category = $type;
7e6d00f8 696 $isobj = 1 ;
697 }
d3a7d8c7 698 $offset = $Offsets{$category};
c3186b65 699 Croaker("Unknown warnings category '$category'")
d3a7d8c7 700 unless defined $offset;
701 }
702 else {
0ca4541c 703 $category = (caller(1))[0] ;
d3a7d8c7 704 $offset = $Offsets{$category};
c3186b65 705 Croaker("package '$category' not registered for warnings")
d3a7d8c7 706 unless defined $offset ;
707 }
708
0ca4541c 709 my $this_pkg = (caller(1))[0] ;
7e6d00f8 710 my $i = 2 ;
711 my $pkg ;
712
713 if ($isobj) {
714 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
715 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
716 }
717 $i -= 2 ;
718 }
719 else {
4f527b71 720 $i = _error_loc(); # see where Carp will allocate the error
7e6d00f8 721 }
722
0ca4541c 723 my $callers_bitmask = (caller($i))[9] ;
7e6d00f8 724 return ($callers_bitmask, $offset, $i) ;
725}
726
4f527b71 727sub _error_loc {
728 require Carp::Heavy;
729 goto &Carp::short_error_loc; # don't introduce another stack frame
730}
731
7e6d00f8 732sub enabled
733{
c3186b65 734 Croaker("Usage: warnings::enabled([category])")
7e6d00f8 735 unless @_ == 1 || @_ == 0 ;
736
737 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
738
739 return 0 unless defined $callers_bitmask ;
d3a7d8c7 740 return vec($callers_bitmask, $offset, 1) ||
741 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73 742}
743
d3a7d8c7 744
e476b1b5 745sub warn
746{
c3186b65 747 Croaker("Usage: warnings::warn([category,] 'message')")
d3a7d8c7 748 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 749
7e6d00f8 750 my $message = pop ;
751 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
09e96b99 752 require Carp;
8becbb3b 753 Carp::croak($message)
d3a7d8c7 754 if vec($callers_bitmask, $offset+1, 1) ||
755 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
8becbb3b 756 Carp::carp($message) ;
e476b1b5 757}
758
7e6d00f8 759sub warnif
760{
c3186b65 761 Croaker("Usage: warnings::warnif([category,] 'message')")
7e6d00f8 762 unless @_ == 2 || @_ == 1 ;
763
764 my $message = pop ;
765 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
7e6d00f8 766
0ca4541c 767 return
7e6d00f8 768 unless defined $callers_bitmask &&
769 (vec($callers_bitmask, $offset, 1) ||
770 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
771
09e96b99 772 require Carp;
8becbb3b 773 Carp::croak($message)
7e6d00f8 774 if vec($callers_bitmask, $offset+1, 1) ||
775 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
776
8becbb3b 777 Carp::carp($message) ;
7e6d00f8 778}
0d658bf5 779
599cee73 7801;