integrate cfgperl contents into mainline
[p5sagit/p5-mst-13.2.git] / lib / warnings.pm
index 977395b..11fd5b0 100644 (file)
@@ -17,98 +17,141 @@ warnings - Perl pragma to control optional warnings
     use warnings "all";
     no warnings "all";
 
+    if (warnings::enabled("void") {
+        warnings::warn("void", "some warning");
+    }
+
 =head1 DESCRIPTION
 
 If no import list is supplied, all possible warnings are either enabled
 or disabled.
 
-See L<perlmod/Pragmatic Modules> and L<perllexwarn>.
+Two functions are provided to assist module authors.
+
+=over 4
+
+=item warnings::enabled($category)
+
+Returns TRUE if the warnings category in C<$category> is enabled in the
+calling module. Otherwise returns FALSE.
+
+
+=item warnings::warn($category, $message)
 
+If the calling module has I<not> set C<$category> to "FATAL", print
+C<$message> to STDERR.
+If the calling module has set C<$category> to "FATAL", print C<$message>
+STDERR then die.
+
+=back
+
+See L<perlmod/Pragmatic Modules> and L<perllexwarn>.
 
 =cut
 
 use Carp ;
 
 %Bits = (
-    'all'              => "\x55\x55\x55\x55\x55\x55\x55\x55\x55", # [0..35]
-    'ambiguous'                => "\x00\x00\x00\x00\x01\x00\x00\x00\x00", # [16]
-    'closed'           => "\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
-    'closure'          => "\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [27]
-    'debugging'                => "\x00\x00\x00\x01\x00\x00\x00\x00\x00", # [12]
-    'deprecated'       => "\x00\x00\x00\x00\x04\x00\x00\x00\x00", # [17]
-    'digit'            => "\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [18]
-    'exec'             => "\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
-    'inplace'          => "\x00\x00\x00\x04\x00\x00\x00\x00\x00", # [13]
-    'internal'         => "\x00\x00\x00\x10\x00\x00\x00\x00\x00", # [14]
-    'io'               => "\x55\x05\x00\x00\x00\x00\x00\x00\x00", # [0..5]
-    'misc'             => "\x00\x10\x00\x00\x00\x00\x00\x00\x00", # [6]
-    'newline'          => "\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
-    'numeric'          => "\x00\x40\x00\x00\x00\x00\x00\x00\x00", # [7]
-    'octal'            => "\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [19]
-    'once'             => "\x00\x00\x01\x00\x00\x00\x00\x00\x00", # [8]
-    'overflow'         => "\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [28]
-    'parenthesis'      => "\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [20]
-    'pipe'             => "\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [4]
-    'portable'         => "\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [29]
-    'precedence'       => "\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [21]
-    'printf'           => "\x00\x00\x00\x00\x00\x10\x00\x00\x00", # [22]
-    'recursion'                => "\x00\x00\x04\x00\x00\x00\x00\x00\x00", # [9]
-    'redefine'         => "\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [10]
-    'reserved'         => "\x00\x00\x00\x00\x00\x40\x00\x00\x00", # [23]
-    'semicolon'                => "\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [24]
-    'severe'           => "\x00\x00\x40\x15\x00\x00\x00\x00\x00", # [11..14]
-    'signal'           => "\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [30]
-    'substr'           => "\x00\x00\x00\x00\x00\x00\x00\x40\x00", # [31]
-    'syntax'           => "\x00\x00\x00\x40\x55\x55\x01\x00\x00", # [15..24]
-    'taint'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [32]
-    'uninitialized'    => "\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [25]
-    'unopened'         => "\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [5]
-    'unsafe'           => "\x00\x00\x00\x00\x00\x00\x50\x55\x15", # [26..34]
-    'untie'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [33]
-    'utf8'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [34]
-    'void'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x40", # [35]
+    'all'              => "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55", # [0..47]
+    'ambiguous'                => "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00", # [27]
+    'bareword'         => "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00", # [28]
+    'chmod'            => "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [0]
+    'closed'           => "\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5]
+    'closure'          => "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
+    'debugging'                => "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", # [20]
+    'deprecated'       => "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00", # [29]
+    'digit'            => "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [30]
+    'exec'             => "\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
+    'exiting'          => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
+    'glob'             => "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
+    'inplace'          => "\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00", # [21]
+    'internal'         => "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [22]
+    'io'               => "\x00\x55\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4..9]
+    'malloc'           => "\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00", # [23]
+    'misc'             => "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10]
+    'newline'          => "\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
+    'numeric'          => "\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11]
+    'once'             => "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
+    'overflow'         => "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [13]
+    'pack'             => "\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [14]
+    'parenthesis'      => "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [31]
+    'pipe'             => "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
+    'portable'         => "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [15]
+    'precedence'       => "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [32]
+    'printf'           => "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [33]
+    'prototype'                => "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00", # [34]
+    'qw'               => "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00", # [35]
+    'recursion'                => "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [16]
+    'redefine'         => "\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [17]
+    'regexp'           => "\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00", # [18]
+    'reserved'         => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [36]
+    'semicolon'                => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [37]
+    'severe'           => "\x00\x00\x00\x00\x40\x55\x00\x00\x00\x00\x00\x00", # [19..23]
+    'signal'           => "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00", # [24]
+    'substr'           => "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00", # [25]
+    'syntax'           => "\x00\x00\x00\x00\x00\x00\x50\x55\x55\x05\x00\x00", # [26..37]
+    'taint'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00", # [38]
+    'umask'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [39]
+    'uninitialized'    => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [40]
+    'unopened'         => "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
+    'unpack'           => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [41]
+    'untie'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [42]
+    'utf8'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00", # [43]
+    'void'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [44]
+    'y2k'              => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [45]
   );
 
 %DeadBits = (
-    'all'              => "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", # [0..35]
-    'ambiguous'                => "\x00\x00\x00\x00\x02\x00\x00\x00\x00", # [16]
-    'closed'           => "\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
-    'closure'          => "\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [27]
-    'debugging'                => "\x00\x00\x00\x02\x00\x00\x00\x00\x00", # [12]
-    'deprecated'       => "\x00\x00\x00\x00\x08\x00\x00\x00\x00", # [17]
-    'digit'            => "\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [18]
-    'exec'             => "\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
-    'inplace'          => "\x00\x00\x00\x08\x00\x00\x00\x00\x00", # [13]
-    'internal'         => "\x00\x00\x00\x20\x00\x00\x00\x00\x00", # [14]
-    'io'               => "\xaa\x0a\x00\x00\x00\x00\x00\x00\x00", # [0..5]
-    'misc'             => "\x00\x20\x00\x00\x00\x00\x00\x00\x00", # [6]
-    'newline'          => "\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
-    'numeric'          => "\x00\x80\x00\x00\x00\x00\x00\x00\x00", # [7]
-    'octal'            => "\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [19]
-    'once'             => "\x00\x00\x02\x00\x00\x00\x00\x00\x00", # [8]
-    'overflow'         => "\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [28]
-    'parenthesis'      => "\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [20]
-    'pipe'             => "\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [4]
-    'portable'         => "\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [29]
-    'precedence'       => "\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [21]
-    'printf'           => "\x00\x00\x00\x00\x00\x20\x00\x00\x00", # [22]
-    'recursion'                => "\x00\x00\x08\x00\x00\x00\x00\x00\x00", # [9]
-    'redefine'         => "\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [10]
-    'reserved'         => "\x00\x00\x00\x00\x00\x80\x00\x00\x00", # [23]
-    'semicolon'                => "\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [24]
-    'severe'           => "\x00\x00\x80\x2a\x00\x00\x00\x00\x00", # [11..14]
-    'signal'           => "\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [30]
-    'substr'           => "\x00\x00\x00\x00\x00\x00\x00\x80\x00", # [31]
-    'syntax'           => "\x00\x00\x00\x80\xaa\xaa\x02\x00\x00", # [15..24]
-    'taint'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [32]
-    'uninitialized'    => "\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [25]
-    'unopened'         => "\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [5]
-    'unsafe'           => "\x00\x00\x00\x00\x00\x00\xa0\xaa\x2a", # [26..34]
-    'untie'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [33]
-    'utf8'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [34]
-    'void'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x80", # [35]
+    'all'              => "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", # [0..47]
+    'ambiguous'                => "\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00", # [27]
+    'bareword'         => "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00", # [28]
+    'chmod'            => "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [0]
+    'closed'           => "\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5]
+    'closure'          => "\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
+    'debugging'                => "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00", # [20]
+    'deprecated'       => "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00", # [29]
+    'digit'            => "\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [30]
+    'exec'             => "\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
+    'exiting'          => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
+    'glob'             => "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
+    'inplace'          => "\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00", # [21]
+    'internal'         => "\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [22]
+    'io'               => "\x00\xaa\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4..9]
+    'malloc'           => "\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00", # [23]
+    'misc'             => "\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10]
+    'newline'          => "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
+    'numeric'          => "\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11]
+    'once'             => "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
+    'overflow'         => "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [13]
+    'pack'             => "\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [14]
+    'parenthesis'      => "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [31]
+    'pipe'             => "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
+    'portable'         => "\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [15]
+    'precedence'       => "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [32]
+    'printf'           => "\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [33]
+    'prototype'                => "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00", # [34]
+    'qw'               => "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00", # [35]
+    'recursion'                => "\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [16]
+    'redefine'         => "\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [17]
+    'regexp'           => "\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00", # [18]
+    'reserved'         => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [36]
+    'semicolon'                => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [37]
+    'severe'           => "\x00\x00\x00\x00\x80\xaa\x00\x00\x00\x00\x00\x00", # [19..23]
+    'signal'           => "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00", # [24]
+    'substr'           => "\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00", # [25]
+    'syntax'           => "\x00\x00\x00\x00\x00\x00\xa0\xaa\xaa\x0a\x00\x00", # [26..37]
+    'taint'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00", # [38]
+    'umask'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [39]
+    'uninitialized'    => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [40]
+    'unopened'         => "\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
+    'unpack'           => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [41]
+    'untie'            => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [42]
+    'utf8'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00", # [43]
+    'void'             => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [44]
+    'y2k'              => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [45]
   );
 
+$NONE = "\0\0\0\0\0\0\0\0\0\0\0\0";
 
 sub bits {
     my $mask ;
@@ -131,22 +174,44 @@ sub bits {
 
 sub import {
     shift;
-    ${^Warnings} |= bits(@_ ? @_ : 'all') ;
+    ${^WARNING_BITS} |= bits(@_ ? @_ : 'all') ;
 }
 
 sub unimport {
     shift;
-    ${^Warnings} &= ~ bits(@_ ? @_ : 'all') ;
+    ${^WARNING_BITS} &= ~ bits(@_ ? @_ : 'all') ;
 }
 
 sub enabled
 {
-    my $string = shift ;
-
+    # If no parameters, check for any lexical warnings enabled
+    # in the users scope.
+    my $callers_bitmask = (caller(1))[9] ; 
+    return ($callers_bitmask ne $NONE) if @_ == 0 ;
+
+    # otherwise check for the category supplied.
+    my $category = shift ;
+    return 0
+       unless $Bits{$category} ;
+    return 0 unless defined $callers_bitmask ;
     return 1
-       if $bits{$string} && ${^Warnings} & $bits{$string} ;
+       if ($callers_bitmask & $Bits{$category}) ne $NONE ;
    
     return 0 ; 
 }
 
+sub warn
+{
+    croak "Usage: warnings::warn('category', 'message')"
+       unless @_ == 2 ;
+    my $category = shift ;
+    my $message = shift ;
+    local $Carp::CarpLevel = 1 ;
+    my $callers_bitmask = (caller(1))[9] ; 
+    croak($message) 
+       if defined $callers_bitmask &&
+           ($callers_bitmask & $DeadBits{$category}) ne $NONE ;
+    carp($message) ;
+}
+
 1;