From ee8bf98f942d2fb91ce92ce71eb3ac1cb86b40b7 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 15 Apr 2015 18:01:26 -0500 Subject: [PATCH] Generate documentation from Perl modules Add rules to generate HTML from POD in Perl modules and scripts. Generate docs from several EPICS/ Perl modules. --- configure/RULES.Db | 9 +++- src/tools/EPICS/Getopts.pm | 70 +++++++++++++++++++++++++++++++ src/tools/EPICS/Path.pm | 51 +++++++++++++--------- src/tools/EPICS/Readfile.pm | 84 ++++++++++++++++++++++++++++++++++++- src/tools/Makefile | 4 ++ src/tools/podToHtml.pl | 69 +++++++++++++++++++++++++++--- 6 files changed, 259 insertions(+), 28 deletions(-) diff --git a/configure/RULES.Db b/configure/RULES.Db index 63b06dfed..7ea4defd7 100644 --- a/configure/RULES.Db +++ b/configure/RULES.Db @@ -443,7 +443,14 @@ $(COMMON_DIR)/%.html: %.pm $(TOOLS)/podToHtml.pl $(COMMON_DIR)/%.html: ../%.pm $(TOOLS)/podToHtml.pl @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $< + $(PERL) $(TOOLS)/podToHtml.pl -s -o $(notdir $@) $< + @$(MKDIR) -p $(dir $@) + @$(MV) $(notdir $@) $@ + +$(COMMON_DIR)/%.html: ../%.pl $(TOOLS)/podToHtml.pl + @$(RM) $(notdir $@) + $(PERL) $(TOOLS)/podToHtml.pl -s -o $(notdir $@) $< + @$(MKDIR) -p $(dir $@) @$(MV) $(notdir $@) $@ .PRECIOUS: $(COMMON_DIR)/%.html %.html diff --git a/src/tools/EPICS/Getopts.pm b/src/tools/EPICS/Getopts.pm index c08db62aa..f448985d0 100644 --- a/src/tools/EPICS/Getopts.pm +++ b/src/tools/EPICS/Getopts.pm @@ -2,6 +2,76 @@ package EPICS::Getopts; require 5.000; require Exporter; +=head1 NAME + +EPICS::Getopts - Process single-character command-line options + +=head1 SYNOPSIS + + use EPICS::Getopts; + + getopts('vo:I@') or die "Bad option\n"; + # -v is a counted flag; -o takes an argument and + # sets $opt_o to its value; -I may be used more than + # once, the values are pushed onto @opt_I + +=head1 DESCRIPTION + +This version of getopts has been modified from the Perl original to add +functionality that was needed by EPICS Perl applications. Some functionality of +the original has also been removed. The main changes were: + +=over 2 + +=item * + +Arguments without any modifiers are now counted, rather than storing a binary +value in the C<$opt_x> variable. This means that multiple copies of the same +option can be detected by the program. + +=item * + +A new B> modifier is supported which collects the option arguments in an +array C<@opt_x>. Multiple copies of this option can be given, which pushes each +argument value onto the end of the array. + +=back + + +=head1 FUNCTIONS + +=over 4 + +=item B> + +The getopts() function processes single-character options. It takes one +argument, a string containing all the options that should be recognized. For +option letters in the string that are followed by a colon B> it sets +C<$opt_x> (where x is the option letter) to the value of that argument. For +option letters followed by an at sign B> it pushes each subsequent argument +onto the array C<@opt_x> (where x is the option letter). For option letters +without any qualifier it adds 1 to the value of C<$opt_x>. Options which take an +argument don't care whether there is a space between the option and the +argument. + +If unspecified switches are found on the command-line, the user will be warned +that an unknown option was given. The getopts() function returns true unless an +invalid option was found. + +Note that, if your code is running under the recommended C +pragma, you will need to declare the necesary package variables with "our" +before the call to getopts: + + our($opt_v, $opt_o, @opt_I); + +To allow programs to process arguments that look like options but aren't, the +function will stop processing options when it sees the argument B>. The +B> will be removed from @ARGV. + +=back + +=cut + @ISA = qw(Exporter); @EXPORT = qw(getopts); diff --git a/src/tools/EPICS/Path.pm b/src/tools/EPICS/Path.pm index 83a91efb3..4ddbbc59e 100644 --- a/src/tools/EPICS/Path.pm +++ b/src/tools/EPICS/Path.pm @@ -7,17 +7,17 @@ # $Revision-Id$ -use Carp; -use Cwd qw(getcwd abs_path); -use File::Spec; +package EPICS::Path; +require 5.000; +require Exporter; -=head1 EPICS::Path +=head1 NAME EPICS::Path - Path-handling utilities for EPICS tools =head1 SYNOPSIS - use lib '@EPICS_BASE@/lib/perl'; + use lib '/path/to/base/lib/perl'; use EPICS::Path; my $dir = UnixPath('C:\Program Files\EPICS'); @@ -26,17 +26,29 @@ EPICS::Path - Path-handling utilities for EPICS tools =head1 DESCRIPTION -C provides functions for processing pathnames that are commonly -needed by EPICS tools. Windows is not the only culprit, some older automount -daemons insert strange prefixes into absolute directory paths that we have to -remove before storing the result for use later. +This module provides functions for processing pathnames that are commonly needed +by EPICS tools. Windows is not the only culprit, some older automount daemons +insert strange prefixes into absolute directory paths that we have to remove +before storing the result for use later. +Note that these functions are only designed to work on operating systems that +recognize a forward slash C as a directory separator; this does include +Windows, but not pre-OS-X versions of MacOS which used a colon C<:> instead. =head1 FUNCTIONS =over 4 -=item UnixPath( I ) +=cut + +use Carp; +use Cwd qw(getcwd abs_path); +use File::Spec; + +@ISA = qw(Exporter); +@EXPORT = qw(UnixPath LocalPath AbsPath); + +=item B> C should be used on any pathnames provided by external tools to convert them into a form that Perl understands. @@ -57,7 +69,7 @@ sub UnixPath { return $newpath; } -=item LocalPath( I ) +=item B> C should be used when generating pathnames for external tools or to put into a file. It converts paths from the Unix form that Perl understands to @@ -65,7 +77,7 @@ any necessary external representation, and also removes automounter prefixes to put the path into its canonical form. Before Leopard, the Mac OS X automounter inserted a verbose prefix, and in case -anyone is still using SunOS it adds its own prefix as well. +anyone is still using SunOS (pre-Solaris) it added its own prefix as well. =cut @@ -81,19 +93,19 @@ sub LocalPath { return $newpath; } -=item AbsPath( I ) +=item B> -=item AbsPath( I, I ) +=item B> -The C function in Perl's C module doesn't like non-existent +The C function in Perl's F module doesn't like non-existent path components other than in the final position, but EPICS tools needs to be able to handle them in paths like F<$(TOP)/lib/$(T_A)> before the F<$(TOP)/lib> directory has been created. -C takes a path I and optionally an absolute path to a directory -that first is relative to; if the second argument is not provided the current -working directory is used. The result returned has been filtered through -C to remove any automounter prefixes. +C takes a path C<$path> and optionally an absolute path to a directory +that the first is relative to; if the second argument is not provided the +current working directory is used instead. The result returned has also been +filtered through C to remove any automounter prefixes. =cut @@ -139,5 +151,4 @@ This software is distributed under the terms of the EPICS Open License. =cut - 1; diff --git a/src/tools/EPICS/Readfile.pm b/src/tools/EPICS/Readfile.pm index 43ee493f4..325efb17b 100644 --- a/src/tools/EPICS/Readfile.pm +++ b/src/tools/EPICS/Readfile.pm @@ -1,5 +1,5 @@ #************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne +# Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. # EPICS BASE is distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. @@ -11,6 +11,28 @@ package EPICS::Readfile; require 5.000; require Exporter; +=head1 NAME + +EPICS::Readfile - DBD and DB-file input for EPICS tools + +=head1 SYNOPSIS + + use lib '/path/to/base/lib/perl'; + use EPICS::macLib; + use EPICS::Readfile; + + my $macros = EPICS::macLib->new('a=1', 'b=2'); + my @path = qw(../dbd /opt/epics/base/dbd); + my $contents = Readfile('input.dbd', $macros, \@path); + printf "Read in %d files", scalar @inputfiles; + +=head1 DESCRIPTION + +This module provides a function for reading DBD and DB files that is commonly +needed by EPICS tools. + +=cut + use EPICS::macLib; @ISA = qw(Exporter); @@ -69,6 +91,57 @@ sub unquote { return $s; } + +=head1 FUNCTIONS + +=over 4 + +=item B> + +This function reads an EPICS DBD or DB file into a string, substitutes any +macros present, then parses the contents for any C, C and +C commands found therein and recursively executes those commands. The +return value from the function is a string comprising the fully expanded +contents of those files. Before executing them any commands will be replaced +with specially formatted comments that allow the original command to be +recovered during later parsing. + +I takes as arguments the input filename, an optional handle to a set +of macro values from L, and a reference to an array +containing the current search path. + +If macro expansion is not required, the second argument may be any boolean False +value such as C<0> or C<()>. See L for more details about +this argument. + +The path argument is a reference to an array of directory paths to be searched, +in order. These paths may be used to locate the original input file and any +include files that it references. The path array will be modified by any +C or C commands found while parsing the input files. + +While processing input filenames (either the original argument or an include +filename) if the filename does not contain any forward-slash C characters the +path will be searched and the first file matching that name will be used. If the +filename contains one or more forward-slash characters it must be either an +absolute path or one that is relative to the current working directory; the +search path is not used in this case. + +=back + +=head1 VARIABLES + +=over 4 + +=item B> + +As new files are processed their names are added to this array which may be +examimed after the I function returns, for example to calculate the +complete set of dependencies for the input file. + +=back + +=cut + sub Readfile { my ($file, $macros, $Rpath) = @_; print "Readfile($file)\n" if $debug; @@ -98,4 +171,13 @@ sub Readfile { return join "\n", @output; } +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2015 UChicago Argonne LLC, as Operator of Argonne National +Laboratory. + +This software is distributed under the terms of the EPICS Open License. + +=cut + 1; diff --git a/src/tools/Makefile b/src/tools/Makefile index 54115bc79..00314e824 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -54,6 +54,10 @@ PERL_SCRIPTS += podToHtml.pl PERL_SCRIPTS += registerRecordDeviceDriver.pl HTMLS = style.css +HTMLS += EPICS/Getopts.html +HTMLS += EPICS/Path.html +HTMLS += EPICS/Readfile.html +HTMLS += podToHtml.html # Build Package Config Files diff --git a/src/tools/podToHtml.pl b/src/tools/podToHtml.pl index 2baf9e80f..d5817c797 100644 --- a/src/tools/podToHtml.pl +++ b/src/tools/podToHtml.pl @@ -14,24 +14,72 @@ use warnings; use Getopt::Std; use Pod::Simple::HTML; -our ($opt_o); +=head1 NAME + +podToHtml.pl - convert EPICS .pod files to .html + +=head1 SYNOPSIS + +B [B<-s>] [B<-o> file.html] file.pod + +=head1 DESCRIPTION + +Converts files from Perl's POD format into HTML format. + +The generated HTML output file refers to a CSS style sheet F which +can be located in a parent directory of the final installation directory. The +relative path to that file (i.e. the number of parent directories to traverse) +is calculated based on the number of components in the path to the input file. + +=head1 OPTIONS + +I understands the following options: + +=over 4 + +=item B<-s> + +Indicates that the first component of the input file path is not part of the +final installation path, thus should be removed before calculating the relative +path to the style-sheet file. + +=item B<-o> file.html + +Name of the HTML output file to be created. + +=back + +If no output filename is set, the file created will be named after the input +file, removing any directory components in the path and replacing any file +extension with .html. + +=cut + +our $opt_o; +our $opt_s = 0; $Getopt::Std::OUTPUT_HELP_VERSION = 1; -&HELP_MESSAGE if !getopts('o:') || @ARGV != 1; +&HELP_MESSAGE if !getopts('o:s') || @ARGV != 1; my $infile = shift @ARGV; +my @inpath = split /\//, $infile; +my $file = pop @inpath; + if (!$opt_o) { - ($opt_o = $infile) =~ s/\. \w+ $/.html/x; - $opt_o =~ s/^.*\///; + ($opt_o = $file) =~ s/\. \w+ $/.html/x; } +# Calculate path to style.css file +shift @inpath if $opt_s; # Remove leading .. +my $root = '../' x scalar @inpath; + open my $out, '>', $opt_o or die "Can't create $opt_o: $!\n"; my $podHtml = Pod::Simple::HTML->new(); -$podHtml->html_css('style.css'); +$podHtml->html_css($root . 'style.css'); $podHtml->perldoc_url_prefix(''); $podHtml->perldoc_url_postfix('.html'); $podHtml->set_source($infile); @@ -42,6 +90,15 @@ print $out $html; close $out; sub HELP_MESSAGE { - print STDERR "Usage: podToHtml.pl [-o file.html] file.pod\n"; + print STDERR "Usage: podToHtml.pl [-s] [-o file.html] file.pod\n"; exit 2; } + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2010 UChicago Argonne LLC, as Operator of Argonne National +Laboratory. + +This software is distributed under the terms of the EPICS Open License. + +=cut