67e43b2d5f988168b214ceb3e58aa364481c26ae
[oweals/busybox.git] / docs / autodocifier.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Getopt::Long;
5
6 # collect lines continued with a '\' into an array 
7 sub continuation {
8         my $fh = shift;
9         my @line;
10
11         while (<$fh>) {
12                 my $s = $_;
13                 $s =~ s/\\\s*$//;
14                 $s =~ s/#.*$//;
15                 push @line, $s;
16                 last unless (/\\\s*$/);
17         }
18         return @line;
19 }
20
21 # regex && eval away unwanted strings from documentation
22 sub beautify {
23         my $text = shift;
24         $text =~ s/USAGE_NOT\w+\(.*?"\s*\)//sxg;
25         $text =~ s/USAGE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg;
26         $text =~ s/"\s*"//sg;
27         my @line = split("\n", $text);
28         $text = join('',
29                 map { eval }
30                 map { qq[ sprintf(qq#$_#) ] }
31                 map { 
32                         s/^\s*//;
33                         s/"//g;
34                         s/% /%% /g;
35                         $_
36                 }
37                 @line
38         );
39         return $text;
40 }
41
42 # generate POD for an applet
43 sub pod_for_usage {
44         my $name  = shift;
45         my $usage = shift;
46
47         # make options bold
48         my $trivial = $usage->{trivial};
49         $trivial =~s/(?<!\w)(-\w+)/B<$1>/sxg;
50         my @f1;
51         my @f0 = 
52                 map { $_ !~ /^\s/ && s/(?<!\w)(-\w+)/B<$1>/g; $_ }
53                 split("\n", $usage->{full});
54
55         # add "\n" prior to certain lines to make indented
56         # lines look right
57         my $len = @f0;
58         for (my $i = 0; $i < $len; $i++) {
59                 push @f1, $f0[$i];
60                 if (($i+1) != $len && $f0[$i] !~ /^\s/ && $f0[$i+1] =~ /^\s/) {
61                         next if ($f0[$i] =~ /^$/);
62                         push(@f1, "") unless ($f0[$i+1] =~ /^\s*$/s);
63                 }
64         }
65
66         my $full = join("\n", @f1);
67         return
68                 "-------------------------------\n".
69                 "\n".
70                 "=item $name".
71                 "\n\n".
72                 "$name $trivial".
73                 "\n\n".
74                 $full.
75                 "\n\n"
76         ;
77 }
78
79 # generate SGML for an applet
80 sub sgml_for_usage {
81         my $name  = shift;
82         my $usage = shift;
83         return
84                 "<fixme>\n".
85                 "  $name\n".
86                 "</fixme>\n"
87         ;
88 }
89
90 # the keys are applet names, and 
91 # the values will contain hashrefs of the form:
92 #
93 # {
94 #     trivial => "...",
95 #     full    => "...",
96 # }
97 my %docs;
98
99 # get command-line options
100 my %opt;
101
102 GetOptions(
103         \%opt,
104         "help|h",
105         "sgml|s",
106         "pod|p",
107         "verbose|v",
108 );
109
110 if (defined $opt{help}) {
111         print
112                 "$0 [OPTION]... [FILE]...\n",
113                 "\t--help\n",
114                 "\t--sgml\n",
115                 "\t--pod\n",
116                 "\t--verbose\n",
117         ;
118         exit 1;
119 }
120
121 # collect documenation into %docs
122 foreach (@ARGV) {
123         open(USAGE, $_) || die("$0: $!");
124         my $fh = *USAGE;
125         my ($applet, $type, @line);
126         while (<$fh>) {
127
128                 if (/^#define (\w+)_(\w+)_usage/) {
129                         $applet = $1;
130                         $type   = $2;
131                         @line   = continuation($fh);
132                         my $doc = $docs{$applet} ||= { };
133
134                         my $text      = join("\n", @line);
135                         $doc->{$type} = beautify($text);
136                 }
137
138         }
139 }
140
141 my $generator = \&pod_for_usage;
142 if (defined $opt{sgml}) {
143     $generator = \&sgml_for_usage;
144 }
145
146 foreach my $name (sort keys %docs) {
147         print $generator->($name, $docs{$name});
148 }
149
150 exit 0;
151
152 __END__
153
154 =head1 NAME
155
156 autodocifier.pl - generate docs for busybox based on usage.h
157
158 =head1 SYNOPSIS
159
160 autodocifier.pl usage.h > something
161
162 =head1 DESCRIPTION
163
164 The purpose of this script is to automagically generate documentation
165 for busybox using its usage.h as the original source for content.
166 Currently, the same content has to be duplicated in 3 places in
167 slightly different formats -- F<usage.h>, F<docs/busybox.pod>, and
168 F<docs/busybox.sgml>.  This is tedious, so Perl has come to the rescue.
169
170 This script was based on a script by Erik Andersen (andersen@lineo.com).
171
172 =head1 OPTIONS
173
174 =over 4
175
176 =item --help
177
178 This displays the help message.
179
180 =item --pod
181
182 Generate POD (this is the default)
183
184 =item --sgml
185
186 Generate SGML
187
188 =item --verbose
189
190 Be verbose (not implemented)
191
192 =back
193
194 =head1 FILES
195
196 F<usage.h>
197
198 =head1 COPYRIGHT
199
200 Copyright (c) 2001 John BEPPU.  All rights reserved.  This program is
201 free software; you can redistribute it and/or modify it under the same
202 terms as Perl itself.
203
204 =head1 AUTHOR
205
206 John BEPPU <beppu@lineo.com>
207
208 =cut
209
210 # $Id: autodocifier.pl,v 1.10 2001/02/23 17:55:03 beppu Exp $