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'
90 # Stuff deeper than main level is ignored
96 # Allow multi-line headers
102 $cur_entry =~ s/ ?\z/ $_/;
105 $cur_entry =~ s/\n/ /gs; # Fix multi-line headers if they have \n's
106 $cur_entry =~ s/\s+\z//;
107 $cur_entry =~ s/E<lt>/</g;
108 $cur_entry =~ s/E<gt>/>/g;
109 $cur_entry =~ s,E<sol>,/,g;
110 $cur_entry =~ s/[BCIFS](?:<<< (.*?) >>>|<< (.*?) >>|<(.*?)>)/$+/g;
112 if (exists $entries{$cur_entry} && $entries{$cur_entry}{todo}
113 && !$entries{$cur_entry}{cattodo}) {
115 local $::TODO = "Remove the TODO entry \"$cur_entry\" from DATA as it is already in $pod near line $.";
119 # Make sure to init this here, so an actual entry in perldiag
120 # overwrites one in DATA.
121 $entries{$cur_entry}{todo} = 0;
122 $entries{$cur_entry}{line_number} = $.;
125 next if ! defined $cur_entry;
127 if (! $entries{$cur_entry}{severity}) {
128 if (/^ \( ( $severity_re )
130 # Can have multiple categories separated by commas
131 ( $category_re (?: , $category_re)* )? \) /x)
133 $entries{$cur_entry}{severity} = $1;
134 $entries{$cur_entry}{category} =
135 $2 && join ", ", sort split " ", $2 =~ y/,//dr;
137 # Record it also for other messages sharing the same description
138 @$_{qw<severity category>} =
139 @{$entries{$cur_entry}}{qw<severity category>}
142 elsif (! $entries{$cur_entry}{first_line} && $_ =~ /\S/) {
144 # Keep track of first line of text if doesn't contain a severity, so
145 # that can later examine it to determine if that is ok or not
146 $entries{$cur_entry}{first_line} = $_;
152 push @same_descr, $entries{$cur_entry};
158 diag ("Unbalance =over/=back. Fix before proceeding; over - back = " . $depth);
162 foreach my $cur_entry ( keys %entries) {
163 next if $entries{$cur_entry}{todo}; # If in this file, won't have a severity
164 if (! exists $entries{$cur_entry}{severity}
166 # If there is no first line, it was two =items in a row, so the
167 # second one is the one with with text, not this one.
168 && exists $entries{$cur_entry}{first_line}
170 # If the first line refers to another message, no need for severity
171 && $entries{$cur_entry}{first_line} !~ /^See/)
175 " $pod entry at line $entries{$cur_entry}{line_number}\n"
176 . " \"$cur_entry\"\n"
177 . " is missing a severity and/or category"
182 # List from perlguts.pod "Formatted Printing of IVs, UVs, and NVs"
183 # Convert from internal formats to ones that the readers will be familiar
184 # with, while removing any format modifiers, such as precision, the
185 # presence of which would just confuse the pod's explanation
186 my %specialformats = (IVdf => 'd',
201 my $format_modifiers = qr/ [#0\ +-]* # optional flags
202 (?: [1-9][0-9]* | \* )? # optional field width
203 (?: \. \d* )? # optional precision
204 (?: h|l )? # optional length modifier
208 join '|', sort { length $b cmp length $a } keys %specialformats;
209 my $specialformats_re = qr/%$format_modifiers"\s*($specialformats)(\s*")?/;
212 check_file($_) for @ARGV;
215 open my $fh, '<', 'MANIFEST' or die "Can't open MANIFEST: $!";
216 while (my $file = <$fh>) {
219 next unless $file =~ /\.(?:c|cpp|h|xs|y)\z/ or $file =~ /^perly\./;
220 # OS/2 extensions have never been migrated to ext/, hence the special case:
221 next if $file =~ m!\A(?:ext|dist|cpan|lib|t|os2/OS2)/!
222 && $file !~ m!\Aext/DynaLoader/!;
227 # Standardize messages with variants into the form that appears
228 # in perldiag.pod -- useful for things without a diag_listed_as annotation
232 if ( $name =~ m/^(Invalid strict version format) \([^\)]*\)/ ) {
235 elsif ( $name =~ m/^(Invalid version format) \([^\)]*\)/ ) {
238 elsif ($name =~ m/^panic: /) {
239 $name = "panic: \%s";
248 print "# Checking $codefn\n";
250 open my $codefh, "<", $codefn
251 or die "Can't open $codefn: $!";
255 my $sub = 'top of file';
258 # Getting too much here isn't a problem; we only use this to skip
259 # errors inside of XS modules, which should get documented in the
260 # docs for the module.
261 if (m<^[^#\s]> and $_ !~ m/^[{}]*$/) {
264 next if $sub =~ m/^XS/;
265 if (m</\*\s*diag_listed_as: (.*?)\s*\*/>) {
267 $listed_as_line = $.+1;
269 elsif (m</\*\s*diag_listed_as: (.*?)\s*\z>) {
274 $listed_as .= $` =~ s/^\s*/ /r =~ s/\s+\z//r;
275 $listed_as_line = $.+1;
280 $listed_as .= s/^\s*/ /r =~ s/\s+\z//r;
283 if (!$finished) { $listed_as = undef }
288 # Loop to accumulate the message text all on one line.
289 if (m/(?!^)\b(?:$source_msg_re(?:_nocontext)?|$regcomp_re)\s*\(/) {
290 while (not m/\);\s*$/) {
291 my $nextline = <$codefh>;
292 # Means we fell off the end of the file. Not terribly surprising;
293 # this code tries to merge a lot of things that aren't regular C
294 # code (preprocessor stuff, long comments). That's OK; we don't
296 last if not defined $nextline;
298 $nextline =~ s/^\s+//;
300 # Note that we only want to do this where *both* are true.
301 if ($_ =~ m/"\s*$/ and $nextline =~ m/^"/) {
309 # This should happen *after* unwrapping, or we don't reformat the things
312 s/$specialformats_re/"%$specialformats{$1}" . (defined $2 ? '' : '"')/ge;
314 # Remove any remaining format modifiers, but not in %%
315 s/ (?<!%) % $format_modifiers ( [dioxXucsfeEgGp] ) /%$1/xg;
317 # The %"foo" thing needs to happen *before* this regex.
319 # DIE is just return Perl_die
320 my ($name, $category, $routine);
321 if (/\b$source_msg_call_re/) {
322 ($name, $category, $routine) = ($+{'text'}, $+{'category'}, $+{'routine'});
323 # Sometimes the regexp will pick up too much for the category
324 # e.g., WARN_UNINITIALIZED), PL_warn_uninit_sv ... up to the next )
325 $category && $category =~ s/\).*//s;
326 # Special-case yywarn
327 /yywarn/ and $category = 'syntax';
328 if (/win32_croak_not_implemented\(/) {
329 $name .= " not implemented!"
332 elsif (/$bad_version_re/) {
333 ($name, $category) = ($+{'text'}, undef);
335 elsif (/$regcomp_fail_re/) {
336 # FAIL("foo") -> "foo in regex m/%s/"
337 # vFAIL("foo") -> "foo in regex; marked by <-- HERE in m/%s/"
338 ($name, $category) = ($+{'text'}, undef);
340 " in regex" . ("; marked by <-- HERE in" x /vFAIL/) . " m/%s/";
342 elsif (/$regcomp_call_re/) {
343 # vWARN/ckWARNreg("foo") -> "foo in regex; marked by <-- HERE in m/%s/
344 ($name, $category, $routine) = ($+{'text'}, undef, $+{'routine'});
345 $name .= " in regex; marked by <-- HERE in m/%s/";
346 $category = 'WARN_REGEXP';
347 if ($routine =~ /dep/) {
348 $category .= ',WARN_DEPRECATED';
355 # Try to guess what the severity should be. In the case of
356 # Perl_ck_warner and other _ck_ functions, we can tell whether it is
357 # a severe/default warning or no by the _d suffix. In the case of
358 # other warn functions we cannot tell, because Perl_warner may be pre-
359 # ceded by if(ckWARN) or if(ckWARN_d).
360 my $severity = !$routine ? '[PFX]'
361 : $routine =~ /warn.*_d\z/ ? '[DS]'
362 : $routine =~ /ck_warn/ ? 'W'
363 : $routine =~ /warner/ ? '[WDS]'
364 : $routine =~ /warn/ ? 'S'
365 : $routine =~ /ckWARN.*dep/ ? 'D'
366 : $routine =~ /ckWARN\d*reg_d/? 'S'
367 : $routine =~ /ckWARN\d*reg/ ? 'W'
368 : $routine =~ /vWARN\d/ ? '[WDS]'
371 if (defined $category) {
372 $category =~ s/__/::/g;
375 sort map {s/^WARN_//; lc $_} split /\s*[|,]\s*/, $category;
377 if ($listed_as and $listed_as_line == $. - $multiline) {
380 # The form listed in perldiag ignores most sorts of fancy printf
381 # formatting, or makes it more perlish.
383 $name =~ s/%l[ud]/%d/g;
384 $name =~ s/%\.(\d+|\*)s/\%s/g;
385 $name =~ s/(?:%s){2,}/%s/g;
386 $name =~ s/(\\")|("\s*[A-Z_]+\s*")/$1 ? '"' : '%s'/egg;
390 $name =~ s/(\\)\\/$1/g;
393 # Extra explanatory info on an already-listed error, doesn't
394 # need it's own listing.
395 next if $name =~ m/^\t/;
397 # Happens fairly often with PL_no_modify.
398 next if $name eq '%s';
400 # Special syntax for magic comment, allows ignoring the fact
401 # that it isn't listed. Only use in very special circumstances,
402 # like this script failing to notice that the Perl_croak call is
403 # inside an #if 0 block.
404 next if $name eq 'SKIPME';
406 next if $name=~/\[TESTING\]/; # ignore these as they are works in progress
408 check_message(standardize($name),$codefn,$severity,$categories);
413 my($name,$codefn,$severity,$categories,$partial) = @_;
414 my $key = $name =~ y/\n/ /r;
417 # Try to reduce printf() formats to simplest forms
418 # Really this should be matching %s, etc like diagnostics.pm does
421 $key =~ s/%[#0\-+]/%/g;
424 $key =~ s/\%(\d+|\*)/%/g;
427 $key =~ s/\%\.(\d+|\*)/%/g;
429 if (exists $entries{$key} and
430 # todo + cattodo means it is not found and it is not in the
431 # regular todo list, either
432 !$entries{$key}{todo} || !$entries{$key}{cattodo}) {
434 if ( $entries{$key}{seen}++ ) {
435 # no need to repeat entries we've tested
436 } elsif ($entries{$key}{todo}) {
439 local $::TODO = 'in DATA';
440 # There is no listing, but it is in the list of exceptions. TODO FAIL.
443 " Message '$name'\n from $codefn line $. is not listed in $pod\n".
444 " (but it wasn't documented in 5.10 either, so marking it TODO)."
448 # We found an actual valid entry in perldiag.pod for this error.
452 if $entries{$key}{cattodo};
454 # Now check the category and severity
456 # Cache our severity qr thingies
459 my $qr = $qrs{$severity} ||= qr/$severity/;
461 like($entries{$key}{severity}, $qr,
463 ? "severity is one of $severity for $key"
464 : "severity is $severity for $key");
466 is($entries{$key}{category}, $categories,
467 ($categories ? "categories are [$categories]" : "no category")
476 check_message($_,$codefn,$severity,$categories,1) or $ok = 0, last
477 for split /\n/, $name;
481 } elsif ($make_exceptions_list) {
482 # We're making an updated version of the exception list, to
483 # stick in the __DATA__ section. I honestly can't think of
484 # a situation where this is the right thing to do, but I'm
485 # leaving it here, just in case one of my descendents thinks
487 print STDERR "$key\n";
489 # No listing found, and no excuse either.
490 # Find the correct place in perldiag.pod, and add a stanza beginning =item $name.
492 diag(" Message '$name'\n from $codefn line $. is not listed in $pod");
494 # seen it, so only fail once for this message
495 $entries{$name}{seen}++;
498 die if $name =~ /%$/;
502 # Lists all missing things as of the inauguration of this script, so we
503 # don't have to go from "meh" to perfect all at once.
505 # PLEASE DO NOT ADD TO THIS LIST. Instead, write an entry in
506 # pod/perldiag.pod for your new (warning|error). Nevertheless,
507 # listing exceptions here when this script is not smart enough
508 # to recognize the messages is not so bad, as long as there are
509 # entries in perldiag.
511 # Entries after __CATEGORIES__ are those that are in perldiag but fail the
512 # severity/category test.
514 # Also FIXME this test, as the first entry in TODO *is* covered by the
515 # description: Malformed UTF-8 character (%s)
517 Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
519 Cannot apply "%s" in non-PerlIO perl
521 Can't find DLL name for the module `%s' by the handle %d, rc=%u=%x
522 Can't find string terminator %c%s%c anywhere before EOF
523 Can't fix broken locale name "%s"
524 Can't get short module name from a handle
525 Can't load DLL `%s', possible problematic module `%s'
528 Can't set type on DOS
531 Can't %s script `%s' with ARGV[0] being `%s'
533 Can't %s `%s' with ARGV[0] being `%s' (looking for executables only, not found)
534 Can't use string ("%s"%s) as a subroutine ref while "strict refs" in use
535 Character(s) in '%c' format wrapped in %s
536 chown not implemented!
538 Code missing after '/' in pack
539 Code missing after '/' in unpack
540 Could not find version 1.1 of winsock dll
541 Could not find version 2.0 of winsock dll
542 '%c' outside of string in pack
543 Debug leaking scalars child failed%s with errno %d: %s
544 detach of a thread which could not start
545 detach on an already detached thread
546 detach on a thread with a waiter
547 '/' does not take a repeat count in %s
548 -Dp not implemented on this platform
549 Empty array reference given to mod2fname
550 endhostent not implemented!
551 endnetent not implemented!
552 endprotoent not implemented!
553 endservent not implemented!
554 Error loading module '%s': %s
555 Error reading "%s": %s
556 execl not implemented!
557 EVAL without pos change exceeded limit in regex
558 Filehandle opened only for %sput
559 Filehandle %s opened only for %sput
560 Filehandle STD%s reopened as %s only for input
561 file_type not implemented on DOS
562 filter_del can only delete in reverse order (currently)
564 fork() not implemented!
565 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!
567 Free to wrong pool %p not %p
568 Function "endnetent" not implemented in this version of perl.
569 Function "endprotoent" not implemented in this version of perl.
570 Function "endservent" not implemented in this version of perl.
571 Function "getnetbyaddr" not implemented in this version of perl.
572 Function "getnetbyname" not implemented in this version of perl.
573 Function "getnetent" not implemented in this version of perl.
574 Function "getprotobyname" not implemented in this version of perl.
575 Function "getprotobynumber" not implemented in this version of perl.
576 Function "getprotoent" not implemented in this version of perl.
577 Function "getservbyport" not implemented in this version of perl.
578 Function "getservent" not implemented in this version of perl.
579 Function "getsockopt" not implemented in this version of perl.
580 Function "recvmsg" not implemented in this version of perl.
581 Function "sendmsg" not implemented in this version of perl.
582 Function "sethostent" not implemented in this version of perl.
583 Function "setnetent" not implemented in this version of perl.
584 Function "setprotoent" not implemented in this version of perl.
585 Function "setservent" not implemented in this version of perl.
586 Function "setsockopt" not implemented in this version of perl.
587 Function "tcdrain" not implemented in this version of perl.
588 Function "tcflow" not implemented in this version of perl.
589 Function "tcflush" not implemented in this version of perl.
590 Function "tcsendbreak" not implemented in this version of perl.
592 gethostent not implemented!
593 getnetbyaddr not implemented!
594 getnetbyname not implemented!
595 getnetent not implemented!
596 getprotoent not implemented!
597 getpwnam returned invalid UIC %o for user "%s"
598 getservent not implemented!
599 glob failed (can't start child: %s)
600 glob failed (child exited with status %d%s)
601 Got an error from DosAllocMem: %i
602 Goto undefined subroutine
603 Goto undefined subroutine &%s
605 ()-group starts with a count in %s
606 Illegal binary digit '%c' ignored
607 Illegal character %sin prototype for %s : %s
608 Illegal hexadecimal digit '%c' ignored
609 Illegal octal digit '%c' ignored
610 INSTALL_PREFIX too long: `%s'
611 Invalid argument to sv_cat_decode
612 Invalid range "%c-%c" in transliteration operator
613 Invalid separator character %c%c%c in PerlIO layer specification %s
614 Invalid TOKEN object ignored
615 Invalid type '%c' in pack
616 Invalid type '%c' in %s
617 Invalid type '%c' in unpack
618 Invalid type ',' in %s
619 ioctl implemented only on sockets
620 ioctlsocket not implemented!
621 join with a thread with a waiter
622 killpg not implemented!
623 List form of pipe open not implemented
624 Looks like we have no PM; will not load DLL %s without $ENV{PERL_ASIF_PM}
625 Malformed integer in [] in %s
627 Malformed UTF-8 character (fatal)
628 Missing (suid) fd script name
629 More than one argument to open
630 More than one argument to open(,':%s')
632 No %s allowed while running setgid
633 No %s allowed with (suid) fdscript
634 Not an XSUB reference
635 Not a reference given to mod2fname
636 Not array reference given to mod2fname
637 Operator or semicolon missing before %c%s
638 Out of memory during list extend
641 PerlApp::TextQuery: no arguments, please
642 POSIX syntax [%c %c] is reserved for future extensions in regex; marked by <-- HERE in m/%s/
643 ptr wrong %p != %p fl=%x nl=%p e=%p for %d
645 Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)
646 recursion detected in %s
647 Regexp *+ operand could be empty in regex; marked by <-- HERE in m/%s/
648 Reversed %c= operator
649 %s: Can't parse EXE/DLL name: '%s'
651 %sCompilation failed in require
652 %s: Error stripping dirs from EXE/DLL/INSTALLDIR name
653 sethostent not implemented!
654 setnetent not implemented!
655 setprotoent not implemented!
657 setservent not implemented!
658 %s free() ignored (RMAGIC, PERL_CORE)
659 %s has too many errors.
660 SIG%s handler "%s" not defined.
662 Size magic not implemented
663 %s: name `%s' too long
665 %s number > %s non-portable
666 %srealloc() %signored
669 socketpair not implemented!
671 Starting Full Screen process with flag=%d, mytype=%d
672 Starting PM process with flag=%d, mytype=%d
673 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
674 switching effective gid is not implemented
675 switching effective uid is not implemented
676 System V IPC is not implemented on this machine
677 Terminating on signal SIG%s(%d)
678 The crypt() function is not implemented on NetWare
679 The flock() function is not implemented on NetWare
680 The rewinddir() function is not implemented on NetWare
681 The seekdir() function is not implemented on NetWare
682 The telldir() function is not implemented on NetWare
683 This perl was compiled without taint support. Cowardly refusing to run with -t or -T flags
684 This version of OS/2 does not support %s.%s
685 Too deeply nested ()-groups in %s
686 Too many args on %s line of "%s"
687 U0 mode on a byte string
688 unable to find VMSPIPE.COM for i/o piping
689 Unable to locate winsock library!
690 Unexpected program mode %d when morphing back from PM
691 Unrecognized character %s; marked by <-- HERE after %s<-- HERE near column %d
692 Unstable directory path, current directory changed unexpectedly
693 Unterminated compressed integer in unpack
696 Usage: CODE(0x%x)(%s)
697 Usage: File::Copy::rmscopy(from,to[,date_flag])
698 Usage: VMS::Filespec::candelete(spec)
699 Usage: VMS::Filespec::fileify(spec)
700 Usage: VMS::Filespec::pathify(spec)
701 Usage: VMS::Filespec::rmsexpand(spec[,defspec])
702 Usage: VMS::Filespec::unixify(spec)
703 Usage: VMS::Filespec::unixpath(spec)
704 Usage: VMS::Filespec::unixrealpath(spec)
705 Usage: VMS::Filespec::vmsify(spec)
706 Usage: VMS::Filespec::vmspath(spec)
707 Usage: VMS::Filespec::vmsrealpath(spec)
708 utf8 "\x%X" does not map to Unicode
709 Value of logical "%s" too long. Truncating to %i bytes
710 waitpid: process %x is not a child of process %x
713 win32_get_osfhandle() TBD on this platform
714 win32_open_osfhandle() TBD on this platform
715 Within []-length '*' not allowed in %s
716 Within []-length '%c' not allowed in %s
717 Wrong size of loadOrdinals array: expected %d, actual %d
718 Wrong syntax (suid) fd script name "%s"
719 'X' outside of string in %s
720 'X' outside of string in unpack
724 # This is a warning, but is currently followed immediately by a croak (toke.c)
725 Illegal character \%o (carriage return)
727 # Because uses WARN_MISSING as a synonym for WARN_UNINITIALIZED (sv.c)
728 Missing argument in %s
730 # This message can be both fatal and non-
731 False [] range "%s" in regex; marked by <-- HERE in m/%s/