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