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