11 # --make-exceptions-list outputs the list of strings that don't have
12 # perldiag.pod entries to STDERR without TAP formatting, so they can
13 # easily be put in the __DATA__ section of this file. This was done
14 # initially so as to not create new test failures upon the initial
15 # creation of this test file. You probably shouldn't do it again.
16 # Just add the documentation instead.
17 my $make_exceptions_list = ($ARGV[0]||'') eq '--make-exceptions-list';
19 chdir '..' or die "Can't chdir ..: $!";
20 BEGIN { defined $ENV{PERL_UNICODE} and push @INC, "lib"; }
24 open my $func_fh, "<", "embed.fnc" or die "Can't open embed.fnc: $!";
26 # Look for functions in embed.fnc that look like they could be diagnostic ones.
30 while (s/\s*\\$//) { # Grab up all continuation lines, these end in \
31 my $next = <$func_fh>;
36 next if /^:/; # Lines beginning with colon are comments.
37 next unless /\|/; # Lines without a vertical bar are something we can't deal
39 my @fields = split /\s*\|\s*/;
40 next unless $fields[2] =~ /warn|err|(\b|_)die|croak/i;
41 push @functions, $fields[2];
43 # The flag p means that this function may have a 'Perl_' prefix
44 # The flag s means that this function may have a 'S_' prefix
45 push @functions, "Perl_$fields[2]", if $fields[0] =~ /p/;
46 push @functions, "S_$fields[2]", if $fields[0] =~ /s/;
51 my $function_re = join '|', @functions;
52 my $source_msg_re = qr/(?<routine>\bDIE\b|$function_re)/;
56 # Get the ignores that are compiled into this file
62 my $pod = "pod/perldiag.pod";
64 open my $diagfh, "<", $pod
65 or die "Can't open $pod: $!";
67 my $category_re = qr/ [a-z0-9]+?/; # Note: requires an initial space
68 my $severity_re = qr/ . (?: \| . )* /x; # A severity is a single char, but can
69 # be of the form 'S|P|W'
74 if (exists $entries{$cur_entry}) {
76 diag(" Remove the TODO entry \"$cur_entry\",\n"
77 . " from $0 as it is already in $pod near line $.");
79 # Make sure to init this here, so an actual entry in perldiag
80 # overwrites one in DATA.
81 $entries{$cur_entry}{todo} = 0;
82 $entries{$cur_entry}{line_number} = $.;
86 next if ! defined $cur_entry;
88 if (! $entries{$cur_entry}{severity}) {
89 if (/^ \( ( $severity_re )
91 # Can have multiple categories separated by commas
92 (?: ( $category_re ) (?: , $category_re)* )? \) /x)
94 $entries{$cur_entry}{severity} = $1;
95 $entries{$cur_entry}{category} = $2;
97 elsif (! $entries{$cur_entry}{first_line} && $_ =~ /\S/) {
99 # Keep track of first line of text if doesn't contain a severity, so
100 # that can later examine it to determine if that is ok or not
101 $entries{$cur_entry}{first_line} = $_;
106 foreach my $cur_entry ( keys %entries) {
107 next if $entries{$cur_entry}{todo}; # If in this file, won't have a severity
108 if (! exists $entries{$cur_entry}{severity}
110 # If there is no first line, it was two =items in a row, so the
111 # second one is the one with with text, not this one.
112 && exists $entries{$cur_entry}{first_line}
114 # If the first line refers to another message, no need for severity
115 && $entries{$cur_entry}{first_line} !~ /^See/)
119 " $pod entry at line $entries{$cur_entry}{line_number}\n"
120 . " \"$cur_entry\"\n"
121 . " is missing a severity and/or category"
126 # Recursively descend looking for source files.
129 my $todo = shift @todo;
130 next if $todo ~~ ['t', 'lib', 'ext', 'dist', 'cpan'];
131 # opmini.c is just a copy of op.c, so there's no need to check again.
132 next if $todo eq 'opmini.c';
134 unshift @todo, sort glob "$todo/*";
135 } elsif ($todo =~ m/\.[ch]$/) {
142 my $text_re = qr/"(?<text>(?:\\"|[^"])*?)"/;
143 if ($line =~ m/$source_msg_re(?:_nocontext)? \s*
145 (?:packWARN\d*\((?<category>.*?)\),)? \s*
148 return [$+{'text'}, $+{'category'}];
150 elsif ( $line =~ m{BADVERSION\([^"]*$text_re}) {
151 return [$+{'text'}, undef];
156 # Standardize messages with variants into the form that appears
157 # in perldiag.pod -- useful for things without a diag_listed_as annotation
161 if ( $name =~ m/^(Invalid strict version format) \([^\)]*\)/ ) {
164 elsif ( $name =~ m/^(Invalid version format) \([^\)]*\)/ ) {
167 elsif ($name =~ m/^panic: /) {
168 $name = "panic: \%s";
177 print "# Checking $codefn\n";
179 open my $codefh, "<", $codefn
180 or die "Can't open $codefn: $!";
184 my $sub = 'top of file';
187 # Getting too much here isn't a problem; we only use this to skip
188 # errors inside of XS modules, which should get documented in the
189 # docs for the module.
190 if (m<^([^#\s].*)> and $1 !~ m/^[{}]*$/) {
193 next if $sub =~ m/^XS/;
194 if (m</\* diag_listed_as: (.*) \*/>) {
196 $listed_as_line = $.+1;
202 # Loop to accumulate the message text all on one line.
203 while (m/$source_msg_re/ and not m/\);$/) {
204 my $nextline = <$codefh>;
205 # Means we fell off the end of the file. Not terribly surprising;
206 # this code tries to merge a lot of things that aren't regular C
207 # code (preprocessor stuff, long comments). That's OK; we don't
209 last if not defined $nextline;
211 $nextline =~ s/^\s+//;
212 # Note that we only want to do this where *both* are true.
214 if ($_ =~ m/"$/ and $nextline =~ m/^"/) {
221 # This should happen *after* unwrapping, or we don't reformat the things
223 # List from perlguts.pod "Formatted Printing of IVs, UVs, and NVs"
224 # Convert from internal formats to ones that the readers will be familiar
225 # with, while removing any format modifiers, such as precision, the
226 # presence of which would just confuse the pod's explanation
227 my %specialformats = (IVdf => 'd',
236 my $format_modifiers = qr/ [#0\ +-]* # optional flags
237 (?: [1-9][0-9]* | \* )? # optional field width
238 (?: \. \d* )? # optional precision
239 (?: h|l )? # optional length modifier
241 for my $from (keys %specialformats) {
242 s/%$format_modifiers"\s*$from\s*"/\%$specialformats{$from}/g;
243 s/%$format_modifiers"\s*$from/\%$specialformats{$from}"/g;
246 # Remove any remaining format modifiers, but not in %%
247 s/ (?<!%) % $format_modifiers ( [dioxXucsfeEgGp] ) /%$1/xg;
249 # The %"foo" thing needs to happen *before* this regex.
250 if ( my $found = find_message($_) ) {
252 # DIE is just return Perl_die
253 my ($name, $category) = @$found;
254 my $severity = {croak => [qw/P F/],
257 }->{$+{'routine'}||'die'};
259 if (defined $category) {
260 @categories = map {s/^WARN_//; lc $_} split /\s*[|,]\s*/, $category;
262 if ($listed_as and $listed_as_line == $. - $multiline) {
265 # The form listed in perldiag ignores most sorts of fancy printf
266 # formatting, or makes it more perlish.
268 $name =~ s/%l[ud]/%d/g;
269 $name =~ s/%\.(\d+|\*)s/\%s/g;
274 $name =~ s/(\\)\\/$1/g;
277 # Extra explanatory info on an already-listed error, doesn't
278 # need it's own listing.
279 next if $name =~ m/^\t/;
281 # Happens fairly often with PL_no_modify.
282 next if $name eq '%s';
284 # Special syntax for magic comment, allows ignoring the fact
285 # that it isn't listed. Only use in very special circumstances,
286 # like this script failing to notice that the Perl_croak call is
287 # inside an #if 0 block.
288 next if $name eq 'SKIPME';
290 $name = standardize($name);
292 if (exists $entries{$name}) {
293 if ( $entries{$name}{seen}++ ) {
294 # no need to repeat entries we've tested
295 } elsif ($entries{$name}{todo}) {
298 local $::TODO = 'in DATA';
299 # There is no listing, but it is in the list of exceptions. TODO FAIL.
302 " Message '$name'\n from $codefn line $. is not listed in $pod\n".
303 " (but it wasn't documented in 5.10 either, so marking it TODO)."
307 # We found an actual valid entry in perldiag.pod for this error.
310 # Later, should start checking that the severity is correct, too.
312 if ($make_exceptions_list) {
313 # We're making an updated version of the exception list, to
314 # stick in the __DATA__ section. I honestly can't think of
315 # a situation where this is the right thing to do, but I'm
316 # leaving it here, just in case one of my descendents thinks
318 print STDERR "$name\n";
320 # No listing found, and no excuse either.
321 # Find the correct place in perldiag.pod, and add a stanza beginning =item $name.
323 diag(" Message '$name'\n from $codefn line $. is not listed in $pod");
325 # seen it, so only fail once for this message
326 $entries{$name}{seen}++;
329 die if $name =~ /%$/;
333 # Lists all missing things as of the inauguration of this script, so we
334 # don't have to go from "meh" to perfect all at once.
336 # PLEASE DO NOT ADD TO THIS LIST. Instead, write an entry in
337 # pod/perldiag.pod for your new (warning|error).
339 # Also FIXME this test, as the first entry in TODO *is* covered by the
340 # description: Malformed UTF-8 character (%s)
342 Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
344 %s (%d) does not match %s (%d),
345 %s (%d) smaller than %s (%d),
346 Argument "%s" isn't numeric
347 Argument "%s" isn't numeric in %s
348 Attempt to clear deleted array
349 Attempt to free non-existent shared string '%s'%s
350 Attempt to free temp prematurely: SV 0x%x
351 Attempt to free unreferenced scalar: SV 0x%x
352 Attempt to reload %s aborted. Compilation failed in require
353 av_reify called on tied array
356 bad top format reference
360 Can't call method "%s" %s
361 Can't coerce readonly %s to string
362 Can't coerce readonly %s to string in %s
363 Can't fix broken locale name "%s"
364 Can't get short module name from a handle
365 Can't goto subroutine from an eval-block
366 Can't goto subroutine from an eval-string
367 Can't locate object method "%s" via package "%s" (perhaps you forgot to load "%s"?)
368 Can't modify non-existent substring
370 Can't open perl script "%s": %s
372 Can't reset \%ENV on this system
373 Can't return array to lvalue scalar context
374 Can't return a %s from lvalue subroutine
375 Can't return hash to lvalue scalar context
377 Can't %s script `%s' with ARGV[0] being `%s'
380 Can't %s `%s' with ARGV[0] being `%s' (looking for executables only, not found)
382 Can't use '%c' after -mname
383 Can't use string ("%s"%s) as a subroutine ref while "strict refs" in use
384 Can't use when() outside a topicalizer
385 \%c better written as $%c
386 Character(s) in '%c' format wrapped in %s
387 $%c is no longer supported
388 Cloning substitution context is unimplemented
389 Code missing after '/' in pack
390 Code missing after '/' in unpack
391 Corrupted regexp opcode %d > %d
392 '%c' outside of string in pack
393 Debug leaking scalars child failed%s%s with errno %d: %s
394 Deep recursion on anonymous subroutine
395 defined(\%hash) is deprecated
396 Don't know how to handle magic of type \%o
397 -Dp not implemented on this platform
398 entering effective gid failed
399 entering effective uid failed
400 Error reading "%s": %s
402 Filehandle opened only for %sput
403 Filehandle %s opened only for %sput
404 Filehandle STD%s reopened as %s only for input
405 YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET! FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!
406 Format STDOUT redefined
407 Free to wrong pool %p not %p
409 glob failed (can't start child: %s)
410 glob failed (child exited with status %d%s)
411 Goto undefined subroutine
412 Goto undefined subroutine &%s
413 Hash \%%s missing the \% in argument %d of %s()
414 Illegal character %sin prototype for %s : %s
415 Integer overflow in binary number
416 Integer overflow in decimal number
417 Integer overflow in hexadecimal number
418 Integer overflow in octal number
419 Integer overflow in version %d
420 internal \%<num>p might conflict with future printf extensions
421 invalid control request: '\%o'
422 Invalid module name %s with -%c option: contains single ':'
423 invalid option -D%c, use -D'' to see choices
424 Invalid range "%c-%c" in transliteration operator
425 Invalid separator character %c%c%c in PerlIO layer specification %s
426 Invalid TOKEN object ignored
427 Invalid type '%c' in pack
428 Invalid type '%c' in %s
429 Invalid type '%c' in unpack
430 Invalid type ',' in %s
431 It is proposed that "\c{" no longer be valid. It has historically evaluated to ";". If you disagree with this proposal, send email to perl5-porters@perl.org Otherwise, or in the meantime, you can work around this failure by changing "\c{" to ";"
432 'j' not supported on this platform
433 'J' not supported on this platform
434 leaving effective gid failed
435 leaving effective uid failed
436 List form of piped open not implemented
437 Lost precision when decrementing %f by 1
438 Lost precision when incrementing %f by 1
440 Malformed UTF-8 character (fatal)
441 '\%' may not be used in pack
442 Missing (suid) fd script name
443 More than one argument to open
444 More than one argument to open(,':%s')
445 mprotect for %p %u failed with %d
446 mprotect RW for %p %u failed with %d
447 No code specified for -%c
448 No directory specified for -I
449 No such class field "%s"
450 Not an XSUB reference
452 Operator or semicolon missing before %c%s
453 Perl %s required (did you mean %s?)--this is only %s, stopped
454 Perl %s required--this is only %s, stopped
455 Perls since %s too modern--this is %s, stopped
456 ptr wrong %p != %p fl=%x nl=%p e=%p for %d
457 Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)
458 Recursive call to Perl_load_module in PerlIO_find_layer
459 refcnt_dec: fd %d < 0
460 refcnt_dec: fd %d: %d <= 0
461 refcnt_dec: fd %d >= refcnt_size %d
462 refcnt_inc: fd %d < 0
463 refcnt_inc: fd %d: %d <= 0
464 Reversed %c= operator
470 Scalar value %s better written as $%s
471 %sCompilation failed in regexp
472 %sCompilation failed in require
474 %s free() ignored (RMAGIC, PERL_CORE)
475 %s has too many errors.
476 SIG%s handler "%s" not defined.
477 %s: illegal mapping '%s'
479 Size magic not implemented
480 %s limit (%d) exceeded
481 %s method "%s" overloading "%s" in package "%s"
482 %s number > %s non-portable
483 %s object version %s does not match %s%s%s%s %s
484 %srealloc() %signored
485 %s returned from lvalue subroutine in scalar context
486 %s%s has too many errors.
489 Starting Full Screen process with flag=%d, mytype=%d
490 Starting PM process with flag=%d, mytype=%d
491 strxfrm() gets absurd
492 SWASHNEW didn't return an HV ref
493 -T and -B not implemented on filehandles
494 The flock() function is not implemented on NetWare
495 The rewinddir() function is not implemented on NetWare
496 The seekdir() function is not implemented on NetWare
497 The stat preceding lstat() wasn't an lstat
498 The telldir() function is not implemented on NetWare
499 Too deeply nested ()-groups in %s
500 Too late to run CHECK block
501 Too late to run INIT block
502 Too many args on %s line of "%s"
503 U0 mode on a byte string
504 Unbalanced string table refcount: (%d) for "%s"
505 Undefined top format called
506 Unexpected constant lvalue entersub entry via type/targ %d:%d
507 Unicode non-character 0x%X
508 Unknown PerlIO layer "scalar"
509 Unstable directory path, current directory changed unexpectedly
510 Unsupported script encoding UTF-16BE
511 Unsupported script encoding UTF-16LE
512 Unsupported script encoding UTF-32BE
513 Unsupported script encoding UTF-32LE
514 Unterminated compressed integer in unpack
515 Usage: CODE(0x%x)(%s)
518 Usage: VMS::Filespec::unixrealpath(spec)
519 Usage: VMS::Filespec::vmsrealpath(spec)
520 Use of inherited AUTOLOAD for non-method %s::%s() is deprecated
521 utf8 "\x%X" does not map to Unicode
522 Value of logical "%s" too long. Truncating to %i bytes
523 value of node is %d in Offset macro
524 Value of %s%s can be "0"; test with defined()
525 Variable "%c%s" is not imported
526 vector argument not supported with alpha versions
529 Wide character in print
530 Within []-length '%c' not allowed in %s
531 Wrong syntax (suid) fd script name "%s"
532 'X' outside of string in unpack