+#!/usr/bin/perl -w
+# -*- cperl -*-
+
+# cdoc - generate man pages for C code
+# Copyright (C) 2000 Bibliotech Ltd., Unit 2-3, 50 Carnwath Road,
+# London, SW6 3EG, United Kingdom.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# $Id: cdoc,v 1.4 2001/02/16 17:02:15 rich Exp $
+
+use strict;
+
+my $arg;
+
+my $date = `date +'%B %d, %Y'`;
+$date =~ s/[\r\n]+$//;
+
+my $author;
+my $version;
+my $license;
+
+while ($arg = shift @ARGV)
+ {
+ my ($type, $header_file);
+
+ if ($arg eq "--help" || $arg eq "-?" || $arg eq "-h")
+ {
+ print STDERR
+ "cdoc [--options ...] files ...\n",
+ "Options are:\n",
+ " --author \"Author name\" Details for the AUTHOR section\n",
+ " --version package-version Details for the VERSION section\n",
+ " --license \"License data\" Details for the LICENSE section\n";
+ exit 1;
+ }
+ elsif ($arg eq "--author")
+ {
+ $author = shift @ARGV;
+ next;
+ }
+ elsif ($arg eq "--version")
+ {
+ $version = shift @ARGV;
+ next;
+ }
+ elsif ($arg eq "--license")
+ {
+ $license = shift @ARGV;
+ next;
+ }
+ elsif ($arg =~ /(.*)\.h$/)
+ {
+ header:
+ $type = "header file";
+ $header_file = $1;
+ open FILE, "<$arg"
+ or die "$arg: cannot open file: $!";
+ }
+ else
+ {
+ print STDERR "$arg: unknown file type: assuming it's a header file";
+ goto header;
+ }
+
+ while (<FILE>)
+ {
+ s/[\n\r]+$//;
+
+ # Look for intro line.
+ if (m(^\s*/\*\s*(Function|Variable):\s*(.*?)\s+-\s+(.*))o)
+ {
+ my $manpage = $2;
+ my $name_text = $3;
+
+ my @functions = ();
+ push @functions, { name => $manpage };
+
+ my $description = "";
+ my $bugs = "";
+ my $history = "";
+ my $see_also = "";
+ my $returns = "";
+ my $section = \$description;
+
+ # Read the rest of the comment block.
+ while (<FILE>)
+ {
+ s/[\n\r]+$//;
+ s/^\s*\*\s*//; # Remove leading " * ".
+
+ last if m(^/)o; # End of comment block?
+
+ if (m(^(Function|Variable):\s*(.*))o)
+ {
+ push @functions, { name => $2 };
+ }
+ elsif (m(^Bugs:\s*(.*))o)
+ {
+ $section = \$bugs;
+ $$section .= $1 . " ";
+ }
+ elsif (m(^History:\s*(.*))o)
+ {
+ $section = \$history;
+ $$section .= $1 . " ";
+ }
+ elsif (m(^See also:\s*(.*))o)
+ {
+ $section = \$see_also;
+ $$section .= $1 . " ";
+ }
+ elsif (m(^Returns:\s*(.*))o)
+ {
+ $section = \$returns;
+ $$section .= $1 . " ";
+ }
+ elsif (m/^\s*$/)
+ {
+ $$section .= "\n";
+ }
+ else
+ {
+ $$section .= $_;
+ $$section .= " ";
+ }
+ }
+
+ # Mark up the sections.
+ $description = mark_up ($description);
+ $bugs = mark_up ($bugs);
+ $history = mark_up ($history);
+ $see_also = mark_up ($see_also);
+ $returns = mark_up ($returns);
+
+ # Read the functions which should follow, one per line, in order.
+ my $fn;
+ foreach $fn (@functions)
+ {
+ $_ = <FILE>;
+
+ if (!$_ || !m($fn->{name}))
+ {
+ print STDERR "$arg: could not find prototype of variable/function: $fn->{name}\n";
+ exit 1;
+ }
+
+ s/[\n\r]+$//;
+ s/^extern\s+//;
+ $fn->{prototype} = $_;
+ }
+
+ # Now we're in a situation to produce the manual page.
+ print "cdoc: creating $manpage.3\n";
+
+ open MANPAGE, ">$manpage.3"
+ or die "$manpage.3: cannot open file: $!";
+
+ my $names = join ", ", map { $_->{name} } @functions;
+
+ print MANPAGE
+ ".TH $manpage 3 \"$date\" \"GNU\" \"Programmer's Manual\"\n",
+ ".SH NAME\n",
+ "$names \\- $name_text\n",
+ ".SH SYNOPSIS\n",
+ ".nf\n",
+ ".B #include <$header_file.h>\n",
+ ".sp\n";
+
+ foreach (@functions)
+ {
+ print MANPAGE ".BI \"$_->{prototype}\"\n";
+ }
+
+ print MANPAGE
+ ".fi\n",
+ ".SH DESCRIPTION\n",
+ "$description\n";
+
+ print MANPAGE ".SH RETURNS\n$returns\n" if $returns;
+ print MANPAGE ".SH BUGS\n$bugs\n" if $bugs;
+ print MANPAGE ".SH AUTHOR\n$author\n" if $author;
+ print MANPAGE ".SH LICENSE\n$license\n" if $license;
+ print MANPAGE ".SH VERSION\n$version\n" if $version;
+ print MANPAGE ".SH HISTORY\n$history\n" if $history;
+ print MANPAGE ".SH SEE ALSO\n$see_also\n" if $see_also;
+
+ close MANPAGE;
+
+ # Links for other pages.
+ my @other_pages = @functions;
+ shift @other_pages;
+
+ foreach $fn (@other_pages)
+ {
+ print "cdoc: creating $fn->{name}.3\n";
+
+ open MANPAGE, ">$fn->{name}.3"
+ or die "$fn->{name}.3: cannot open file: $!";
+
+ print MANPAGE
+ ".so man3/$manpage.3\n";
+
+ close MANPAGE;
+ }
+ }
+ }
+
+ close FILE;
+ }
+
+exit;
+
+sub mark_up
+ {
+ local $_ = shift;
+
+ s/\n/\n.PP\n/ogs;
+ s/\@code{(.*?)}/\\fB$1\\fP/ogs;
+ s/\@ref{(.*?)}/\\fB$1\\fP/ogs; # Should be able to handle this better. XXX
+
+ return $_;
+ }