289 lines
6.9 KiB
Perl
289 lines
6.9 KiB
Perl
#!/usr/bin/perl
|
|
|
|
# Doxygen is usefull for html documentation, but sucks
|
|
# in making manual pages. Still tool also parses the .h
|
|
# files with the doxygen documentation and creates
|
|
# the man page we want
|
|
#
|
|
# 2 way process
|
|
# 1. All the .h files are processed to create in file in which:
|
|
# filename | API | description | return values
|
|
# are documented
|
|
# 2. Another file is parsed which states which function should
|
|
# be grouped together in which manpage. Symlinks are also created.
|
|
#
|
|
# With this all in place, all documentation should be autogenerated
|
|
# from the doxydoc.
|
|
|
|
use Getopt::Std;
|
|
|
|
my $state;
|
|
my $description;
|
|
my $struct_description;
|
|
my $key;
|
|
my $return;
|
|
my $param;
|
|
my $api;
|
|
my $const;
|
|
|
|
my %description;
|
|
my %api;
|
|
my %return;
|
|
my %options;
|
|
my %manpages;
|
|
my %see_also;
|
|
|
|
my $BASE="doc/man";
|
|
my $MAN_SECTION = "3";
|
|
my $MAN_HEADER = ".TH ldns $MAN_SECTION \"30 May 2006\"\n";
|
|
my $MAN_MIDDLE = ".SH AUTHOR
|
|
The ldns team at NLnet Labs. Which consists out of
|
|
Jelte Jansen and Miek Gieben.
|
|
|
|
.SH REPORTING BUGS
|
|
Please report bugs to ldns-team\@nlnetlabs.nl or in
|
|
our bugzilla at
|
|
http://www.nlnetlabs.nl/bugs/index.html
|
|
|
|
.SH COPYRIGHT
|
|
Copyright (c) 2004 - 2006 NLnet Labs.
|
|
.PP
|
|
Licensed under the BSD License. There is NO warranty; not even for
|
|
MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE.
|
|
";
|
|
my $MAN_FOOTER = ".SH REMARKS
|
|
This manpage was automaticly generated from the ldns source code by
|
|
use of Doxygen and some perl.
|
|
";
|
|
|
|
getopts("m:",\%options);
|
|
# if -m manpage file is given process that file
|
|
# parse the file which tells us what manpages go together
|
|
my $functions, $see_also;
|
|
if (defined $options{'m'}) {
|
|
# process
|
|
open(MAN, "<$options{'m'}") or die "Cannot open $options{'m'}";
|
|
# it's line based:
|
|
# func1, func2, .. | see_also1, see_also2, ...
|
|
while(<MAN>) {
|
|
chomp;
|
|
if (/^#/) { next; }
|
|
if (/^$/) { next; }
|
|
($functions, $see_also) = split /[\t ]*\|[\t ]*/, $_;
|
|
#print "{$functions}\n";
|
|
#print "{$see_also}\n";
|
|
my @funcs = split /[\t ]*,[\t ]*/, $functions;
|
|
my @also = split /[\t ]*,[\t ]*/, $see_also;
|
|
$manpages{$funcs[0]} = \@funcs;
|
|
$see_also{$funcs[0]} = \@also;
|
|
#print "[", $funcs[0], "]\n";
|
|
}
|
|
close(MAN);
|
|
} else {
|
|
print "Need -m file to process the .h files\n";
|
|
exit 1;
|
|
}
|
|
|
|
# 0 - somewhere in the file
|
|
# 1 - in a doxygen par
|
|
# 2 - after doxygen, except funcion
|
|
|
|
# create our pwd
|
|
mkdir "doc";
|
|
mkdir "doc/man";
|
|
mkdir "doc/man/man$MAN_SECTION";
|
|
|
|
$state = 0;
|
|
my $i;
|
|
my @lines = <STDIN>;
|
|
my $max = @lines;
|
|
|
|
while($i < $max) {
|
|
$typedef = "";
|
|
if ($lines[$i] =~ /^typedef struct/ and $lines[$i + 1] =~ /^struct/) {
|
|
# move typedef to below struct
|
|
$typedef = $lines[$i];
|
|
$j = $i;
|
|
while ($lines[$j] !~ /}/) {
|
|
$lines[$j] = $lines[$j+1];
|
|
$j++;
|
|
}
|
|
$lines[$j] = $lines[$j+1];
|
|
$lines[$j + 1] = $typedef;
|
|
}
|
|
|
|
$cur_line = $lines[$i];
|
|
chomp($cur_line);
|
|
if ($cur_line =~ /^\/\*\*[\t ]*$/) {
|
|
# /** Seen
|
|
#print "Comment seen! [$cur_line]\n";
|
|
$state = 1;
|
|
undef $description;
|
|
undef $struct_description;
|
|
$i++;
|
|
next;
|
|
}
|
|
if ($cur_line =~ /\*\// and $state == 1) {
|
|
#print "END Comment seen!\n";
|
|
$state = 2;
|
|
$i++;
|
|
next;
|
|
}
|
|
|
|
if ($state == 1) {
|
|
# inside doxygen
|
|
$cur_line =~ s/\\/\\\\/g;
|
|
$cur_line =~ s/^[ \t]*\* ?//;
|
|
$description = $description . "\n" . $cur_line;
|
|
#$description = $description . "\n.br\n" . $cur_line;
|
|
}
|
|
if ($state == 2 and $cur_line =~ /const/) {
|
|
# the const word exists in the function call
|
|
#$const = "const";
|
|
#s/[\t ]*const[\t ]*//;
|
|
} else {
|
|
#undef $const;
|
|
}
|
|
|
|
if ($cur_line =~ /^INLINE/) {
|
|
$cur_line =~ s/^INLINE\s*//;
|
|
while ($cur_line !~ /{/) {
|
|
$i++;
|
|
$cur_line .= " ".$lines[$i];
|
|
$cur_line =~ s/\n//;
|
|
}
|
|
$cur_line =~ s/{/;/;
|
|
}
|
|
|
|
if ($cur_line =~ /^[^#*\/ ]([\w\*]+)[\t ]+(.*?)[({](.*)\s*/ and $state == 2) {
|
|
while ($cur_line !~ /\)\s*;/) {
|
|
$i++;
|
|
$cur_line .= $lines[$i];
|
|
chomp($cur_line);
|
|
$cur_line =~ s/\n/ /g;
|
|
$cur_line =~ s/\s\s*/ /g;
|
|
}
|
|
$cur_line =~ /([\w\* ]+)[\t ]+(.*?)\((.*)\)\s*;/;
|
|
# this should also end the current comment parsing
|
|
$return = $1;
|
|
$key = $2;
|
|
$api = $3;
|
|
# sometimes the * is stuck to the function
|
|
# name instead to the return type
|
|
if ($key =~ /^\*/) {
|
|
#print"Name starts with *\n";
|
|
$key =~ s/^\*//;
|
|
if (defined($const)) {
|
|
$return = $const . " " . $return . '*';
|
|
} else {
|
|
$return = $return . '*';
|
|
}
|
|
}
|
|
$description =~ s/\\param\[in\][ \t]*([\*\w]+)[ \t]+/.br\n\\fB$1\\fR: /g;
|
|
$description =~ s/\\param\[out\][ \t]*([\*\w]+)[ \t]+/.br\n\\fB$1\\fR: /g;
|
|
$description =~ s/\\return[ \t]*/.br\nReturns /g;
|
|
|
|
$description{$key} = $description;
|
|
$api{$key} = $api;
|
|
$return{$key} = $return;
|
|
undef $description;
|
|
undef $struct_description;
|
|
$state = 0;
|
|
} elsif ($state == 2 and (
|
|
$cur_line =~ /^typedef\sstruct\s(\w+)\s(\w+);/ or
|
|
$cur_line =~ /^typedef\senum\s(\w+)\s(\w+);/)) {
|
|
$struct_description .= "\n.br\n" . $cur_line;
|
|
$key = $2;
|
|
$struct_description =~ s/\/\*\*\s*(.*?)\s*\*\//\\fB$1:\\fR/g;
|
|
$description{$key} = $struct_description;
|
|
$api{$key} = "struct";
|
|
$return{$key} = $1;
|
|
undef $description;
|
|
undef $struct_description;
|
|
$state = 0;
|
|
} else {
|
|
$struct_description .= "\n.br\n" . $cur_line;
|
|
}
|
|
$i++;
|
|
}
|
|
|
|
# create the manpages
|
|
foreach (keys %manpages) {
|
|
$name = $manpages{$_};
|
|
$also = $see_also{$_};
|
|
|
|
$filename = @$name[0];
|
|
$filename = "$BASE/man$MAN_SECTION/$filename.$MAN_SECTION";
|
|
|
|
my $symlink_file = @$name[0] . "." . $MAN_SECTION;
|
|
|
|
# print STDOUT $filename,"\n";
|
|
open (MAN, ">$filename") or die "Can not open $filename";
|
|
|
|
print MAN $MAN_HEADER;
|
|
print MAN ".SH NAME\n";
|
|
print MAN join ", ", @$name;
|
|
print MAN "\n\n";
|
|
print MAN ".SH SYNOPSIS\n";
|
|
|
|
print MAN "#include <stdint.h>\n.br\n";
|
|
print MAN "#include <stdbool.h>\n.br\n";
|
|
|
|
print MAN ".PP\n";
|
|
print MAN "#include <ldns/ldns.h>\n";
|
|
print MAN ".PP\n";
|
|
|
|
foreach (@$name) {
|
|
$b = $return{$_};
|
|
$b =~ s/\s+$//;
|
|
if ($api{$_} ne "struct") {
|
|
print MAN $b, " ", $_;
|
|
print MAN "(", $api{$_},");\n";
|
|
print MAN ".PP\n";
|
|
}
|
|
}
|
|
|
|
print MAN "\n.SH DESCRIPTION\n";
|
|
foreach (@$name) {
|
|
print MAN ".HP\n";
|
|
print MAN "\\fI", $_, "\\fR";
|
|
if ($api{$_} ne "struct") {
|
|
print MAN "()";
|
|
}
|
|
# print MAN ".br\n";
|
|
print MAN $description{$_};
|
|
print MAN "\n.PP\n";
|
|
}
|
|
|
|
print MAN $MAN_MIDDLE;
|
|
|
|
if (defined(@$also)) {
|
|
print MAN "\n.SH SEE ALSO\n\\fI";
|
|
print MAN join "\\fR, \\fI", @$also;
|
|
print MAN "\\fR.\nAnd ";
|
|
print MAN "\\fBperldoc Net::DNS\\fR, \\fBRFC1034\\fR,
|
|
\\fBRFC1035\\fR, \\fBRFC4033\\fR, \\fBRFC4034\\fR and \\fBRFC4035\\fR.\n";
|
|
} else {
|
|
print MAN ".SH SEE ALSO
|
|
\\fBperldoc Net::DNS\\fR, \\fBRFC1034\\fR,
|
|
\\fBRFC1035\\fR, \\fBRFC4033\\fR, \\fBRFC4034\\fR and \\fBRFC4035\\fR.\n";
|
|
}
|
|
|
|
print MAN $MAN_FOOTER;
|
|
|
|
# create symlinks
|
|
chdir("$BASE/man$MAN_SECTION");
|
|
foreach (@$name) {
|
|
print STDERR $_,"\n";
|
|
my $new_file = $_ . "." . $MAN_SECTION;
|
|
if ($new_file eq $symlink_file) {
|
|
next;
|
|
}
|
|
#print STDOUT "\t", $new_file, " -> ", $symlink_file, "\n";
|
|
symlink $symlink_file, $new_file;
|
|
}
|
|
chdir("../../.."); # and back, tricky and fragile...
|
|
close(MAN);
|
|
}
|