| #! /usr/bin/env perl |
| # Copyright 2002-2016 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 |
| # in the file LICENSE in the source distribution or at |
| # https://www.openssl.org/source/license.html |
| |
| |
| require 5.10.0; |
| use warnings; |
| use strict; |
| use File::Basename; |
| |
| # Collection of links in each POD file. |
| # filename => [ "foo(1)", "bar(3)", ... ] |
| my %link_collection = (); |
| # Collection of names in each POD file. |
| # "name(s)" => filename |
| my %name_collection = (); |
| |
| sub collect { |
| my $filename = shift; |
| $filename =~ m|man(\d)/|; |
| my $section = $1; |
| my $simplename = basename($filename, ".pod"); |
| my $err = 0; |
| |
| my $contents = ''; |
| { |
| local $/ = undef; |
| open POD, $filename or die "Couldn't open $filename, $!"; |
| $contents = <POD>; |
| close POD; |
| } |
| |
| $contents =~ /=head1 NAME([^=]*)=head1 /ms; |
| my $tmp = $1; |
| unless (defined $tmp) { |
| warn "weird name section in $filename\n"; |
| return 1; |
| } |
| $tmp =~ tr/\n/ /; |
| $tmp =~ s/-.*//g; |
| |
| my @names = map { s/\s+//g; $_ } split(/,/, $tmp); |
| unless (grep { $simplename eq $_ } @names) { |
| warn "$simplename missing among the names in $filename\n"; |
| push @names, $simplename; |
| } |
| foreach my $name (@names) { |
| next if $name eq ""; |
| my $namesection = "$name($section)"; |
| if (exists $name_collection{$namesection}) { |
| warn "$namesection, found in $filename, already exists in $name_collection{$namesection}\n"; |
| $err++; |
| } else { |
| $name_collection{$namesection} = $filename; |
| } |
| } |
| |
| my @foreign_names = |
| map { map { s/\s+//g; $_ } split(/,/, $_) } |
| $contents =~ /=for\s+comment\s+foreign\s+manuals:\s*(.*)\n\n/; |
| foreach (@foreign_names) { |
| $name_collection{$_} = undef; # It still exists! |
| } |
| |
| my @links = $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... |
| (?:(?:[^\|]|<[^>]*>)*\|)? |
| # we're only interested in referenses that have |
| # a one digit section number |
| ([^\/>\(]+\(\d\)) |
| /gx; |
| $link_collection{$filename} = [ @links ]; |
| |
| return $err; |
| } |
| |
| sub check { |
| foreach my $filename (sort keys %link_collection) { |
| foreach my $link (@{$link_collection{$filename}}) { |
| warn "$link in $filename refers to a non-existing manual\n" |
| unless exists $name_collection{$link}; |
| } |
| } |
| } |
| |
| |
| my $errs = 0; |
| foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) { |
| $errs += collect($_); |
| } |
| check() unless $errs > 0; |
| |
| exit; |