3 # Regenerate (overwriting only if changed):
8 # from information hardcoded into this script (the $tree hash), plus the
9 # template for warnings.pm in the DATA section.
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.
14 # This script is normally invoked from regen.pl.
19 require 'regen_lib.pl';
24 sub DEFAULT_ON () { 1 }
25 sub DEFAULT_OFF () { 2 }
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],
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],
50 'severe' => [ 5.008, {
51 'inplace' => [ 5.008, DEFAULT_ON],
52 'internal' => [ 5.008, DEFAULT_ON],
53 'debugging' => [ 5.008, DEFAULT_ON],
54 'malloc' => [ 5.008, DEFAULT_ON],
56 'deprecated' => [ 5.008, DEFAULT_OFF],
57 'void' => [ 5.008, DEFAULT_OFF],
58 'recursion' => [ 5.008, DEFAULT_OFF],
59 'redefine' => [ 5.008, DEFAULT_OFF],
60 'numeric' => [ 5.008, DEFAULT_OFF],
61 'uninitialized' => [ 5.008, DEFAULT_OFF],
62 'once' => [ 5.008, DEFAULT_OFF],
63 'misc' => [ 5.008, DEFAULT_OFF],
64 'regexp' => [ 5.008, DEFAULT_OFF],
65 'glob' => [ 5.008, DEFAULT_OFF],
66 'untie' => [ 5.008, DEFAULT_OFF],
67 'substr' => [ 5.008, DEFAULT_OFF],
68 'taint' => [ 5.008, DEFAULT_OFF],
69 'signal' => [ 5.008, DEFAULT_OFF],
70 'closure' => [ 5.008, DEFAULT_OFF],
71 'overflow' => [ 5.008, DEFAULT_OFF],
72 'portable' => [ 5.008, DEFAULT_OFF],
73 'utf8' => [ 5.008, DEFAULT_OFF],
74 'exiting' => [ 5.008, DEFAULT_OFF],
75 'pack' => [ 5.008, DEFAULT_OFF],
76 'unpack' => [ 5.008, DEFAULT_OFF],
77 'threads' => [ 5.008, DEFAULT_OFF],
78 'imprecision' => [ 5.011, DEFAULT_OFF],
80 #'default' => [ 5.008, DEFAULT_ON ],
84 ###########################################################################
87 $t .= "\t" x ($l - (length($t) + 1) / 8);
91 ###########################################################################
107 foreach $k (sort keys %$tre) {
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' ;
113 my ($ver, $rest) = @{ $v } ;
114 push @{ $v_list{$ver} }, $k;
117 { valueWalk ($rest) }
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 ++ ;
136 ###########################################################################
144 foreach $k (sort keys %$tre) {
146 die "duplicate key $k\n" if defined $list{$k} ;
147 #$Value{$index} = uc $k ;
148 die "Can't find key '$k'"
149 if ! defined $NameToValue{uc $k} ;
150 push @{ $list{$k} }, $NameToValue{uc $k} ;
151 die "Value associated with key '$k' is not an ARRAY reference"
152 if !ref $v || ref $v ne 'ARRAY' ;
154 my ($ver, $rest) = @{ $v } ;
156 { push (@{ $list{$k} }, walk ($rest)) }
158 push @list, @{ $list{$k} } ;
164 ###########################################################################
173 for ($i = 1 ; $i < @a; ++ $i) {
175 if $a[$i] == $a[$i - 1] + 1 && $a[$i] + 1 == $a[$i + 1] ;
178 my $out = join(",",@out);
180 $out =~ s/,(\.\.,)+/../g ;
184 ###########################################################################
191 my $max = (sort {$a <=> $b} map { length $_ } keys %$tre)[-1] ;
192 my @keys = sort keys %$tre ;
194 while ($k = shift @keys) {
196 die "Value associated with key '$k' is not an ARRAY reference"
197 if !ref $v || ref $v ne 'ARRAY' ;
201 print $prefix . "|\n" ;
202 print $prefix . "+- $k" ;
203 $offset = ' ' x ($max + 4) ;
206 print $prefix . "$k" ;
207 $offset = ' ' x ($max + 1) ;
210 my ($ver, $rest) = @{ $v } ;
213 my $bar = @keys ? "|" : " ";
214 print " -" . "-" x ($max - length $k ) . "+\n" ;
215 printTree ($rest, $prefix . $bar . $offset )
223 ###########################################################################
227 my ($f, $max, @a) = @_ ;
228 my $mask = "\x00" x $max ;
232 vec($mask, $_, 1) = 1 ;
235 foreach (unpack("C*", $mask)) {
237 $string .= '\x' . sprintf("%2.2x", $_)
240 $string .= '\\' . sprintf("%o", $_)
249 return mkHexOct("x", $max, @a);
255 return mkHexOct("o", $max, @a);
258 ###########################################################################
260 if (@ARGV && $ARGV[0] eq "tree")
262 printTree($tree, " ") ;
266 my $warn = safer_open("warnings.h-new");
267 my $pm = safer_open("lib/warnings.pm-new");
269 print $warn <<'EOM' ;
270 /* -*- buffer-read-only: t -*-
271 !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
272 This file is built by warnings.pl
273 Any changes made here will be lost!
277 #define Off(x) ((x) / 8)
278 #define Bit(x) (1 << ((x) % 8))
279 #define IsSet(a, x) ((a)[Off(x)] & Bit(x))
282 #define G_WARN_OFF 0 /* $^W == 0 */
283 #define G_WARN_ON 1 /* -w flag and $^W != 0 */
284 #define G_WARN_ALL_ON 2 /* -W flag */
285 #define G_WARN_ALL_OFF 4 /* -X flag */
286 #define G_WARN_ONCE 8 /* set if 'once' ever enabled */
287 #define G_WARN_ALL_MASK (G_WARN_ALL_ON|G_WARN_ALL_OFF)
289 #define pWARN_STD NULL
290 #define pWARN_ALL (((STRLEN*)0)+1) /* use warnings 'all' */
291 #define pWARN_NONE (((STRLEN*)0)+2) /* no warnings 'all' */
293 #define specialWARN(x) ((x) == pWARN_STD || (x) == pWARN_ALL || \
296 /* if PL_warnhook is set to this value, then warnings die */
297 #define PERL_WARNHOOK_FATAL (&PL_sv_placeholder)
303 #@{ $list{"all"} } = walk ($tree) ;
305 my $index = orderValues();
307 die <<EOM if $index > 255 ;
308 Too many warnings categories -- max is 255
309 rewrite packWARN* & unpackWARN* macros
315 my $warn_size = int($index / 8) + ($index % 8 != 0) ;
319 foreach $k (sort { $a <=> $b } keys %ValueToName) {
320 my ($name, $version) = @{ $ValueToName{$k} };
321 print $warn "\n/* Warnings Categories added in Perl $version */\n\n"
322 if $last_ver != $version ;
323 print $warn tab(5, "#define WARN_$name"), "$k\n" ;
324 $last_ver = $version ;
328 print $warn tab(5, '#define WARNsize'), "$warn_size\n" ;
329 #print WARN tab(5, '#define WARN_ALLstring'), '"', ('\377' x $warn_size) , "\"\n" ;
330 print $warn tab(5, '#define WARN_ALLstring'), '"', ('\125' x $warn_size) , "\"\n" ;
331 print $warn tab(5, '#define WARN_NONEstring'), '"', ('\0' x $warn_size) , "\"\n" ;
335 #define isLEXWARN_on (PL_curcop->cop_warnings != pWARN_STD)
336 #define isLEXWARN_off (PL_curcop->cop_warnings == pWARN_STD)
337 #define isWARN_ONCE (PL_dowarn & (G_WARN_ON|G_WARN_ONCE))
338 #define isWARN_on(c,x) (IsSet((U8 *)(c + 1), 2*(x)))
339 #define isWARNf_on(c,x) (IsSet((U8 *)(c + 1), 2*(x)+1))
341 #define DUP_WARNINGS(p) \
342 (specialWARN(p) ? (STRLEN*)(p) \
343 : (STRLEN*)CopyD(p, PerlMemShared_malloc(sizeof(*p)+*p), sizeof(*p)+*p, \
346 #define ckWARN(w) Perl_ckwarn(aTHX_ packWARN(w))
347 #define ckWARN2(w1,w2) Perl_ckwarn(aTHX_ packWARN2(w1,w2))
348 #define ckWARN3(w1,w2,w3) Perl_ckwarn(aTHX_ packWARN3(w1,w2,w3))
349 #define ckWARN4(w1,w2,w3,w4) Perl_ckwarn(aTHX_ packWARN4(w1,w2,w3,w4))
351 #define ckWARN_d(w) Perl_ckwarn_d(aTHX_ packWARN(w))
352 #define ckWARN2_d(w1,w2) Perl_ckwarn_d(aTHX_ packWARN2(w1,w2))
353 #define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
354 #define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
358 #define packWARN(a) (a )
359 #define packWARN2(a,b) ((a) | ((b)<<8) )
360 #define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
361 #define packWARN4(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d) <<24))
363 #define unpackWARN1(x) ((x) & 0xFF)
364 #define unpackWARN2(x) (((x) >>8) & 0xFF)
365 #define unpackWARN3(x) (((x) >>16) & 0xFF)
366 #define unpackWARN4(x) (((x) >>24) & 0xFF)
369 ( ! specialWARN(PL_curcop->cop_warnings) && \
370 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
371 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
372 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
373 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
374 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
376 /* end of file warnings.h */
381 rename_if_different("warnings.h-new", "warnings.h");
384 last if /^KEYWORDS$/ ;
388 #$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
391 print $pm "our %Offsets = (\n" ;
392 foreach my $k (sort { $a <=> $b } keys %ValueToName) {
393 my ($name, $version) = @{ $ValueToName{$k} };
396 if ( $last_ver != $version ) {
398 print $pm tab(4, " # Warnings Categories added in Perl $version");
401 print $pm tab(4, " '$name'"), "=> $k,\n" ;
402 $last_ver = $version;
405 print $pm " );\n\n" ;
407 print $pm "our %Bits = (\n" ;
408 foreach $k (sort keys %list) {
411 my @list = sort { $a <=> $b } @$v ;
413 print $pm tab(4, " '$k'"), '=> "',
414 # mkHex($warn_size, @list),
415 mkHex($warn_size, map $_ * 2 , @list),
416 '", # [', mkRange(@list), "]\n" ;
419 print $pm " );\n\n" ;
421 print $pm "our %DeadBits = (\n" ;
422 foreach $k (sort keys %list) {
425 my @list = sort { $a <=> $b } @$v ;
427 print $pm tab(4, " '$k'"), '=> "',
428 # mkHex($warn_size, @list),
429 mkHex($warn_size, map $_ * 2 + 1 , @list),
430 '", # [', mkRange(@list), "]\n" ;
433 print $pm " );\n\n" ;
434 print $pm '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
435 print $pm '$LAST_BIT = ' . "$index ;\n" ;
436 print $pm '$BYTES = ' . "$warn_size ;\n" ;
441 print $pm "# ex: set ro:\n";
443 rename_if_different("lib/warnings.pm-new", "lib/warnings.pm");
446 # -*- buffer-read-only: t -*-
447 # !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
448 # This file was created by warnings.pl
449 # Any changes made here will be lost.
454 our $VERSION = '1.08';
456 # Verify that we're called correctly so that warnings will work.
457 # see also strict.pm.
458 unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
459 my (undef, $f, $l) = caller;
460 die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
465 warnings - Perl pragma to control optional warnings
475 use warnings::register;
476 if (warnings::enabled()) {
477 warnings::warn("some warning");
480 if (warnings::enabled("void")) {
481 warnings::warn("void", "some warning");
484 if (warnings::enabled($object)) {
485 warnings::warn($object, "some warning");
488 warnings::warnif("some warning");
489 warnings::warnif("void", "some warning");
490 warnings::warnif($object, "some warning");
494 The C<warnings> pragma is a replacement for the command line flag C<-w>,
495 but the pragma is limited to the enclosing block, while the flag is global.
496 See L<perllexwarn> for more information.
498 If no import list is supplied, all possible warnings are either enabled
501 A number of functions are provided to assist module authors.
505 =item use warnings::register
507 Creates a new warnings category with the same name as the package where
508 the call to the pragma is used.
510 =item warnings::enabled()
512 Use the warnings category with the same name as the current package.
514 Return TRUE if that warnings category is enabled in the calling module.
515 Otherwise returns FALSE.
517 =item warnings::enabled($category)
519 Return TRUE if the warnings category, C<$category>, is enabled in the
521 Otherwise returns FALSE.
523 =item warnings::enabled($object)
525 Use the name of the class for the object reference, C<$object>, as the
528 Return TRUE if that warnings category is enabled in the first scope
529 where the object is used.
530 Otherwise returns FALSE.
532 =item warnings::fatal_enabled()
534 Return TRUE if the warnings category with the same name as the current
535 package has been set to FATAL in the calling module.
536 Otherwise returns FALSE.
538 =item warnings::fatal_enabled($category)
540 Return TRUE if the warnings category C<$category> has been set to FATAL in
542 Otherwise returns FALSE.
544 =item warnings::fatal_enabled($object)
546 Use the name of the class for the object reference, C<$object>, as the
549 Return TRUE if that warnings category has been set to FATAL in the first
550 scope where the object is used.
551 Otherwise returns FALSE.
553 =item warnings::warn($message)
555 Print C<$message> to STDERR.
557 Use the warnings category with the same name as the current package.
559 If that warnings category has been set to "FATAL" in the calling module
560 then die. Otherwise return.
562 =item warnings::warn($category, $message)
564 Print C<$message> to STDERR.
566 If the warnings category, C<$category>, has been set to "FATAL" in the
567 calling module then die. Otherwise return.
569 =item warnings::warn($object, $message)
571 Print C<$message> to STDERR.
573 Use the name of the class for the object reference, C<$object>, as the
576 If that warnings category has been set to "FATAL" in the scope where C<$object>
577 is first used then die. Otherwise return.
580 =item warnings::warnif($message)
584 if (warnings::enabled())
585 { warnings::warn($message) }
587 =item warnings::warnif($category, $message)
591 if (warnings::enabled($category))
592 { warnings::warn($category, $message) }
594 =item warnings::warnif($object, $message)
598 if (warnings::enabled($object))
599 { warnings::warn($object, $message) }
603 See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
609 $All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
613 require Carp; # this initializes %CarpInternal
614 local $Carp::CarpInternal{'warnings'};
615 delete $Carp::CarpInternal{'warnings'};
621 # called from B::Deparse.pm
623 push @_, 'all' unless @_;
630 foreach my $word ( @_ ) {
631 if ($word eq 'FATAL') {
635 elsif ($word eq 'NONFATAL') {
639 elsif ($catmask = $Bits{$word}) {
641 $mask |= $DeadBits{$word} if $fatal ;
642 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
645 { Croaker("Unknown warnings category '$word'")}
659 my $mask = ${^WARNING_BITS} ;
661 if (vec($mask, $Offsets{'all'}, 1)) {
662 $mask |= $Bits{'all'} ;
663 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
666 push @_, 'all' unless @_;
668 foreach my $word ( @_ ) {
669 if ($word eq 'FATAL') {
673 elsif ($word eq 'NONFATAL') {
677 elsif ($catmask = $Bits{$word}) {
679 $mask |= $DeadBits{$word} if $fatal ;
680 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
683 { Croaker("Unknown warnings category '$word'")}
686 ${^WARNING_BITS} = $mask ;
694 my $mask = ${^WARNING_BITS} ;
696 if (vec($mask, $Offsets{'all'}, 1)) {
697 $mask |= $Bits{'all'} ;
698 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
701 push @_, 'all' unless @_;
703 foreach my $word ( @_ ) {
704 if ($word eq 'FATAL') {
707 elsif ($catmask = $Bits{$word}) {
708 $mask &= ~($catmask | $DeadBits{$word} | $All);
711 { Croaker("Unknown warnings category '$word'")}
714 ${^WARNING_BITS} = $mask ;
717 my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
726 # check the category supplied.
728 if (my $type = ref $category) {
729 Croaker("not an object")
730 if exists $builtin_type{$type};
734 $offset = $Offsets{$category};
735 Croaker("Unknown warnings category '$category'")
736 unless defined $offset;
739 $category = (caller(1))[0] ;
740 $offset = $Offsets{$category};
741 Croaker("package '$category' not registered for warnings")
742 unless defined $offset ;
745 my $this_pkg = (caller(1))[0] ;
750 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
751 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
756 $i = _error_loc(); # see where Carp will allocate the error
759 my $callers_bitmask = (caller($i))[9] ;
760 return ($callers_bitmask, $offset, $i) ;
765 goto &Carp::short_error_loc; # don't introduce another stack frame
770 Croaker("Usage: warnings::enabled([category])")
771 unless @_ == 1 || @_ == 0 ;
773 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
775 return 0 unless defined $callers_bitmask ;
776 return vec($callers_bitmask, $offset, 1) ||
777 vec($callers_bitmask, $Offsets{'all'}, 1) ;
782 Croaker("Usage: warnings::fatal_enabled([category])")
783 unless @_ == 1 || @_ == 0 ;
785 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
787 return 0 unless defined $callers_bitmask;
788 return vec($callers_bitmask, $offset + 1, 1) ||
789 vec($callers_bitmask, $Offsets{'all'} + 1, 1) ;
794 Croaker("Usage: warnings::warn([category,] 'message')")
795 unless @_ == 2 || @_ == 1 ;
798 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
800 Carp::croak($message)
801 if vec($callers_bitmask, $offset+1, 1) ||
802 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
803 Carp::carp($message) ;
808 Croaker("Usage: warnings::warnif([category,] 'message')")
809 unless @_ == 2 || @_ == 1 ;
812 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
815 unless defined $callers_bitmask &&
816 (vec($callers_bitmask, $offset, 1) ||
817 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
820 Carp::croak($message)
821 if vec($callers_bitmask, $offset+1, 1) ||
822 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
824 Carp::carp($message) ;