70169311191018dfb5dc1ea131b86b509a2798ea
[debian/tar] / debian / tarman
1 #
2 # tarman - make tar man page from src/tar.c
3 # some text cribbed from debian tar man page
4 #
5
6 use strict;
7
8 my $t = "".localtime(time);
9 my $datestr = substr($t,4,3)." ".substr($t,8,2).", ".substr($t,20,4);
10
11 @ARGV=qw(src/tar.c);
12 my $mode;
13 my @operations;
14 my $lastoperation;
15 my @options;
16 my @formats;
17 my @short;
18 my $examples;
19 my $saw_format;
20 my @env_vars;
21 while (<>) {
22         my $nflag = 0;
23         chomp;
24 # print "$mode: $_\n";
25         if (/getenv.*"/) {
26                 next if defined($mode);
27                 my @c1 = split('"');
28                 if ($#c1 > 0) {
29                         push @env_vars, $c1[1];
30                 }
31         }
32         if (/Main operation mode:/) {
33                 $mode = 1;
34                 next;
35         }
36         if (/Operation modifiers:/) {
37                 $mode = 2;
38                 next;
39         }
40         if (/Examples:/) {
41                 $mode = 3;
42                 next;
43         }
44         if (/define GRID/) {
45                 $mode = 2;
46         }
47         if (/undef GRID/) {
48                 undef $lastoperation;
49                 undef $mode;
50                 next;
51         }
52         if ($mode == 1 || $mode == 2) {
53                 if (/{"/) {     # }
54                         my @j = split(',');
55                         my @c1 = split('"', $j[0]);
56                         if (/OPTION_ALIAS/) {
57                                 next unless defined($lastoperation);
58                                 push @{$$lastoperation{'alias'} }, $c1[1];
59                                 next;
60                         }
61                         my %newhash = ();
62                         $lastoperation = \%newhash;
63                         my $name = $c1[1];
64                         if ($name =~ /^  /) {
65                                 $name =~ s/^  */format=/;
66                                 push @formats, $lastoperation;
67                         } elsif ($mode == 1) {
68                                 push @operations, $lastoperation;
69                         } else {
70                                 push @options, $lastoperation;
71                         }
72                         $newhash{'name'} = $name;
73                         if ($mode == 2 && $name eq 'format') {
74                                 $saw_format = $lastoperation;
75                         }
76                         my @c2 = split("'", $j[1]);
77                         if ($#c2 > 0) {
78                                 $newhash{'short'} = $c2[1];
79                                 push @short, $c2[1] if ($mode == 1);
80                         }
81                         if ($j[2] =~ /N_/) {
82                                 $nflag = 1;
83                         }
84                 }
85                 if (/N_/) {
86                         next unless defined($lastoperation);
87                         my $nrest = $_;
88                         $nrest =~ s/.*N_//;
89                         my @c3 = split('"', $nrest);
90                         if ($#c3 > 0) {
91                                 if ($nflag) {
92                                         $$lastoperation{'operand'} .= $c3[1];
93                                 } else {
94                                         $$lastoperation{'description'} .= $c3[1];
95                                 }
96                         }
97                         if (!$nflag && !/\}/) {
98                                 while (<>) {
99                                         my @extended_desc = split('"', $_);
100                                         $$lastoperation{'description'} .= $extended_desc[1];
101                                         if (/\}/) {
102                                                 last;
103                                         }
104                                 }
105                         }
106                 }
107         }
108         if ($mode == 3 ) {
109                 my $j = $_;
110                 $j =~ s/\\n.*//;
111                 my ($c1, $c2) = split('#', $j, 2);
112                 $c1 =~ s/  *$//;
113                 $c1 =~ s/^  *//;
114 $c1 =~ s/-/\\-/g;
115                 $c2 =~ s/^  *//;
116 $examples .= <<".";
117 $c2
118 .Bd -literal -offset indent -compact
119 $c1
120 .Ed
121 .
122                 # (
123                 if (/"\)/) {
124                         undef $mode;
125                 }
126         }
127 }
128
129 # for my $q ( @operations) {
130 #       print "\nshort=".$$q{'short'}."\n";
131 #       print "name=".$$q{'name'}."\n";
132 #       print "desc=".$$q{'description'}."\n";
133 #       if (defined($$q{'alias'})) {
134 #               print "alias=".join(',',@{ $$q{'alias'}})."\n";
135 #       }
136 # }
137
138 sub long2nroff {
139         my $f = shift;
140         if ($f !~ /^-/) {
141                 $f = "Fl -$f";
142         }
143         $f =~ s/-/\\-/g;
144         return $f;
145 }
146
147 sub format_options
148 {
149         my $h = shift;
150         my $r;
151         for my $q ( @$h ) {
152                 $r .= ".It";
153                 my @functions;
154                 push @functions, " Fl ".$$q{'short'} if defined($$q{'short'});
155                 push @functions, " ".long2nroff($$q{'name'});
156                 push @functions, join(' ', '', map {long2nroff $_} @{ $$q{'alias'} })
157                         if defined($$q{'alias'});
158                 $r .= join(' ,', @functions);
159                 if (defined($$q{'operand'})) {
160                         if ($#functions > 0) {
161                                 $r .= " ";
162                         } else {
163                                 $r .= " Ns \\= Ns ";
164                         }
165                         $r .= "Ar ".$$q{'operand'};
166                 }
167                 $r .= "\n".$$q{'description'}."\n";
168                 $r .= $$q{'extra'};
169         }
170         return $r;
171 }
172
173 sub optionkeyword
174 {
175         my $h = shift;
176         my $k = $$h{'short'};
177         $k = $$h{'name'} if !defined($k);
178         my $l = $k;
179         if ($l =~ s/^no-//) {
180                 $l .= "-no";
181         }
182         return ($l,$k);
183 }
184
185 sub optioncmp
186 {
187         my ($x1, $x2) = optionkeyword($a);
188         my ($y1, $y2) = optionkeyword($b);
189         my $r = lc($x1) cmp lc($y1);
190         return $r if $r;
191         $r = $y1 cmp $x1;
192         return $r if $r;
193         return $x2 cmp $y2;
194 }
195
196 @operations = sort optioncmp @operations;
197 @operations = sort optioncmp @operations;
198 @options = sort optioncmp @options;
199 @formats = sort optioncmp @formats;
200
201 if ($#formats >= 0 && !$saw_format) {
202         print STDERR "FIXME: saw --format=X but no root --format!\n";
203         exit(1);
204 }
205
206 my $function_letters;
207 my $short_letters = join('', sort @short);
208 my $option_letters;
209 my $format_letters;
210 my $command_string = <<".";
211 .Nm tar
212 .
213 $command_string .= ".Oo Fl Oc";
214 my $env_variables;
215 my %env_description = (
216 'SIMPLE_BACKUP_SUFFIX' => <<".",
217 Backup prefix to use when extracting, if
218 .Fl \\-suffix
219 is not specified.
220 The backup suffix defaults to `~' if neither is specified.
221 .
222 'TAPE' => <<".",
223 Device or file to use for the archive if 
224 .Fl \\-file
225 is not specified.
226 If this environment variable is unset, use stdin or stdout instead.
227 .
228 'TAR_OPTIONS' => <<".",
229 Options to prepend to those specified on the command line, separated by
230 whitespace.  Embedded backslashes may be used to escape whitespace or
231 backslashes within an option.
232 .
233 );
234 my $sep = "";
235 for my $q ( @operations) {
236         $command_string .= " Cm";
237         $command_string .= $sep;
238         $command_string .= " ".$$q{'short'} if defined($$q{'short'});
239         $command_string .= " ".long2nroff($$q{'name'});
240         if (defined($$q{'alias'})) {
241                 my $t = join(' ', '', map{long2nroff $_} @{ $$q{'alias'} });
242                 $t =~ s/ Fl / /g;
243                 $command_string .= $t;
244         }
245         $sep = " \\||\\|";
246 }
247 $function_letters = ".Bl -tag -width flag\n";
248 $function_letters .= format_options(\@operations);
249 $function_letters .= ".El";
250 if ($#formats >= 0) {
251         $format_letters = ".Bl -tag -width flag\n";
252         $format_letters .= format_options(\@formats);
253         $format_letters .= ".El\n";
254         $$saw_format{'extra'} = $format_letters;
255 }
256 ### Ar Cm Ic Li Nm Op Pa Va
257 $option_letters = ".Bl -tag -width flag\n";
258 $option_letters .= format_options(\@options);
259 $option_letters .= ".El";
260 $env_variables .= ".Bl -tag -width Ds\n";
261 for my $q ( @env_vars) {
262         $env_variables .= ".It Ev $q\n";
263         $env_variables .= $env_description{$q};
264 }
265 $env_variables .= ".El";
266
267 $examples =~ s/\n$//;
268 $function_letters =~ s/\n$//;
269 $option_letters =~ s/\n$//;
270 $env_variables =~ s/\n$//;
271 print <<".";
272 .\\" generated by script on $t
273 .Dd $datestr
274 .Dt TAR 1
275 .Sh NAME
276 .Nm tar
277 .Nd The GNU version of the tar archiving utility
278 .Sh SYNOPSIS
279 $command_string
280 .Op Ar options
281 .Op Ar pathname ...
282 .Sh DESCRIPTION
283 .Nm Tar
284 stores and extracts files from a tape or disk archive.
285 .Pp
286 The first argument to
287 tar
288 should be a function; either one of the letters
289 .Cm $short_letters ,
290 or one of the long function names.
291 A function letter need not be prefixed with ``\\-'', and may be combined
292 with other single-letter options.
293 A long function name must be prefixed with
294 .Cm \\\\-\\\\- .
295 Some options take a parameter; with the single-letter form
296 these must be given as separate arguments.
297 With the long form, they may be given by appending
298 .Cm = Ns Ar value
299 to the option.
300 .Sh FUNCTION LETTERS
301 Main operation mode:
302 $function_letters
303 .Sh OTHER OPTIONS
304 Operation modifiers:
305 $option_letters
306 .Sh ENVIRONMENT
307 The behavior of tar is controlled by the following environment variables,
308 among others:
309 $env_variables
310 .Sh EXAMPLES
311 $examples
312 .Sh SEE ALSO
313 .\\" libarchive
314 .Xr tar 5 ,
315 .\\" man-pages
316 .Xr symlink 7 ,
317 .Xr rmt 8
318 .Sh HISTORY
319 The
320 .Nm tar
321 command appeared in
322 .At v7 .
323 .Sh BUGS
324 The GNU folks, in general, abhor man pages, and create info documents instead.
325 Unfortunately, the info document describing tar is licensed under the GFDL with
326 invariant cover texts, which makes it impossible to include any text
327 from that document in this man page.
328 Most of the text in this document was automatically extracted from the usage
329 text in the source.
330 It may not completely describe all features of the program.
331 .
332 __END__