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