1 2# This file was created by warnings.pl 3# Any changes made here will be lost. 4# 5 6package warnings; 7 8=head1 NAME 9 10warnings - Perl pragma to control optional warnings 11 12=head1 SYNOPSIS 13 14 use warnings; 15 no warnings; 16 17 use warnings "all"; 18 no warnings "all"; 19 20 use warnings::register; 21 if (warnings::enabled()) { 22 warnings::warn("some warning"); 23 } 24 25 if (warnings::enabled("void")) { 26 warnings::warn("void", "some warning"); 27 } 28 29 if (warnings::enabled($object)) { 30 warnings::warn($object, "some warning"); 31 } 32 33 warnif("some warning"); 34 warnif("void", "some warning"); 35 warnif($object, "some warning"); 36 37=head1 DESCRIPTION 38 39If no import list is supplied, all possible warnings are either enabled 40or disabled. 41 42A number of functions are provided to assist module authors. 43 44=over 4 45 46=item use warnings::register 47 48Creates a new warnings category with the same name as the package where 49the call to the pragma is used. 50 51=item warnings::enabled() 52 53Use the warnings category with the same name as the current package. 54 55Return TRUE if that warnings category is enabled in the calling module. 56Otherwise returns FALSE. 57 58=item warnings::enabled($category) 59 60Return TRUE if the warnings category, C<$category>, is enabled in the 61calling module. 62Otherwise returns FALSE. 63 64=item warnings::enabled($object) 65 66Use the name of the class for the object reference, C<$object>, as the 67warnings category. 68 69Return TRUE if that warnings category is enabled in the first scope 70where the object is used. 71Otherwise returns FALSE. 72 73=item warnings::warn($message) 74 75Print C<$message> to STDERR. 76 77Use the warnings category with the same name as the current package. 78 79If that warnings category has been set to "FATAL" in the calling module 80then die. Otherwise return. 81 82=item warnings::warn($category, $message) 83 84Print C<$message> to STDERR. 85 86If the warnings category, C<$category>, has been set to "FATAL" in the 87calling module then die. Otherwise return. 88 89=item warnings::warn($object, $message) 90 91Print C<$message> to STDERR. 92 93Use the name of the class for the object reference, C<$object>, as the 94warnings category. 95 96If that warnings category has been set to "FATAL" in the scope where C<$object> 97is first used then die. Otherwise return. 98 99 100=item warnings::warnif($message) 101 102Equivalent to: 103 104 if (warnings::enabled()) 105 { warnings::warn($message) } 106 107=item warnings::warnif($category, $message) 108 109Equivalent to: 110 111 if (warnings::enabled($category)) 112 { warnings::warn($category, $message) } 113 114=item warnings::warnif($object, $message) 115 116Equivalent to: 117 118 if (warnings::enabled($object)) 119 { warnings::warn($object, $message) } 120 121=back 122 123See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>. 124 125=cut 126 127use Carp ; 128 129%Offsets = ( 130 'all' => 0, 131 'chmod' => 2, 132 'closure' => 4, 133 'exiting' => 6, 134 'glob' => 8, 135 'io' => 10, 136 'closed' => 12, 137 'exec' => 14, 138 'newline' => 16, 139 'pipe' => 18, 140 'unopened' => 20, 141 'misc' => 22, 142 'numeric' => 24, 143 'once' => 26, 144 'overflow' => 28, 145 'pack' => 30, 146 'portable' => 32, 147 'recursion' => 34, 148 'redefine' => 36, 149 'regexp' => 38, 150 'severe' => 40, 151 'debugging' => 42, 152 'inplace' => 44, 153 'internal' => 46, 154 'malloc' => 48, 155 'signal' => 50, 156 'substr' => 52, 157 'syntax' => 54, 158 'ambiguous' => 56, 159 'bareword' => 58, 160 'deprecated' => 60, 161 'digit' => 62, 162 'parenthesis' => 64, 163 'precedence' => 66, 164 'printf' => 68, 165 'prototype' => 70, 166 'qw' => 72, 167 'reserved' => 74, 168 'semicolon' => 76, 169 'taint' => 78, 170 'umask' => 80, 171 'uninitialized' => 82, 172 'unpack' => 84, 173 'untie' => 86, 174 'utf8' => 88, 175 'void' => 90, 176 'y2k' => 92, 177 ); 178 179%Bits = ( 180 'all' => "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x15", # [0..46] 181 'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00", # [28] 182 'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00", # [29] 183 'chmod' => "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 184 'closed' => "\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 185 'closure' => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2] 186 'debugging' => "\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00", # [21] 187 'deprecated' => "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [30] 188 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [31] 189 'exec' => "\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7] 190 'exiting' => "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3] 191 'glob' => "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4] 192 'inplace' => "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [22] 193 'internal' => "\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00", # [23] 194 'io' => "\x00\x54\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..10] 195 'malloc' => "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00", # [24] 196 'misc' => "\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11] 197 'newline' => "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8] 198 'numeric' => "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", # [12] 199 'once' => "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [13] 200 'overflow' => "\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [14] 201 'pack' => "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [15] 202 'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [32] 203 'pipe' => "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9] 204 'portable' => "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [16] 205 'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [33] 206 'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00", # [34] 207 'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00", # [35] 208 'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [36] 209 'recursion' => "\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [17] 210 'redefine' => "\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00", # [18] 211 'regexp' => "\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00", # [19] 212 'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [37] 213 'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00", # [38] 214 'severe' => "\x00\x00\x00\x00\x00\x55\x01\x00\x00\x00\x00\x00", # [20..24] 215 'signal' => "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00", # [25] 216 'substr' => "\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00", # [26] 217 'syntax' => "\x00\x00\x00\x00\x00\x00\x40\x55\x55\x15\x00\x00", # [27..38] 218 'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [39] 219 'umask' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [40] 220 'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [41] 221 'unopened' => "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10] 222 'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [42] 223 'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00", # [43] 224 'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [44] 225 'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [45] 226 'y2k' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [46] 227 ); 228 229%DeadBits = ( 230 'all' => "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x2a", # [0..46] 231 'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00", # [28] 232 'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00", # [29] 233 'chmod' => "\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 234 'closed' => "\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 235 'closure' => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2] 236 'debugging' => "\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00", # [21] 237 'deprecated' => "\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [30] 238 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [31] 239 'exec' => "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7] 240 'exiting' => "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3] 241 'glob' => "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4] 242 'inplace' => "\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [22] 243 'internal' => "\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00", # [23] 244 'io' => "\x00\xa8\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..10] 245 'malloc' => "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00", # [24] 246 'misc' => "\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11] 247 'newline' => "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8] 248 'numeric' => "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", # [12] 249 'once' => "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [13] 250 'overflow' => "\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [14] 251 'pack' => "\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [15] 252 'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [32] 253 'pipe' => "\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9] 254 'portable' => "\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [16] 255 'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [33] 256 'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00", # [34] 257 'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00", # [35] 258 'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [36] 259 'recursion' => "\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [17] 260 'redefine' => "\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00", # [18] 261 'regexp' => "\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00", # [19] 262 'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [37] 263 'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00", # [38] 264 'severe' => "\x00\x00\x00\x00\x00\xaa\x02\x00\x00\x00\x00\x00", # [20..24] 265 'signal' => "\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00", # [25] 266 'substr' => "\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00", # [26] 267 'syntax' => "\x00\x00\x00\x00\x00\x00\x80\xaa\xaa\x2a\x00\x00", # [27..38] 268 'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [39] 269 'umask' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [40] 270 'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [41] 271 'unopened' => "\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10] 272 'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [42] 273 'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00", # [43] 274 'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [44] 275 'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [45] 276 'y2k' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [46] 277 ); 278 279$NONE = "\0\0\0\0\0\0\0\0\0\0\0\0"; 280$LAST_BIT = 94 ; 281$BYTES = 12 ; 282 283$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ; 284 285sub bits { 286 my $mask ; 287 my $catmask ; 288 my $fatal = 0 ; 289 foreach my $word (@_) { 290 if ($word eq 'FATAL') { 291 $fatal = 1; 292 } 293 elsif ($catmask = $Bits{$word}) { 294 $mask |= $catmask ; 295 $mask |= $DeadBits{$word} if $fatal ; 296 } 297 else 298 { croak("unknown warnings category '$word'")} 299 } 300 301 return $mask ; 302} 303 304sub import { 305 shift; 306 my $mask = ${^WARNING_BITS} ; 307 if (vec($mask, $Offsets{'all'}, 1)) { 308 $mask |= $Bits{'all'} ; 309 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1); 310 } 311 ${^WARNING_BITS} = $mask | bits(@_ ? @_ : 'all') ; 312} 313 314sub unimport { 315 shift; 316 my $mask = ${^WARNING_BITS} ; 317 if (vec($mask, $Offsets{'all'}, 1)) { 318 $mask |= $Bits{'all'} ; 319 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1); 320 } 321 ${^WARNING_BITS} = $mask & ~ (bits(@_ ? @_ : 'all') | $All) ; 322} 323 324sub __chk 325{ 326 my $category ; 327 my $offset ; 328 my $isobj = 0 ; 329 330 if (@_) { 331 # check the category supplied. 332 $category = shift ; 333 if (ref $category) { 334 croak ("not an object") 335 if $category !~ /^([^=]+)=/ ;+ 336 $category = $1 ; 337 $isobj = 1 ; 338 } 339 $offset = $Offsets{$category}; 340 croak("unknown warnings category '$category'") 341 unless defined $offset; 342 } 343 else { 344 $category = (caller(1))[0] ; 345 $offset = $Offsets{$category}; 346 croak("package '$category' not registered for warnings") 347 unless defined $offset ; 348 } 349 350 my $this_pkg = (caller(1))[0] ; 351 my $i = 2 ; 352 my $pkg ; 353 354 if ($isobj) { 355 while (do { { package DB; $pkg = (caller($i++))[0] } } ) { 356 last unless @DB::args && $DB::args[0] =~ /^$category=/ ; 357 } 358 $i -= 2 ; 359 } 360 else { 361 for ($i = 2 ; $pkg = (caller($i))[0] ; ++ $i) { 362 last if $pkg ne $this_pkg ; 363 } 364 $i = 2 365 if !$pkg || $pkg eq $this_pkg ; 366 } 367 368 my $callers_bitmask = (caller($i))[9] ; 369 return ($callers_bitmask, $offset, $i) ; 370} 371 372sub enabled 373{ 374 croak("Usage: warnings::enabled([category])") 375 unless @_ == 1 || @_ == 0 ; 376 377 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 378 379 return 0 unless defined $callers_bitmask ; 380 return vec($callers_bitmask, $offset, 1) || 381 vec($callers_bitmask, $Offsets{'all'}, 1) ; 382} 383 384 385sub warn 386{ 387 croak("Usage: warnings::warn([category,] 'message')") 388 unless @_ == 2 || @_ == 1 ; 389 390 my $message = pop ; 391 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 392 local $Carp::CarpLevel = $i ; 393 croak($message) 394 if vec($callers_bitmask, $offset+1, 1) || 395 vec($callers_bitmask, $Offsets{'all'}+1, 1) ; 396 carp($message) ; 397} 398 399sub warnif 400{ 401 croak("Usage: warnings::warnif([category,] 'message')") 402 unless @_ == 2 || @_ == 1 ; 403 404 my $message = pop ; 405 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 406 local $Carp::CarpLevel = $i ; 407 408 return 409 unless defined $callers_bitmask && 410 (vec($callers_bitmask, $offset, 1) || 411 vec($callers_bitmask, $Offsets{'all'}, 1)) ; 412 413 croak($message) 414 if vec($callers_bitmask, $offset+1, 1) || 415 vec($callers_bitmask, $Offsets{'all'}+1, 1) ; 416 417 carp($message) ; 418} 4191; 420