4 @INC = '..' if -f '../TestInit.pm';
6 use TestInit qw(T); # T is chdir to the top level
12 require './t/test.pl';
14 if ( $Config{usecrosscompile} ) {
15 skip_all( "Not all files are available during cross-compilation" );
20 # --make-exceptions-list outputs the list of strings that don't have
21 # perldiag.pod entries to STDERR without TAP formatting, so they can
22 # easily be put in the __DATA__ section of this file. This was done
23 # initially so as to not create new test failures upon the initial
24 # creation of this test file. You probably shouldn't do it again.
25 # Just add the documentation instead.
26 my $make_exceptions_list = ($ARGV[0]||'') eq '--make-exceptions-list'
29 require './regen/embed_lib.pl';
31 # Look for functions that look like they could be diagnostic ones.
33 foreach (@{(setup_embed())[0]}) {
35 next unless $_->[2] =~ /warn|(?<!ov)err|(\b|_)die|croak/i;
36 # The flag p means that this function may have a 'Perl_' prefix
37 # The flag s means that this function may have a 'S_' prefix
38 push @functions, $_->[2];
39 push @functions, 'Perl_' . $_->[2] if $_->[0] =~ /p/;
40 push @functions, 'S_' . $_->[2] if $_->[0] =~ /s/;
42 push @functions, 'Perl_mess';
44 my $regcomp_fail_re = '\b(?:(?:Simple_)?v)?FAIL[2-4]?(?:utf8f)?\b';
46 "(?<routine>ckWARN(?:\\d+)?reg\\w*|vWARN\\d+|$regcomp_fail_re)";
47 my $function_re = join '|', @functions;
49 "(?<routine>\\bDIE\\b|$function_re)";
50 my $text_re = '"(?<text>(?:\\\\"|[^"]|"\s*[A-Z_]+\s*")*)"';
51 my $source_msg_call_re = qr/$source_msg_re(?:_nocontext)? \s*
52 \( (?: \s* Perl_form \( )? (?:aTHX_)? \s*
53 (?:packWARN\d*\((?<category>.*?)\),)? \s*
55 my $bad_version_re = qr{BADVERSION\([^"]*$text_re};
56 $regcomp_fail_re = qr/$regcomp_fail_re\([^"]*$text_re/;
57 my $regcomp_call_re = qr/$regcomp_re.*?$text_re/;
61 # Get the ignores that are compiled into this file
62 my $reading_categorical_exceptions;
65 $entries{$_}{todo} = 1;
66 $reading_categorical_exceptions and $entries{$_}{cattodo}=1;
67 /__CATEGORIES__/ and ++$reading_categorical_exceptions;
70 my $pod = "pod/perldiag.pod";
72 open my $diagfh, "<", $pod
73 or die "Can't open $pod: $!";
75 my $category_re = qr/ [a-z0-9_:]+?/; # Note: requires an initial space
76 my $severity_re = qr/ . (?: \| . )* /x; # A severity is a single char, but can
77 # be of the form 'S|P|W'
83 # Allow multi-line headers
89 $cur_entry =~ s/ ?\z/ $_/;
92 $cur_entry =~ s/\n/ /gs; # Fix multi-line headers if they have \n's
93 $cur_entry =~ s/\s+\z//;
94 $cur_entry =~ s/E<lt>/</g;
95 $cur_entry =~ s/E<gt>/>/g;
96 $cur_entry =~ s,E<sol>,/,g;
97 $cur_entry =~ s/[BCIFS](?:<<< (.*?) >>>|<< (.*?) >>|<(.*?)>)/$+/g;
99 if (exists $entries{$cur_entry} && $entries{$cur_entry}{todo}
100 && !$entries{$cur_entry}{cattodo}) {
102 local $::TODO = "Remove the TODO entry \"$cur_entry\" from DATA as it is already in $pod near line $.";
106 # Make sure to init this here, so an actual entry in perldiag
107 # overwrites one in DATA.
108 $entries{$cur_entry}{todo} = 0;
109 $entries{$cur_entry}{line_number} = $.;
112 next if ! defined $cur_entry;
114 if (! $entries{$cur_entry}{severity}) {
115 if (/^ \( ( $severity_re )
117 # Can have multiple categories separated by commas
118 ( $category_re (?: , $category_re)* )? \) /x)
120 $entries{$cur_entry}{severity} = $1;
121 $entries{$cur_entry}{category} =
122 $2 && join ", ", sort split " ", $2 =~ y/,//dr;
124 # Record it also for other messages sharing the same description
125 @$_{qw<severity category>} =
126 @{$entries{$cur_entry}}{qw<severity category>}
129 elsif (! $entries{$cur_entry}{first_line} && $_ =~ /\S/) {
131 # Keep track of first line of text if doesn't contain a severity, so
132 # that can later examine it to determine if that is ok or not
133 $entries{$cur_entry}{first_line} = $_;
139 push @same_descr, $entries{$cur_entry};
144 foreach my $cur_entry ( keys %entries) {
145 next if $entries{$cur_entry}{todo}; # If in this file, won't have a severity
146 if (! exists $entries{$cur_entry}{severity}
148 # If there is no first line, it was two =items in a row, so the
149 # second one is the one with with text, not this one.
150 && exists $entries{$cur_entry}{first_line}
152 # If the first line refers to another message, no need for severity
153 && $entries{$cur_entry}{first_line} !~ /^See/)
157 " $pod entry at line $entries{$cur_entry}{line_number}\n"
158 . " \"$cur_entry\"\n"
159 . " is missing a severity and/or category"
164 # List from perlguts.pod "Formatted Printing of IVs, UVs, and NVs"
165 # Convert from internal formats to ones that the readers will be familiar
166 # with, while removing any format modifiers, such as precision, the
167 # presence of which would just confuse the pod's explanation
168 my %specialformats = (IVdf => 'd',
183 my $format_modifiers = qr/ [#0\ +-]* # optional flags
184 (?: [1-9][0-9]* | \* )? # optional field width
185 (?: \. \d* )? # optional precision
186 (?: h|l )? # optional length modifier
190 join '|', sort { length $b cmp length $a } keys %specialformats;
191 my $specialformats_re = qr/%$format_modifiers"\s*($specialformats)(\s*")?/;
194 check_file($_) for @ARGV;
197 open my $fh, '<', 'MANIFEST' or die "Can't open MANIFEST: $!";
198 while (my $file = <$fh>) {
201 next unless $file =~ /\.(?:c|cpp|h|xs|y)\z/ or $file =~ /^perly\./;
202 # OS/2 extensions have never been migrated to ext/, hence the special case:
203 next if $file =~ m!\A(?:ext|dist|cpan|lib|t|os2/OS2)/!
204 && $file !~ m!\Aext/DynaLoader/!;
209 # Standardize messages with variants into the form that appears
210 # in perldiag.pod -- useful for things without a diag_listed_as annotation
214 if ( $name =~ m/^(Invalid strict version format) \([^\)]*\)/ ) {
217 elsif ( $name =~ m/^(Invalid version format) \([^\)]*\)/ ) {
220 elsif ($name =~ m/^panic: /) {
221 $name = "panic: \%s";
230 print "# Checking $codefn\n";
232 open my $codefh, "<", $codefn
233 or die "Can't open $codefn: $!";
237 my $sub = 'top of file';
240 # Getting too much here isn't a problem; we only use this to skip
241 # errors inside of XS modules, which should get documented in the
242 # docs for the module.
243 if (m<^[^#\s]> and $_ !~ m/^[{}]*$/) {
246 next if $sub =~ m/^XS/;
247 if (m</\*\s*diag_listed_as: (.*?)\s*\*/>) {
249 $listed_as_line = $.+1;
251 elsif (m</\*\s*diag_listed_as: (.*?)\s*\z>) {
256 $listed_as .= $` =~ s/^\s*/ /r =~ s/\s+\z//r;
257 $listed_as_line = $.+1;
262 $listed_as .= s/^\s*/ /r =~ s/\s+\z//r;
265 if (!$finished) { $listed_as = undef }
270 # Loop to accumulate the message text all on one line.
271 if (m/(?!^)\b(?:$source_msg_re(?:_nocontext)?|$regcomp_re)\s*\(/) {
272 while (not m/\);\s*$/) {
273 my $nextline = <$codefh>;
274 # Means we fell off the end of the file. Not terribly surprising;
275 # this code tries to merge a lot of things that aren't regular C
276 # code (preprocessor stuff, long comments). That's OK; we don't
278 last if not defined $nextline;
280 $nextline =~ s/^\s+//;
282 # Note that we only want to do this where *both* are true.
283 if ($_ =~ m/"\s*$/ and $nextline =~ m/^"/) {
291 # This should happen *after* unwrapping, or we don't reformat the things
294 s/$specialformats_re/"%$specialformats{$1}" . (defined $2 ? '' : '"')/ge;
296 # Remove any remaining format modifiers, but not in %%
297 s/ (?<!%) % $format_modifiers ( [dioxXucsfeEgGp] ) /%$1/xg;
299 # The %"foo" thing needs to happen *before* this regex.
301 # DIE is just return Perl_die
302 my ($name, $category, $routine);
303 if (/\b$source_msg_call_re/) {
304 ($name, $category, $routine) = ($+{'text'}, $+{'category'}, $+{'routine'});
305 # Sometimes the regexp will pick up too much for the category
306 # e.g., WARN_UNINITIALIZED), PL_warn_uninit_sv ... up to the next )
307 $category && $category =~ s/\).*//s;
308 # Special-case yywarn
309 /yywarn/ and $category = 'syntax';
310 if (/win32_croak_not_implemented\(/) {
311 $name .= " not implemented!"
314 elsif (/$bad_version_re/) {
315 ($name, $category) = ($+{'text'}, undef);
317 elsif (/$regcomp_fail_re/) {
318 # FAIL("foo") -> "foo in regex m/%s/"
319 # vFAIL("foo") -> "foo in regex; marked by <-- HERE in m/%s/"
320 ($name, $category) = ($+{'text'}, undef);
322 " in regex" . ("; marked by <-- HERE in" x /vFAIL/) . " m/%s/";
324 elsif (/$regcomp_call_re/) {
325 # vWARN/ckWARNreg("foo") -> "foo in regex; marked by <-- HERE in m/%s/
326 ($name, $category, $routine) = ($+{'text'}, undef, $+{'routine'});
327 $name .= " in regex; marked by <-- HERE in m/%s/";
328 $category = 'WARN_REGEXP';
329 if ($routine =~ /dep/) {
330 $category .= ',WARN_DEPRECATED';
337 # Try to guess what the severity should be. In the case of
338 # Perl_ck_warner and other _ck_ functions, we can tell whether it is
339 # a severe/default warning or no by the _d suffix. In the case of
340 # other warn functions we cannot tell, because Perl_warner may be pre-
341 # ceded by if(ckWARN) or if(ckWARN_d).
342 my $severity = !$routine ? '[PFX]'
343 : $routine =~ /warn.*_d\z/ ? '[DS]'
344 : $routine =~ /ck_warn/ ? 'W'
345 : $routine =~ /warner/ ? '[WDS]'
346 : $routine =~ /warn/ ? 'S'
347 : $routine =~ /ckWARN.*dep/ ? 'D'
348 : $routine =~ /ckWARN\d*reg_d/? 'S'
349 : $routine =~ /ckWARN\d*reg/ ? 'W'
350 : $routine =~ /vWARN\d/ ? '[WDS]'
353 if (defined $category) {
354 $category =~ s/__/::/g;
357 sort map {s/^WARN_//; lc $_} split /\s*[|,]\s*/, $category;
359 if ($listed_as and $listed_as_line == $. - $multiline) {
362 # The form listed in perldiag ignores most sorts of fancy printf
363 # formatting, or makes it more perlish.
365 $name =~ s/%l[ud]/%d/g;
366 $name =~ s/%\.(\d+|\*)s/\%s/g;
367 $name =~ s/(?:%s){2,}/%s/g;
368 $name =~ s/(\\")|("\s*[A-Z_]+\s*")/$1 ? '"' : '%s'/egg;
372 $name =~ s/(\\)\\/$1/g;
375 # Extra explanatory info on an already-listed error, doesn't
376 # need it's own listing.
377 next if $name =~ m/^\t/;
379 # Happens fairly often with PL_no_modify.
380 next if $name eq '%s';
382 # Special syntax for magic comment, allows ignoring the fact
383 # that it isn't listed. Only use in very special circumstances,
384 # like this script failing to notice that the Perl_croak call is
385 # inside an #if 0 block.
386 next if $name eq 'SKIPME';
388 next if $name=~/\[TESTING\]/; # ignore these as they are works in progress
390 check_message(standardize($name),$codefn,$severity,$categories);
395 my($name,$codefn,$severity,$categories,$partial) = @_;
396 my $key = $name =~ y/\n/ /r;
399 # Try to reduce printf() formats to simplest forms
400 # Really this should be matching %s, etc like diagnostics.pm does
403 $key =~ s/%[#0\-+]/%/g;
406 $key =~ s/\%(\d+|\*)/%/g;
409 $key =~ s/\%\.(\d+|\*)/%/g;
411 if (exists $entries{$key} and
412 # todo + cattodo means it is not found and it is not in the
413 # regular todo list, either
414 !$entries{$key}{todo} || !$entries{$key}{cattodo}) {
416 if ( $entries{$key}{seen}++ ) {
417 # no need to repeat entries we've tested
418 } elsif ($entries{$key}{todo}) {
421 local $::TODO = 'in DATA';
422 # There is no listing, but it is in the list of exceptions. TODO FAIL.
425 " Message '$name'\n from $codefn line $. is not listed in $pod\n".
426 " (but it wasn't documented in 5.10 either, so marking it TODO)."
430 # We found an actual valid entry in perldiag.pod for this error.
434 if $entries{$key}{cattodo};
436 # Now check the category and severity
438 # Cache our severity qr thingies
441 my $qr = $qrs{$severity} ||= qr/$severity/;
443 like($entries{$key}{severity}, $qr,
445 ? "severity is one of $severity for $key"
446 : "severity is $severity for $key");
448 is($entries{$key}{category}, $categories,
449 ($categories ? "categories are [$categories]" : "no category")
458 check_message($_,$codefn,$severity,$categories,1) or $ok = 0, last
459 for split /\n/, $name;
463 } elsif ($make_exceptions_list) {
464 # We're making an updated version of the exception list, to
465 # stick in the __DATA__ section. I honestly can't think of
466 # a situation where this is the right thing to do, but I'm
467 # leaving it here, just in case one of my descendents thinks
469 print STDERR "$key\n";
471 # No listing found, and no excuse either.
472 # Find the correct place in perldiag.pod, and add a stanza beginning =item $name.
474 diag(" Message '$name'\n from $codefn line $. is not listed in $pod");
476 # seen it, so only fail once for this message
477 $entries{$name}{seen}++;
480 die if $name =~ /%$/;
484 # Lists all missing things as of the inauguration of this script, so we
485 # don't have to go from "meh" to perfect all at once.
487 # PLEASE DO NOT ADD TO THIS LIST. Instead, write an entry in
488 # pod/perldiag.pod for your new (warning|error). Nevertheless,
489 # listing exceptions here when this script is not smart enough
490 # to recognize the messages is not so bad, as long as there are
491 # entries in perldiag.
493 # Entries after __CATEGORIES__ are those that are in perldiag but fail the
494 # severity/category test.
496 # Also FIXME this test, as the first entry in TODO *is* covered by the
497 # description: Malformed UTF-8 character (%s)
499 Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
501 Cannot apply "%s" in non-PerlIO perl
503 Can't find DLL name for the module `%s' by the handle %d, rc=%u=%x
504 Can't find string terminator %c%s%c anywhere before EOF
505 Can't fix broken locale name "%s"
506 Can't get short module name from a handle
507 Can't load DLL `%s', possible problematic module `%s'
510 Can't set type on DOS
513 Can't %s script `%s' with ARGV[0] being `%s'
515 Can't %s `%s' with ARGV[0] being `%s' (looking for executables only, not found)
516 Can't use string ("%s"%s) as a subroutine ref while "strict refs" in use
517 Character(s) in '%c' format wrapped in %s
518 chown not implemented!
520 Code missing after '/' in pack
521 Code missing after '/' in unpack
522 Could not find version 1.1 of winsock dll
523 Could not find version 2.0 of winsock dll
524 '%c' outside of string in pack
525 Debug leaking scalars child failed%s with errno %d: %s
526 detach of a thread which could not start
527 detach on an already detached thread
528 detach on a thread with a waiter
529 '/' does not take a repeat count in %s
530 -Dp not implemented on this platform
531 Empty array reference given to mod2fname
532 endhostent not implemented!
533 endnetent not implemented!
534 endprotoent not implemented!
535 endservent not implemented!
536 Error loading module '%s': %s
537 Error reading "%s": %s
538 execl not implemented!
539 EVAL without pos change exceeded limit in regex
540 Filehandle opened only for %sput
541 Filehandle %s opened only for %sput
542 Filehandle STD%s reopened as %s only for input
543 file_type not implemented on DOS
544 filter_del can only delete in reverse order (currently)
546 fork() not implemented!
547 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!
549 Free to wrong pool %p not %p
550 Function "endnetent" not implemented in this version of perl.
551 Function "endprotoent" not implemented in this version of perl.
552 Function "endservent" not implemented in this version of perl.
553 Function "getnetbyaddr" not implemented in this version of perl.
554 Function "getnetbyname" not implemented in this version of perl.
555 Function "getnetent" not implemented in this version of perl.
556 Function "getprotobyname" not implemented in this version of perl.
557 Function "getprotobynumber" not implemented in this version of perl.
558 Function "getprotoent" not implemented in this version of perl.
559 Function "getservbyport" not implemented in this version of perl.
560 Function "getservent" not implemented in this version of perl.
561 Function "getsockopt" not implemented in this version of perl.
562 Function "recvmsg" not implemented in this version of perl.
563 Function "sendmsg" not implemented in this version of perl.
564 Function "sethostent" not implemented in this version of perl.
565 Function "setnetent" not implemented in this version of perl.
566 Function "setprotoent" not implemented in this version of perl.
567 Function "setservent" not implemented in this version of perl.
568 Function "setsockopt" not implemented in this version of perl.
569 Function "tcdrain" not implemented in this version of perl.
570 Function "tcflow" not implemented in this version of perl.
571 Function "tcflush" not implemented in this version of perl.
572 Function "tcsendbreak" not implemented in this version of perl.
574 gethostent not implemented!
575 getnetbyaddr not implemented!
576 getnetbyname not implemented!
577 getnetent not implemented!
578 getprotoent not implemented!
579 getpwnam returned invalid UIC %o for user "%s"
580 getservent not implemented!
581 glob failed (can't start child: %s)
582 glob failed (child exited with status %d%s)
583 Got an error from DosAllocMem: %i
584 Goto undefined subroutine
585 Goto undefined subroutine &%s
587 ()-group starts with a count in %s
588 Illegal binary digit '%c' ignored
589 Illegal character %sin prototype for %s : %s
590 Illegal hexadecimal digit '%c' ignored
591 Illegal octal digit '%c' ignored
592 INSTALL_PREFIX too long: `%s'
593 Invalid argument to sv_cat_decode
594 Invalid range "%c-%c" in transliteration operator
595 Invalid separator character %c%c%c in PerlIO layer specification %s
596 Invalid TOKEN object ignored
597 Invalid type '%c' in pack
598 Invalid type '%c' in %s
599 Invalid type '%c' in unpack
600 Invalid type ',' in %s
601 ioctl implemented only on sockets
602 ioctlsocket not implemented!
603 join with a thread with a waiter
604 killpg not implemented!
605 List form of pipe open not implemented
606 Looks like we have no PM; will not load DLL %s without $ENV{PERL_ASIF_PM}
607 Malformed integer in [] in %s
609 Malformed UTF-8 character (fatal)
610 Missing (suid) fd script name
611 More than one argument to open
612 More than one argument to open(,':%s')
614 No %s allowed while running setgid
615 No %s allowed with (suid) fdscript
616 Not an XSUB reference
617 Not a reference given to mod2fname
618 Not array reference given to mod2fname
619 Operator or semicolon missing before %c%s
620 Out of memory during list extend
623 PerlApp::TextQuery: no arguments, please
624 POSIX syntax [%c %c] is reserved for future extensions in regex; marked by <-- HERE in m/%s/
625 ptr wrong %p != %p fl=%x nl=%p e=%p for %d
627 Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)
628 recursion detected in %s
629 Regexp *+ operand could be empty in regex; marked by <-- HERE in m/%s/
630 Reversed %c= operator
631 %s: Can't parse EXE/DLL name: '%s'
633 %sCompilation failed in require
634 %s: Error stripping dirs from EXE/DLL/INSTALLDIR name
635 sethostent not implemented!
636 setnetent not implemented!
637 setprotoent not implemented!
639 setservent not implemented!
640 %s free() ignored (RMAGIC, PERL_CORE)
641 %s has too many errors.
642 SIG%s handler "%s" not defined.
644 Size magic not implemented
645 %s: name `%s' too long
647 %s number > %s non-portable
648 %srealloc() %signored
651 socketpair not implemented!
653 Starting Full Screen process with flag=%d, mytype=%d
654 Starting PM process with flag=%d, mytype=%d
655 sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%f U_V is 0x%x, IV_MAX is 0x%x
656 switching effective gid is not implemented
657 switching effective uid is not implemented
658 System V IPC is not implemented on this machine
659 Terminating on signal SIG%s(%d)
660 The crypt() function is not implemented on NetWare
661 The flock() function is not implemented on NetWare
662 The rewinddir() function is not implemented on NetWare
663 The seekdir() function is not implemented on NetWare
664 The telldir() function is not implemented on NetWare
665 This perl was compiled without taint support. Cowardly refusing to run with -t or -T flags
666 This version of OS/2 does not support %s.%s
667 Too deeply nested ()-groups in %s
668 Too many args on %s line of "%s"
669 U0 mode on a byte string
670 unable to find VMSPIPE.COM for i/o piping
671 Unable to locate winsock library!
672 Unexpected program mode %d when morphing back from PM
673 Unrecognized character %s; marked by <-- HERE after %s<-- HERE near column %d
674 Unstable directory path, current directory changed unexpectedly
675 Unterminated compressed integer in unpack
678 Usage: CODE(0x%x)(%s)
679 Usage: File::Copy::rmscopy(from,to[,date_flag])
680 Usage: VMS::Filespec::candelete(spec)
681 Usage: VMS::Filespec::fileify(spec)
682 Usage: VMS::Filespec::pathify(spec)
683 Usage: VMS::Filespec::rmsexpand(spec[,defspec])
684 Usage: VMS::Filespec::unixify(spec)
685 Usage: VMS::Filespec::unixpath(spec)
686 Usage: VMS::Filespec::unixrealpath(spec)
687 Usage: VMS::Filespec::vmsify(spec)
688 Usage: VMS::Filespec::vmspath(spec)
689 Usage: VMS::Filespec::vmsrealpath(spec)
690 utf8 "\x%X" does not map to Unicode
691 Value of logical "%s" too long. Truncating to %i bytes
692 waitpid: process %x is not a child of process %x
695 win32_get_osfhandle() TBD on this platform
696 win32_open_osfhandle() TBD on this platform
697 Within []-length '*' not allowed in %s
698 Within []-length '%c' not allowed in %s
699 Wrong size of loadOrdinals array: expected %d, actual %d
700 Wrong syntax (suid) fd script name "%s"
701 'X' outside of string in %s
702 'X' outside of string in unpack
706 # This is a warning, but is currently followed immediately by a croak (toke.c)
707 Illegal character \%o (carriage return)
709 # Because uses WARN_MISSING as a synonym for WARN_UNINITIALIZED (sv.c)
710 Missing argument in %s
712 # This message can be both fatal and non-
713 False [] range "%s" in regex; marked by <-- HERE in m/%s/