summaryrefslogtreecommitdiff
path: root/lib/cli++/cli++topod.pl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cli++/cli++topod.pl')
-rw-r--r--lib/cli++/cli++topod.pl213
1 files changed, 213 insertions, 0 deletions
diff --git a/lib/cli++/cli++topod.pl b/lib/cli++/cli++topod.pl
new file mode 100644
index 0000000..5d2ef13
--- /dev/null
+++ b/lib/cli++/cli++topod.pl
@@ -0,0 +1,213 @@
+#!/usr/bin/perl
+
+sub cstr2pod {
+ local($_) = shift;
+ s/\\"/"/go;
+ s/"([^\"]*)"/"C<$1>"/go;
+ $_;
+}
+
+$section = 1;
+
+@section_order = (
+ 'NAME',
+ 'SYNOPSIS',
+ 'DESCRIPTION',
+ 'OPTIONS',
+ 'RETURN VALUE',
+ 'ERRORS',
+ 'EXAMPLES',
+ 'ENVIRONMENT',
+ 'FILES',
+ 'SEE ALSO',
+ 'NOTES',
+ 'CAVEATS',
+ 'WARNINGS',
+ 'DIAGNOSTICS',
+ 'BUGS',
+ 'RESTRICTIONS',
+ 'AUTHOR',
+ 'AUTHORS',
+ 'HISTORY'
+ );
+
+sub type2word {
+ my($type) = shift;
+ return 'INT' if $type eq 'integer';
+ return 'UINT' if $type eq 'ulong';
+ return 'STR' if $type eq 'string' || $type eq 'stringlist';
+ return '' if $type eq 'flag' || $type eq 'counter';
+ die "Invalid cli option type '$type'";
+}
+
+sub add_option {
+ my($short, $long, $type, $desc) = @_;
+
+ my $s = '[B<';
+ my $o = '=item B<';
+ if($short) {
+ $s .= "-$short";
+ $o .= "-$short";
+ if($type) {
+ $s .= " $type";
+ $o .= " $type";
+ }
+ }
+ if($short && $long) {
+ $s .= ">]\n[B<";
+ $o .= ">, B<";
+ }
+ if($long) {
+ $s .= "--$long";
+ $o .= "--$long";
+ if($type) {
+ $s .= "=$type";
+ $o .= "=$type";
+ }
+ }
+ $s .= ">]\n";
+ $o .= ">\n\n$desc\n\n";
+
+ $synopsis .= $s;
+ $options = "=over 8\n\n" unless $options;
+ $options .= $o;
+}
+
+sub parse_option {
+ local($_) = shift;
+ s/^\s*\{\s*//o;
+ s/\s*\},?\s*/ /o;
+
+ my $short = $1 if s/^'([^\'])',\s*//o;
+ die "Invalid cli option" unless $short || s/^0,\s*//o;
+
+ my $long = $1 if s/^"([^\"]+)",\s*//o;
+ die "Invalid cli_option" unless $long || s/^0,\s*//o;
+
+ my $type = $1 if s/^cli_option::(\S+),\s*//o;
+ die "Invalid cli_option" unless $type;
+ $type = &type2word($type);
+
+ my $val = $1 if s/^([^,]+),\s*//o;
+ my $var = $1 if s/^&([^,]+),\s*//o;
+
+ my $desc = cstr2pod($1) if s/^"([^,]+)",\s*//o;
+ die "Invalid cli_option" unless $desc;
+ $desc =~ s/\.?$/./o if $desc;
+
+ my $default = $1 if s/^"([^\"]+)"\s+//o;
+ die "Invalid cli_option" unless $default || s/^0\s+//o;
+ $desc .= " Defaults to $default." if $default;
+
+ s/\s*\/\/\s*/ /go;
+ s/^\s*//o;
+
+ add_option($short, $long, $type, $_ || $desc);
+}
+
+sub parse_options {
+ $synopsis = "B<$program>\n";
+
+ my $line;
+ while(<>) {
+ s/^\s+//o;
+ s/\s+$//o;
+ if($line && /^\{/o) {
+ &parse_option($line);
+ $line = "";
+ }
+ next if /^\{\s*0\s*\},?/o;
+ next if /^\{\s*0\s*,\s*\},?/o;
+ last if /^\s*\};/o;
+ $line =~ s/$/ $_/;
+ }
+ &parse_option($line) if $line;
+
+ $synopsis .= "I<$usage>" if $usage;
+ $options .= "=back" if $options;
+ $sections{'SYNOPSIS'} = $synopsis;
+ $sections{'OPTIONS'} = $options;
+}
+
+sub parse_notes {
+ my $section;
+ my $title;
+ while(<>) {
+ chomp;
+ last unless /^$/o || s/^\/\/\s*//o;
+ if(/^[\sA-Z]+$/o) {
+ $sections{$title} = $section if $title && $section;
+ undef $section;
+ $title = $_;
+ } else {
+ $section .= "$_\n";
+ }
+ }
+ $sections{$title} = $section if $title && $section;
+}
+
+sub parse_header_line {
+ local($_, $comment) = @_;
+ if(s/^\s*const\s+char\s*\*\s*cli_(\S+)\s*=\s*//o) {
+ my $name = $1;
+ s/;\s*$//o;
+ s/^\"//;
+ s/\"$//o;
+ s/\\n$//o;
+ s/\\n""/\n/go;
+ $program = $_ if $name eq 'program';
+ $prefix = $_ if $name eq 'help_prefix';
+ $usage = $_ if $name eq 'args_usage';
+ $suffix = $_ if $name eq 'help_suffix';
+ }
+}
+
+sub parse_header {
+ my $comment = '';
+ my $line = '';
+ while(<>) {
+ s/^\s+//o;
+ s/\s+$//o;
+ if(s/^.*Copyright\s*\(C\)\s*[\d,]+\s*//o) {
+ $author = $_;
+ } else {
+ last if ($program && $prefix && /^$/o);
+ next if /^#/o;
+ $comment .= "$1\n" if s|\s*//\s*(.*)$||o;
+ $line =~ s/$/\n$_/;
+ if(/;$/o) {
+ &parse_header_line($line, $comment);
+ undef $line;
+ undef $comment;
+ }
+ }
+ }
+}
+
+sub parse_description {
+ while(<>) {
+ s/^\s+//o;
+ s/\s+$//o;
+ last if / cli_options\[\]\s*=\s*\{/o;
+ next unless s/^\/\/\s*//o;
+ $description .= "$_\n";
+ }
+}
+
+&parse_header;
+&parse_description;
+&parse_options;
+&parse_notes;
+
+$description .= "\n\n$suffix\n" if $suffix;
+
+$sections{'NAME'} = "$program - $prefix";
+$sections{'DESCRIPTION'} = $description;
+$sections{'AUTHORS'} = $author if $author;
+
+foreach $section (@section_order) {
+ print "=head1 $section\n\n$sections{$section}\n\n"
+ if $sections{$section};
+}
+
+1;