Move the #7390 test from warn/op to comp/redef.
[p5sagit/p5-mst-13.2.git] / lib / warnings.pm
CommitLineData
599cee73 1
4438c4b7 2# This file was created by warnings.pl
599cee73 3# Any changes made here will be lost.
4#
5
4438c4b7 6package warnings;
599cee73 7
8=head1 NAME
9
4438c4b7 10warnings - Perl pragma to control optional warnings
599cee73 11
12=head1 SYNOPSIS
13
4438c4b7 14 use warnings;
15 no warnings;
599cee73 16
4438c4b7 17 use warnings "all";
18 no warnings "all";
599cee73 19
d3a7d8c7 20 use warnings::register;
21 if (warnings::enabled()) {
22 warnings::warn("some warning");
23 }
24
25 if (warnings::enabled("void")) {
e476b1b5 26 warnings::warn("void", "some warning");
27 }
28
7e6d00f8 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
599cee73 37=head1 DESCRIPTION
38
0453d815 39If no import list is supplied, all possible warnings are either enabled
40or disabled.
599cee73 41
d3a7d8c7 42A number of functions are provided to assist module authors.
e476b1b5 43
44=over 4
45
d3a7d8c7 46=item use warnings::register
47
7e6d00f8 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.
e476b1b5 88
7e6d00f8 89=item warnings::warn($object, $message)
e476b1b5 90
7e6d00f8 91Print C<$message> to STDERR.
e476b1b5 92
7e6d00f8 93Use the name of the class for the object reference, C<$object>, as the
94warnings category.
d3a7d8c7 95
7e6d00f8 96If that warnings category has been set to "FATAL" in the scope where C<$object>
97is first used then die. Otherwise return.
599cee73 98
e476b1b5 99
7e6d00f8 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) }
d3a7d8c7 120
e476b1b5 121=back
122
749f83fa 123See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
599cee73 124
125=cut
126
127use Carp ;
128
d3a7d8c7 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
599cee73 179%Bits = (
d3a7d8c7 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]
599cee73 227 );
228
229%DeadBits = (
d3a7d8c7 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]
599cee73 277 );
278
d3a7d8c7 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 ;
599cee73 284
285sub bits {
286 my $mask ;
287 my $catmask ;
288 my $fatal = 0 ;
289 foreach my $word (@_) {
327afb7f 290 if ($word eq 'FATAL') {
291 $fatal = 1;
292 }
d3a7d8c7 293 elsif ($catmask = $Bits{$word}) {
294 $mask |= $catmask ;
295 $mask |= $DeadBits{$word} if $fatal ;
599cee73 296 }
d3a7d8c7 297 else
298 { croak("unknown warnings category '$word'")}
599cee73 299 }
300
301 return $mask ;
302}
303
304sub import {
305 shift;
f1f33818 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') ;
599cee73 312}
313
314sub unimport {
315 shift;
d3a7d8c7 316 my $mask = ${^WARNING_BITS} ;
317 if (vec($mask, $Offsets{'all'}, 1)) {
f1f33818 318 $mask |= $Bits{'all'} ;
d3a7d8c7 319 $mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
320 }
321 ${^WARNING_BITS} = $mask & ~ (bits(@_ ? @_ : 'all') | $All) ;
599cee73 322}
323
7e6d00f8 324sub __chk
599cee73 325{
d3a7d8c7 326 my $category ;
327 my $offset ;
7e6d00f8 328 my $isobj = 0 ;
d3a7d8c7 329
330 if (@_) {
331 # check the category supplied.
332 $category = shift ;
7e6d00f8 333 if (ref $category) {
334 croak ("not an object")
335 if $category !~ /^([^=]+)=/ ;+
336 $category = $1 ;
337 $isobj = 1 ;
338 }
d3a7d8c7 339 $offset = $Offsets{$category};
340 croak("unknown warnings category '$category'")
341 unless defined $offset;
342 }
343 else {
7e6d00f8 344 $category = (caller(1))[0] ;
d3a7d8c7 345 $offset = $Offsets{$category};
346 croak("package '$category' not registered for warnings")
347 unless defined $offset ;
348 }
349
7e6d00f8 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 ;
d3a7d8c7 380 return vec($callers_bitmask, $offset, 1) ||
381 vec($callers_bitmask, $Offsets{'all'}, 1) ;
599cee73 382}
383
d3a7d8c7 384
e476b1b5 385sub warn
386{
d3a7d8c7 387 croak("Usage: warnings::warn([category,] 'message')")
388 unless @_ == 2 || @_ == 1 ;
d3a7d8c7 389
7e6d00f8 390 my $message = pop ;
391 my ($callers_bitmask, $offset, $i) = __chk(@_) ;
392 local $Carp::CarpLevel = $i ;
e476b1b5 393 croak($message)
d3a7d8c7 394 if vec($callers_bitmask, $offset+1, 1) ||
395 vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
e476b1b5 396 carp($message) ;
397}
398
7e6d00f8 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}
599cee73 4191;