use File::Find; use strict; my $file = $ARGV[0]; if(!$file) { print "Usage: parsedoc.pl \n"; exit(0); } my $paramhelp = ""; sub add_option_to_manpage { my $shortopt = shift; my $longopt = shift; my $params = shift; my $doc = shift; my $longdoc = shift; chomp $longdoc; chomp $longdoc; $shortopt =~ s|-|\\-|; $params =~ s|<(.*)>|\\fI\1\\fR|; $longdoc =~ s/<([a-zA-Z0-9_-]+)>/\\fI\1\\fR/; $longdoc =~ s/%/%%$1/g; print manpage << "EOF" .TP \\fB\\-$shortopt\\fR, \\fB\\-\\-$longopt\\fR $params $longdoc EOF ; } sub add_option_to_help { my $shortopt = shift; my $longopt = shift; my $params = shift; my $doc = shift; my $longdoc = shift; chomp $doc; chomp $doc; my $s1 = " "x(2-length($shortopt)); my $s2 = " "x(20-length($longopt." ".$params)); $doc =~ s/"/\\"/g; $paramhelp .= " printf(\"-$shortopt$s1, --$longopt $params$s2$doc\\n\");\n"; } sub add_header_to_manpage { my $package = shift; my $progname = shift; my $short_description = shift; my $long_description = shift; my $usage = shift; my $date = `date +"%B %Y"`; my $newusage = ""; chomp $date; split(/\n/,$usage); my $p = ""; foreach my $u (@_) { $u =~ s/%s/$progname/g; $newusage .= "$p.B $u\n"; $p = ".PP\n"; } print manpage << "EOF" .TH $progname "1" "$date" "$progname" "$package" .SH NAME $progname - $short_description .SH Synopsis $newusage .SH DESCRIPTION $long_description .SH OPTIONS EOF ; } open(fi, "$file") or die "File not found"; my $package = "swftools"; my $progname = $file; $progname =~ s|(^/?([^/]+/))*([^/]+).doc|$3|; my $path = $1; open(manpage, ">$path$progname.1") or die; my $usage = ""; my $short_description = ""; my $long_description = ""; while() { last if(/^\s*$/); s/^\s*Usage:\s*//g; s/^\s*OR:\s*//g; $usage .= $_; } while() { last if(/^\s*$/); $short_description .= $_; } while() { last if(/^\s*$/); $long_description .= $_; } add_header_to_manpage($package, $progname, $short_description, $long_description, $usage); $_=; my $numopts = 0; my @shortopts; my @longopts; while(1) { if(/^-([^\s,]+)[\s,]+--([^\s]+)(\s+(.*))?$/) { my $shortopt = $1; my $longopt = $2; my $params = $4; my $doc = ""; my $longdoc = ""; while() { last if(/^-/); last if(/^\s*$/); if(!$doc) { $doc .= $_; } else { $longdoc .= $_; } } $longdoc = $doc if(!$longdoc || ($longdoc =~ /^\s*$/)); $shortopts[$numopts] = $shortopt; $longopts[$numopts] = $longopt; $numopts++; add_option_to_manpage($shortopt,$longopt,$params,$doc,$longdoc); add_option_to_help($shortopt,$longopt,$params,$doc,$longdoc); last if(eof(fi)); next; } last if(/^\s*/); last if(!($_=)); last if(/^\s*/); } my $tail = ""; while() { $tail .= $_; } print manpage $tail; close(manpage); my $filename = "$path$progname.c"; my $cfile; if(!open($cfile, "<$filename")) { $filename = "$path$progname.cpp"; if(!open($cfile, "<$filename")) { $filename = "$path$progname.cc"; if(!open($cfile, "<$filename")) { $filename = "$path$progname.c++"; open($cfile, "<$filename") or die; } } } my $src=""; while(<$cfile>) { if(/void\s*args_callback_usage.*\(.*\*/) { print "substituting usage in $filename\n"; if(!/{/) {<$cfile>;} $src .= "void args_callback_usage(char *name)\n"; $src .= "{\n"; $src .= " printf(\"\\n\");\n"; while(<$cfile>) { last if(/}\s*$/); } split(/\n/,$usage); my $prefix = "Usage:"; my $u; foreach $u (@_) { if($u =~ /%s/) { $src .= " printf(\"$prefix $u\\n\", name);\n"; } else { $src .= " printf(\"$prefix $u\\n\");\n"; } $prefix = "OR: "; } $src .= " printf(\"\\n\");\n"; $src .= "$paramhelp"; $src .= " printf(\"\\n\");\n"; $src .= "}\n"; next; } if(/^\s*(static\s+)?(struct\s+)?options_t.*=/) { print "substituting options_t in $filename\n"; while(<$cfile>) { last if(/;$/); } split(/\n/,$usage); $src .= "static struct options_t options[] = {\n"; for(my $t=0;$t<$numopts;$t++) { my $s = $shortopts[$t]; my $l = $longopts[$t]; $src .= "{\"$s\", \"$l\"},\n"; } $src .= "{0,0}\n};\n"; next; } $src .= $_; } close($cfile); open($cfile, ">$filename") or die; print $cfile $src; close($cfile);