1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
# Copyright 2016-2021 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});
$podinfo{lastsecttext} = ""; # init needed in case input file is empty
# 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;
|