coar 98/05/03 13:00:23
Added: apidoc mkapidict Log: This is the Perl script that turns the api-dict.html template, the api.list definition file, and the dict-*.html entity documentation files into a single monolithic cross-referenced dictionary. Revision Changes Path 1.1 apache-devsite/apidoc/mkapidict Index: mkapidict =================================================================== #!/usr/local/bin/perl # # Read from STDIN, produce HTML. Simple, really. The first argument on the # command line ($ARGV[0]) is the name of the file which provides the # framework into which the generated text is inserted. # # Edit history: # # 1998-05-03 Ken Coar # Cleaned up a little bit, from horrible to bad, before checking in to # CVS. # 1998-04-?? Ken Coar # Prototyped.. # if (! $ARGV[0]) { print "Template file must be specified.\n"; die ("missing required input."); }; $InFile = $ARGV[0]; $OutFile = "$ARGV[0].bak"; %Routine = (); %Constant = (); %Structure = (); %Cell = (); %Entity = (); %SeeAlso = (); @Prologue = (); @Epilogue = (); # # # 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. # open INFILE, "<$InFile" || dir ("Can't open input file $InFile"); open OUTFILE, ">$OutFile" || die ("Can't open output file $OutFile"); $state = 1; while ($line = <INFILE>) { print OUTFILE $line; if ($state == 1) { push (@Prologue, $line); } elsif ($state == 2) { push (@Epilogue, $line); }; if ($line =~ m:<!--.*%%BEGIN%%.*-->:) { $state = 0; } elsif ($line =~ m:<!--.*%%END%%.*-->:) { push (@Epilogue, $line); $state = 2; }; }; close INFILE; close OUTFILE; $DataLine = 0; while (! eof(STDIN)) { local (@field) = ("", "", "", "", "", "", "", ""); local ($rec); $rec = &get_record(1); next if (! $rec); chomp($rec); @field = split(m:\|:, $rec); $rec =~ s:\$\*:$field[1]:g; @field = split(m:\|:, $rec); if ($field[0] !~ m:^[RSCDX]$:i) { print STDERR "Unrecognised record identifier /$field[0]/ ", "for record ending on line $DataLine;\n", "\tmissing continuation character?\n"; next; }; if ($Entity{$field[1]}) { print STDERR "Entity $field[1] redefined at line $DataLine.\n"; }; $Entity{$field[1]} = 1; if ($field[0] =~ /R/i) { $Routine{$field[1]} = $rec; } elsif ($field[0] =~ /S/i) { $Structure{$field[1]} = $rec; } elsif ($field[0] =~ /C/i) { $Constant{$field[1]} = $rec; } elsif ($field[0] =~ /D/i) { $Cell{$field[1]} = $rec; } elsif ($field[0] =~ /X/i) { $SeeAlso{$field[1]} = $field[4]; }; }; # # Done reading in the input.. time to make the doughnuts. # print @Prologue; print <<EOHT; <H2>Table of Contents</H2> <UL> <LI><A HREF="#Routines">Routine Descriptions</A> </LI> <LI><A HREF="#Structures">Data Structure Definitions</A> </LI> <LI><A HREF="#Cells">Global Data Cells</A> </LI> <LI><A HREF="#Constants">Constant Definitions</A> </LI> </UL> <HR> EOHT print <<EOHT; <H2> <A NAME="Routines"> Routine Descriptions </A> </H2> <HR> EOHT &dump_list(%Routine); print <<EOHT; <H2> <A NAME="Structures"> Data Structure Definitions </A> </H2> <HR> EOHT &dump_list(%Structure); print <<EOHT; <H2> <A NAME="Cells"> Global Data Cells </A> </H2> <HR> EOHT &dump_list(%Cell); print <<EOHT; <H2> <A NAME="Constants"> Constant Definitions </A> </H2> <P> Many of the compile-time choices are determined by the settings of various constants created with <CODE>#define</CODE> 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. </P> <P> Some of the Apache Web server's constants (such as <A HREF="#SERVER_VERSION"><SAMP>SERVER_VERSION</SAMP></A>) can be overridden with compile-time definitions on the compiler command line. Others, like <A HREF="#MAX_STRING_LEN"><SAMP>MAX_STRING_LEN</SAMP></A>, are provided as conveniences, and shouldn't be modified except under special circumstances. Still others, such as <A HREF="#OR_LIMIT"><SAMP>OR_LIMIT</SAMP></A>, have specific values that <STRONG>must not</STRONG> be altered. </P> <HR> EOHT &dump_list(%Constant); print @Epilogue; # # Dump a hash in alphabetical order. # sub dump_list { local (%list) = @_; local (@keys) = sort {uc($a) cmp uc($b)} (keys(%list)); foreach $key (@keys) { my ($edited, $iname, $idef, $isamp, $iref, $idesc) = split(m:\|:, $list{$key}); print <<EOHT; <H3> <A NAME="$iname"> $iname </A> </H3> EOHT $edited = &edit_inline($idef, $iname); if (! $edited) { $edited = "No prototype or definition available."; }; print <<EOHT; <P> Definition: </P> <DL> <DD> <PRE> $edited </PRE> </DD> </DL> EOHT $edited = &edit_inline($isamp, $iname); if (! $edited) { $edited = "No examples available."; }; print <<EOHT; <P> Usage example: </P> <DL> <DD> <PRE> $edited </PRE> </DD> </DL> EOHT if (! $idesc) { print <<EOHT; <P> No documentation available. </P> EOHT } elsif (! -r $idesc) { print <<EOHT; <P> Documentation file not accessible. </P> EOHT } else { open DFILE, "<$idesc"; print <DFILE>; close (DFILE); }; $edited = $iref; $edited =~ s/[\s,]//g; if ($edited) { local ($ref) = $iref; local ($ref_list) = " <DD>"; local ($sees) = ""; $ref =~ s/\s+//g; print <<EOHT; <DL COMPACT> <DT><EM>See also:</EM> </DT> EOHT # # Expand any aliased 'see-also' entries. # foreach (split(m:,:, $ref)) { if ($SeeAlso{$_}) { $sees .= ",$SeeAlso{$_}"; } else { $sees .= ",$_"; }; }; $ref = $sees; foreach (sort(split(m:,:, $ref))) { local ($item) = "<SAMP>$_</SAMP>"; next if (($_ eq "") || ($_ eq $iname)); if ($Entity{$_}) { $item = "<A HREF=\"#$_\">$item</A>"; } else { print STDERR "$iname cross-references to undefined "; print STDERR "entity $_.\n"; }; $ref_list .= $item . ",\n "; }; $ref_list =~ s:,\n $:\n:; print $ref_list; print <<EOHT; </DD> </DL> EOHT }; print " <HR>\n"; }; }; # # Turn any inline references to other structures or constants into links. # sub edit_inline { local ($wip, $rname) = @_; local ($ref); foreach $ref (keys(%Entity)) { if ($ref ne $rname) { $wip =~ s:\b$ref\b:<A HREF="#$ref">$ref</A>:g; }; }; return $wip; }; # # Read a record from the input stream. Comments are trimmed, as is # trailing whitespace. Leading whitespace is trimmed IFF the argument to the # functional evaluates as true. A terminal slosh indicates that the next # line should be read and the record re-processed. All '\n' occurrences # in the input are converted to newlines before being returned. # sub get_record { local ($trim_leading_ws) = @_; local ($trim_next) = 1; my ($line); $line = <STDIN> || return ""; $DataLine++; chomp ($line); $line =~ s/#;.*//; $line =~ s/\s+$//; if ($trim_leading_ws) { $line =~ s/^\s+//; }; if ($line =~ m:\\$:) { $line =~ s:\\n\s+\\$:\\n\\:; $line =~ s:\\$::; $trim_next = 0 if ($line =~ m:\\n$:); $line .= &get_record($trim_next); }; $line =~ s:\\n:\n:g; return ($line); };