Richard Levitte 8270c4791d Rework util/find-doc-nits to distinguish internal documentation
We didn't really distinguish internal and public documentation, or
matched that with the state of the documented symbols.  we therefore
needed to rework the logic to account for the state of each symbol.

To simplify things, and make them consistent, we load all of
util/*.num, util/*.syms and util/missing*.txt unconditionally.

Also, we rework the reading of the manuals to happen only once (or
well, not quite, Pod::Checker reads from file too, but at the very
least, our script isn't reading the same file multiple times).

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11476)
2020-04-11 15:51:43 +02:00

193 lines
4.9 KiB
Perl

# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (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
package OpenSSL::Util::Pod;
use strict;
use warnings;
use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = "0.1";
@ISA = qw(Exporter);
@EXPORT = qw(extract_pod_info);
@EXPORT_OK = qw();
=head1 NAME
OpenSSL::Util::Pod - utilities to manipulate .pod files
=head1 SYNOPSIS
use OpenSSL::Util::Pod;
my %podinfo = extract_pod_info("foo.pod");
# or if the file is already opened... Note that this consumes the
# remainder of the file.
my %podinfo = extract_pod_info(\*STDIN);
=head1 DESCRIPTION
=over
=item B<extract_pod_info "FILENAME", HASHREF>
=item B<extract_pod_info "FILENAME">
=item B<extract_pod_info GLOB, HASHREF>
=item B<extract_pod_info GLOB>
Extracts information from a .pod file, given a STRING (file name) or a
GLOB (a file handle). The result is given back as a hash table.
The additional hash is for extra parameters:
=over
=item B<section =E<gt> N>
The value MUST be a number, and will be the man section number
to be used with the given .pod file.
=item B<debug =E<gt> 0|1>
If set to 1, extra debug text will be printed on STDERR
=back
=back
=head1 RETURN VALUES
=over
=item B<extract_pod_info> returns a hash table with the following
items:
=over
=item B<section =E<gt> N>
The man section number this .pod file belongs to. Often the same as
was given as input.
=item B<names =E<gt> [ "name", ... ]>
All the names extracted from the NAME section.
=item B<contents =E<gt> "...">
The whole contents of the .pod file.
=back
=back
=cut
sub extract_pod_info {
my $input = shift;
my $defaults_ref = shift || {};
my %defaults = ( debug => 0, section => 0, %$defaults_ref );
my $fh = undef;
my $filename = undef;
my $contents;
# If not a file handle, then it's assume to be a file path (a string)
if (ref $input eq "") {
$filename = $input;
open $fh, $input or die "Trying to read $filename: $!\n";
print STDERR "DEBUG: Reading $input\n" if $defaults{debug};
$input = $fh;
}
if (ref $input eq "GLOB") {
local $/ = undef;
$contents = <$input>;
} else {
die "Unknown input type";
}
my @invisible_names = ();
my %podinfo = ( section => $defaults{section});
# Regexp to split a text into paragraphs found at
# https://www.perlmonks.org/?node_id=584367
# Most of all, \G (continue at last match end) and /g (anchor
# this match for \G) are significant
foreach (map { /\G((?:(?!\n\n).)*\n+|.+\z)/sg } $contents) {
# Remove as many line endings as possible from the end of the paragraph
while (s|\R$||) {}
print STDERR "DEBUG: Paragraph:\n$_\n"
if $defaults{debug};
# Stop reading when we have reached past the NAME section.
last if (m|^=head1|
&& defined $podinfo{lastsect}
&& $podinfo{lastsect} eq "NAME");
# Collect the section name
if (m|^=head1\s*(.*)|) {
$podinfo{lastsect} = $1;
$podinfo{lastsect} =~ s/\s+$//;
print STDERR "DEBUG: Found new pod section $1\n"
if $defaults{debug};
print STDERR "DEBUG: Clearing pod section text\n"
if $defaults{debug};
$podinfo{lastsecttext} = "";
}
# Add invisible names
if (m|^=for\s+openssl\s+names:\s*(.*)|s) {
my $x = $1;
my @tmp = map { map { s/\s+//g; $_ } split(/,/, $_) } $x;
print STDERR
"DEBUG: Found invisible names: ", join(', ', @tmp), "\n"
if $defaults{debug};
push @invisible_names, @tmp;
}
next if (m|^=| || m|^\s*$|);
# Collect the section text
print STDERR "DEBUG: accumulating pod section text \"$_\"\n"
if $defaults{debug};
$podinfo{lastsecttext} .= " " if $podinfo{lastsecttext};
$podinfo{lastsecttext} .= $_;
}
if (defined $fh) {
close $fh;
print STDERR "DEBUG: Done reading $filename\n" if $defaults{debug};
}
$podinfo{lastsecttext} =~ s|\s+-\s+.*$||s;
my @names =
map { s/^\s+//g; # Trim prefix blanks
s/\s+$//g; # Trim suffix blanks
s|/|-|g; # Treat slash as dash
$_ }
split(m|,|, $podinfo{lastsecttext});
print STDERR
"DEBUG: Collected names are: ",
join(', ', @names, @invisible_names), "\n"
if $defaults{debug};
return ( section => $podinfo{section},
names => [ @names, @invisible_names ],
contents => $contents,
filename => $filename );
}
1;