This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add perl-5.12.2 to perlhist.pod
[perl5.git] / warnings.pl
... / ...
CommitLineData
1#!/usr/bin/perl
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.
15
16$VERSION = '1.02_03';
17
18BEGIN {
19 require 'regen_lib.pl';
20 push @INC, './lib';
21}
22use strict ;
23
24sub DEFAULT_ON () { 1 }
25sub DEFAULT_OFF () { 2 }
26
27my $tree = {
28
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 'illegalproto' => [ 5.011, DEFAULT_OFF],
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],
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],
78 'threads' => [ 5.008, DEFAULT_OFF],
79 'imprecision' => [ 5.011, DEFAULT_OFF],
80
81 #'default' => [ 5.008, DEFAULT_ON ],
82 }],
83} ;
84
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 ;
96my %ValueToName ;
97my %NameToValue ;
98my $index ;
99
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
139sub walk
140{
141 my $tre = shift ;
142 my @list = () ;
143 my ($k, $v) ;
144
145 foreach $k (sort keys %$tre) {
146 $v = $tre->{$k};
147 die "duplicate key $k\n" if defined $list{$k} ;
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
159 push @list, @{ $list{$k} } ;
160 }
161
162 return @list ;
163}
164
165###########################################################################
166
167sub mkRange
168{
169 my @a = @_ ;
170 my @out = @a ;
171
172 for my $i (1 .. @a - 1) {
173 $out[$i] = ".."
174 if $a[$i] == $a[$i - 1] + 1
175 && ($i >= @a - 1 || $a[$i] + 1 == $a[$i + 1] );
176 }
177 $out[-1] = $a[-1] if $out[-1] eq "..";
178
179 my $out = join(",",@out);
180
181 $out =~ s/,(\.\.,)+/../g ;
182 return $out;
183}
184
185###########################################################################
186sub printTree
187{
188 my $tre = shift ;
189 my $prefix = shift ;
190 my ($k, $v) ;
191
192 my $max = (sort {$a <=> $b} map { length $_ } keys %$tre)[-1] ;
193 my @keys = sort keys %$tre ;
194
195 while ($k = shift @keys) {
196 $v = $tre->{$k};
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)
213 {
214 my $bar = @keys ? "|" : " ";
215 print " -" . "-" x ($max - length $k ) . "+\n" ;
216 printTree ($rest, $prefix . $bar . $offset )
217 }
218 else
219 { print "\n" }
220 }
221
222}
223
224###########################################################################
225
226sub mkHexOct
227{
228 my ($f, $max, @a) = @_ ;
229 my $mask = "\x00" x $max ;
230 my $string = "" ;
231
232 foreach (@a) {
233 vec($mask, $_, 1) = 1 ;
234 }
235
236 foreach (unpack("C*", $mask)) {
237 if ($f eq 'x') {
238 $string .= '\x' . sprintf("%2.2x", $_)
239 }
240 else {
241 $string .= '\\' . sprintf("%o", $_)
242 }
243 }
244 return $string ;
245}
246
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
259###########################################################################
260
261if (@ARGV && $ARGV[0] eq "tree")
262{
263 printTree($tree, " ") ;
264 exit ;
265}
266
267my $warn = safer_open("warnings.h-new");
268my $pm = safer_open("lib/warnings.pm-new");
269
270print $warn <<'EOM' ;
271/* -*- buffer-read-only: t -*-
272 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
273 This file is built by warnings.pl
274 Any changes made here will be lost!
275*/
276
277
278#define Off(x) ((x) / 8)
279#define Bit(x) (1 << ((x) % 8))
280#define IsSet(a, x) ((a)[Off(x)] & Bit(x))
281
282
283#define G_WARN_OFF 0 /* $^W == 0 */
284#define G_WARN_ON 1 /* -w flag and $^W != 0 */
285#define G_WARN_ALL_ON 2 /* -W flag */
286#define G_WARN_ALL_OFF 4 /* -X flag */
287#define G_WARN_ONCE 8 /* set if 'once' ever enabled */
288#define G_WARN_ALL_MASK (G_WARN_ALL_ON|G_WARN_ALL_OFF)
289
290#define pWARN_STD NULL
291#define pWARN_ALL (((STRLEN*)0)+1) /* use warnings 'all' */
292#define pWARN_NONE (((STRLEN*)0)+2) /* no warnings 'all' */
293
294#define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
295 (x) == pWARN_NONE)
296
297/* if PL_warnhook is set to this value, then warnings die */
298#define PERL_WARNHOOK_FATAL (&PL_sv_placeholder)
299EOM
300
301my $offset = 0 ;
302
303$index = $offset ;
304#@{ $list{"all"} } = walk ($tree) ;
305valueWalk ($tree) ;
306my $index = orderValues();
307
308die <<EOM if $index > 255 ;
309Too many warnings categories -- max is 255
310 rewrite packWARN* & unpackWARN* macros
311EOM
312
313walk ($tree) ;
314
315$index *= 2 ;
316my $warn_size = int($index / 8) + ($index % 8 != 0) ;
317
318my $k ;
319my $last_ver = 0;
320foreach $k (sort { $a <=> $b } keys %ValueToName) {
321 my ($name, $version) = @{ $ValueToName{$k} };
322 print $warn "\n/* Warnings Categories added in Perl $version */\n\n"
323 if $last_ver != $version ;
324 print $warn tab(5, "#define WARN_$name"), "$k\n" ;
325 $last_ver = $version ;
326}
327print $warn "\n" ;
328
329print $warn tab(5, '#define WARNsize'), "$warn_size\n" ;
330#print WARN tab(5, '#define WARN_ALLstring'), '"', ('\377' x $warn_size) , "\"\n" ;
331print $warn tab(5, '#define WARN_ALLstring'), '"', ('\125' x $warn_size) , "\"\n" ;
332print $warn tab(5, '#define WARN_NONEstring'), '"', ('\0' x $warn_size) , "\"\n" ;
333
334print $warn <<'EOM';
335
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))
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) \
343 (specialWARN(p) ? (STRLEN*)(p) \
344 : (STRLEN*)CopyD(p, PerlMemShared_malloc(sizeof(*p)+*p), sizeof(*p)+*p, \
345 char))
346
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))
356
357#define WARNshift 8
358
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))
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
377/* end of file warnings.h */
378/* ex: set ro: */
379EOM
380
381safer_close $warn;
382rename_if_different("warnings.h-new", "warnings.h");
383
384while (<DATA>) {
385 last if /^KEYWORDS$/ ;
386 print $pm $_ ;
387}
388
389#$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
390
391$last_ver = 0;
392print $pm "our %Offsets = (\n" ;
393foreach my $k (sort { $a <=> $b } keys %ValueToName) {
394 my ($name, $version) = @{ $ValueToName{$k} };
395 $name = lc $name;
396 $k *= 2 ;
397 if ( $last_ver != $version ) {
398 print $pm "\n";
399 print $pm tab(4, " # Warnings Categories added in Perl $version");
400 print $pm "\n\n";
401 }
402 print $pm tab(4, " '$name'"), "=> $k,\n" ;
403 $last_ver = $version;
404}
405
406print $pm " );\n\n" ;
407
408print $pm "our %Bits = (\n" ;
409foreach $k (sort keys %list) {
410
411 my $v = $list{$k} ;
412 my @list = sort { $a <=> $b } @$v ;
413
414 print $pm tab(4, " '$k'"), '=> "',
415 # mkHex($warn_size, @list),
416 mkHex($warn_size, map $_ * 2 , @list),
417 '", # [', mkRange(@list), "]\n" ;
418}
419
420print $pm " );\n\n" ;
421
422print $pm "our %DeadBits = (\n" ;
423foreach $k (sort keys %list) {
424
425 my $v = $list{$k} ;
426 my @list = sort { $a <=> $b } @$v ;
427
428 print $pm tab(4, " '$k'"), '=> "',
429 # mkHex($warn_size, @list),
430 mkHex($warn_size, map $_ * 2 + 1 , @list),
431 '", # [', mkRange(@list), "]\n" ;
432}
433
434print $pm " );\n\n" ;
435print $pm '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
436print $pm '$LAST_BIT = ' . "$index ;\n" ;
437print $pm '$BYTES = ' . "$warn_size ;\n" ;
438while (<DATA>) {
439 print $pm $_ ;
440}
441
442print $pm "# ex: set ro:\n";
443safer_close $pm;
444rename_if_different("lib/warnings.pm-new", "lib/warnings.pm");
445
446__END__
447# -*- buffer-read-only: t -*-
448# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
449# This file was created by warnings.pl
450# Any changes made here will be lost.
451#
452
453package warnings;
454
455our $VERSION = '1.11';
456
457# Verify that we're called correctly so that warnings will work.
458# see also strict.pm.
459unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
460 my (undef, $f, $l) = caller;
461 die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
462}
463
464=head1 NAME
465
466warnings - Perl pragma to control optional warnings
467
468=head1 SYNOPSIS
469
470 use warnings;
471 no warnings;
472
473 use warnings "all";
474 no warnings "all";
475
476 use warnings::register;
477 if (warnings::enabled()) {
478 warnings::warn("some warning");
479 }
480
481 if (warnings::enabled("void")) {
482 warnings::warn("void", "some warning");
483 }
484
485 if (warnings::enabled($object)) {
486 warnings::warn($object, "some warning");
487 }
488
489 warnings::warnif("some warning");
490 warnings::warnif("void", "some warning");
491 warnings::warnif($object, "some warning");
492
493=head1 DESCRIPTION
494
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
499If no import list is supplied, all possible warnings are either enabled
500or disabled.
501
502A number of functions are provided to assist module authors.
503
504=over 4
505
506=item use warnings::register
507
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
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
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.
569
570=item warnings::warn($object, $message)
571
572Print C<$message> to STDERR.
573
574Use the name of the class for the object reference, C<$object>, as the
575warnings category.
576
577If that warnings category has been set to "FATAL" in the scope where C<$object>
578is first used then die. Otherwise return.
579
580
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) }
601
602=item warnings::register_categories(@names)
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
607=back
608
609See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
610
611=cut
612
613KEYWORDS
614
615$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
616
617sub Croaker
618{
619 require Carp; # this initializes %CarpInternal
620 local $Carp::CarpInternal{'warnings'};
621 delete $Carp::CarpInternal{'warnings'};
622 Carp::croak(@_);
623}
624
625sub _bits {
626 my $mask = shift ;
627 my $catmask ;
628 my $fatal = 0 ;
629 my $no_fatal = 0 ;
630
631 foreach my $word ( @_ ) {
632 if ($word eq 'FATAL') {
633 $fatal = 1;
634 $no_fatal = 0;
635 }
636 elsif ($word eq 'NONFATAL') {
637 $fatal = 0;
638 $no_fatal = 1;
639 }
640 elsif ($catmask = $Bits{$word}) {
641 $mask |= $catmask ;
642 $mask |= $DeadBits{$word} if $fatal ;
643 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
644 }
645 else
646 { Croaker("Unknown warnings category '$word'")}
647 }
648
649 return $mask ;
650}
651
652sub bits
653{
654 # called from B::Deparse.pm
655 push @_, 'all' unless @_ ;
656 return _bits(undef, @_) ;
657}
658
659sub import
660{
661 shift;
662
663 my $mask = ${^WARNING_BITS} ;
664
665 if (vec($mask, $Offsets{'all'}, 1)) {
666 $mask |= $Bits{'all'} ;
667 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
668 }
669
670 # Empty @_ is equivalent to @_ = 'all' ;
671 ${^WARNING_BITS} = @_ ? _bits($mask, @_) : $mask | $Bits{all} ;
672}
673
674sub unimport
675{
676 shift;
677
678 my $catmask ;
679 my $mask = ${^WARNING_BITS} ;
680
681 if (vec($mask, $Offsets{'all'}, 1)) {
682 $mask |= $Bits{'all'} ;
683 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
684 }
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 ;
700}
701
702my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
703
704sub MESSAGE () { 4 };
705sub FATAL () { 2 };
706sub NORMAL () { 1 };
707
708sub __chk
709{
710 my $category ;
711 my $offset ;
712 my $isobj = 0 ;
713 my $wanted = shift;
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;
723
724 if (@_) {
725 # check the category supplied.
726 $category = shift ;
727 if (my $type = ref $category) {
728 Croaker("not an object")
729 if exists $builtin_type{$type};
730 $category = $type;
731 $isobj = 1 ;
732 }
733 $offset = $Offsets{$category};
734 Croaker("Unknown warnings category '$category'")
735 unless defined $offset;
736 }
737 else {
738 $category = (caller(1))[0] ;
739 $offset = $Offsets{$category};
740 Croaker("package '$category' not registered for warnings")
741 unless defined $offset ;
742 }
743
744 my $i;
745
746 if ($isobj) {
747 my $pkg;
748 $i = 2;
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 {
755 $i = _error_loc(); # see where Carp will allocate the error
756 }
757
758 # Defaulting this to 0 reduces complexity in code paths below.
759 my $callers_bitmask = (caller($i))[9] || 0 ;
760
761 my @results;
762 foreach my $type (FATAL, NORMAL) {
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 }
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);
781}
782
783sub _mkMask
784{
785 my ($bit) = @_;
786 my $mask = "";
787
788 vec($mask, $bit, 1) = 1;
789 return $mask;
790}
791
792sub register_categories
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
810sub _error_loc {
811 require Carp;
812 goto &Carp::short_error_loc; # don't introduce another stack frame
813}
814
815sub enabled
816{
817 return __chk(NORMAL, @_);
818}
819
820sub fatal_enabled
821{
822 return __chk(FATAL, @_);
823}
824
825sub warn
826{
827 return __chk(FATAL | MESSAGE, @_);
828}
829
830sub warnif
831{
832 return __chk(NORMAL | FATAL | MESSAGE, @_);
833}
834
835# These are not part of any public interface, so we can delete them to save
836# space.
837delete $warnings::{$_} foreach qw(NORMAL FATAL MESSAGE);
838
8391;