4 @INC = '..' if -f '../TestInit.pm';
6 use TestInit qw(T); # T is chdir to the top level
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*
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/[BCIFS](?:<<< (.*?) >>>|<< (.*?) >>|<(.*?)>)/$+/g;
96 if (exists $entries{$cur_entry} && $entries{$cur_entry}{todo}
97 && !$entries{$cur_entry}{cattodo}) {
99 local $::TODO = "Remove the TODO entry \"$cur_entry\" from DATA as it is already in $pod near line $.";
103 # Make sure to init this here, so an actual entry in perldiag
104 # overwrites one in DATA.
105 $entries{$cur_entry}{todo} = 0;
106 $entries{$cur_entry}{line_number} = $.;
109 next if ! defined $cur_entry;
111 if (! $entries{$cur_entry}{severity}) {
112 if (/^ \( ( $severity_re )
114 # Can have multiple categories separated by commas
115 ( $category_re (?: , $category_re)* )? \) /x)
117 $entries{$cur_entry}{severity} = $1;
118 $entries{$cur_entry}{category} =
119 $2 && join ", ", sort split " ", $2 =~ y/,//dr;
121 # Record it also for other messages sharing the same description
122 @$_{qw<severity category>} =
123 @{$entries{$cur_entry}}{qw<severity category>}
126 elsif (! $entries{$cur_entry}{first_line} && $_ =~ /\S/) {
128 # Keep track of first line of text if doesn't contain a severity, so
129 # that can later examine it to determine if that is ok or not
130 $entries{$cur_entry}{first_line} = $_;
136 push @same_descr, $entries{$cur_entry};
141 foreach my $cur_entry ( keys %entries) {
142 next if $entries{$cur_entry}{todo}; # If in this file, won't have a severity
143 if (! exists $entries{$cur_entry}{severity}
145 # If there is no first line, it was two =items in a row, so the
146 # second one is the one with with text, not this one.
147 && exists $entries{$cur_entry}{first_line}
149 # If the first line refers to another message, no need for severity
150 && $entries{$cur_entry}{first_line} !~ /^See/)
154 " $pod entry at line $entries{$cur_entry}{line_number}\n"
155 . " \"$cur_entry\"\n"
156 . " is missing a severity and/or category"
161 # List from perlguts.pod "Formatted Printing of IVs, UVs, and NVs"
162 # Convert from internal formats to ones that the readers will be familiar
163 # with, while removing any format modifiers, such as precision, the
164 # presence of which would just confuse the pod's explanation
165 my %specialformats = (IVdf => 'd',
180 my $format_modifiers = qr/ [#0\ +-]* # optional flags
181 (?: [1-9][0-9]* | \* )? # optional field width
182 (?: \. \d* )? # optional precision
183 (?: h|l )? # optional length modifier
187 join '|', sort { length $b cmp length $a } keys %specialformats;
188 my $specialformats_re = qr/%$format_modifiers"\s*($specialformats)(\s*")?/;
191 check_file($_) for @ARGV;
194 open my $fh, '<', 'MANIFEST' or die "Can't open MANIFEST: $!";
195 while (my $file = <$fh>) {
198 next unless $file =~ /\.(?:c|cpp|h|xs|y)\z/ or $file =~ /^perly\./;
199 # OS/2 extensions have never been migrated to ext/, hence the special case:
200 next if $file =~ m!\A(?:ext|dist|cpan|lib|t|os2/OS2)/!
201 && $file !~ m!\Aext/DynaLoader/!;
206 # Standardize messages with variants into the form that appears
207 # in perldiag.pod -- useful for things without a diag_listed_as annotation
211 if ( $name =~ m/^(Invalid strict version format) \([^\)]*\)/ ) {
214 elsif ( $name =~ m/^(Invalid version format) \([^\)]*\)/ ) {
217 elsif ($name =~ m/^panic: /) {
218 $name = "panic: \%s";
227 print "# Checking $codefn\n";
229 open my $codefh, "<", $codefn
230 or die "Can't open $codefn: $!";
234 my $sub = 'top of file';
237 # Getting too much here isn't a problem; we only use this to skip
238 # errors inside of XS modules, which should get documented in the
239 # docs for the module.
240 if (m<^[^#\s]> and $_ !~ m/^[{}]*$/) {
243 next if $sub =~ m/^XS/;
244 if (m</\*\s*diag_listed_as: (.*?)\s*\*/>) {
246 $listed_as_line = $.+1;
248 elsif (m</\*\s*diag_listed_as: (.*?)\s*\z>) {
253 $listed_as .= $` =~ s/^\s*/ /r =~ s/\s+\z//r;
254 $listed_as_line = $.+1;
259 $listed_as .= s/^\s*/ /r =~ s/\s+\z//r;
262 if (!$finished) { $listed_as = undef }
267 # Loop to accumulate the message text all on one line.
268 if (m/(?!^)\b(?:$source_msg_re(?:_nocontext)?|$regcomp_re)\s*\(/) {
269 while (not m/\);\s*$/) {
270 my $nextline = <$codefh>;
271 # Means we fell off the end of the file. Not terribly surprising;
272 # this code tries to merge a lot of things that aren't regular C
273 # code (preprocessor stuff, long comments). That's OK; we don't
275 last if not defined $nextline;
277 $nextline =~ s/^\s+//;
279 # Note that we only want to do this where *both* are true.
280 if ($_ =~ m/"\s*$/ and $nextline =~ m/^"/) {
288 # This should happen *after* unwrapping, or we don't reformat the things
291 s/$specialformats_re/"%$specialformats{$1}" . (defined $2 ? '' : '"')/ge;
293 # Remove any remaining format modifiers, but not in %%
294 s/ (?<!%) % $format_modifiers ( [dioxXucsfeEgGp] ) /%$1/xg;
296 # The %"foo" thing needs to happen *before* this regex.
298 # DIE is just return Perl_die
299 my ($name, $category, $routine);
300 if (/\b$source_msg_call_re/) {
301 ($name, $category, $routine) = ($+{'text'}, $+{'category'}, $+{'routine'});
302 # Sometimes the regexp will pick up too much for the category
303 # e.g., WARN_UNINITIALIZED), PL_warn_uninit_sv ... up to the next )
304 $category && $category =~ s/\).*//s;
305 if (/win32_croak_not_implemented\(/) {
306 $name .= " not implemented!"
309 elsif (/$bad_version_re/) {
310 ($name, $category) = ($+{'text'}, undef);
312 elsif (/$regcomp_fail_re/) {
313 # FAIL("foo") -> "foo in regex m/%s/"
314 # vFAIL("foo") -> "foo in regex; marked by <-- HERE in m/%s/"
315 ($name, $category) = ($+{'text'}, undef);
317 " in regex" . ("; marked by <-- HERE in" x /vFAIL/) . " m/%s/";
319 elsif (/$regcomp_call_re/) {
320 # vWARN/ckWARNreg("foo") -> "foo in regex; marked by <-- HERE in m/%s/
321 ($name, $category, $routine) = ($+{'text'}, undef, $+{'routine'});
322 $name .= " in regex; marked by <-- HERE in m/%s/";
323 $category = 'WARN_REGEXP';
324 if ($routine =~ /dep/) {
325 $category .= ',WARN_DEPRECATED';
332 # Try to guess what the severity should be. In the case of
333 # Perl_ck_warner and other _ck_ functions, we can tell whether it is
334 # a severe/default warning or no by the _d suffix. In the case of
335 # other warn functions we cannot tell, because Perl_warner may be pre-
336 # ceded by if(ckWARN) or if(ckWARN_d).
337 my $severity = !$routine ? '[PFX]'
338 : $routine =~ /warn.*_d\z/ ? '[DS]'
339 : $routine =~ /ck_warn/ ? 'W'
340 : $routine =~ /warner/ ? '[WDS]'
341 : $routine =~ /warn/ ? 'S'
342 : $routine =~ /ckWARN.*dep/ ? 'D'
343 : $routine =~ /ckWARN\d*reg_d/? 'S'
344 : $routine =~ /ckWARN\d*reg/ ? 'W'
345 : $routine =~ /vWARN\d/ ? '[WDS]'
348 if (defined $category) {
349 $category =~ s/__/::/g;
352 sort map {s/^WARN_//; lc $_} split /\s*[|,]\s*/, $category;
354 if ($listed_as and $listed_as_line == $. - $multiline) {
357 # The form listed in perldiag ignores most sorts of fancy printf
358 # formatting, or makes it more perlish.
360 $name =~ s/%l[ud]/%d/g;
361 $name =~ s/%\.(\d+|\*)s/\%s/g;
362 $name =~ s/(?:%s){2,}/%s/g;
363 $name =~ s/(\\")|("\s*[A-Z_]+\s*")/$1 ? '"' : '%s'/egg;
367 $name =~ s/(\\)\\/$1/g;
370 # Extra explanatory info on an already-listed error, doesn't
371 # need it's own listing.
372 next if $name =~ m/^\t/;
374 # Happens fairly often with PL_no_modify.
375 next if $name eq '%s';
377 # Special syntax for magic comment, allows ignoring the fact
378 # that it isn't listed. Only use in very special circumstances,
379 # like this script failing to notice that the Perl_croak call is
380 # inside an #if 0 block.
381 next if $name eq 'SKIPME';
383 next if $name=~/\[TESTING\]/; # ignore these as they are works in progress
385 check_message(standardize($name),$codefn,$severity,$categories);
390 my($name,$codefn,$severity,$categories,$partial) = @_;
391 my $key = $name =~ y/\n/ /r;
394 # Try to reduce printf() formats to simplest forms
395 # Really this should be matching %s, etc like diagnostics.pm does
398 $key =~ s/%[#0\-+]/%/g;
401 $key =~ s/\%(\d+|\*)/%/g;
404 $key =~ s/\%\.(\d+|\*)/%/g;
406 if (exists $entries{$key} and
407 # todo + cattodo means it is not found and it is not in the
408 # regular todo list, either
409 !$entries{$key}{todo} || !$entries{$key}{cattodo}) {
411 if ( $entries{$key}{seen}++ ) {
412 # no need to repeat entries we've tested
413 } elsif ($entries{$key}{todo}) {
416 local $::TODO = 'in DATA';
417 # There is no listing, but it is in the list of exceptions. TODO FAIL.
420 " Message '$name'\n from $codefn line $. is not listed in $pod\n".
421 " (but it wasn't documented in 5.10 either, so marking it TODO)."
425 # We found an actual valid entry in perldiag.pod for this error.
429 if $entries{$key}{cattodo};
431 # Now check the category and severity
433 # Cache our severity qr thingies
436 my $qr = $qrs{$severity} ||= qr/$severity/;
438 like($entries{$key}{severity}, $qr,
440 ? "severity is one of $severity for $key"
441 : "severity is $severity for $key");
443 is($entries{$key}{category}, $categories,
444 ($categories ? "categories are [$categories]" : "no category")
453 check_message($_,$codefn,$severity,$categories,1) or $ok = 0, last
454 for split /\n/, $name;
458 } elsif ($make_exceptions_list) {
459 # We're making an updated version of the exception list, to
460 # stick in the __DATA__ section. I honestly can't think of
461 # a situation where this is the right thing to do, but I'm
462 # leaving it here, just in case one of my descendents thinks
464 print STDERR "$key\n";
466 # No listing found, and no excuse either.
467 # Find the correct place in perldiag.pod, and add a stanza beginning =item $name.
469 diag(" Message '$name'\n from $codefn line $. is not listed in $pod");
471 # seen it, so only fail once for this message
472 $entries{$name}{seen}++;
475 die if $name =~ /%$/;
479 # Lists all missing things as of the inauguration of this script, so we
480 # don't have to go from "meh" to perfect all at once.
482 # PLEASE DO NOT ADD TO THIS LIST. Instead, write an entry in
483 # pod/perldiag.pod for your new (warning|error). Nevertheless,
484 # listing exceptions here when this script is not smart enough
485 # to recognize the messages is not so bad, as long as there are
486 # entries in perldiag.
488 # Entries after __CATEGORIES__ are those that are in perldiag but fail the
489 # severity/category test.
491 # Also FIXME this test, as the first entry in TODO *is* covered by the
492 # description: Malformed UTF-8 character (%s)
494 Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
496 Cannot apply "%s" in non-PerlIO perl
498 Can't find DLL name for the module `%s' by the handle %d, rc=%u=%x
499 Can't find string terminator %c%s%c anywhere before EOF
500 Can't fix broken locale name "%s"
501 Can't get short module name from a handle
502 Can't load DLL `%s', possible problematic module `%s'
505 Can't set type on DOS
508 Can't %s script `%s' with ARGV[0] being `%s'
510 Can't %s `%s' with ARGV[0] being `%s' (looking for executables only, not found)
511 Can't use string ("%s"%s) as a subroutine ref while "strict refs" in use
512 Character(s) in '%c' format wrapped in %s
513 chown not implemented!
515 Code missing after '/' in pack
516 Code missing after '/' in unpack
517 Could not find version 1.1 of winsock dll
518 Could not find version 2.0 of winsock dll
519 '%c' outside of string in pack
520 Debug leaking scalars child failed%s with errno %d: %s
521 detach of a thread which could not start
522 detach on an already detached thread
523 detach on a thread with a waiter
524 '/' does not take a repeat count in %s
525 -Dp not implemented on this platform
526 Empty array reference given to mod2fname
527 endhostent not implemented!
528 endnetent not implemented!
529 endprotoent not implemented!
530 endservent not implemented!
531 Error loading module '%s': %s
532 Error reading "%s": %s
533 execl not implemented!
534 EVAL without pos change exceeded limit in regex
535 Filehandle opened only for %sput
536 Filehandle %s opened only for %sput
537 Filehandle STD%s reopened as %s only for input
538 file_type not implemented on DOS
539 filter_del can only delete in reverse order (currently)
541 fork() not implemented!
542 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!
544 Free to wrong pool %p not %p
545 Function "endnetent" not implemented in this version of perl.
546 Function "endprotoent" not implemented in this version of perl.
547 Function "endservent" not implemented in this version of perl.
548 Function "getnetbyaddr" not implemented in this version of perl.
549 Function "getnetbyname" not implemented in this version of perl.
550 Function "getnetent" not implemented in this version of perl.
551 Function "getprotobyname" not implemented in this version of perl.
552 Function "getprotobynumber" not implemented in this version of perl.
553 Function "getprotoent" not implemented in this version of perl.
554 Function "getservbyport" not implemented in this version of perl.
555 Function "getservent" not implemented in this version of perl.
556 Function "getsockopt" not implemented in this version of perl.
557 Function "recvmsg" not implemented in this version of perl.
558 Function "sendmsg" not implemented in this version of perl.
559 Function "sethostent" not implemented in this version of perl.
560 Function "setnetent" not implemented in this version of perl.
561 Function "setprotoent" not implemented in this version of perl.
562 Function "setservent" not implemented in this version of perl.
563 Function "setsockopt" not implemented in this version of perl.
564 Function "tcdrain" not implemented in this version of perl.
565 Function "tcflow" not implemented in this version of perl.
566 Function "tcflush" not implemented in this version of perl.
567 Function "tcsendbreak" not implemented in this version of perl.
569 gethostent not implemented!
570 getnetbyaddr not implemented!
571 getnetbyname not implemented!
572 getnetent not implemented!
573 getprotoent not implemented!
574 getpwnam returned invalid UIC %o for user "%s"
575 getservent not implemented!
576 glob failed (can't start child: %s)
577 glob failed (child exited with status %d%s)
578 Got an error from DosAllocMem: %i
579 Goto undefined subroutine
580 Goto undefined subroutine &%s
582 ()-group starts with a count in %s
583 Illegal binary digit '%c' ignored
584 Illegal character %sin prototype for %s : %s
585 Illegal hexadecimal digit '%c' ignored
586 Illegal octal digit '%c' ignored
587 INSTALL_PREFIX too long: `%s'
588 Invalid argument to sv_cat_decode
589 Invalid range "%c-%c" in transliteration operator
590 Invalid separator character %c%c%c in PerlIO layer specification %s
591 Invalid TOKEN object ignored
592 Invalid type '%c' in pack
593 Invalid type '%c' in %s
594 Invalid type '%c' in unpack
595 Invalid type ',' in %s
596 ioctl implemented only on sockets
597 ioctlsocket not implemented!
598 join with a thread with a waiter
599 killpg not implemented!
600 List form of pipe open not implemented
601 Looks like we have no PM; will not load DLL %s without $ENV{PERL_ASIF_PM}
602 Malformed integer in [] in %s
604 Malformed UTF-8 character (fatal)
605 Missing (suid) fd script name
606 More than one argument to open
607 More than one argument to open(,':%s')
609 No %s allowed while running setgid
610 No %s allowed with (suid) fdscript
611 Not an XSUB reference
612 Not a reference given to mod2fname
613 Not array reference given to mod2fname
614 Operator or semicolon missing before %c%s
615 Out of memory during list extend
618 PerlApp::TextQuery: no arguments, please
619 POSIX syntax [%c %c] is reserved for future extensions in regex; marked by <-- HERE in m/%s/
620 ptr wrong %p != %p fl=%x nl=%p e=%p for %d
622 Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)
623 recursion detected in %s
624 Regexp *+ operand could be empty in regex; marked by <-- HERE in m/%s/
625 Reversed %c= operator
626 %s: Can't parse EXE/DLL name: '%s'
628 %sCompilation failed in require
629 %s: Error stripping dirs from EXE/DLL/INSTALLDIR name
630 sethostent not implemented!
631 setnetent not implemented!
632 setprotoent not implemented!
634 setservent not implemented!
635 %s free() ignored (RMAGIC, PERL_CORE)
636 %s has too many errors.
637 SIG%s handler "%s" not defined.
639 Size magic not implemented
640 %s: name `%s' too long
642 %s number > %s non-portable
643 %srealloc() %signored
646 socketpair not implemented!
648 Starting Full Screen process with flag=%d, mytype=%d
649 Starting PM process with flag=%d, mytype=%d
650 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
651 switching effective gid is not implemented
652 switching effective uid is not implemented
653 System V IPC is not implemented on this machine
654 Terminating on signal SIG%s(%d)
655 The crypt() function is not implemented on NetWare
656 The flock() function is not implemented on NetWare
657 The rewinddir() function is not implemented on NetWare
658 The seekdir() function is not implemented on NetWare
659 The telldir() function is not implemented on NetWare
660 This perl was compiled without taint support. Cowardly refusing to run with -t or -T flags
661 This version of OS/2 does not support %s.%s
662 Too deeply nested ()-groups in %s
663 Too many args on %s line of "%s"
664 U0 mode on a byte string
665 unable to find VMSPIPE.COM for i/o piping
666 Unable to locate winsock library!
667 Unexpected program mode %d when morphing back from PM
668 Unrecognized character %s; marked by <-- HERE after %s<-- HERE near column %d
669 Unstable directory path, current directory changed unexpectedly
670 Unterminated compressed integer in unpack
673 Usage: CODE(0x%x)(%s)
674 Usage: File::Copy::rmscopy(from,to[,date_flag])
675 Usage: VMS::Filespec::candelete(spec)
676 Usage: VMS::Filespec::fileify(spec)
677 Usage: VMS::Filespec::pathify(spec)
678 Usage: VMS::Filespec::rmsexpand(spec[,defspec])
679 Usage: VMS::Filespec::unixify(spec)
680 Usage: VMS::Filespec::unixpath(spec)
681 Usage: VMS::Filespec::unixrealpath(spec)
682 Usage: VMS::Filespec::vmsify(spec)
683 Usage: VMS::Filespec::vmspath(spec)
684 Usage: VMS::Filespec::vmsrealpath(spec)
685 Use of inherited AUTOLOAD for non-method %s::%s() is deprecated
686 utf8 "\x%X" does not map to Unicode
687 Value of logical "%s" too long. Truncating to %i bytes
688 waitpid: process %x is not a child of process %x
691 win32_get_osfhandle() TBD on this platform
692 win32_open_osfhandle() TBD on this platform
693 Within []-length '*' not allowed in %s
694 Within []-length '%c' not allowed in %s
695 Wrong size of loadOrdinals array: expected %d, actual %d
696 Wrong syntax (suid) fd script name "%s"
697 'X' outside of string in %s
698 'X' outside of string in unpack
702 # This is a warning, but is currently followed immediately by a croak (toke.c)
703 Illegal character \%o (carriage return)
705 # Because uses WARN_MISSING as a synonym for WARN_UNINITIALIZED (sv.c)
706 Missing argument in %s
708 # This message can be both fatal and non-
709 False [] range "%s" in regex; marked by <-- HERE in m/%s/