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