#! /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 = ; 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, # 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;