#!/usr/local/bin/perl
#
# Build documentation from a definition file, a template, and possibly
# a bunch of individual description files.
#
# -d identifies the definition file (see api.list for documentation).
#
# -l specifies a layout type:
#
# 0 means full, with each entry in a separate document starting with an
# H3 heading and the main document containing a linked subtable of
# contents for each type of entry (routines, constants, et cetera);
# 1 is the same as 0, except everything is in a single monolithic file;
# 2 means simpler, with no tables of subcontents and each entry jumping
# right to the definition without the preamble.
#
# Layout 2 results in reduced file size (though it's still huge), but
# is slightly susceptible to potentially confusing display values if
# an entry has no definition in the data file. Layout 1 guarantees
# a little more text in such a case, but at a significant cost in file size.
# Layout 0 is the best for reference work, but scanning through
# definitions is more difficult since they're in separate files.
#
# -n indicates that there should be NO hyperlinks in the output. (Useful
# if destined for inclusion in a on-electronic format.)
#
# -o specifies the name of the master output file, or "-" for stdout.
# Note that "-" is not permitted in combination with "-l 0" because this
# name is used in anchors with that layout.
#
# -t specifies the template file for the main dictionary page.
#
# -v enables verbose mode.
#
# -D enable debug messages (if any are implemented).
#
# Edit history:
#
# 2001-05-04 Ken Coar
# Added -n option (no hyperlinks).
# 2000-09-16 Ken Coar
# Reworked to use the APIdict.pm module, to which a lot of the
# file reading/writing functionality has been moved.
# 2000-07-23 Ken Coar
# Fix up the handling of '\\' in the formatter. Also added
# messages when description files are missing or not specified.
# 2000-07-12 Ken Coar
# Add some more verbosity, and fix item emission for layout styles > 0.
# 1999-12-08 Ken Coar
# Downcase the HTML tags and do some line merging.
# 1999-03-31 Ken Coar
# Get rid of the ARGV processing and use command-line options
# instead. Add a third level of layout; 0 now means 'full,'
# with each definition in its own file.
# 1998-06-23 Chuck Murcko
# Bug fix for ARGV[1] processing of arguments with value 0.
# 1998-05-26 Ken Coar
# Change missing-args message to a 'usage' display, change references
# to s, clean up some style issues, and document what Ben's
# changes meant and how to use them.
# 1998-05-25 Ben Laurie
# Add capability for alternate, simpler, layout of output. ARGV[1] is
# either 0 for full cross-linked output or 1 for simple.
# 1998-05-03 Ken Coar
# Cleaned up a little bit, from horrible to bad, before checking in to
# CVS.
# 1998-04-?? Ken Coar
# Prototyped..
#
use APIdict;
#
# Make sure that anything we utter to stderr shows up instanter..
#
$tfh = select(STDERR);
$| = 1;
select($tfh);
$command_line = join(" ", $0, @ARGV);
use Getopt::Std;
@errors = ();
$ofh = \*STDOUT;
getopts("Dd:l:no:t:v", \%arg);
$Verbose = defined($arg{'v'});
$Debug = defined($arg{'D'});
if (! defined($arg{'d'})) {
push(@errors, "definition file (-d option) is required");
}
else {
$Dfile = $arg{'d'};
}
if ((! defined($arg{'l'})) || ($arg{'l'} < 0) || ($arg{'l'} > 2)) {
push(@errors, "layout type (-l option) must be a value 0-2");
}
else {
$Layout = $arg{'l'};
&verbose("Using layout style $Layout");
}
$nolinks = $arg{'n'};
&verbose("Hyperlinking is " . ($nolinks ? "OFF" : "ON"));
if ((! defined($arg{'o'})) && ($Layout < 1)) {
push(@errors, "output filename (-o option) is required with -l 0");
}
elsif (($arg{'o'} eq '-') && ($Layout < 1)) {
push(@errors, "output filename (-o options) may not be '-' with -l 0");
}
elsif (defined($arg{'o'}) && ($arg{'o'} ne '-')) {
open $ofh, ">$arg{'o'}" || die "can't open output file";
}
if (! defined($arg{'t'})) {
push(@errors, "output template file (-t option) is required");
}
else {
$InFile = $arg{'t'};
}
if ($#errors > -1) {
foreach (@errors) {
print STDERR "$0: $_\n";
}
&usage();
exit(1);
}
$dict = new APIdict($Dfile);
$dict->hyperlinks(! $nolinks);
$OutFile = "$InFile.bak";
%URL = ();
%HREF = ();
@Prologue = ();
@Epilogue = ();
@code_bracket = ("
Many of the compile-time choices are determined by the settings of
various constants created with
Some of the Apache Web server's constants (such as SERVER_VERSION)
can be overridden with
compile-time definitions on the compiler command line. Others, like
MAX_STRING_LEN,
are provided as conveniences, and shouldn't be modified except under
special circumstances. Still others, such as
OR_LIMIT,
have specific values that must not be altered.
", "
");
@no_bracket = ("", "");
#
#
# Just in case the input template was the output from a previous run,
# save it in case *this* run doesn't work as expected.
#
# Now copy the input file to a backup, extracting the prologue and
# epilogue sections as we go.
#
&verbose("Copying input template ($InFile) to backup ($OutFile)");
open INFILE, "<$InFile" || die ("Can't open input file $InFile");
open OUTFILE, ">$OutFile" || die ("Can't open output file $OutFile");
$state = 1;
while ($line =
EOHT
print $ofh <
EOHT
&verbose("Analysing routines: \\c");
@keys = $dict->routine_list();
push(@keys, $dict->macro_list());
&list_items(@keys);
&verbose(($#keys + 1) . " found.");
&verbose("Dumping routines.");
&dump_list('R', @keys);
print $ofh <
EOHT
&verbose("Analysing structures: \\c");
@keys = $dict->structure_list();
&list_items(@keys);
&verbose(($#keys + 1) . " found.");
&verbose("Dumping structures.");
&dump_list('S', @keys);
print $ofh <
EOHT
&verbose("Analysing data cells: \\c");
@keys = $dict->cell_list();
&list_items(@keys);
&verbose(($#keys + 1) . " found.");
&verbose("Dumping data cells.");
&dump_list('D', @keys);
$etext = <#define
statements.
Things like the maximum size of fixed-length buffers, the server
version string, and operating system-specific code fragment compilation
are controlled by constants.
EOHT
$etext = $dict->add_links($etext, "", %HREF);
print $ofh $etext;
&verbose("Analysing constants: \\c");
@keys = $dict->constant_list();
&list_items(@keys);
&verbose(($#keys + 1) . " found.");
&verbose("Dumping constants.");
&dump_list('C', @keys);
&verbose("Dumping epilogue.");
print $ofh @Epilogue;
exit(0);
#
# Dump a hash in alphabetical order.
#
sub dump_list {
local($prefix, @keys) = @_;
my($i) = 0;
@keys = sort {uc($a) cmp uc($b)} (@keys);
foreach $key (@keys) {
local (*dfh);
local ($previous, $next) = ("", "");
$previous = $keys[$i - 1] if ($i > 0);
$next = $keys[$i + 1] if ($i < $#keys);
if ($Layout == 0) {
open(dfh, ">$URL{$key}");
&dump_item(\*dfh, $prefix, $key, $list{$key}, $previous, $next);
close(dfh);
}
else {
&dump_item($ofh, $prefix, $key, $list{$key}, $previous, $next);
}
$i++;
}
}
sub list_items {
local(@items) = @_;
if ($Layout == 0) {
print $ofh <Apache 1.3 API Documentation
EOHT
my($p) = $dict->category_name($rtype);
if ($Layout == 0) {
print $ofh <
$edited
$edited\n"; } $edited = $dict->add_links($isamp, $iname, @code_bracket, %HREF); if ((! $edited) && ($Layout < 2)) { $edited = "No examples available."; &verbose("$0: no examples for $iname"); } if (($Layout < 2) || $edited) { print $ofh <
$edited
EOHT
print $ofh &link('Table of Contents', $arg{'o'}) . "\n";
print $ofh "(" . &link('Routines', "$arg{'o'}#Routines") . ",\n";
print $ofh &link('Structures', "$arg{'o'}#Structures") . ",\n";
print $ofh &link('Data Cells', "$arg{'o'}#Cells") . ",\n";
print $ofh &link('Constants', "$arg{'o'}#Constants") . ")\n";
print $ofh <$anchor
";
&verbose("No link for '$anchor'");
}
else {
$result = "$anchor
";
&verbose("Hyperlinking '$anchor'")
if ($sayso);
}
return $result;
}