Latest update.

This commit is contained in:
2020-01-17 19:45:12 +09:00
parent 016df9f433
commit 0f7abb4eb6
1100 changed files with 47785 additions and 16292 deletions
+77 -74
View File
@@ -140,25 +140,33 @@ sub name_synopsis {
foreach my $line ( split /\n+/, $syn ) {
next unless $line =~ /^\s/;
my $sym;
my $is_prototype = 1;
$line =~ s/STACK_OF\([^)]+\)/int/g;
$line =~ s/SPARSE_ARRAY_OF\([^)]+\)/int/g;
$line =~ s/__declspec\([^)]+\)//;
if ( $line =~ /typedef.*\(\*\S+\)\s+\(/ ) {
# a callback function with whitespace before the argument list:
# typedef ... (*NAME) (...
err($id, "function typedef has space before arg list: $line");
}
if ( $line =~ /env (\S*)=/ ) {
# environment variable env NAME=...
$sym = $1;
} elsif ( $line =~ /typedef.*\(\*(\S+)\)\(.*/ ) {
} elsif ( $line =~ /typedef.*\(\*(\S+)\)\s*\(/ ) {
# a callback function pointer: typedef ... (*NAME)(...
$sym = $1;
} elsif ( $line =~ /typedef.* (\S+)\(.*/ ) {
} elsif ( $line =~ /typedef.* (\S+)\(/ ) {
# a callback function signature: typedef ... NAME(...
$sym = $1;
} elsif ( $line =~ /typedef.* (\S+);/ ) {
# a simple typedef: typedef ... NAME;
$is_prototype = 0;
$sym = $1;
} elsif ( $line =~ /enum (\S*) \{/ ) {
# an enumeration: enum ... {
$sym = $1;
} elsif ( $line =~ /#(?:define|undef) ([A-Za-z0-9_]+)/ ) {
$is_prototype = 0;
$sym = $1;
} elsif ( $line =~ /([A-Za-z0-9_]+)\(/ ) {
$sym = $1;
@@ -172,7 +180,7 @@ sub name_synopsis {
# Do some sanity checks on the prototype.
err($id, "prototype missing spaces around commas: $line")
if ( $line =~ /[a-z0-9],[^ ]/ );
if $is_prototype && $line =~ /[a-z0-9],[^ ]/;
}
foreach my $n ( keys %names ) {
@@ -235,7 +243,7 @@ sub check_head_style {
my $markup_re =
qr/( # Capture group
[BIL]< # The start of what we recurse on
(?:(?-1)|.)*? # recurse the whole regexp (refering to
(?:(?-1)|.)*? # recurse the whole regexp (referring to
# the last opened capture group, i.e. the
# start of this regexp), or pick next
# character. Do NOT be greedy!
@@ -447,6 +455,35 @@ sub check {
check_section_location($id, $contents, "EXAMPLES", "SEE ALSO");
}
# Make sure every link has a section.
while ( $contents =~ /$markup_re/msg ) {
my $target = $1;
next unless $target =~ /^L<(.*)>$/; # Skip if not L<...>
$target = $1; # Peal away L< and >
$target =~ s/\/[^\/]*$//; # Peal away possible anchor
$target =~ s/.*\|//g; # Peal away possible link text
next if $target eq ''; # Skip if links within page, or
next if $target =~ /::/; # links to a Perl module, or
next if $target =~ /^https?:/; # is a URL link, or
next if $target =~ /\([1357]\)$/; # it has a section
err($id, "Section missing in $target")
}
# Check for proper links to commands.
while ( $contents =~ /L<([^>]*)\(1\)(?:\/.*)?>/g ) {
my $target = $1;
next if $target =~ /openssl-?/;
next if -f "doc/man1/$target.pod";
# TODO: Filter out "foreign manual" links.
next if $target =~ /ps|apropos|sha1sum|procmail|perl/;
err($id, "Bad command link L<$target(1)>");
}
# Check for proper in-man-3 API links.
while ( $contents =~ /L<([^>]*)\(3\)(?:\/.*)?>/g ) {
my $target = $1;
err($id, "Bad L<$target>")
unless $target =~ /^[_[:alpha:]][_[:alnum:]]*$/
}
unless ( $contents =~ /=for openssl generic/ ) {
if ( $filename =~ m|man3/| ) {
name_synopsis($id, $filename, $contents);
@@ -548,27 +585,6 @@ sub parsenum {
# Parse all the manpages, getting return map of what they document
# (by looking at their NAME sections).
sub getdocced
{
my $dir = shift;
my %return;
my %dups;
foreach my $pod ( glob("$dir/*.pod") ) {
my %podinfo = extract_pod_info($pod);
foreach my $n ( @{$podinfo{names}} ) {
$return{$n} = $pod;
err("# Duplicate $n in $pod and $dups{$n}")
if defined $dups{$n} && $dups{$n} ne $pod;
$dups{$n} = $pod;
}
}
return %return;
}
# Map of documented functions; function => manpage
my %docced;
# Map of links in each POD file; filename => [ "foo(1)", "bar(3)", ... ]
my %link_map = ();
# Map of names in each POD file; "name(s)" => filename
@@ -589,6 +605,11 @@ sub loadmissing($)
}
close FH;
for (@missing) {
err("$missingfile:", "$_ is documented in $name_map{$_}")
if exists $name_map{$_} && defined $name_map{$_};
}
return @missing;
}
@@ -613,17 +634,18 @@ sub checkmacros {
open(IN, $f) || die "Can't open $f, $!";
while ( <IN> ) {
next unless /^#\s*define\s*(\S+)\(/;
my $macro = $1;
next if $docced{$macro} || defined $seen{$macro};
next if $macro =~ /i2d_/
|| $macro =~ /d2i_/
|| $macro =~ /DEPRECATEDIN/
|| $macro =~ /IMPLEMENT_/
|| $macro =~ /DECLARE_/;
my $macro = "$1(3)"; # We know they're all in section 3
next if exists $name_map{$macro} || defined $seen{$macro};
next if $macro =~ /^i2d_/
|| $macro =~ /^d2i_/
|| $macro =~ /^DEPRECATEDIN/
|| $macro =~ /\Q_fnsig(3)\E$/
|| $macro =~ /^IMPLEMENT_/
|| $macro =~ /^_?DECLARE_/;
# Skip macros known to be missing
next if $opt_v && grep( /^$macro$/, @missing);
next if $opt_v && grep( /^\Q$macro\E$/, @missing);
err("$f:", "macro $macro undocumented")
if $opt_d || $opt_e;
$count++;
@@ -647,13 +669,14 @@ sub printem {
my @missing = loadmissing($missingfile) if ( $opt_v );
foreach my $func ( parsenum($numfile) ) {
next if $docced{$func} || defined $seen{$func};
$func .= '(3)'; # We know they're all in section 3
next if exists $name_map{$func} || defined $seen{$func};
# Skip ASN1 utilities
next if $func =~ /^ASN1_/;
# Skip functions known to be missing
next if $opt_v && grep( /^$func$/, @missing);
# Skip functions known to be missing.
next if $opt_v && grep( /^\Q$func\E$/, @missing);
err("$libname:", "function $func undocumented")
if $opt_d || $opt_e;
@@ -671,42 +694,21 @@ sub collectnames {
my $section = $1;
my $simplename = basename($filename, ".pod");
my $id = "${filename}:1:";
my %podinfo = extract_pod_info($filename, { debug => $debug });
my $contents = '';
{
local $/ = undef;
open POD, $filename or die "Couldn't open $filename, $!";
$contents = <POD>;
close POD;
unless ( grep { $simplename eq $_ } @{$podinfo{names}} ) {
err($id, "$simplename not in NAME section");
push @{$podinfo{names}}, $simplename;
}
$contents =~ /=head1 NAME([^=]*)=head1 /ms;
my $tmp = $1;
unless ( defined $tmp ) {
err($id, "weird name section");
return;
}
$tmp =~ tr/\n/ /;
$tmp =~ s/ -.*//g;
my @names =
map { s|/|-|g; $_ } # Treat slash as dash
map { s/^\s+//g; s/\s+$//g; $_ } # Trim prefix and suffix blanks
split(/,/, $tmp);
unless ( grep { $simplename eq $_ } @names ) {
err($id, "missing $simplename");
push @names, $simplename;
}
foreach my $name (@names) {
foreach my $name (@{$podinfo{names}}) {
next if $name eq "";
if ( $name =~ /\s/ ) {
err($id, "'$name' contains white space")
}
err($id, "'$name' contains white space")
if $name =~ /\s/;
my $name_sec = "$name($section)";
if ( !exists $name_map{$name_sec} ) {
$name_map{$name_sec} = $filename;
} elsif ( $filename eq $name_map{$name_sec} ) {
err($id, "$name_sec repeated in NAME section of",
err($id, "$name_sec duplicated in NAME section of",
$name_map{$name_sec});
} else {
err($id, "$name_sec also in NAME section of",
@@ -716,12 +718,13 @@ sub collectnames {
my @foreign_names =
map { map { s/\s+//g; $_ } split(/,/, $_) }
$contents =~ /=for\s+comment\s+foreign\s+manuals:\s*(.*)\n\n/;
$podinfo{contents} =~ /=for\s+openssl\s+foreign\s+manuals:\s*(.*)\n\n/;
foreach ( @foreign_names ) {
$name_map{$_} = undef; # It still exists!
}
my @links = $contents =~ /L<
my @links =
$podinfo{contents} =~ /L<
# if the link is of the form L<something|name(s)>,
# then remove 'something'. Note that 'something'
# may contain POD codes as well...
@@ -871,10 +874,14 @@ if ( $opt_c ) {
exit $status;
}
if ( $opt_l ) {
foreach ( @ARGV ? @ARGV : glob('doc/*/*.pod doc/internal/*/*.pod') ) {
# Preparation for some options, populate %name_map and %link_map
if ( $opt_l || $opt_u || $opt_v ) {
foreach ( glob('doc/*/*.pod doc/internal/*/*.pod') ) {
collectnames($_);
}
}
if ( $opt_l ) {
checklinks();
}
@@ -894,10 +901,6 @@ if ( $opt_n ) {
}
if ( $opt_u || $opt_v) {
my %temp = getdocced('doc/man3');
foreach ( keys %temp ) {
$docced{$_} = $temp{$_};
}
if ( $opt_o ) {
printem('crypto', 'util/libcrypto.num', 'util/missingcrypto111.txt');
printem('ssl', 'util/libssl.num', 'util/missingssl111.txt');