Make Win32 treat IO-Compress as an XS extension, as was done elsewhere by
[p5sagit/p5-mst-13.2.git] / warnings.pl
CommitLineData
599cee73 1#!/usr/bin/perl
6294c161 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
8bc6a5d5 16$VERSION = '1.02_03';
b75c8c73 17
73f0cc2d 18BEGIN {
b6b9a099 19 require 'regen_lib.pl';
20 push @INC, './lib';
73f0cc2d 21}
599cee73 22use strict ;
23
24sub DEFAULT_ON () { 1 }
25sub DEFAULT_OFF () { 2 }
26
27my $tree = {
d3a7d8c7 28
0d658bf5 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 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 80 #'default' => [ 5.008, DEFAULT_ON ],
81 }],
d3a7d8c7 82} ;
599cee73 83
599cee73 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 95my %ValueToName ;
96my %NameToValue ;
d3a7d8c7 97my $index ;
599cee73 98
0d658bf5 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 138sub walk
139{
140 my $tre = shift ;
141 my @list = () ;
142 my ($k, $v) ;
143
95dfd3ab 144 foreach $k (sort keys %$tre) {
145 $v = $tre->{$k};
599cee73 146 die "duplicate key $k\n" if defined $list{$k} ;
0d658bf5 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 158 push @list, @{ $list{$k} } ;
159 }
160
161 return @list ;
599cee73 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 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 185sub printTree
186{
187 my $tre = shift ;
188 my $prefix = shift ;
e476b1b5 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 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 213 my $bar = @keys ? "|" : " ";
214 print " -" . "-" x ($max - length $k ) . "+\n" ;
215 printTree ($rest, $prefix . $bar . $offset )
e476b1b5 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 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 236 if ($f eq 'x') {
237 $string .= '\x' . sprintf("%2.2x", $_)
238 }
239 else {
240 $string .= '\\' . sprintf("%o", $_)
241 }
599cee73 242 }
243 return $string ;
244}
245
317ea90d 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 258###########################################################################
259
e476b1b5 260if (@ARGV && $ARGV[0] eq "tree")
261{
0d658bf5 262 printTree($tree, " ") ;
e476b1b5 263 exit ;
264}
599cee73 265
424a4936 266my $warn = safer_open("warnings.h-new");
267my $pm = safer_open("lib/warnings.pm-new");
599cee73 268
424a4936 269print $warn <<'EOM' ;
37442d52 270/* -*- buffer-read-only: t -*-
271 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
4438c4b7 272 This file is built by warnings.pl
599cee73 273 Any changes made here will be lost!
274*/
275
276
0453d815 277#define Off(x) ((x) / 8)
278#define Bit(x) (1 << ((x) % 8))
599cee73 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 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 287#define G_WARN_ALL_MASK (G_WARN_ALL_ON|G_WARN_ALL_OFF)
288
a0714e2c 289#define pWARN_STD NULL
72dc9ed5 290#define pWARN_ALL (((STRLEN*)0)+1) /* use warnings 'all' */
291#define pWARN_NONE (((STRLEN*)0)+2) /* no warnings 'all' */
599cee73 292
d3a7d8c7 293#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
294 (x) == pWARN_NONE)
5f2d9966 295
296/* if PL_warnhook is set to this value, then warnings die */
06dcd5bf 297#define PERL_WARNHOOK_FATAL (&PL_sv_placeholder)
599cee73 298EOM
299
d3a7d8c7 300my $offset = 0 ;
301
302$index = $offset ;
303#@{ $list{"all"} } = walk ($tree) ;
0d658bf5 304valueWalk ($tree) ;
305my $index = orderValues();
599cee73 306
12bcd1a6 307die <<EOM if $index > 255 ;
308Too many warnings categories -- max is 255
309 rewrite packWARN* & unpackWARN* macros
310EOM
599cee73 311
0d658bf5 312walk ($tree) ;
313
599cee73 314$index *= 2 ;
315my $warn_size = int($index / 8) + ($index % 8 != 0) ;
316
317my $k ;
0d658bf5 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 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 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 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 342 (specialWARN(p) ? (STRLEN*)(p) \
343 : (STRLEN*)CopyD(p, PerlMemShared_malloc(sizeof(*p)+*p), sizeof(*p)+*p, \
344 char))
d5a71f30 345
f54ba1c2 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 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 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 376EOM
377
08858ed2 378safer_close $warn;
424a4936 379rename_if_different("warnings.h-new", "warnings.h");
599cee73 380
381while (<DATA>) {
382 last if /^KEYWORDS$/ ;
424a4936 383 print $pm $_ ;
599cee73 384}
385
d3a7d8c7 386#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
387
0d658bf5 388$last_ver = 0;
424a4936 389print $pm "our %Offsets = (\n" ;
0d658bf5 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 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 401}
402
424a4936 403print $pm " );\n\n" ;
d3a7d8c7 404
424a4936 405print $pm "our %Bits = (\n" ;
599cee73 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 412 # mkHex($warn_size, @list),
413 mkHex($warn_size, map $_ * 2 , @list),
599cee73 414 '", # [', mkRange(@list), "]\n" ;
415}
416
424a4936 417print $pm " );\n\n" ;
599cee73 418
424a4936 419print $pm "our %DeadBits = (\n" ;
599cee73 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 426 # mkHex($warn_size, @list),
427 mkHex($warn_size, map $_ * 2 + 1 , @list),
599cee73 428 '", # [', mkRange(@list), "]\n" ;
429}
430
424a4936 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 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 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 447# Any changes made here will be lost.
448#
449
4438c4b7 450package warnings;
599cee73 451
8bc6a5d5 452our $VERSION = '1.07';
f2c3e829 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 461=head1 NAME
462
4438c4b7 463warnings - Perl pragma to control optional warnings
599cee73 464
465=head1 SYNOPSIS
466
4438c4b7 467 use warnings;
468 no warnings;
599cee73 469
4438c4b7 470 use warnings "all";
471 no warnings "all";
599cee73 472
d3a7d8c7 473 use warnings::register;
474 if (warnings::enabled()) {
475 warnings::warn("some warning");
476 }
477
478 if (warnings::enabled("void")) {
e476b1b5 479 warnings::warn("void", "some warning");
480 }
481
7e6d00f8 482 if (warnings::enabled($object)) {
483 warnings::warn($object, "some warning");
484 }
485
721f911b 486 warnings::warnif("some warning");
487 warnings::warnif("void", "some warning");
488 warnings::warnif($object, "some warning");
7e6d00f8 489
599cee73 490=head1 DESCRIPTION
491
fe2e802c 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 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 500
501=over 4
502
d3a7d8c7 503=item use warnings::register
504
7e6d00f8 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 550Use the name of the class for the object reference, C<$object>, as the
551warnings category.
e476b1b5 552
7e6d00f8 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 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 578=back
579
749f83fa 580See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73 581
582=cut
583
599cee73 584KEYWORDS
585
d3a7d8c7 586$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
587
c3186b65 588sub Croaker
589{
4dd71923 590 require Carp; # this initializes %CarpInternal
dbab294c 591 local $Carp::CarpInternal{'warnings'};
c3186b65 592 delete $Carp::CarpInternal{'warnings'};
8becbb3b 593 Carp::croak(@_);
c3186b65 594}
595
6e9af7e4 596sub bits
597{
598 # called from B::Deparse.pm
599
600 push @_, 'all' unless @_;
601
602 my $mask;
599cee73 603 my $catmask ;
604 my $fatal = 0 ;
6e9af7e4 605 my $no_fatal = 0 ;
606
607 foreach my $word ( @_ ) {
608 if ($word eq 'FATAL') {
327afb7f 609 $fatal = 1;
6e9af7e4 610 $no_fatal = 0;
611 }
612 elsif ($word eq 'NONFATAL') {
613 $fatal = 0;
614 $no_fatal = 1;
327afb7f 615 }
d3a7d8c7 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 623 }
624
625 return $mask ;
626}
627
6e9af7e4 628sub import
629{
599cee73 630 shift;
6e9af7e4 631
632 my $catmask ;
633 my $fatal = 0 ;
634 my $no_fatal = 0 ;
635
f1f33818 636 my $mask = ${^WARNING_BITS} ;
6e9af7e4 637
f1f33818 638 if (vec($mask, $Offsets{'all'}, 1)) {
639 $mask |= $Bits{'all'} ;
640 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
641 }
6e9af7e4 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 664}
665
6e9af7e4 666sub unimport
667{
599cee73 668 shift;
6e9af7e4 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 675 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
676 }
6e9af7e4 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 692}
693
9df0f64f 694my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
695
7e6d00f8 696sub __chk
599cee73 697{
d3a7d8c7 698 my $category ;
699 my $offset ;
7e6d00f8 700 my $isobj = 0 ;
d3a7d8c7 701
702 if (@_) {
703 # check the category supplied.
704 $category = shift ;
9df0f64f 705 if (my $type = ref $category) {
706 Croaker("not an object")
707 if exists $builtin_type{$type};
708 $category = $type;
7e6d00f8 709 $isobj = 1 ;
710 }
d3a7d8c7 711 $offset = $Offsets{$category};
c3186b65 712 Croaker("Unknown warnings category '$category'")
d3a7d8c7 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 719 unless defined $offset ;
720 }
721
0ca4541c 722 my $this_pkg = (caller(1))[0] ;
7e6d00f8 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 734 }
735
0ca4541c 736 my $callers_bitmask = (caller($i))[9] ;
7e6d00f8 737 return ($callers_bitmask, $offset, $i) ;
738}
739
4f527b71 740sub _error_loc {
4dd71923 741 require Carp;
4f527b71 742 goto &Carp::short_error_loc; # don't introduce another stack frame
743}
744
7e6d00f8 745sub enabled
746{
c3186b65 747 Croaker("Usage: warnings::enabled([category])")
7e6d00f8 748 unless @_ == 1 || @_ == 0 ;
749
750 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
751
752 return 0 unless defined $callers_bitmask ;
d3a7d8c7 753 return vec($callers_bitmask, $offset, 1) ||
754 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73 755}
756
d3a7d8c7 757
e476b1b5 758sub warn
759{
c3186b65 760 Croaker("Usage: warnings::warn([category,] 'message')")
d3a7d8c7 761 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 762
7e6d00f8 763 my $message = pop ;
764 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
09e96b99 765 require Carp;
8becbb3b 766 Carp::croak($message)
d3a7d8c7 767 if vec($callers_bitmask, $offset+1, 1) ||
768 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
8becbb3b 769 Carp::carp($message) ;
e476b1b5 770}
771
7e6d00f8 772sub warnif
773{
c3186b65 774 Croaker("Usage: warnings::warnif([category,] 'message')")
7e6d00f8 775 unless @_ == 2 || @_ == 1 ;
776
777 my $message = pop ;
778 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
7e6d00f8 779
0ca4541c 780 return
7e6d00f8 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 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;