This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In change 24266 I failed to actually change anything. Sigh.
[perl5.git] / warnings.pl
CommitLineData
599cee73
PM
1#!/usr/bin/perl
2
8becbb3b 3$VERSION = '1.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],
0d658bf5
PM
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
SF
64 'assertions' => [ 5.009, DEFAULT_OFF],
65
0d658bf5
PM
66 #'default' => [ 5.008, DEFAULT_ON ],
67 }],
d3a7d8c7 68} ;
599cee73 69
599cee73
PM
70###########################################################################
71sub tab {
72 my($l, $t) = @_;
73 $t .= "\t" x ($l - (length($t) + 1) / 8);
74 $t;
75}
76
77###########################################################################
78
79my %list ;
80my %Value ;
0d658bf5
PM
81my %ValueToName ;
82my %NameToValue ;
d3a7d8c7 83my $index ;
599cee73 84
0d658bf5
PM
85my %v_list = () ;
86
87sub valueWalk
88{
89 my $tre = shift ;
90 my @list = () ;
91 my ($k, $v) ;
92
93 foreach $k (sort keys %$tre) {
94 $v = $tre->{$k};
95 die "duplicate key $k\n" if defined $list{$k} ;
96 die "Value associated with key '$k' is not an ARRAY reference"
97 if !ref $v || ref $v ne 'ARRAY' ;
98
99 my ($ver, $rest) = @{ $v } ;
100 push @{ $v_list{$ver} }, $k;
101
102 if (ref $rest)
103 { valueWalk ($rest) }
104
105 }
106
107}
108
109sub orderValues
110{
111 my $index = 0;
112 foreach my $ver ( sort { $a <=> $b } keys %v_list ) {
113 foreach my $name (@{ $v_list{$ver} } ) {
114 $ValueToName{ $index } = [ uc $name, $ver ] ;
115 $NameToValue{ uc $name } = $index ++ ;
116 }
117 }
118
119 return $index ;
120}
121
122###########################################################################
123
599cee73
PM
124sub walk
125{
126 my $tre = shift ;
127 my @list = () ;
128 my ($k, $v) ;
129
95dfd3ab
GS
130 foreach $k (sort keys %$tre) {
131 $v = $tre->{$k};
599cee73 132 die "duplicate key $k\n" if defined $list{$k} ;
0d658bf5
PM
133 #$Value{$index} = uc $k ;
134 die "Can't find key '$k'"
135 if ! defined $NameToValue{uc $k} ;
136 push @{ $list{$k} }, $NameToValue{uc $k} ;
137 die "Value associated with key '$k' is not an ARRAY reference"
138 if !ref $v || ref $v ne 'ARRAY' ;
139
140 my ($ver, $rest) = @{ $v } ;
141 if (ref $rest)
142 { push (@{ $list{$k} }, walk ($rest)) }
143
599cee73
PM
144 push @list, @{ $list{$k} } ;
145 }
146
147 return @list ;
599cee73
PM
148}
149
150###########################################################################
151
152sub mkRange
153{
154 my @a = @_ ;
155 my @out = @a ;
156 my $i ;
157
158
159 for ($i = 1 ; $i < @a; ++ $i) {
0ca4541c 160 $out[$i] = ".."
599cee73
PM
161 if $a[$i] == $a[$i - 1] + 1 && $a[$i] + 1 == $a[$i + 1] ;
162 }
163
164 my $out = join(",",@out);
165
166 $out =~ s/,(\.\.,)+/../g ;
167 return $out;
168}
169
170###########################################################################
e476b1b5
GS
171sub printTree
172{
173 my $tre = shift ;
174 my $prefix = shift ;
e476b1b5
GS
175 my ($k, $v) ;
176
177 my $max = (sort {$a <=> $b} map { length $_ } keys %$tre)[-1] ;
0d658bf5 178 my @keys = sort keys %$tre ;
e476b1b5 179
0d658bf5 180 while ($k = shift @keys) {
e476b1b5 181 $v = $tre->{$k};
0d658bf5
PM
182 die "Value associated with key '$k' is not an ARRAY reference"
183 if !ref $v || ref $v ne 'ARRAY' ;
184
185 my $offset ;
186 if ($tre ne $tree) {
187 print $prefix . "|\n" ;
188 print $prefix . "+- $k" ;
189 $offset = ' ' x ($max + 4) ;
190 }
191 else {
192 print $prefix . "$k" ;
193 $offset = ' ' x ($max + 1) ;
194 }
195
196 my ($ver, $rest) = @{ $v } ;
197 if (ref $rest)
0ca4541c 198 {
0d658bf5
PM
199 my $bar = @keys ? "|" : " ";
200 print " -" . "-" x ($max - length $k ) . "+\n" ;
201 printTree ($rest, $prefix . $bar . $offset )
e476b1b5
GS
202 }
203 else
204 { print "\n" }
205 }
206
207}
208
209###########################################################################
599cee73 210
317ea90d 211sub mkHexOct
599cee73 212{
317ea90d 213 my ($f, $max, @a) = @_ ;
599cee73
PM
214 my $mask = "\x00" x $max ;
215 my $string = "" ;
216
217 foreach (@a) {
218 vec($mask, $_, 1) = 1 ;
219 }
220
599cee73 221 foreach (unpack("C*", $mask)) {
317ea90d
MS
222 if ($f eq 'x') {
223 $string .= '\x' . sprintf("%2.2x", $_)
224 }
225 else {
226 $string .= '\\' . sprintf("%o", $_)
227 }
599cee73
PM
228 }
229 return $string ;
230}
231
317ea90d
MS
232sub mkHex
233{
234 my($max, @a) = @_;
235 return mkHexOct("x", $max, @a);
236}
237
238sub mkOct
239{
240 my($max, @a) = @_;
241 return mkHexOct("o", $max, @a);
242}
243
599cee73
PM
244###########################################################################
245
e476b1b5
GS
246if (@ARGV && $ARGV[0] eq "tree")
247{
0d658bf5 248 printTree($tree, " ") ;
e476b1b5
GS
249 exit ;
250}
599cee73 251
918426be
NC
252unlink "warnings.h";
253unlink "lib/warnings.pm";
4438c4b7 254open(WARN, ">warnings.h") || die "Can't create warnings.h: $!\n";
dfb1454f 255binmode WARN;
4438c4b7 256open(PM, ">lib/warnings.pm") || die "Can't create lib/warnings.pm: $!\n";
dfb1454f 257binmode PM;
599cee73
PM
258
259print WARN <<'EOM' ;
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))
327#define isWARN_on(c,x) (IsSet(SvPVX(c), 2*(x)))
328#define isWARNf_on(c,x) (IsSet(SvPVX(c), 2*(x)+1))
329
d5a71f30
GS
330#define ckWARN(x) \
331 ( (isLEXWARN_on && PL_curcop->cop_warnings != pWARN_NONE && \
332 (PL_curcop->cop_warnings == pWARN_ALL || \
333 isWARN_on(PL_curcop->cop_warnings, x) ) ) \
334 || (isLEXWARN_off && PL_dowarn & G_WARN_ON) )
335
336#define ckWARN2(x,y) \
337 ( (isLEXWARN_on && PL_curcop->cop_warnings != pWARN_NONE && \
338 (PL_curcop->cop_warnings == pWARN_ALL || \
339 isWARN_on(PL_curcop->cop_warnings, x) || \
340 isWARN_on(PL_curcop->cop_warnings, y) ) ) \
341 || (isLEXWARN_off && PL_dowarn & G_WARN_ON) )
342
12bcd1a6
PM
343#define ckWARN3(x,y,z) \
344 ( (isLEXWARN_on && PL_curcop->cop_warnings != pWARN_NONE && \
345 (PL_curcop->cop_warnings == pWARN_ALL || \
346 isWARN_on(PL_curcop->cop_warnings, x) || \
347 isWARN_on(PL_curcop->cop_warnings, y) || \
348 isWARN_on(PL_curcop->cop_warnings, z) ) ) \
349 || (isLEXWARN_off && PL_dowarn & G_WARN_ON) )
350
351#define ckWARN4(x,y,z,t) \
352 ( (isLEXWARN_on && PL_curcop->cop_warnings != pWARN_NONE && \
353 (PL_curcop->cop_warnings == pWARN_ALL || \
354 isWARN_on(PL_curcop->cop_warnings, x) || \
355 isWARN_on(PL_curcop->cop_warnings, y) || \
356 isWARN_on(PL_curcop->cop_warnings, z) || \
357 isWARN_on(PL_curcop->cop_warnings, t) ) ) \
358 || (isLEXWARN_off && PL_dowarn & G_WARN_ON) )
359
d5a71f30
GS
360#define ckWARN_d(x) \
361 (isLEXWARN_off || PL_curcop->cop_warnings == pWARN_ALL || \
362 (PL_curcop->cop_warnings != pWARN_NONE && \
363 isWARN_on(PL_curcop->cop_warnings, x) ) )
364
365#define ckWARN2_d(x,y) \
366 (isLEXWARN_off || PL_curcop->cop_warnings == pWARN_ALL || \
367 (PL_curcop->cop_warnings != pWARN_NONE && \
368 (isWARN_on(PL_curcop->cop_warnings, x) || \
369 isWARN_on(PL_curcop->cop_warnings, y) ) ) )
370
12bcd1a6
PM
371#define ckWARN3_d(x,y,z) \
372 (isLEXWARN_off || PL_curcop->cop_warnings == pWARN_ALL || \
373 (PL_curcop->cop_warnings != pWARN_NONE && \
374 (isWARN_on(PL_curcop->cop_warnings, x) || \
375 isWARN_on(PL_curcop->cop_warnings, y) || \
376 isWARN_on(PL_curcop->cop_warnings, z) ) ) )
377
378#define ckWARN4_d(x,y,z,t) \
379 (isLEXWARN_off || PL_curcop->cop_warnings == pWARN_ALL || \
380 (PL_curcop->cop_warnings != pWARN_NONE && \
381 (isWARN_on(PL_curcop->cop_warnings, x) || \
382 isWARN_on(PL_curcop->cop_warnings, y) || \
383 isWARN_on(PL_curcop->cop_warnings, z) || \
384 isWARN_on(PL_curcop->cop_warnings, t) ) ) )
385
386#define packWARN(a) (a )
387#define packWARN2(a,b) ((a) | (b)<<8 )
388#define packWARN3(a,b,c) ((a) | (b)<<8 | (c) <<16 )
389#define packWARN4(a,b,c,d) ((a) | (b)<<8 | (c) <<16 | (d) <<24)
390
391#define unpackWARN1(x) ((x) & 0xFF)
392#define unpackWARN2(x) (((x) >>8) & 0xFF)
393#define unpackWARN3(x) (((x) >>16) & 0xFF)
394#define unpackWARN4(x) (((x) >>24) & 0xFF)
395
396#define ckDEAD(x) \
397 ( ! specialWARN(PL_curcop->cop_warnings) && \
398 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
399 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
400 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
401 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
402 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
403
4438c4b7 404/* end of file warnings.h */
599cee73
PM
405
406EOM
407
408close WARN ;
409
410while (<DATA>) {
411 last if /^KEYWORDS$/ ;
412 print PM $_ ;
413}
414
d3a7d8c7
GS
415#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
416
0d658bf5 417$last_ver = 0;
53c33732 418print PM "our %Offsets = (\n" ;
0d658bf5
PM
419foreach my $k (sort { $a <=> $b } keys %ValueToName) {
420 my ($name, $version) = @{ $ValueToName{$k} };
421 $name = lc $name;
d3a7d8c7 422 $k *= 2 ;
0d658bf5
PM
423 if ( $last_ver != $version ) {
424 print PM "\n";
425 print PM tab(4, " # Warnings Categories added in Perl $version");
426 print PM "\n\n";
427 }
428 print PM tab(4, " '$name'"), "=> $k,\n" ;
429 $last_ver = $version;
d3a7d8c7
GS
430}
431
432print PM " );\n\n" ;
433
53c33732 434print PM "our %Bits = (\n" ;
599cee73
PM
435foreach $k (sort keys %list) {
436
437 my $v = $list{$k} ;
438 my @list = sort { $a <=> $b } @$v ;
439
0ca4541c
NIS
440 print PM tab(4, " '$k'"), '=> "',
441 # mkHex($warn_size, @list),
442 mkHex($warn_size, map $_ * 2 , @list),
599cee73
PM
443 '", # [', mkRange(@list), "]\n" ;
444}
445
446print PM " );\n\n" ;
447
53c33732 448print PM "our %DeadBits = (\n" ;
599cee73
PM
449foreach $k (sort keys %list) {
450
451 my $v = $list{$k} ;
452 my @list = sort { $a <=> $b } @$v ;
453
0ca4541c
NIS
454 print PM tab(4, " '$k'"), '=> "',
455 # mkHex($warn_size, @list),
456 mkHex($warn_size, map $_ * 2 + 1 , @list),
599cee73
PM
457 '", # [', mkRange(@list), "]\n" ;
458}
459
460print PM " );\n\n" ;
d3a7d8c7
GS
461print PM '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
462print PM '$LAST_BIT = ' . "$index ;\n" ;
463print PM '$BYTES = ' . "$warn_size ;\n" ;
599cee73
PM
464while (<DATA>) {
465 print PM $_ ;
466}
467
468close PM ;
469
470__END__
471
38875929 472# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 473# This file was created by warnings.pl
599cee73
PM
474# Any changes made here will be lost.
475#
476
4438c4b7 477package warnings;
599cee73 478
09e96b99 479our $VERSION = '1.04';
b75c8c73 480
599cee73
PM
481=head1 NAME
482
4438c4b7 483warnings - Perl pragma to control optional warnings
599cee73
PM
484
485=head1 SYNOPSIS
486
4438c4b7
JH
487 use warnings;
488 no warnings;
599cee73 489
4438c4b7
JH
490 use warnings "all";
491 no warnings "all";
599cee73 492
d3a7d8c7
GS
493 use warnings::register;
494 if (warnings::enabled()) {
495 warnings::warn("some warning");
496 }
497
498 if (warnings::enabled("void")) {
e476b1b5
GS
499 warnings::warn("void", "some warning");
500 }
501
7e6d00f8
PM
502 if (warnings::enabled($object)) {
503 warnings::warn($object, "some warning");
504 }
505
721f911b
PM
506 warnings::warnif("some warning");
507 warnings::warnif("void", "some warning");
508 warnings::warnif($object, "some warning");
7e6d00f8 509
599cee73
PM
510=head1 DESCRIPTION
511
fe2e802c
EM
512The C<warnings> pragma is a replacement for the command line flag C<-w>,
513but the pragma is limited to the enclosing block, while the flag is global.
514See L<perllexwarn> for more information.
515
0453d815
PM
516If no import list is supplied, all possible warnings are either enabled
517or disabled.
599cee73 518
0ca4541c 519A number of functions are provided to assist module authors.
e476b1b5
GS
520
521=over 4
522
d3a7d8c7
GS
523=item use warnings::register
524
7e6d00f8
PM
525Creates a new warnings category with the same name as the package where
526the call to the pragma is used.
527
528=item warnings::enabled()
529
530Use the warnings category with the same name as the current package.
531
532Return TRUE if that warnings category is enabled in the calling module.
533Otherwise returns FALSE.
534
535=item warnings::enabled($category)
536
537Return TRUE if the warnings category, C<$category>, is enabled in the
538calling module.
539Otherwise returns FALSE.
540
541=item warnings::enabled($object)
542
543Use the name of the class for the object reference, C<$object>, as the
544warnings category.
545
546Return TRUE if that warnings category is enabled in the first scope
547where the object is used.
548Otherwise returns FALSE.
549
550=item warnings::warn($message)
551
552Print C<$message> to STDERR.
553
554Use the warnings category with the same name as the current package.
555
556If that warnings category has been set to "FATAL" in the calling module
557then die. Otherwise return.
558
559=item warnings::warn($category, $message)
560
561Print C<$message> to STDERR.
562
563If the warnings category, C<$category>, has been set to "FATAL" in the
564calling module then die. Otherwise return.
d3a7d8c7 565
7e6d00f8 566=item warnings::warn($object, $message)
e476b1b5 567
7e6d00f8 568Print C<$message> to STDERR.
e476b1b5 569
7e6d00f8
PM
570Use the name of the class for the object reference, C<$object>, as the
571warnings category.
e476b1b5 572
7e6d00f8
PM
573If that warnings category has been set to "FATAL" in the scope where C<$object>
574is first used then die. Otherwise return.
599cee73 575
e476b1b5 576
7e6d00f8
PM
577=item warnings::warnif($message)
578
579Equivalent to:
580
581 if (warnings::enabled())
582 { warnings::warn($message) }
583
584=item warnings::warnif($category, $message)
585
586Equivalent to:
587
588 if (warnings::enabled($category))
589 { warnings::warn($category, $message) }
590
591=item warnings::warnif($object, $message)
592
593Equivalent to:
594
595 if (warnings::enabled($object))
596 { warnings::warn($object, $message) }
d3a7d8c7 597
e476b1b5
GS
598=back
599
749f83fa 600See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73
PM
601
602=cut
603
599cee73
PM
604KEYWORDS
605
d3a7d8c7
GS
606$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
607
c3186b65
PM
608sub Croaker
609{
09e96b99 610 require Carp;
c3186b65 611 delete $Carp::CarpInternal{'warnings'};
8becbb3b 612 Carp::croak(@_);
c3186b65
PM
613}
614
6e9af7e4
PM
615sub bits
616{
617 # called from B::Deparse.pm
618
619 push @_, 'all' unless @_;
620
621 my $mask;
599cee73
PM
622 my $catmask ;
623 my $fatal = 0 ;
6e9af7e4
PM
624 my $no_fatal = 0 ;
625
626 foreach my $word ( @_ ) {
627 if ($word eq 'FATAL') {
327afb7f 628 $fatal = 1;
6e9af7e4
PM
629 $no_fatal = 0;
630 }
631 elsif ($word eq 'NONFATAL') {
632 $fatal = 0;
633 $no_fatal = 1;
327afb7f 634 }
d3a7d8c7
GS
635 elsif ($catmask = $Bits{$word}) {
636 $mask |= $catmask ;
637 $mask |= $DeadBits{$word} if $fatal ;
6e9af7e4 638 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
599cee73 639 }
d3a7d8c7 640 else
c3186b65 641 { Croaker("Unknown warnings category '$word'")}
599cee73
PM
642 }
643
644 return $mask ;
645}
646
6e9af7e4
PM
647sub import
648{
599cee73 649 shift;
6e9af7e4
PM
650
651 my $catmask ;
652 my $fatal = 0 ;
653 my $no_fatal = 0 ;
654
f1f33818 655 my $mask = ${^WARNING_BITS} ;
6e9af7e4 656
f1f33818
PM
657 if (vec($mask, $Offsets{'all'}, 1)) {
658 $mask |= $Bits{'all'} ;
659 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
660 }
6e9af7e4
PM
661
662 push @_, 'all' unless @_;
663
664 foreach my $word ( @_ ) {
665 if ($word eq 'FATAL') {
666 $fatal = 1;
667 $no_fatal = 0;
668 }
669 elsif ($word eq 'NONFATAL') {
670 $fatal = 0;
671 $no_fatal = 1;
672 }
673 elsif ($catmask = $Bits{$word}) {
674 $mask |= $catmask ;
675 $mask |= $DeadBits{$word} if $fatal ;
676 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
677 }
678 else
679 { Croaker("Unknown warnings category '$word'")}
680 }
681
682 ${^WARNING_BITS} = $mask ;
599cee73
PM
683}
684
6e9af7e4
PM
685sub unimport
686{
599cee73 687 shift;
6e9af7e4
PM
688
689 my $catmask ;
d3a7d8c7 690 my $mask = ${^WARNING_BITS} ;
6e9af7e4 691
d3a7d8c7 692 if (vec($mask, $Offsets{'all'}, 1)) {
f1f33818 693 $mask |= $Bits{'all'} ;
d3a7d8c7
GS
694 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
695 }
6e9af7e4
PM
696
697 push @_, 'all' unless @_;
698
699 foreach my $word ( @_ ) {
700 if ($word eq 'FATAL') {
701 next;
702 }
703 elsif ($catmask = $Bits{$word}) {
704 $mask &= ~($catmask | $DeadBits{$word} | $All);
705 }
706 else
707 { Croaker("Unknown warnings category '$word'")}
708 }
709
710 ${^WARNING_BITS} = $mask ;
599cee73
PM
711}
712
9df0f64f
MK
713my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
714
7e6d00f8 715sub __chk
599cee73 716{
d3a7d8c7
GS
717 my $category ;
718 my $offset ;
7e6d00f8 719 my $isobj = 0 ;
d3a7d8c7
GS
720
721 if (@_) {
722 # check the category supplied.
723 $category = shift ;
9df0f64f
MK
724 if (my $type = ref $category) {
725 Croaker("not an object")
726 if exists $builtin_type{$type};
727 $category = $type;
7e6d00f8
PM
728 $isobj = 1 ;
729 }
d3a7d8c7 730 $offset = $Offsets{$category};
c3186b65 731 Croaker("Unknown warnings category '$category'")
d3a7d8c7
GS
732 unless defined $offset;
733 }
734 else {
0ca4541c 735 $category = (caller(1))[0] ;
d3a7d8c7 736 $offset = $Offsets{$category};
c3186b65 737 Croaker("package '$category' not registered for warnings")
d3a7d8c7
GS
738 unless defined $offset ;
739 }
740
0ca4541c 741 my $this_pkg = (caller(1))[0] ;
7e6d00f8
PM
742 my $i = 2 ;
743 my $pkg ;
744
745 if ($isobj) {
746 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
747 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
748 }
749 $i -= 2 ;
750 }
751 else {
4f527b71 752 $i = _error_loc(); # see where Carp will allocate the error
7e6d00f8
PM
753 }
754
0ca4541c 755 my $callers_bitmask = (caller($i))[9] ;
7e6d00f8
PM
756 return ($callers_bitmask, $offset, $i) ;
757}
758
4f527b71
AS
759sub _error_loc {
760 require Carp::Heavy;
761 goto &Carp::short_error_loc; # don't introduce another stack frame
762}
763
7e6d00f8
PM
764sub enabled
765{
c3186b65 766 Croaker("Usage: warnings::enabled([category])")
7e6d00f8
PM
767 unless @_ == 1 || @_ == 0 ;
768
769 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
770
771 return 0 unless defined $callers_bitmask ;
d3a7d8c7
GS
772 return vec($callers_bitmask, $offset, 1) ||
773 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73
PM
774}
775
d3a7d8c7 776
e476b1b5
GS
777sub warn
778{
c3186b65 779 Croaker("Usage: warnings::warn([category,] 'message')")
d3a7d8c7 780 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 781
7e6d00f8
PM
782 my $message = pop ;
783 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
09e96b99 784 require Carp;
8becbb3b 785 Carp::croak($message)
d3a7d8c7
GS
786 if vec($callers_bitmask, $offset+1, 1) ||
787 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
8becbb3b 788 Carp::carp($message) ;
e476b1b5
GS
789}
790
7e6d00f8
PM
791sub warnif
792{
c3186b65 793 Croaker("Usage: warnings::warnif([category,] 'message')")
7e6d00f8
PM
794 unless @_ == 2 || @_ == 1 ;
795
796 my $message = pop ;
797 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
7e6d00f8 798
0ca4541c 799 return
7e6d00f8
PM
800 unless defined $callers_bitmask &&
801 (vec($callers_bitmask, $offset, 1) ||
802 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
803
09e96b99 804 require Carp;
8becbb3b 805 Carp::croak($message)
7e6d00f8
PM
806 if vec($callers_bitmask, $offset+1, 1) ||
807 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
808
8becbb3b 809 Carp::carp($message) ;
7e6d00f8 810}
0d658bf5 811
599cee73 8121;