1# -*- buffer-read-only: t -*- 2# !!!!!!! DO NOT EDIT THIS FILE !!!!!!! 3# This file was created by warnings.pl 4# Any changes made here will be lost. 5# 6 7package warnings; 8 9our $VERSION = '1.06'; 10 11# Verify that we're called correctly so that warnings will work. 12# see also strict.pm. 13unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) { 14 my (undef, $f, $l) = caller; 15 die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n"); 16} 17 18=head1 NAME 19 20warnings - Perl pragma to control optional warnings 21 22=head1 SYNOPSIS 23 24 use warnings; 25 no warnings; 26 27 use warnings "all"; 28 no warnings "all"; 29 30 use warnings::register; 31 if (warnings::enabled()) { 32 warnings::warn("some warning"); 33 } 34 35 if (warnings::enabled("void")) { 36 warnings::warn("void", "some warning"); 37 } 38 39 if (warnings::enabled($object)) { 40 warnings::warn($object, "some warning"); 41 } 42 43 warnings::warnif("some warning"); 44 warnings::warnif("void", "some warning"); 45 warnings::warnif($object, "some warning"); 46 47=head1 DESCRIPTION 48 49The C<warnings> pragma is a replacement for the command line flag C<-w>, 50but the pragma is limited to the enclosing block, while the flag is global. 51See L<perllexwarn> for more information. 52 53If no import list is supplied, all possible warnings are either enabled 54or disabled. 55 56A number of functions are provided to assist module authors. 57 58=over 4 59 60=item use warnings::register 61 62Creates a new warnings category with the same name as the package where 63the call to the pragma is used. 64 65=item warnings::enabled() 66 67Use the warnings category with the same name as the current package. 68 69Return TRUE if that warnings category is enabled in the calling module. 70Otherwise returns FALSE. 71 72=item warnings::enabled($category) 73 74Return TRUE if the warnings category, C<$category>, is enabled in the 75calling module. 76Otherwise returns FALSE. 77 78=item warnings::enabled($object) 79 80Use the name of the class for the object reference, C<$object>, as the 81warnings category. 82 83Return TRUE if that warnings category is enabled in the first scope 84where the object is used. 85Otherwise returns FALSE. 86 87=item warnings::warn($message) 88 89Print C<$message> to STDERR. 90 91Use the warnings category with the same name as the current package. 92 93If that warnings category has been set to "FATAL" in the calling module 94then die. Otherwise return. 95 96=item warnings::warn($category, $message) 97 98Print C<$message> to STDERR. 99 100If the warnings category, C<$category>, has been set to "FATAL" in the 101calling module then die. Otherwise return. 102 103=item warnings::warn($object, $message) 104 105Print C<$message> to STDERR. 106 107Use the name of the class for the object reference, C<$object>, as the 108warnings category. 109 110If that warnings category has been set to "FATAL" in the scope where C<$object> 111is first used then die. Otherwise return. 112 113 114=item warnings::warnif($message) 115 116Equivalent to: 117 118 if (warnings::enabled()) 119 { warnings::warn($message) } 120 121=item warnings::warnif($category, $message) 122 123Equivalent to: 124 125 if (warnings::enabled($category)) 126 { warnings::warn($category, $message) } 127 128=item warnings::warnif($object, $message) 129 130Equivalent to: 131 132 if (warnings::enabled($object)) 133 { warnings::warn($object, $message) } 134 135=back 136 137See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>. 138 139=cut 140 141our %Offsets = ( 142 143 # Warnings Categories added in Perl 5.008 144 145 'all' => 0, 146 'closure' => 2, 147 'deprecated' => 4, 148 'exiting' => 6, 149 'glob' => 8, 150 'io' => 10, 151 'closed' => 12, 152 'exec' => 14, 153 'layer' => 16, 154 'newline' => 18, 155 'pipe' => 20, 156 'unopened' => 22, 157 'misc' => 24, 158 'numeric' => 26, 159 'once' => 28, 160 'overflow' => 30, 161 'pack' => 32, 162 'portable' => 34, 163 'recursion' => 36, 164 'redefine' => 38, 165 'regexp' => 40, 166 'severe' => 42, 167 'debugging' => 44, 168 'inplace' => 46, 169 'internal' => 48, 170 'malloc' => 50, 171 'signal' => 52, 172 'substr' => 54, 173 'syntax' => 56, 174 'ambiguous' => 58, 175 'bareword' => 60, 176 'digit' => 62, 177 'parenthesis' => 64, 178 'precedence' => 66, 179 'printf' => 68, 180 'prototype' => 70, 181 'qw' => 72, 182 'reserved' => 74, 183 'semicolon' => 76, 184 'taint' => 78, 185 'threads' => 80, 186 'uninitialized' => 82, 187 'unpack' => 84, 188 'untie' => 86, 189 'utf8' => 88, 190 'void' => 90, 191 ); 192 193our %Bits = ( 194 'all' => "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x05", # [0..45] 195 'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00", # [29] 196 'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [30] 197 'closed' => "\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 198 'closure' => "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 199 'debugging' => "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [22] 200 'deprecated' => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2] 201 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [31] 202 'exec' => "\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7] 203 'exiting' => "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3] 204 'glob' => "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4] 205 'inplace' => "\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00", # [23] 206 'internal' => "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00", # [24] 207 'io' => "\x00\x54\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..11] 208 'layer' => "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8] 209 'malloc' => "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00", # [25] 210 'misc' => "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", # [12] 211 'newline' => "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9] 212 'numeric' => "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [13] 213 'once' => "\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [14] 214 'overflow' => "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [15] 215 'pack' => "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [16] 216 'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [32] 217 'pipe' => "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10] 218 'portable' => "\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [17] 219 'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [33] 220 'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00", # [34] 221 'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00", # [35] 222 'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [36] 223 'recursion' => "\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00", # [18] 224 'redefine' => "\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00", # [19] 225 'regexp' => "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", # [20] 226 'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [37] 227 'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00", # [38] 228 'severe' => "\x00\x00\x00\x00\x00\x54\x05\x00\x00\x00\x00\x00", # [21..25] 229 'signal' => "\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00", # [26] 230 'substr' => "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00", # [27] 231 'syntax' => "\x00\x00\x00\x00\x00\x00\x00\x55\x55\x15\x00\x00", # [28..38] 232 'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [39] 233 'threads' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [40] 234 'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [41] 235 'unopened' => "\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11] 236 'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [42] 237 'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00", # [43] 238 'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [44] 239 'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [45] 240 ); 241 242our %DeadBits = ( 243 'all' => "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x0a", # [0..45] 244 'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00", # [29] 245 'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [30] 246 'closed' => "\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6] 247 'closure' => "\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1] 248 'debugging' => "\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [22] 249 'deprecated' => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2] 250 'digit' => "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [31] 251 'exec' => "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7] 252 'exiting' => "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3] 253 'glob' => "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4] 254 'inplace' => "\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00", # [23] 255 'internal' => "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00", # [24] 256 'io' => "\x00\xa8\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..11] 257 'layer' => "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8] 258 'malloc' => "\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00", # [25] 259 'misc' => "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", # [12] 260 'newline' => "\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9] 261 'numeric' => "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [13] 262 'once' => "\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [14] 263 'overflow' => "\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [15] 264 'pack' => "\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [16] 265 'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [32] 266 'pipe' => "\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10] 267 'portable' => "\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [17] 268 'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [33] 269 'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00", # [34] 270 'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00", # [35] 271 'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [36] 272 'recursion' => "\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00", # [18] 273 'redefine' => "\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00", # [19] 274 'regexp' => "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00", # [20] 275 'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [37] 276 'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00", # [38] 277 'severe' => "\x00\x00\x00\x00\x00\xa8\x0a\x00\x00\x00\x00\x00", # [21..25] 278 'signal' => "\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00", # [26] 279 'substr' => "\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00", # [27] 280 'syntax' => "\x00\x00\x00\x00\x00\x00\x00\xaa\xaa\x2a\x00\x00", # [28..38] 281 'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [39] 282 'threads' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [40] 283 'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [41] 284 'unopened' => "\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11] 285 'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [42] 286 'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00", # [43] 287 'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [44] 288 'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [45] 289 ); 290 291$NONE = "\0\0\0\0\0\0\0\0\0\0\0\0"; 292$LAST_BIT = 92 ; 293$BYTES = 12 ; 294 295$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ; 296 297sub Croaker 298{ 299 require Carp::Heavy; # this initializes %CarpInternal 300 local $Carp::CarpInternal{'warnings'}; 301 delete $Carp::CarpInternal{'warnings'}; 302 Carp::croak(@_); 303} 304 305sub bits 306{ 307 # called from B::Deparse.pm 308 309 push @_, 'all' unless @_; 310 311 my $mask; 312 my $catmask ; 313 my $fatal = 0 ; 314 my $no_fatal = 0 ; 315 316 foreach my $word ( @_ ) { 317 if ($word eq 'FATAL') { 318 $fatal = 1; 319 $no_fatal = 0; 320 } 321 elsif ($word eq 'NONFATAL') { 322 $fatal = 0; 323 $no_fatal = 1; 324 } 325 elsif ($catmask = $Bits{$word}) { 326 $mask |= $catmask ; 327 $mask |= $DeadBits{$word} if $fatal ; 328 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ; 329 } 330 else 331 { Croaker("Unknown warnings category '$word'")} 332 } 333 334 return $mask ; 335} 336 337sub import 338{ 339 shift; 340 341 my $catmask ; 342 my $fatal = 0 ; 343 my $no_fatal = 0 ; 344 345 my $mask = ${^WARNING_BITS} ; 346 347 if (vec($mask, $Offsets{'all'}, 1)) { 348 $mask |= $Bits{'all'} ; 349 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1); 350 } 351 352 push @_, 'all' unless @_; 353 354 foreach my $word ( @_ ) { 355 if ($word eq 'FATAL') { 356 $fatal = 1; 357 $no_fatal = 0; 358 } 359 elsif ($word eq 'NONFATAL') { 360 $fatal = 0; 361 $no_fatal = 1; 362 } 363 elsif ($catmask = $Bits{$word}) { 364 $mask |= $catmask ; 365 $mask |= $DeadBits{$word} if $fatal ; 366 $mask &= ~($DeadBits{$word}|$All) if $no_fatal ; 367 } 368 else 369 { Croaker("Unknown warnings category '$word'")} 370 } 371 372 ${^WARNING_BITS} = $mask ; 373} 374 375sub unimport 376{ 377 shift; 378 379 my $catmask ; 380 my $mask = ${^WARNING_BITS} ; 381 382 if (vec($mask, $Offsets{'all'}, 1)) { 383 $mask |= $Bits{'all'} ; 384 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1); 385 } 386 387 push @_, 'all' unless @_; 388 389 foreach my $word ( @_ ) { 390 if ($word eq 'FATAL') { 391 next; 392 } 393 elsif ($catmask = $Bits{$word}) { 394 $mask &= ~($catmask | $DeadBits{$word} | $All); 395 } 396 else 397 { Croaker("Unknown warnings category '$word'")} 398 } 399 400 ${^WARNING_BITS} = $mask ; 401} 402 403my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = (); 404 405sub __chk 406{ 407 my $category ; 408 my $offset ; 409 my $isobj = 0 ; 410 411 if (@_) { 412 # check the category supplied. 413 $category = shift ; 414 if (my $type = ref $category) { 415 Croaker("not an object") 416 if exists $builtin_type{$type}; 417 $category = $type; 418 $isobj = 1 ; 419 } 420 $offset = $Offsets{$category}; 421 Croaker("Unknown warnings category '$category'") 422 unless defined $offset; 423 } 424 else { 425 $category = (caller(1))[0] ; 426 $offset = $Offsets{$category}; 427 Croaker("package '$category' not registered for warnings") 428 unless defined $offset ; 429 } 430 431 my $this_pkg = (caller(1))[0] ; 432 my $i = 2 ; 433 my $pkg ; 434 435 if ($isobj) { 436 while (do { { package DB; $pkg = (caller($i++))[0] } } ) { 437 last unless @DB::args && $DB::args[0] =~ /^$category=/ ; 438 } 439 $i -= 2 ; 440 } 441 else { 442 $i = _error_loc(); # see where Carp will allocate the error 443 } 444 445 my $callers_bitmask = (caller($i))[9] ; 446 return ($callers_bitmask, $offset, $i) ; 447} 448 449sub _error_loc { 450 require Carp::Heavy; 451 goto &Carp::short_error_loc; # don't introduce another stack frame 452} 453 454sub enabled 455{ 456 Croaker("Usage: warnings::enabled([category])") 457 unless @_ == 1 || @_ == 0 ; 458 459 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 460 461 return 0 unless defined $callers_bitmask ; 462 return vec($callers_bitmask, $offset, 1) || 463 vec($callers_bitmask, $Offsets{'all'}, 1) ; 464} 465 466 467sub warn 468{ 469 Croaker("Usage: warnings::warn([category,] 'message')") 470 unless @_ == 2 || @_ == 1 ; 471 472 my $message = pop ; 473 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 474 require Carp; 475 Carp::croak($message) 476 if vec($callers_bitmask, $offset+1, 1) || 477 vec($callers_bitmask, $Offsets{'all'}+1, 1) ; 478 Carp::carp($message) ; 479} 480 481sub warnif 482{ 483 Croaker("Usage: warnings::warnif([category,] 'message')") 484 unless @_ == 2 || @_ == 1 ; 485 486 my $message = pop ; 487 my ($callers_bitmask, $offset, $i) = __chk(@_) ; 488 489 return 490 unless defined $callers_bitmask && 491 (vec($callers_bitmask, $offset, 1) || 492 vec($callers_bitmask, $Offsets{'all'}, 1)) ; 493 494 require Carp; 495 Carp::croak($message) 496 if vec($callers_bitmask, $offset+1, 1) || 497 vec($callers_bitmask, $Offsets{'all'}+1, 1) ; 498 499 Carp::carp($message) ; 500} 501 5021; 503# ex: set ro: 504