diff options
Diffstat (limited to 'busybox/docs/autodocifier.pl')
-rwxr-xr-x | busybox/docs/autodocifier.pl | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/busybox/docs/autodocifier.pl b/busybox/docs/autodocifier.pl new file mode 100755 index 000000000..eee67cf09 --- /dev/null +++ b/busybox/docs/autodocifier.pl | |||
@@ -0,0 +1,274 @@ | |||
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 { | ||
30 | s/^\s*"//; | ||
31 | s/"\s*$//; | ||
32 | s/%/%%/g; | ||
33 | s/\$/\\\$/g; | ||
34 | eval qq[ sprintf(qq{$_}) ] | ||
35 | } @line | ||
36 | ); | ||
37 | return $text; | ||
38 | } | ||
39 | |||
40 | # generate POD for an applet | ||
41 | sub pod_for_usage { | ||
42 | my $name = shift; | ||
43 | my $usage = shift; | ||
44 | |||
45 | # Sigh. Fixup the known odd-name applets. | ||
46 | $name =~ s/dpkg_deb/dpkg-deb/g; | ||
47 | $name =~ s/fsck_minix/fsck.minix/g; | ||
48 | $name =~ s/mkfs_minix/mkfs.minix/g; | ||
49 | $name =~ s/run_parts/run-parts/g; | ||
50 | $name =~ s/start_stop_daemon/start-stop-daemon/g; | ||
51 | |||
52 | # make options bold | ||
53 | my $trivial = $usage->{trivial}; | ||
54 | $trivial =~ s/(?<!\w)(-\w+)/B<$1>/sxg; | ||
55 | my @f0 = | ||
56 | map { $_ !~ /^\s/ && s/(?<!\w)(-\w+)/B<$1>/g; $_ } | ||
57 | split("\n", $usage->{full}); | ||
58 | |||
59 | # add "\n" prior to certain lines to make indented | ||
60 | # lines look right | ||
61 | my @f1; | ||
62 | my $len = @f0; | ||
63 | for (my $i = 0; $i < $len; $i++) { | ||
64 | push @f1, $f0[$i]; | ||
65 | if (($i+1) != $len && $f0[$i] !~ /^\s/ && $f0[$i+1] =~ /^\s/) { | ||
66 | next if ($f0[$i] =~ /^$/); | ||
67 | push(@f1, "") unless ($f0[$i+1] =~ /^\s*$/s); | ||
68 | } | ||
69 | } | ||
70 | my $full = join("\n", @f1); | ||
71 | |||
72 | # prepare notes if they exist | ||
73 | my $notes = (defined $usage->{notes}) | ||
74 | ? "$usage->{notes}\n\n" | ||
75 | : ""; | ||
76 | |||
77 | # prepare examples if they exist | ||
78 | my $example = (defined $usage->{example}) | ||
79 | ? | ||
80 | "Example:\n\n" . | ||
81 | join ("\n", | ||
82 | map { "\t$_" } | ||
83 | split("\n", $usage->{example})) . "\n\n" | ||
84 | : ""; | ||
85 | |||
86 | return | ||
87 | "=item B<$name>". | ||
88 | "\n\n$name $trivial\n\n". | ||
89 | "$full\n\n" . | ||
90 | "$notes" . | ||
91 | "$example" . | ||
92 | "-------------------------------". | ||
93 | "\n\n" | ||
94 | ; | ||
95 | } | ||
96 | |||
97 | # the keys are applet names, and | ||
98 | # the values will contain hashrefs of the form: | ||
99 | # | ||
100 | # { | ||
101 | # trivial => "...", | ||
102 | # full => "...", | ||
103 | # notes => "...", | ||
104 | # example => "...", | ||
105 | # } | ||
106 | my %docs; | ||
107 | |||
108 | |||
109 | # get command-line options | ||
110 | |||
111 | my %opt; | ||
112 | |||
113 | GetOptions( | ||
114 | \%opt, | ||
115 | "help|h", | ||
116 | "pod|p", | ||
117 | "verbose|v", | ||
118 | ); | ||
119 | |||
120 | if (defined $opt{help}) { | ||
121 | |||
122 | "$0 [OPTION]... [FILE]...\n", | ||
123 | "\t--help\n", | ||
124 | "\t--pod\n", | ||
125 | "\t--verbose\n", | ||
126 | ; | ||
127 | exit 1; | ||
128 | } | ||
129 | |||
130 | |||
131 | # collect documenation into %docs | ||
132 | |||
133 | foreach (@ARGV) { | ||
134 | open(USAGE, $_) || die("$0: $_: $!"); | ||
135 | my $fh = *USAGE; | ||
136 | my ($applet, $type, @line); | ||
137 | while (<$fh>) { | ||
138 | if (/^#define (\w+)_(\w+)_usage/) { | ||
139 | $applet = $1; | ||
140 | $type = $2; | ||
141 | @line = continuation($fh); | ||
142 | my $doc = $docs{$applet} ||= { }; | ||
143 | my $text = join("\n", @line); | ||
144 | $doc->{$type} = beautify($text); | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | |||
150 | # generate structured documentation | ||
151 | |||
152 | my $generator = \&pod_for_usage; | ||
153 | foreach my $applet (sort keys %docs) { | ||
154 | print $generator->($applet, $docs{$applet}); | ||
155 | } | ||
156 | |||
157 | exit 0; | ||
158 | |||
159 | __END__ | ||
160 | |||
161 | =head1 NAME | ||
162 | |||
163 | autodocifier.pl - generate docs for busybox based on usage.h | ||
164 | |||
165 | =head1 SYNOPSIS | ||
166 | |||
167 | autodocifier.pl [OPTION]... [FILE]... | ||
168 | |||
169 | Example: | ||
170 | |||
171 | ( cat docs/busybox_header.pod; \ | ||
172 | docs/autodocifier.pl usage.h; \ | ||
173 | cat docs/busybox_footer.pod ) > docs/busybox.pod | ||
174 | |||
175 | =head1 DESCRIPTION | ||
176 | |||
177 | The purpose of this script is to automagically generate | ||
178 | documentation for busybox using its usage.h as the original source | ||
179 | for content. It used to be that same content has to be duplicated | ||
180 | in 3 places in slightly different formats -- F<usage.h>, | ||
181 | F<docs/busybox.pod>. This was tedious and error-prone, so it was | ||
182 | decided that F<usage.h> would contain all the text in a | ||
183 | machine-readable form, and scripts could be used to transform this | ||
184 | text into other forms if necessary. | ||
185 | |||
186 | F<autodocifier.pl> is one such script. It is based on a script by | ||
187 | Erik Andersen <andersen@codepoet.org> which was in turn based on a | ||
188 | script by Mark Whitley <markw@codepoet.org> | ||
189 | |||
190 | =head1 OPTIONS | ||
191 | |||
192 | =over 4 | ||
193 | |||
194 | =item B<--help> | ||
195 | |||
196 | This displays the help message. | ||
197 | |||
198 | =item B<--pod> | ||
199 | |||
200 | Generate POD (this is the default) | ||
201 | |||
202 | =item B<--verbose> | ||
203 | |||
204 | Be verbose (not implemented) | ||
205 | |||
206 | =back | ||
207 | |||
208 | =head1 FORMAT | ||
209 | |||
210 | The following is an example of some data this script might parse. | ||
211 | |||
212 | #define length_trivial_usage \ | ||
213 | "STRING" | ||
214 | #define length_full_usage \ | ||
215 | "Prints out the length of the specified STRING." | ||
216 | #define length_example_usage \ | ||
217 | "$ length Hello\n" \ | ||
218 | "5\n" | ||
219 | |||
220 | Each entry is a cpp macro that defines a string. The macros are | ||
221 | named systematically in the form: | ||
222 | |||
223 | $name_$type_usage | ||
224 | |||
225 | $name is the name of the applet. $type can be "trivial", "full", "notes", | ||
226 | or "example". Every documentation macro must end with "_usage". | ||
227 | |||
228 | The definition of the types is as follows: | ||
229 | |||
230 | =over 4 | ||
231 | |||
232 | =item B<trivial> | ||
233 | |||
234 | This should be a brief, one-line description of parameters that | ||
235 | the command expects. This will be displayed when B<-h> is issued to | ||
236 | a command. I<REQUIRED> | ||
237 | |||
238 | =item B<full> | ||
239 | |||
240 | This should contain descriptions of each option. This will also | ||
241 | be displayed along with the trivial help if CONFIG_FEATURE_TRIVIAL_HELP | ||
242 | is disabled. I<REQUIRED> | ||
243 | |||
244 | =item B<notes> | ||
245 | |||
246 | This is documentation that is intended to go in the POD or SGML, but | ||
247 | not be printed when a B<-h> is given to a command. To see an example | ||
248 | of notes being used, see init_notes_usage in F<usage.h>. I<OPTIONAL> | ||
249 | |||
250 | =item B<example> | ||
251 | |||
252 | This should be an example of how the command is actually used. | ||
253 | This will not be printed when a B<-h> is given to a command -- it | ||
254 | will only be included in the POD or SGML documentation. I<OPTIONAL> | ||
255 | |||
256 | =back | ||
257 | |||
258 | =head1 FILES | ||
259 | |||
260 | F<usage.h> | ||
261 | |||
262 | =head1 COPYRIGHT | ||
263 | |||
264 | Copyright (c) 2001 John BEPPU. All rights reserved. This program is | ||
265 | free software; you can redistribute it and/or modify it under the same | ||
266 | terms as Perl itself. | ||
267 | |||
268 | =head1 AUTHOR | ||
269 | |||
270 | John BEPPU <b@ax9.org> | ||
271 | |||
272 | =cut | ||
273 | |||
274 | # $Id: autodocifier.pl,v 1.26 2004/04/06 15:26:25 andersen Exp $ | ||