Update documentation regarding required output buffer memory size
[openssl.git] / util / process_docs.pl
old mode 100644 (file)
new mode 100755 (executable)
index fe8589b..a4287c2
@@ -1,7 +1,7 @@
 #! /usr/bin/env perl
-# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
 #
-# Licensed under the OpenSSL license (the "License").  You may not use
+# 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
@@ -13,52 +13,64 @@ use File::Spec::Functions;
 use File::Basename;
 use File::Copy;
 use File::Path;
-use if $^O ne "VMS", 'File::Glob' => qw/glob/;
+use FindBin;
+use lib "$FindBin::Bin/perl";
+use OpenSSL::Glob;
 use Getopt::Long;
 use Pod::Usage;
 
 use lib '.';
 use configdata;
 
+# We know we are in the 'util' directory and that our perl modules are
+# in util/perl
+use lib catdir(dirname($0), "perl");
+use OpenSSL::Util::Pod;
+
 my %options = ();
 GetOptions(\%options,
-           'sourcedir=s',       # Source directory
-           'subdir=s%',         # Subdirectories to look through,
+           'sourcedir=s@',      # Source directories
+           'section=i@',        # Subdirectories to look through,
                                 # with associated section numbers
            'destdir=s',         # Destination directory
            #'in=s@',             # Explicit files to process (ignores sourcedir)
-           #'section=i',         # Default section used for --in files
            'type=s',            # The result type, 'man' or 'html'
+           'suffix:s',          # Suffix to add to the extension.
+                                # Only used with type=man
            'remove',            # To remove files rather than writing them
            'dry-run|n',         # Only output file names on STDOUT
            'debug|D+',
           );
 
-unless ($options{subdir}) {
-    $options{subdir} = { apps   => '1',
-                         crypto => '3',
-                         ssl    => '3' };
+unless ($options{section}) {
+    $options{section} = [ 1, 3, 5, 7 ];
 }
 unless ($options{sourcedir}) {
-    $options{sourcedir} = catdir($config{sourcedir}, "doc");
+    $options{sourcedir} = [ catdir($config{sourcedir}, "doc"),
+                            catdir($config{builddir}, "doc") ];
 }
-pod2usage(1) unless ( defined $options{subdir}
+pod2usage(1) unless ( defined $options{section}
                       && defined $options{sourcedir}
                       && defined $options{destdir}
                       && defined $options{type}
                       && ($options{type} eq 'man'
                           || $options{type} eq 'html') );
+pod2usage(1) if ( $options{type} eq 'html'
+                  && defined $options{suffix} );
 
 if ($options{debug}) {
     print STDERR "DEBUG: options:\n";
-    print STDERR "DEBUG:   --sourcedir = $options{sourcedir}\n"
-        if defined $options{sourcedir};
+    foreach (sort @{$options{sourcedir}}) {
+        print STDERR "DEBUG:   --sourcedir   = $_\n";
+    }
     print STDERR "DEBUG:   --destdir   = $options{destdir}\n"
         if defined $options{destdir};
     print STDERR "DEBUG:   --type      = $options{type}\n"
         if defined $options{type};
-    foreach (keys %{$options{subdir}}) {
-        print STDERR "DEBUG:   --subdir    = $_=$options{subdir}->{$_}\n";
+    print STDERR "DEBUG:   --suffix    = $options{suffix}\n"
+        if defined $options{suffix};
+    foreach (sort @{$options{section}}) {
+        print STDERR "DEBUG:   --section   = $_\n";
     }
     print STDERR "DEBUG:   --remove    = $options{remove}\n"
         if defined $options{remove};
@@ -70,124 +82,125 @@ if ($options{debug}) {
 
 my $symlink_exists = eval { symlink("",""); 1 };
 
-foreach my $subdir (keys %{$options{subdir}}) {
-    my $section = $options{subdir}->{$subdir};
-    my $podsourcedir = catfile($options{sourcedir}, $subdir);
-    my $podglob = catfile($podsourcedir, "*.pod");
-
-    foreach my $podfile (glob $podglob) {
-        my $podname = basename($podfile, ".pod");
-        my $podpath = catfile($podfile);
-        my %podinfo = ( section => $section );
-
-        print STDERR "DEBUG: Reading $podpath\n" if $options{debug};
-        open my $pod_fh, $podpath or die "Trying to read $podpath: $!\n";
-        while (<$pod_fh>) {
-            s|\R$||;
-            if (m|^=for\s+comment\s+openssl_manual_section:\s*([0-9])\s*$|) {
-                print STDERR "DEBUG: Found man section number $1\n"
-                    if $options{debug};
-                $podinfo{section} = $1;
-            }
-            last if (m|^=head1|
-                     && defined $podinfo{lastsect}
-                     && $podinfo{lastsect} eq "NAME");
-            if (m|^=head1\s*(.*)|) {
-                $podinfo{lastsect} = $1;
-                $podinfo{lastsect} =~ s/\s+$//;
-                print STDERR "DEBUG: Found new pod section $1\n"
-                    if $options{debug};
-                print STDERR "DEBUG: Clearing pod section text\n"
-                    if $options{debug};
-                $podinfo{lastsecttext} = "";
-            }
-            next if (m|^=| || m|^\s*$|);
-            print STDERR "DEBUG: accumulating pod section text \"$_\"\n"
-                if $options{debug};
-            $podinfo{lastsecttext} .= " " if $podinfo{lastsecttext};
-            $podinfo{lastsecttext} .= $_;
-        }
-        close $pod_fh;
-        print STDERR "DEBUG: Done reading $podpath\n" if $options{debug};
-        $podinfo{lastsecttext} =~ s| - .*$||;
-        print STDERR "DEBUG: Done reading $podpath\n" if $options{debug};
-
-        my @podfiles =
-            grep { $_ ne $podname }
-            map { s|\s+||g; $_ }
-            split(m|,|, $podinfo{lastsecttext});
-
-        my $updir = updir();
-        my $name = uc $podname;
-        my $suffix = { man  => ".$podinfo{section}",
-                       html => ".html" } -> {$options{type}};
-        my $generate = { man  => "pod2man --name=$name --section=$podinfo{section} --center=OpenSSL --release=$config{version} \"$podpath\"",
-                         html => "pod2html \"--podroot=$options{sourcedir}\" --htmldir=$updir --podpath=apps:crypto:ssl \"--infile=$podpath\" \"--title=$podname\""
-                         } -> {$options{type}};
-        my $output_dir = catdir($options{destdir}, "man$podinfo{section}");
-        my $output_file = $podname . $suffix;
-        my $output_path = catfile($output_dir, $output_file);
-
-        if (! $options{remove}) {
-            my @output;
-            print STDERR "DEBUG: Processing, using \"$generate\"\n"
-                if $options{debug};
-            unless ($options{"dry-run"}) {
-                @output = `$generate`;
-                map { s|href="http://man\.he\.net/man|href="../man|g; } @output
-                    if $options{type} eq "html";
-            }
-            print STDERR "DEBUG: Done processing\n" if $options{debug};
+foreach my $section (sort @{$options{section}}) {
+    my $subdir = "man$section";
+    foreach my $sourcedir (@{$options{sourcedir}}) {
+        my $podsourcedir = catfile($sourcedir, $subdir);
+        my $podglob = catfile($podsourcedir, "*.pod");
+
+        foreach my $podfile (glob $podglob) {
+            my $podname = basename($podfile, ".pod");
+            my $podpath = catfile($podfile);
+            my %podinfo = extract_pod_info($podpath,
+                                           { debug => $options{debug},
+                                             section => $section });
+            my @podfiles = grep { $_ ne $podname } @{$podinfo{names}};
+
+            my $updir = updir();
+            my $name = uc $podname;
+            my $suffix =
+                { man  => ".$podinfo{section}".($options{suffix} // ""),
+                  html => ".html" } -> {$options{type}};
+            my $generate =
+                { man  => <<"_____",
+pod2man --name=$name --section=$podinfo{section}  --center=OpenSSL --release=$config{version}  "$podpath"
+_____
+                  html => <<"_____",
+pod2html "--podroot=$sourcedir" --htmldir=$updir --podpath=man1:man3:man5:man7 "--infile=$podpath" "--title=$podname" --quiet
+_____
+                } -> {$options{type}};
+            my $output_dir = catdir($options{destdir}, "man$podinfo{section}");
+            my $output_file = $podname . $suffix;
+            my $output_path = catfile($output_dir, $output_file);
 
-            if (! -d $output_dir) {
-                print STDERR "DEBUG: Creating directory $output_dir\n" if $options{debug};
+            if (! $options{remove}) {
+                my @output;
+                print STDERR "DEBUG: Processing, using \"$generate\"\n"
+                    if $options{debug};
                 unless ($options{"dry-run"}) {
-                    mkpath $output_dir
-                        or die "Trying to create directory $output_dir: $!\n";
-                }
-            }
-            print STDERR "DEBUG: Writing $output_path\n" if $options{debug};
-            unless ($options{"dry-run"}) {
-                open my $output_fh, '>', $output_path
-                    or die "Trying to write to $output_path: $!\n";
-                foreach (@output) {
-                    print $output_fh $_;
+                    @output = `$generate`;
+                    map { s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html"|g; } @output
+                        if $options{type} eq "html";
+                    if ($options{type} eq "man") {
+                        # Because some *roff parsers are more strict than
+                        # others, multiple lines in the NAME section must
+                        # be merged into one.
+                        my $in_name = 0;
+                        my $name_line = "";
+                        my @newoutput = ();
+                        foreach (@output) {
+                            if ($in_name) {
+                                if (/^\.SH "/) {
+                                    $in_name = 0;
+                                    push @newoutput, $name_line."\n";
+                                } else {
+                                    chomp (my $x = $_);
+                                    $name_line .= " " if $name_line;
+                                    $name_line .= $x;
+                                    next;
+                                }
+                            }
+                            if (/^\.SH +"NAME" *$/) {
+                                $in_name = 1;
+                            }
+                            push @newoutput, $_;
+                        }
+                        @output = @newoutput;
+                    }
                 }
-                close $output_fh;
-            }
-            print STDERR "DEBUG: Done writing $output_path\n" if $options{debug};
-        } else {
-            print STDERR "DEBUG: Removing $output_path\n" if $options{debug};
-            unless ($options{"dry-run"}) {
-                while (unlink $output_path) {}
-            }
-        }
-        print "$output_path\n";
+                print STDERR "DEBUG: Done processing\n" if $options{debug};
 
-        foreach (@podfiles) {
-            my $link_file = $_ . $suffix;
-            my $link_path = catfile($output_dir, $link_file);
-            if (! $options{remove}) {
-                if ($symlink_exists) {
-                    print STDERR "DEBUG: Linking $link_path -> $output_file\n"
+                if (! -d $output_dir) {
+                    print STDERR "DEBUG: Creating directory $output_dir\n"
                         if $options{debug};
                     unless ($options{"dry-run"}) {
-                        symlink $output_file, $link_path;
+                        mkpath $output_dir
+                            or die "Trying to create directory $output_dir: $!\n";
                     }
-                } else {
-                    print STDERR "DEBUG: Copying $output_path to link_path\n"
-                        if $options{debug};
-                    unless ($options{"dry-run"}) {
-                        copy $output_path, $link_path;
+                }
+                print STDERR "DEBUG: Writing $output_path\n" if $options{debug};
+                unless ($options{"dry-run"}) {
+                    open my $output_fh, '>', $output_path
+                        or die "Trying to write to $output_path: $!\n";
+                    foreach (@output) {
+                        print $output_fh $_;
                     }
+                    close $output_fh;
                 }
+                print STDERR "DEBUG: Done writing $output_path\n" if $options{debug};
             } else {
-                print STDERR "DEBUG: Removing $link_path\n" if $options{debug};
+                print STDERR "DEBUG: Removing $output_path\n" if $options{debug};
                 unless ($options{"dry-run"}) {
-                    while (unlink $link_path) {}
+                    while (unlink $output_path) {}
                 }
             }
-            print "$link_path -> $output_path\n";
+            print "$output_path\n";
+
+            foreach (@podfiles) {
+                my $link_file = $_ . $suffix;
+                my $link_path = catfile($output_dir, $link_file);
+                if (! $options{remove}) {
+                    if ($symlink_exists) {
+                        print STDERR "DEBUG: Linking $link_path -> $output_file\n"
+                            if $options{debug};
+                        unless ($options{"dry-run"}) {
+                            symlink $output_file, $link_path;
+                        }
+                    } else {
+                        print STDERR "DEBUG: Copying $output_path to link_path\n"
+                            if $options{debug};
+                        unless ($options{"dry-run"}) {
+                            copy $output_path, $link_path;
+                        }
+                    }
+                } else {
+                    print STDERR "DEBUG: Removing $link_path\n" if $options{debug};
+                    unless ($options{"dry-run"}) {
+                        while (unlink $link_path) {}
+                    }
+                }
+                print "$link_path -> $output_path\n";
+            }
         }
     }
 }
@@ -206,6 +219,7 @@ B<process_docs.pl>
 [B<--sourcedir>=I<dir>]
 B<--destdir>=I<dir>
 B<--type>=B<man>|B<html>
+[B<--suffix>=I<suffix>]
 [B<--remove>]
 [B<--dry-run>|B<-n>]
 [B<--debug>|B<-D>]
@@ -238,6 +252,10 @@ Top directory where the resulting files should end up
 
 Type of output to produce.  Currently supported are man pages and HTML files.
 
+=item B<--suffix>=I<suffix>
+
+A suffix added to the extension.  Only valid with B<--type>=B<man>
+
 =item B<--remove>
 
 Instead of writing the files, remove them.
@@ -254,9 +272,9 @@ Print extra debugging output.
 
 =head1 COPYRIGHT
 
-Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved.
 
-Licensed under the OpenSSL license (the "License").  You may not use
+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