Add apps/progs.h to gitignore
[openssl.git] / util / find-doc-nits
index 0b85515..8f6d482 100755 (executable)
@@ -24,6 +24,7 @@ our($opt_u);
 our($opt_h);
 our($opt_n);
 our($opt_l);
+our($opt_p);
 
 sub help()
 {
@@ -32,6 +33,7 @@ Find small errors (nits) in documentation.  Options:
     -l Print bogus links
     -n Print nits in POD pages
     -s Also print missing sections in POD pages (implies -n)
+    -p Warn if non-public name documented (implies -n)
     -u List undocumented functions
     -h Print this help message
 EOF
@@ -40,6 +42,7 @@ EOF
 
 my $temp = '/tmp/docnits.txt';
 my $OUT;
+my %public;
 
 my %mandatory_sections =
     ( '*'    => [ 'NAME', 'DESCRIPTION', 'COPYRIGHT' ],
@@ -59,7 +62,10 @@ sub name_synopsis()
     return unless $contents =~ /=head1 NAME(.*)=head1 SYNOPSIS/ms;
     my $tmp = $1;
     $tmp =~ tr/\n/ /;
-    $tmp =~ s/-.*//g;
+    print "$id trailing comma before - in NAME\n" if $tmp =~ /, *-/;
+    $tmp =~ s/ -.*//g;
+    $tmp =~ s/  */ /g;
+    print "$id missing comma in NAME\n" if $tmp =~ /[^,] /;
     $tmp =~ s/,//g;
 
     my $dirname = dirname($filename);
@@ -77,8 +83,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;
@@ -96,6 +106,9 @@ sub name_synopsis()
         } elsif ( $line =~ /typedef.* (\S+);/ ) {
             # a simple typedef: typedef ... NAME;
             $sym = $1;
+        } elsif ( $line =~ /enum (\S*) \{/ ) {
+            # an enumeration: enum ... {
+            $sym = $1;
         } elsif ( $line =~ /#define ([A-Za-z0-9_]+)/ ) {
             $sym = $1;
         } elsif ( $line =~ /([A-Za-z0-9_]+)\(/ ) {
@@ -156,6 +169,10 @@ sub check()
         if $contents =~ /=head1 NAME.*\.\n.*=head1 SYNOPSIS/ms;
     print "$id POD markup in NAME section\n"
         if $contents =~ /=head1 NAME.*[<>].*=head1 SYNOPSIS/ms;
+    print "$id Duplicate $1 in L<>\n"
+        if $contents =~ /L<([^>]*)\|([^>]*)>/ && $1 eq $2;
+    print "$id Bad =over $1\n"
+        if $contents =~ /=over([^ ][^24])/;
 
     # Look for multiple consecutive openssl #include lines.
     # Consecutive because of files like md5.pod. Sometimes it's okay
@@ -212,14 +229,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;
 }
 
@@ -243,6 +264,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 ( <IN> ) {
+            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";
+            $count++;
+        }
+        close(IN);
+    }
+    print "# Found $count macros missing (not all should be documnted)\n"
+}
+
 sub printem()
 {
     my $libname = shift;
@@ -336,14 +385,29 @@ 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;
+    }
+}
+
+getopts('lnsphu');
+
+&help() if $opt_h;
 
-&help() if ( $opt_h );
+die "Need one of -l -n -s -p or -u flags.\n"
+    unless $opt_l or $opt_n or $opt_s or $opt_p or $opt_u;
 
-die "Need one of -l -n -s or -u flags.\n"
-    unless $opt_l or $opt_n or $opt_s or $opt_u;
+$opt_n = 1 if $opt_s or $opt_p;
 
-if ( $opt_n or $opt_s ) {
+if ( $opt_n ) {
+    &publicize() if $opt_p;
     foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) {
         &check($_);
     }
@@ -363,6 +427,7 @@ if ( $opt_u ) {
     }
     &printem('crypto', 'util/libcrypto.num');
     &printem('ssl', 'util/libssl.num');
+    &checkmacros();
 }
 
 exit;