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