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