]>
Commit | Line | Data |
---|---|---|
1 | #! /usr/bin/env perl | |
2 | # Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. | |
3 | # | |
4 | # Licensed under the OpenSSL license (the "License"). You may not use | |
5 | # this file except in compliance with the License. You can obtain a copy | |
6 | # in the file LICENSE in the source distribution or at | |
7 | # https://www.openssl.org/source/license.html | |
8 | ||
9 | ||
10 | require 5.10.0; | |
11 | use warnings; | |
12 | use strict; | |
13 | use Pod::Checker; | |
14 | use File::Find; | |
15 | use File::Basename; | |
16 | ||
17 | my $temp = '/tmp/docnits.txt'; | |
18 | my $OUT; | |
19 | ||
20 | my %mandatory_sections = | |
21 | ( '*' => [ 'NAME', 'DESCRIPTION', 'COPYRIGHT' ], | |
22 | 1 => [ 'SYNOPSIS', '(COMMAND\s+)?OPTIONS' ], | |
23 | 3 => [ 'SYNOPSIS', 'RETURN\s+VALUES' ], | |
24 | 5 => [ ], | |
25 | 7 => [ ] ); | |
26 | my %default_sections = | |
27 | ( apps => 1, | |
28 | crypto => 3, | |
29 | ssl => 3 ); | |
30 | ||
31 | sub check() | |
32 | { | |
33 | my $filename = shift; | |
34 | my $dirname = basename(dirname($filename)); | |
35 | ||
36 | my $contents = ''; | |
37 | { | |
38 | local $/ = undef; | |
39 | open POD, $filename or die "Couldn't open $filename, $!"; | |
40 | $contents = <POD>; | |
41 | close POD; | |
42 | } | |
43 | ||
44 | my $id = "${filename}:1:"; | |
45 | print $OUT "$id doesn't start with =pod\n" | |
46 | if $contents !~ /^=pod/; | |
47 | print $OUT "$id doesn't end with =cut\n" | |
48 | if $contents !~ /=cut\n$/; | |
49 | print $OUT "$id more than one cut line.\n" | |
50 | if $contents =~ /=cut.*=cut/ms; | |
51 | print $OUT "$id missing copyright\n" | |
52 | if $contents !~ /Copyright .* The OpenSSL Project Authors/; | |
53 | print $OUT "$id copyright not last\n" | |
54 | if $contents =~ /head1 COPYRIGHT.*=head/ms; | |
55 | print $OUT "$id head2 in All uppercase\n" | |
56 | if $contents =~ /head2\s+[A-Z ]+\n/; | |
57 | print $OUT "$id period in NAME section\n" | |
58 | if $contents =~ /NAME.*\.\n.*SYNOPSIS/ms; | |
59 | print $OUT "$id POD markup in NAME section\n" | |
60 | if $contents =~ /NAME.*[<>].*SYNOPSIS/ms; | |
61 | ||
62 | # Look for multiple consecutive openssl #include lines. | |
63 | # Consecutive because of files like md5.pod. Sometimes it's okay | |
64 | # or necessary, as in ssl/SSL_set1_host.pod | |
65 | if ( $contents !~ /=for comment multiple includes/ ) { | |
66 | if ( $contents =~ /=head1 SYNOPSIS(.*)=head1 DESCRIPTION/ms ) { | |
67 | my $count = 0; | |
68 | foreach my $line ( split /\n+/, $1 ) { | |
69 | if ( $line =~ m@include <openssl/@ ) { | |
70 | if ( ++$count == 2 ) { | |
71 | print $OUT "$id has multiple includes\n"; | |
72 | } | |
73 | } else { | |
74 | $count = 0; | |
75 | } | |
76 | } | |
77 | } | |
78 | } | |
79 | ||
80 | # Find what section this page is in. If run from "." assume | |
81 | # section 3. | |
82 | my $section = $default_sections{$dirname} || 3; | |
83 | if ($contents =~ /^=for\s+comment\s+openssl_manual_section:\s*(\d+)\s*$/m) { | |
84 | $section = $1; | |
85 | } | |
86 | ||
87 | foreach ((@{$mandatory_sections{'*'}}, @{$mandatory_sections{$section}})) { | |
88 | print $OUT "$id doesn't have a head1 section matching $_\n" | |
89 | if $contents !~ /^=head1\s+${_}\s*$/m; | |
90 | } | |
91 | ||
92 | podchecker($filename, $OUT); | |
93 | } | |
94 | ||
95 | open $OUT, '>', $temp | |
96 | or die "Can't open $temp, $!"; | |
97 | foreach (@ARGV ? @ARGV : glob('*/*.pod')) { | |
98 | &check($_); | |
99 | } | |
100 | close $OUT; | |
101 | ||
102 | my $count = 0; | |
103 | open $OUT, '<', $temp | |
104 | or die "Can't read $temp, $!"; | |
105 | while ( <$OUT> ) { | |
106 | next if /\(section\) in.*deprecated/; | |
107 | $count++; | |
108 | print; | |
109 | } | |
110 | close $OUT; | |
111 | unlink $temp || warn "Can't remove $temp, $!"; | |
112 | ||
113 | exit $count; |