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))
356 #define packWARN(a) (a )
357 #define packWARN2(a,b) ((a) | ((b)<<8) )
358 #define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
359 #define packWARN4(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d) <<24))
361 #define unpackWARN1(x) ((x) & 0xFF)
362 #define unpackWARN2(x) (((x) >>8) & 0xFF)
363 #define unpackWARN3(x) (((x) >>16) & 0xFF)
364 #define unpackWARN4(x) (((x) >>24) & 0xFF)
367 ( ! specialWARN(PL_curcop->cop_warnings) && \
368 ( isWARNf_on(PL_curcop->cop_warnings, WARN_ALL) || \
369 isWARNf_on(PL_curcop->cop_warnings, unpackWARN1(x)) || \
370 isWARNf_on(PL_curcop->cop_warnings, unpackWARN2(x)) || \
371 isWARNf_on(PL_curcop->cop_warnings, unpackWARN3(x)) || \
372 isWARNf_on(PL_curcop->cop_warnings, unpackWARN4(x))))
374 /* end of file warnings.h */
379 rename_if_different("warnings.h-new", "warnings.h");
382 last if /^KEYWORDS$/ ;
386 #$list{'all'} = [ $offset .. 8 * ($warn_size/2) - 1 ] ;
389 print $pm "our %Offsets = (\n" ;
390 foreach my $k (sort { $a <=> $b } keys %ValueToName) {
391 my ($name, $version) = @{ $ValueToName{$k} };
394 if ( $last_ver != $version ) {
396 print $pm tab(4, " # Warnings Categories added in Perl $version");
399 print $pm tab(4, " '$name'"), "=> $k,\n" ;
400 $last_ver = $version;
403 print $pm " );\n\n" ;
405 print $pm "our %Bits = (\n" ;
406 foreach $k (sort keys %list) {
409 my @list = sort { $a <=> $b } @$v ;
411 print $pm tab(4, " '$k'"), '=> "',
412 # mkHex($warn_size, @list),
413 mkHex($warn_size, map $_ * 2 , @list),
414 '", # [', mkRange(@list), "]\n" ;
417 print $pm " );\n\n" ;
419 print $pm "our %DeadBits = (\n" ;
420 foreach $k (sort keys %list) {
423 my @list = sort { $a <=> $b } @$v ;
425 print $pm tab(4, " '$k'"), '=> "',
426 # mkHex($warn_size, @list),
427 mkHex($warn_size, map $_ * 2 + 1 , @list),
428 '", # [', mkRange(@list), "]\n" ;
431 print $pm " );\n\n" ;
432 print $pm '$NONE = "', ('\0' x $warn_size) , "\";\n" ;
433 print $pm '$LAST_BIT = ' . "$index ;\n" ;
434 print $pm '$BYTES = ' . "$warn_size ;\n" ;
439 print $pm "# ex: set ro:\n";
441 rename_if_different("lib/warnings.pm-new", "lib/warnings.pm");
444 # -*- buffer-read-only: t -*-
445 # !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
446 # This file was created by warnings.pl
447 # Any changes made here will be lost.
452 our $VERSION = '1.06';
454 # Verify that we're called correctly so that warnings will work.
455 # see also strict.pm.
456 unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
457 my (undef, $f, $l) = caller;
458 die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
463 warnings - Perl pragma to control optional warnings
473 use warnings::register;
474 if (warnings::enabled()) {
475 warnings::warn("some warning");
478 if (warnings::enabled("void")) {
479 warnings::warn("void", "some warning");
482 if (warnings::enabled($object)) {
483 warnings::warn($object, "some warning");
486 warnings::warnif("some warning");
487 warnings::warnif("void", "some warning");
488 warnings::warnif($object, "some warning");
492 The C<warnings> pragma is a replacement for the command line flag C<-w>,
493 but the pragma is limited to the enclosing block, while the flag is global.
494 See L<perllexwarn> for more information.
496 If no import list is supplied, all possible warnings are either enabled
499 A number of functions are provided to assist module authors.
503 =item use warnings::register
505 Creates a new warnings category with the same name as the package where
506 the call to the pragma is used.
508 =item warnings::enabled()
510 Use the warnings category with the same name as the current package.
512 Return TRUE if that warnings category is enabled in the calling module.
513 Otherwise returns FALSE.
515 =item warnings::enabled($category)
517 Return TRUE if the warnings category, C<$category>, is enabled in the
519 Otherwise returns FALSE.
521 =item warnings::enabled($object)
523 Use the name of the class for the object reference, C<$object>, as the
526 Return TRUE if that warnings category is enabled in the first scope
527 where the object is used.
528 Otherwise returns FALSE.
530 =item warnings::warn($message)
532 Print C<$message> to STDERR.
534 Use the warnings category with the same name as the current package.
536 If that warnings category has been set to "FATAL" in the calling module
537 then die. Otherwise return.
539 =item warnings::warn($category, $message)
541 Print C<$message> to STDERR.
543 If the warnings category, C<$category>, has been set to "FATAL" in the
544 calling module then die. Otherwise return.
546 =item warnings::warn($object, $message)
548 Print C<$message> to STDERR.
550 Use the name of the class for the object reference, C<$object>, as the
553 If that warnings category has been set to "FATAL" in the scope where C<$object>
554 is first used then die. Otherwise return.
557 =item warnings::warnif($message)
561 if (warnings::enabled())
562 { warnings::warn($message) }
564 =item warnings::warnif($category, $message)
568 if (warnings::enabled($category))
569 { warnings::warn($category, $message) }
571 =item warnings::warnif($object, $message)
575 if (warnings::enabled($object))
576 { warnings::warn($object, $message) }
580 See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
586 $All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
590 require Carp; # this initializes %CarpInternal
591 local $Carp::CarpInternal{'warnings'};
592 delete $Carp::CarpInternal{'warnings'};
598 # called from B::Deparse.pm
600 push @_, 'all' unless @_;
607 foreach my $word ( @_ ) {
608 if ($word eq 'FATAL') {
612 elsif ($word eq 'NONFATAL') {
616 elsif ($catmask = $Bits{$word}) {
618 $mask |= $DeadBits{$word} if $fatal ;
619 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
622 { Croaker("Unknown warnings category '$word'")}
636 my $mask = ${^WARNING_BITS} ;
638 if (vec($mask, $Offsets{'all'}, 1)) {
639 $mask |= $Bits{'all'} ;
640 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
643 push @_, 'all' unless @_;
645 foreach my $word ( @_ ) {
646 if ($word eq 'FATAL') {
650 elsif ($word eq 'NONFATAL') {
654 elsif ($catmask = $Bits{$word}) {
656 $mask |= $DeadBits{$word} if $fatal ;
657 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
660 { Croaker("Unknown warnings category '$word'")}
663 ${^WARNING_BITS} = $mask ;
671 my $mask = ${^WARNING_BITS} ;
673 if (vec($mask, $Offsets{'all'}, 1)) {
674 $mask |= $Bits{'all'} ;
675 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
678 push @_, 'all' unless @_;
680 foreach my $word ( @_ ) {
681 if ($word eq 'FATAL') {
684 elsif ($catmask = $Bits{$word}) {
685 $mask &= ~($catmask | $DeadBits{$word} | $All);
688 { Croaker("Unknown warnings category '$word'")}
691 ${^WARNING_BITS} = $mask ;
694 my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
703 # check the category supplied.
705 if (my $type = ref $category) {
706 Croaker("not an object")
707 if exists $builtin_type{$type};
711 $offset = $Offsets{$category};
712 Croaker("Unknown warnings category '$category'")
713 unless defined $offset;
716 $category = (caller(1))[0] ;
717 $offset = $Offsets{$category};
718 Croaker("package '$category' not registered for warnings")
719 unless defined $offset ;
722 my $this_pkg = (caller(1))[0] ;
727 while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
728 last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
733 $i = _error_loc(); # see where Carp will allocate the error
736 my $callers_bitmask = (caller($i))[9] ;
737 return ($callers_bitmask, $offset, $i) ;
742 goto &Carp::short_error_loc; # don't introduce another stack frame
747 Croaker("Usage: warnings::enabled([category])")
748 unless @_ == 1 || @_ == 0 ;
750 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
752 return 0 unless defined $callers_bitmask ;
753 return vec($callers_bitmask, $offset, 1) ||
754 vec($callers_bitmask, $Offsets{'all'}, 1) ;
760 Croaker("Usage: warnings::warn([category,] 'message')")
761 unless @_ == 2 || @_ == 1 ;
764 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
766 Carp::croak($message)
767 if vec($callers_bitmask, $offset+1, 1) ||
768 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
769 Carp::carp($message) ;
774 Croaker("Usage: warnings::warnif([category,] 'message')")
775 unless @_ == 2 || @_ == 1 ;
778 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
781 unless defined $callers_bitmask &&
782 (vec($callers_bitmask, $offset, 1) ||
783 vec($callers_bitmask, $Offsets{'all'}, 1)) ;
786 Carp::croak($message)
787 if vec($callers_bitmask, $offset+1, 1) ||
788 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
790 Carp::carp($message) ;