xref: /netbsd-src/crypto/external/bsd/openssl.old/dist/util/process_docs.pl (revision 4724848cf0da353df257f730694b7882798e5daf)
1*4724848cSchristos#! /usr/bin/env perl
2*4724848cSchristos# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3*4724848cSchristos#
4*4724848cSchristos# Licensed under the OpenSSL license (the "License").  You may not use
5*4724848cSchristos# this file except in compliance with the License.  You can obtain a copy
6*4724848cSchristos# in the file LICENSE in the source distribution or at
7*4724848cSchristos# https://www.openssl.org/source/license.html
8*4724848cSchristos
9*4724848cSchristosuse strict;
10*4724848cSchristosuse warnings;
11*4724848cSchristos
12*4724848cSchristosuse File::Spec::Functions;
13*4724848cSchristosuse File::Basename;
14*4724848cSchristosuse File::Copy;
15*4724848cSchristosuse File::Path;
16*4724848cSchristosuse FindBin;
17*4724848cSchristosuse lib "$FindBin::Bin/perl";
18*4724848cSchristosuse OpenSSL::Glob;
19*4724848cSchristosuse Getopt::Long;
20*4724848cSchristosuse Pod::Usage;
21*4724848cSchristos
22*4724848cSchristosuse lib '.';
23*4724848cSchristosuse configdata;
24*4724848cSchristos
25*4724848cSchristos# We know we are in the 'util' directory and that our perl modules are
26*4724848cSchristos# in util/perl
27*4724848cSchristosuse lib catdir(dirname($0), "perl");
28*4724848cSchristosuse OpenSSL::Util::Pod;
29*4724848cSchristos
30*4724848cSchristosmy %options = ();
31*4724848cSchristosGetOptions(\%options,
32*4724848cSchristos           'sourcedir=s',       # Source directory
33*4724848cSchristos           'section=i@',        # Subdirectories to look through,
34*4724848cSchristos                                # with associated section numbers
35*4724848cSchristos           'destdir=s',         # Destination directory
36*4724848cSchristos           #'in=s@',             # Explicit files to process (ignores sourcedir)
37*4724848cSchristos           'type=s',            # The result type, 'man' or 'html'
38*4724848cSchristos           'suffix:s',          # Suffix to add to the extension.
39*4724848cSchristos                                # Only used with type=man
40*4724848cSchristos           'remove',            # To remove files rather than writing them
41*4724848cSchristos           'dry-run|n',         # Only output file names on STDOUT
42*4724848cSchristos           'debug|D+',
43*4724848cSchristos          );
44*4724848cSchristos
45*4724848cSchristosunless ($options{section}) {
46*4724848cSchristos    $options{section} = [ 1, 3, 5, 7 ];
47*4724848cSchristos}
48*4724848cSchristosunless ($options{sourcedir}) {
49*4724848cSchristos    $options{sourcedir} = catdir($config{sourcedir}, "doc");
50*4724848cSchristos}
51*4724848cSchristospod2usage(1) unless ( defined $options{section}
52*4724848cSchristos                      && defined $options{sourcedir}
53*4724848cSchristos                      && defined $options{destdir}
54*4724848cSchristos                      && defined $options{type}
55*4724848cSchristos                      && ($options{type} eq 'man'
56*4724848cSchristos                          || $options{type} eq 'html') );
57*4724848cSchristospod2usage(1) if ( $options{type} eq 'html'
58*4724848cSchristos                  && defined $options{suffix} );
59*4724848cSchristos
60*4724848cSchristosif ($options{debug}) {
61*4724848cSchristos    print STDERR "DEBUG: options:\n";
62*4724848cSchristos    print STDERR "DEBUG:   --sourcedir = $options{sourcedir}\n"
63*4724848cSchristos        if defined $options{sourcedir};
64*4724848cSchristos    print STDERR "DEBUG:   --destdir   = $options{destdir}\n"
65*4724848cSchristos        if defined $options{destdir};
66*4724848cSchristos    print STDERR "DEBUG:   --type      = $options{type}\n"
67*4724848cSchristos        if defined $options{type};
68*4724848cSchristos    print STDERR "DEBUG:   --suffix    = $options{suffix}\n"
69*4724848cSchristos        if defined $options{suffix};
70*4724848cSchristos    foreach (sort @{$options{section}}) {
71*4724848cSchristos        print STDERR "DEBUG:   --section   = $_\n";
72*4724848cSchristos    }
73*4724848cSchristos    print STDERR "DEBUG:   --remove    = $options{remove}\n"
74*4724848cSchristos        if defined $options{remove};
75*4724848cSchristos    print STDERR "DEBUG:   --debug     = $options{debug}\n"
76*4724848cSchristos        if defined $options{debug};
77*4724848cSchristos    print STDERR "DEBUG:   --dry-run   = $options{\"dry-run\"}\n"
78*4724848cSchristos        if defined $options{"dry-run"};
79*4724848cSchristos}
80*4724848cSchristos
81*4724848cSchristosmy $symlink_exists = eval { symlink("",""); 1 };
82*4724848cSchristos
83*4724848cSchristosforeach my $section (sort @{$options{section}}) {
84*4724848cSchristos    my $subdir = "man$section";
85*4724848cSchristos    my $podsourcedir = catfile($options{sourcedir}, $subdir);
86*4724848cSchristos    my $podglob = catfile($podsourcedir, "*.pod");
87*4724848cSchristos
88*4724848cSchristos    foreach my $podfile (glob $podglob) {
89*4724848cSchristos        my $podname = basename($podfile, ".pod");
90*4724848cSchristos        my $podpath = catfile($podfile);
91*4724848cSchristos        my %podinfo = extract_pod_info($podpath,
92*4724848cSchristos                                       { debug => $options{debug},
93*4724848cSchristos                                         section => $section });
94*4724848cSchristos        my @podfiles = grep { $_ ne $podname } @{$podinfo{names}};
95*4724848cSchristos
96*4724848cSchristos        my $updir = updir();
97*4724848cSchristos        my $name = uc $podname;
98*4724848cSchristos        my $suffix = { man  => ".$podinfo{section}".($options{suffix} // ""),
99*4724848cSchristos                       html => ".html" } -> {$options{type}};
100*4724848cSchristos        my $generate = { man  => "pod2man --name=$name --section=$podinfo{section} --center=OpenSSL --release=$config{version} \"$podpath\"",
101*4724848cSchristos                         html => "pod2html \"--podroot=$options{sourcedir}\" --htmldir=$updir --podpath=man1:man3:man5:man7 \"--infile=$podpath\" \"--title=$podname\" --quiet"
102*4724848cSchristos                         } -> {$options{type}};
103*4724848cSchristos        my $output_dir = catdir($options{destdir}, "man$podinfo{section}");
104*4724848cSchristos        my $output_file = $podname . $suffix;
105*4724848cSchristos        my $output_path = catfile($output_dir, $output_file);
106*4724848cSchristos
107*4724848cSchristos        if (! $options{remove}) {
108*4724848cSchristos            my @output;
109*4724848cSchristos            print STDERR "DEBUG: Processing, using \"$generate\"\n"
110*4724848cSchristos                if $options{debug};
111*4724848cSchristos            unless ($options{"dry-run"}) {
112*4724848cSchristos                @output = `$generate`;
113*4724848cSchristos                map { s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html"|g; } @output
114*4724848cSchristos                    if $options{type} eq "html";
115*4724848cSchristos                if ($options{type} eq "man") {
116*4724848cSchristos                    # Because some *roff parsers are more strict than others,
117*4724848cSchristos                    # multiple lines in the NAME section must be merged into
118*4724848cSchristos                    # one.
119*4724848cSchristos                    my $in_name = 0;
120*4724848cSchristos                    my $name_line = "";
121*4724848cSchristos                    my @newoutput = ();
122*4724848cSchristos                    foreach (@output) {
123*4724848cSchristos                        if ($in_name) {
124*4724848cSchristos                            if (/^\.SH "/) {
125*4724848cSchristos                                $in_name = 0;
126*4724848cSchristos                                push @newoutput, $name_line."\n";
127*4724848cSchristos                            } else {
128*4724848cSchristos                                chomp (my $x = $_);
129*4724848cSchristos                                $name_line .= " " if $name_line;
130*4724848cSchristos                                $name_line .= $x;
131*4724848cSchristos                                next;
132*4724848cSchristos                            }
133*4724848cSchristos                        }
134*4724848cSchristos                        if (/^\.SH +"NAME" *$/) {
135*4724848cSchristos                            $in_name = 1;
136*4724848cSchristos                        }
137*4724848cSchristos                        push @newoutput, $_;
138*4724848cSchristos                    }
139*4724848cSchristos                    @output = @newoutput;
140*4724848cSchristos                }
141*4724848cSchristos            }
142*4724848cSchristos            print STDERR "DEBUG: Done processing\n" if $options{debug};
143*4724848cSchristos
144*4724848cSchristos            if (! -d $output_dir) {
145*4724848cSchristos                print STDERR "DEBUG: Creating directory $output_dir\n" if $options{debug};
146*4724848cSchristos                unless ($options{"dry-run"}) {
147*4724848cSchristos                    mkpath $output_dir
148*4724848cSchristos                        or die "Trying to create directory $output_dir: $!\n";
149*4724848cSchristos                }
150*4724848cSchristos            }
151*4724848cSchristos            print STDERR "DEBUG: Writing $output_path\n" if $options{debug};
152*4724848cSchristos            unless ($options{"dry-run"}) {
153*4724848cSchristos                open my $output_fh, '>', $output_path
154*4724848cSchristos                    or die "Trying to write to $output_path: $!\n";
155*4724848cSchristos                foreach (@output) {
156*4724848cSchristos                    print $output_fh $_;
157*4724848cSchristos                }
158*4724848cSchristos                close $output_fh;
159*4724848cSchristos            }
160*4724848cSchristos            print STDERR "DEBUG: Done writing $output_path\n" if $options{debug};
161*4724848cSchristos        } else {
162*4724848cSchristos            print STDERR "DEBUG: Removing $output_path\n" if $options{debug};
163*4724848cSchristos            unless ($options{"dry-run"}) {
164*4724848cSchristos                while (unlink $output_path) {}
165*4724848cSchristos            }
166*4724848cSchristos        }
167*4724848cSchristos        print "$output_path\n";
168*4724848cSchristos
169*4724848cSchristos        foreach (@podfiles) {
170*4724848cSchristos            my $link_file = $_ . $suffix;
171*4724848cSchristos            my $link_path = catfile($output_dir, $link_file);
172*4724848cSchristos            if (! $options{remove}) {
173*4724848cSchristos                if ($symlink_exists) {
174*4724848cSchristos                    print STDERR "DEBUG: Linking $link_path -> $output_file\n"
175*4724848cSchristos                        if $options{debug};
176*4724848cSchristos                    unless ($options{"dry-run"}) {
177*4724848cSchristos                        symlink $output_file, $link_path;
178*4724848cSchristos                    }
179*4724848cSchristos                } else {
180*4724848cSchristos                    print STDERR "DEBUG: Copying $output_path to link_path\n"
181*4724848cSchristos                        if $options{debug};
182*4724848cSchristos                    unless ($options{"dry-run"}) {
183*4724848cSchristos                        copy $output_path, $link_path;
184*4724848cSchristos                    }
185*4724848cSchristos                }
186*4724848cSchristos            } else {
187*4724848cSchristos                print STDERR "DEBUG: Removing $link_path\n" if $options{debug};
188*4724848cSchristos                unless ($options{"dry-run"}) {
189*4724848cSchristos                    while (unlink $link_path) {}
190*4724848cSchristos                }
191*4724848cSchristos            }
192*4724848cSchristos            print "$link_path -> $output_path\n";
193*4724848cSchristos        }
194*4724848cSchristos    }
195*4724848cSchristos}
196*4724848cSchristos
197*4724848cSchristos__END__
198*4724848cSchristos
199*4724848cSchristos=pod
200*4724848cSchristos
201*4724848cSchristos=head1 NAME
202*4724848cSchristos
203*4724848cSchristosprocess_docs.pl - A script to process OpenSSL docs
204*4724848cSchristos
205*4724848cSchristos=head1 SYNOPSIS
206*4724848cSchristos
207*4724848cSchristosB<process_docs.pl>
208*4724848cSchristos[B<--sourcedir>=I<dir>]
209*4724848cSchristosB<--destdir>=I<dir>
210*4724848cSchristosB<--type>=B<man>|B<html>
211*4724848cSchristos[B<--suffix>=I<suffix>]
212*4724848cSchristos[B<--remove>]
213*4724848cSchristos[B<--dry-run>|B<-n>]
214*4724848cSchristos[B<--debug>|B<-D>]
215*4724848cSchristos
216*4724848cSchristos=head1 DESCRIPTION
217*4724848cSchristos
218*4724848cSchristosThis script looks for .pod files in the subdirectories 'apps', 'crypto'
219*4724848cSchristosand 'ssl' under the given source directory.
220*4724848cSchristos
221*4724848cSchristosThe OpenSSL configuration data file F<configdata.pm> I<must> reside in
222*4724848cSchristosthe current directory, I<or> perl must have the directory it resides in
223*4724848cSchristosin its inclusion array.  For the latter variant, a call like this would
224*4724848cSchristoswork:
225*4724848cSchristos
226*4724848cSchristos perl -I../foo util/process_docs.pl {options ...}
227*4724848cSchristos
228*4724848cSchristos=head1 OPTIONS
229*4724848cSchristos
230*4724848cSchristos=over 4
231*4724848cSchristos
232*4724848cSchristos=item B<--sourcedir>=I<dir>
233*4724848cSchristos
234*4724848cSchristosTop directory where the source files are found.
235*4724848cSchristos
236*4724848cSchristos=item B<--destdir>=I<dir>
237*4724848cSchristos
238*4724848cSchristosTop directory where the resulting files should end up
239*4724848cSchristos
240*4724848cSchristos=item B<--type>=B<man>|B<html>
241*4724848cSchristos
242*4724848cSchristosType of output to produce.  Currently supported are man pages and HTML files.
243*4724848cSchristos
244*4724848cSchristos=item B<--suffix>=I<suffix>
245*4724848cSchristos
246*4724848cSchristosA suffix added to the extension.  Only valid with B<--type>=B<man>
247*4724848cSchristos
248*4724848cSchristos=item B<--remove>
249*4724848cSchristos
250*4724848cSchristosInstead of writing the files, remove them.
251*4724848cSchristos
252*4724848cSchristos=item B<--dry-run>|B<-n>
253*4724848cSchristos
254*4724848cSchristosDo not perform any file writing, directory creation or file removal.
255*4724848cSchristos
256*4724848cSchristos=item B<--debug>|B<-D>
257*4724848cSchristos
258*4724848cSchristosPrint extra debugging output.
259*4724848cSchristos
260*4724848cSchristos=back
261*4724848cSchristos
262*4724848cSchristos=head1 COPYRIGHT
263*4724848cSchristos
264*4724848cSchristosCopyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
265*4724848cSchristos
266*4724848cSchristosLicensed under the OpenSSL license (the "License").  You may not use
267*4724848cSchristosthis file except in compliance with the License.  You can obtain a copy
268*4724848cSchristosin the file LICENSE in the source distribution or at
269*4724848cSchristoshttps://www.openssl.org/source/license.html
270*4724848cSchristos
271*4724848cSchristos=cut
272