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