X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=util%2Ffind-doc-nits;h=860bb9958bd2d8b7d86e0b962009fa2e286d2923;hp=9befeb996d341e3baaf2d66396681d6483f96edf;hb=32305f88509c1d9ccb3ad676209a25fa59b95488;hpb=e1271ac2212f7cde14df478558bfaae2834fa09e diff --git a/util/find-doc-nits b/util/find-doc-nits index 9befeb996d..860bb9958b 100755 --- a/util/find-doc-nits +++ b/util/find-doc-nits @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -19,27 +19,32 @@ use lib catdir(dirname($0), "perl"); use OpenSSL::Util::Pod; # Options. -our($opt_s); -our($opt_u); +our($opt_d); our($opt_h); -our($opt_n); our($opt_l); +our($opt_n); +our($opt_p); +our($opt_u); +our($opt_c); sub help() { print < [ 'NAME', 'DESCRIPTION', 'COPYRIGHT' ], @@ -60,7 +65,9 @@ sub name_synopsis() my $tmp = $1; $tmp =~ tr/\n/ /; print "$id trailing comma before - in NAME\n" if $tmp =~ /, *-/; - $tmp =~ s/-.*//g; + $tmp =~ s/ -.*//g; + $tmp =~ s/ */ /g; + print "$id missing comma in NAME\n" if $tmp =~ /[^,] /; $tmp =~ s/,//g; my $dirname = dirname($filename); @@ -78,8 +85,12 @@ sub name_synopsis() print "$id the following exist as other .pod files:\n", join(" ", sort keys %foundfilenames), "\n" if %foundfilenames; - print "$id $simplename (filename) missing from NAME section\n", + print "$id $simplename (filename) missing from NAME section\n" unless $foundfilename; + foreach my $n ( keys %names ) { + print "$id $n is not public\n" + if $opt_p and !defined $public{$n}; + } # Find all functions in SYNOPSIS return unless $contents =~ /=head1 SYNOPSIS(.*)=head1 DESCRIPTION/ms; @@ -92,7 +103,10 @@ sub name_synopsis() # environment variable env NAME=... $sym = $1; } elsif ( $line =~ /typedef.*\(\*(\S+)\)\(.*/ ) { - # a callback function: typedef ... (*NAME)(... + # a callback function pointer: typedef ... (*NAME)(... + $sym = $1; + } elsif ( $line =~ /typedef.* (\S+)\(.*/ ) { + # a callback function signature: typedef ... NAME(... $sym = $1; } elsif ( $line =~ /typedef.* (\S+);/ ) { # a simple typedef: typedef ... NAME; @@ -163,19 +177,18 @@ sub check() print "$id Duplicate $1 in L<>\n" if $contents =~ /L<([^>]*)\|([^>]*)>/ && $1 eq $2; print "$id Bad =over $1\n" - if $contents =~ /=over([^ ][^4])/; + if $contents =~ /=over([^ ][^24])/; + print "$id Possible version style issue\n" + if $contents =~ /OpenSSL version [019]/; - # Look for multiple consecutive openssl #include lines. - # Consecutive because of files like md5.pod. Sometimes it's okay - # or necessary, as in ssl/SSL_set1_host.pod if ( $contents !~ /=for comment multiple includes/ ) { + # Look for multiple consecutive openssl #include lines + # (non-consecutive lines are okay; see man3/MD5.pod). if ( $contents =~ /=head1 SYNOPSIS(.*)=head1 DESCRIPTION/ms ) { my $count = 0; foreach my $line ( split /\n+/, $1 ) { if ( $line =~ m@include ', $temp or die "Can't open $temp, $!"; podchecker($filename, $OUT); @@ -207,6 +208,16 @@ sub check() } close $OUT; unlink $temp || warn "Can't remove $temp, $!"; + + # Find what section this page is in; assume 3. + my $section = 3; + $section = $1 if $dirname =~ /man([1-9])/; + + foreach ((@{$mandatory_sections{'*'}}, @{$mandatory_sections{$section}})) { + # Skip "return values" if not -s + print "$id: missing $_ head1 section\n" + if $contents !~ /^=head1\s+${_}\s*$/m; + } } my %dups; @@ -220,14 +231,18 @@ sub parsenum() or die "Can't open $file, $!, stopped"; while ( <$IN> ) { + next if /^#/; next if /\bNOEXIST\b/; next if /\bEXPORT_VAR_AS_FUNC\b/; - push @apis, $1 if /([^\s]+).\s/; + my @fields = split(); + die "Malformed line $_" + if scalar @fields != 2 && scalar @fields != 4; + push @apis, $fields[0]; } close $IN; - print "# Found ", scalar(@apis), " in $file\n"; + print "# Found ", scalar(@apis), " in $file\n" unless $opt_p; return sort @apis; } @@ -251,6 +266,34 @@ sub getdocced() my %docced; +sub checkmacros() +{ + my $count = 0; + + print "# Checking macros (approximate)\n"; + foreach my $f ( glob('include/openssl/*.h') ) { + # Skip some internals we don't want to document yet. + next if $f eq 'include/openssl/asn1.h'; + next if $f eq 'include/openssl/asn1t.h'; + next if $f eq 'include/openssl/err.h'; + open(IN, $f) || die "Can't open $f, $!"; + while ( ) { + next unless /^#\s*define\s*(\S+)\(/; + my $macro = $1; + next if $docced{$macro}; + next if $macro =~ /i2d_/ + || $macro =~ /d2i_/ + || $macro =~ /DEPRECATEDIN/ + || $macro =~ /IMPLEMENT_/ + || $macro =~ /DECLARE_/; + print "$f:$macro\n" if $opt_d; + $count++; + } + close(IN); + } + print "# Found $count macros missing (not all should be documented)\n" +} + sub printem() { my $libname = shift; @@ -263,7 +306,7 @@ sub printem() # Skip ASN1 utilities next if $func =~ /^ASN1_/; - print "$libname:$func\n"; + print "$libname:$func\n" if $opt_d; $count++; } print "# Found $count missing from $numfile\n\n"; @@ -328,7 +371,7 @@ sub collectnames { # then remove 'something'. Note that 'something' # may contain POD codes as well... (?:(?:[^\|]|<[^>]*>)*\|)? - # we're only interested in referenses that have + # we're only interested in references that have # a one digit section number ([^\/>\(]+\(\d\)) /gx; @@ -344,17 +387,135 @@ sub checklinks { } } -getopts('lnshu'); +sub publicize() { + foreach my $name ( &parsenum('util/libcrypto.num') ) { + $public{$name} = 1; + } + foreach my $name ( &parsenum('util/libssl.num') ) { + $public{$name} = 1; + } + foreach my $name ( &parsenum('util/private.num') ) { + $public{$name} = 1; + } +} -&help() if ( $opt_h ); +my %skips = ( + 'aes128' => 1, + 'aes192' => 1, + 'aes256' => 1, + 'aria128' => 1, + 'aria192' => 1, + 'aria256' => 1, + 'camellia128' => 1, + 'camellia192' => 1, + 'camellia256' => 1, + 'des' => 1, + 'des3' => 1, + 'idea' => 1, + '[cipher]' => 1, + '[digest]' => 1, +); + +sub checkflags() { + my $cmd = shift; + my %cmdopts; + my %docopts; + my $ok = 1; + + # Get the list of options in the command. + open CFH, "./apps/openssl list --options $cmd|" + || die "Can list options for $cmd, $!"; + while ( ) { + chop; + s/ .$//; + $cmdopts{$_} = 1; + } + close CFH; + + # Get the list of flags from the synopsis + open CFH, " ) { + chop; + last if /DESCRIPTION/; + next unless /\[B<-([^ >]+)/; + $docopts{$1} = 1; + } + close CFH; -die "Need one of -l -n -s or -u flags.\n" - unless $opt_l or $opt_n or $opt_s or $opt_u; + # See what's in the command not the manpage. + my @undocced = (); + foreach my $k ( keys %cmdopts ) { + push @undocced, $k unless $docopts{$k}; + } + if ( scalar @undocced > 0 ) { + $ok = 0; + foreach ( @undocced ) { + print "doc/man1/$cmd.pod: Missing -$_\n"; + } + } -if ( $opt_n or $opt_s ) { - foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) { - &check($_); + # See what's in the command not the manpage. + my @unimpl = (); + foreach my $k ( keys %docopts ) { + push @unimpl, $k unless $cmdopts{$k}; + } + if ( scalar @unimpl > 0 ) { + $ok = 0; + foreach ( @unimpl ) { + next if defined $skips{$_}; + print "doc/man1/$cmd.pod: Not implemented -$_\n"; + } } + + return $ok; +} + +getopts('cdlnphu'); + +&help() if $opt_h; +$opt_n = 1 if $opt_p; +$opt_u = 1 if $opt_d; + +die "Need one of -[cdlnpu] flags.\n" + unless $opt_c or $opt_l or $opt_n or $opt_u; + +if ( $opt_c ) { + my $ok = 1; + my @commands = (); + + # Get list of commands. + open FH, "./apps/openssl list -1 -commands|" + || die "Can't list commands, $!"; + while ( ) { + chop; + push @commands, $_; + } + close FH; + + # See if each has a manpage. + foreach ( @commands ) { + next if $_ eq 'help' || $_ eq 'exit'; + if ( ! -f "doc/man1/$_.pod" ) { + print "doc/man1/$_.pod does not exist\n"; + $ok = 0; + } else { + $ok = 0 if not &checkflags($_); + } + } + + # See what help is missing. + open FH, "./apps/openssl list --missing-help |" + || die "Can't list missing help, $!"; + while ( ) { + chop; + my ($cmd, $flag) = split; + print "$cmd has no help for -$flag\n"; + $ok = 0; + } + close FH; + + exit 1 if not $ok; } if ( $opt_l ) { @@ -364,6 +525,13 @@ if ( $opt_l ) { checklinks(); } +if ( $opt_n ) { + &publicize() if $opt_p; + foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) { + &check($_); + } +} + if ( $opt_u ) { my %temp = &getdocced('doc/man3'); foreach ( keys %temp ) { @@ -371,6 +539,7 @@ if ( $opt_u ) { } &printem('crypto', 'util/libcrypto.num'); &printem('ssl', 'util/libssl.num'); + &checkmacros(); } exit;