~ubuntu-branches/ubuntu/maverick/texinfo/maverick

« back to all changes in this revision

Viewing changes to util/gdoc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2005-10-28 15:10:30 UTC
  • mto: (2.1.1 dapper) (3.1.4 hardy)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20051028151030-9nsf2s2k2z3fktjt
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
 
 
3
## Copyright (c) 2002, 2003 Simon Josefsson                      ##
 
4
##                    added -texinfo, -listfunc                  ##
 
5
##                    man page revamp                            ##
 
6
##                    various improvements                       ##
 
7
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
 
8
##                    hacked to allow -tex option --nmav         ##
 
9
##                                                               ##
 
10
## This software falls under the GNU Public License. Please read ##
 
11
##              the COPYING file for more information            ##
 
12
 
 
13
#
 
14
# This will read a 'c' file and scan for embedded comments in the
 
15
# style of gnome comments (+minor extensions - see below).
 
16
#
 
17
# This program is modified by Nikos Mavroyanopoulos, for the gnutls
 
18
# project.
 
19
 
 
20
# Note: This only supports 'c'.
 
21
 
 
22
# usage:
 
23
# gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ]
 
24
#      [ -sourceversion verno ] [ -includefuncprefix ] [ -bugsto address ]
 
25
#      [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ]
 
26
#      [ -function funcname [ -function funcname ...] ] c file(s)s > outputfil
 
27
e
 
28
#
 
29
#  Set output format using one of -docbook, -html, -text, -man, -tex,
 
30
#  -texinfo, or -listfunc.  Default is man.
 
31
#
 
32
#  -sourceversion
 
33
#       Version number for source code, e.g. '1.0.4'.  Used in 'man' headers.
 
34
#       Defaults to using current date.
 
35
#
 
36
#  -includefuncprefix
 
37
#       For man pages, generate a #include <FILE.h> based on the function
 
38
#       prefix.  For example, a function gss_init_sec_context will generate
 
39
#       an include statement of #include <gss.h>.
 
40
#
 
41
#  -bugsto address
 
42
#       For man pages, include a section about reporting bugs and mention
 
43
#       the given e-mail address, e.g 'bug-libidn@gnu.org'.
 
44
#
 
45
#  -seeinfo infonode
 
46
#       For man pages, include a section that point to an info manual
 
47
#       for more information.
 
48
#
 
49
#  -copyright notice
 
50
#       For man pages, include a copyright section with the given
 
51
#       notice after a preamble.  Use, e.g., '2002, 2003 Simon Josefsson'.
 
52
#
 
53
#  -verbatimcopying
 
54
#       For man pages, and when the -copyright parameter is used,
 
55
#       add a licensing statement that say verbatim copying is permitted.
 
56
#
 
57
#  -function funcname
 
58
#       If set, then only generate documentation for the given function(s).  A
 
59
ll
 
60
#       other functions are ignored.
 
61
#
 
62
#  c files - list of 'c' files to process
 
63
#
 
64
#  All output goes to stdout, with errors to stderr.
 
65
 
 
66
#
 
67
# format of comments.
 
68
# In the following table, (...)? signifies optional structure.
 
69
#                         (...)* signifies 0 or more structure elements
 
70
# /**
 
71
#  * function_name(:)? (- short description)?
 
72
# (* @parameterx: (description of parameter x)?)*
 
73
# (* a blank line)?
 
74
#  * (Description:)? (Description of function)?
 
75
#  * (Section header: (section description)? )*
 
76
#  (*)?*/
 
77
#
 
78
# So .. the trivial example would be:
 
79
#
 
80
# /**
 
81
#  * my_function
 
82
#  **/
 
83
#
 
84
# If the Description: header tag is ommitted, then there must be a blank line
 
85
# after the last parameter specification.
 
86
# e.g.
 
87
# /**
 
88
#  * my_function - does my stuff
 
89
#  * @my_arg: its mine damnit
 
90
#  *
 
91
#  * Does my stuff explained. 
 
92
#  */
 
93
#
 
94
#  or, could also use:
 
95
# /**
 
96
#  * my_function - does my stuff
 
97
#  * @my_arg: its mine damnit
 
98
#  * Description: Does my stuff explained. 
 
99
#  */
 
100
# etc.
 
101
#
 
102
# All descriptions can be multiline, apart from the short function description
 
103
.
 
104
#
 
105
# All descriptive text is further processed, scanning for the following specia
 
106
l
 
107
# patterns, which are highlighted appropriately.
 
108
#
 
109
# 'funcname()' - function
 
110
# '$ENVVAR' - environmental variable
 
111
# '&struct_name' - name of a structure
 
112
# '@parameter' - name of a parameter
 
113
# '%CONST' - name of a constant.
 
114
 
 
115
#
 
116
# Extensions for LaTeX:
 
117
#
 
118
# 1. the symbol '->' will be replaced with a rightarrow
 
119
# 2. x^y with ${x}^{y}$.
 
120
# 3. xxx\: with xxx:
 
121
 
 
122
use POSIX qw(strftime);
 
123
 
 
124
# match expressions used to find embedded type information
 
125
$type_constant = "\\\%(\\w+)";
 
126
$type_func = "(\\w+\\(\\))";
 
127
$type_param = "\\\@(\\w+)";
 
128
$type_struct = "\\\&(\\w+)";
 
129
$type_env = "(\\\$\\w+)";
 
130
 
 
131
 
 
132
# Output conversion substitutions.
 
133
#  One for each output format
 
134
 
 
135
# these work fairly well
 
136
%highlights_html = ( $type_constant, "<i>\$1</i>",
 
137
                     $type_func, "<b>\$1</b>",
 
138
                     $type_struct, "<i>\$1</i>",
 
139
                     $type_param, "<tt><b>\$1</b></tt>" );
 
140
$blankline_html = "<p>";
 
141
 
 
142
%highlights_texinfo = ( $type_constant, "\\\@var{\$1}",
 
143
                        $type_func, "\\\@code{\$1}",
 
144
                        $type_struct, "\\\@code{\$1}",
 
145
                        $type_param, "\\\@code{\$1}" );
 
146
$blankline_texinfo = "";
 
147
 
 
148
%highlights_tex = ( $type_constant, "{\\\\it \$1}",
 
149
                     $type_func, "{\\\\bf \$1}",
 
150
                     $type_struct, "{\\\\it \$1}",
 
151
                     $type_param, "{\\\\bf \$1}" );
 
152
$blankline_tex = "\\\\";
 
153
 
 
154
# sgml, docbook format
 
155
%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</repla
 
156
ceable>",
 
157
                     $type_func, "<function>\$1</function>",
 
158
                     $type_struct, "<structname>\$1</structname>",
 
159
                     $type_env, "<envar>\$1</envar>",
 
160
                     $type_param, "<parameter>\$1</parameter>" );
 
161
$blankline_sgml = "</para><para>\n";
 
162
 
 
163
# these are pretty rough
 
164
%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n",
 
165
                    $type_func, "\\n.B \\\"\$1\\\"\\n",
 
166
                    $type_struct, "\\n.I \\\"\$1\\\"\\n",
 
167
                    $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" );
 
168
$blankline_man = "";
 
169
 
 
170
# text-mode
 
171
%highlights_text = ( $type_constant, "\$1",
 
172
                     $type_func, "\$1",
 
173
                     $type_struct, "\$1",
 
174
                     $type_param, "\$1" );
 
175
$blankline_text = "";
 
176
 
 
177
 
 
178
sub usage {
 
179
    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinf
 
180
o  -listfunc ]\n";
 
181
    print "         [ -sourceversion verno ] [ -includefuncprefix ]\n";
 
182
    print "         [ -bugsto address ] [ -seeinfo infonode ] [ -copyright not
 
183
ice]\n";
 
184
    print "         [ -verbatimcopying ]\n";
 
185
    print "         [ -function funcname [ -function funcname ...] ]\n";
 
186
    print "         c source file(s) > outputfile\n";
 
187
    exit 1;
 
188
}
 
189
 
 
190
# read arguments
 
191
if ($#ARGV==-1) {
 
192
    usage();
 
193
}
 
194
 
 
195
$verbose = 0;
 
196
$output_mode = "man";
 
197
%highlights = %highlights_man;
 
198
$blankline = $blankline_man;
 
199
$modulename = "API Documentation";
 
200
$sourceversion = strftime "%Y-%m-%d", localtime;
 
201
$function_only = 0;
 
202
while ($ARGV[0] =~ m/^-(.*)/) {
 
203
    $cmd = shift @ARGV;
 
204
    if ($cmd eq "-html") {
 
205
        $output_mode = "html";
 
206
        %highlights = %highlights_html;
 
207
        $blankline = $blankline_html;
 
208
    } elsif ($cmd eq "-man") {
 
209
        $output_mode = "man";
 
210
        %highlights = %highlights_man;
 
211
        $blankline = $blankline_man;
 
212
    } elsif ($cmd eq "-tex") {
 
213
        $output_mode = "tex";
 
214
        %highlights = %highlights_tex;
 
215
        $blankline = $blankline_tex;
 
216
    } elsif ($cmd eq "-texinfo") {
 
217
        $output_mode = "texinfo";
 
218
        %highlights = %highlights_texinfo;
 
219
        $blankline = $blankline_texinfo;
 
220
    } elsif ($cmd eq "-text") {
 
221
        $output_mode = "text";
 
222
        %highlights = %highlights_text;
 
223
        $blankline = $blankline_text;
 
224
    } elsif ($cmd eq "-docbook") {
 
225
        $output_mode = "sgml";
 
226
        %highlights = %highlights_sgml;
 
227
        $blankline = $blankline_sgml;
 
228
    } elsif ($cmd eq "-listfunc") {
 
229
        $output_mode = "listfunc";
 
230
    } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling
 
231
 document
 
232
        $modulename = shift @ARGV;
 
233
    } elsif ($cmd eq "-sourceversion") {
 
234
        $sourceversion = shift @ARGV;
 
235
    } elsif ($cmd eq "-includefuncprefix") {
 
236
        $includefuncprefix = 1;
 
237
    } elsif ($cmd eq "-bugsto") {
 
238
        $bugsto = shift @ARGV;
 
239
    } elsif ($cmd eq "-copyright") {
 
240
        $copyright = shift @ARGV;
 
241
    } elsif ($cmd eq "-verbatimcopying") {
 
242
        $verbatimcopying = 1;
 
243
    } elsif ($cmd eq "-seeinfo") {
 
244
        $seeinfo = shift @ARGV;
 
245
    } elsif ($cmd eq "-function") { # to only output specific functions
 
246
        $function_only = 1;
 
247
        $function = shift @ARGV;
 
248
        $function_table{$function} = 1;
 
249
    } elsif ($cmd eq "-v") {
 
250
        $verbose = 1;
 
251
    } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
 
252
        usage();
 
253
    }
 
254
}
 
255
 
 
256
##
 
257
# dumps section contents to arrays/hashes intended for that purpose.
 
258
#
 
259
sub dump_section {
 
260
    my $name = shift @_;
 
261
    my $contents = join "\n", @_;
 
262
 
 
263
    if ($name =~ m/$type_constant/) {
 
264
        $name = $1;
 
265
#       print STDERR "constant section '$1' = '$contents'\n";
 
266
        $constants{$name} = $contents;
 
267
    } elsif ($name =~ m/$type_param/) {
 
268
#       print STDERR "parameter def '$1' = '$contents'\n";
 
269
        $name = $1;
 
270
        $parameters{$name} = $contents;
 
271
    } else {
 
272
#       print STDERR "other section '$name' = '$contents'\n";
 
273
        $sections{$name} = $contents;
 
274
        push @sectionlist, $name;
 
275
    }
 
276
}
 
277
 
 
278
##
 
279
# output function
 
280
#
 
281
# parameters, a hash.
 
282
#  function => "function name"
 
283
#  parameterlist => @list of parameters
 
284
#  parameters => %parameter descriptions
 
285
#  sectionlist => @list of sections
 
286
#  sections => %descriont descriptions
 
287
#  
 
288
 
 
289
sub repstr {
 
290
    $pattern = shift;
 
291
    $repl = shift;
 
292
    $match1 = shift;
 
293
    $match2 = shift;
 
294
    $match3 = shift;
 
295
    $match4 = shift;
 
296
 
 
297
    $output = $repl;
 
298
    $output =~ s,\$1,$match1,g;
 
299
    $output =~ s,\$2,$match2,g;
 
300
    $output =~ s,\$3,$match3,g;
 
301
    $output =~ s,\$4,$match4,g;
 
302
 
 
303
    eval "\$return = qq/$output/";
 
304
 
 
305
#    print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 r
 
306
eplace $repl yielded $output interpolated $return\n";
 
307
 
 
308
    $return;
 
309
}
 
310
 
 
311
sub output_highlight {
 
312
    my $contents = join "\n", @_;
 
313
    my $line;
 
314
 
 
315
    foreach $pattern (keys %highlights) {
 
316
#       print "scanning pattern $pattern ($highlights{$pattern})\n";
 
317
        $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
 
318
, $3, $4):gse;
 
319
    }
 
320
    foreach $line (split "\n", $contents) {
 
321
        if ($line eq ""){
 
322
            print $lineprefix, $blankline;
 
323
        } else {
 
324
            print $lineprefix, $line;
 
325
        }
 
326
        print "\n";
 
327
    }
 
328
}
 
329
 
 
330
sub just_highlight {
 
331
    my $contents = join "\n", @_;
 
332
    my $line;
 
333
    my $ret = "";
 
334
 
 
335
    foreach $pattern (keys %highlights) {
 
336
#       print "scanning pattern $pattern ($highlights{$pattern})\n";
 
337
        $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
 
338
, $3, $4):gse;
 
339
    }
 
340
    foreach $line (split "\n", $contents) {
 
341
        if ($line eq ""){
 
342
            $ret = $ret . $lineprefix . $blankline;
 
343
        } else {
 
344
            $ret = $ret . $lineprefix . $line;
 
345
        }
 
346
        $ret = $ret . "\n";
 
347
    }
 
348
 
 
349
    return $ret;
 
350
}
 
351
 
 
352
# output in texinfo
 
353
sub output_texinfo {
 
354
    my %args = %{$_[0]};
 
355
    my ($parameter, $section);
 
356
    my $count;
 
357
 
 
358
    print "\@deftypefun {" . $args{'functiontype'} . "} ";
 
359
    print "{".$args{'function'}."} ";
 
360
    print "(";
 
361
    $count = 0;
 
362
    foreach $parameter (@{$args{'parameterlist'}}) {
 
363
        print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}";
 
364
        if ($count != $#{$args{'parameterlist'}}) {
 
365
            $count++;
 
366
            print ", ";
 
367
        }
 
368
    }
 
369
    print ")\n";
 
370
    foreach $parameter (@{$args{'parameterlist'}}) {
 
371
        if ($args{'parameters'}{$parameter}) {
 
372
            print "\@var{".$parameter."}: ";
 
373
            output_highlight($args{'parameters'}{$parameter});
 
374
            print "\n";
 
375
        }
 
376
    }
 
377
    foreach $section (@{$args{'sectionlist'}}) {
 
378
        print "\n\@strong{$section:} " if $section ne $section_default;
 
379
        $args{'sections'}{$section} =~ s:([{}]):\@\1:gs;
 
380
        output_highlight($args{'sections'}{$section});
 
381
    }
 
382
    print "\@end deftypefun\n\n";
 
383
}
 
384
 
 
385
# output in html
 
386
sub output_html {
 
387
    my %args = %{$_[0]};
 
388
    my ($parameter, $section);
 
389
    my $count;
 
390
    print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>
 
391
\n";
 
392
 
 
393
    print "<i>".$args{'functiontype'}."</i>\n";
 
394
    print "<b>".$args{'function'}."</b>\n";
 
395
    print "(";
 
396
    $count = 0;
 
397
    foreach $parameter (@{$args{'parameterlist'}}) {
 
398
        print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter.
 
399
"</b>\n";
 
400
        if ($count != $#{$args{'parameterlist'}}) {
 
401
            $count++;
 
402
            print ", ";
 
403
        }
 
404
    }
 
405
    print ")\n";
 
406
 
 
407
    print "<h3>Arguments</h3>\n";
 
408
    print "<dl>\n";
 
409
    foreach $parameter (@{$args{'parameterlist'}}) {
 
410
        print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parame
 
411
ter."</b>\n";
 
412
        print "<dd>";
 
413
        output_highlight($args{'parameters'}{$parameter});
 
414
    }
 
415
    print "</dl>\n";
 
416
    foreach $section (@{$args{'sectionlist'}}) {
 
417
        print "<h3>$section</h3>\n";
 
418
        print "<ul>\n";
 
419
        output_highlight($args{'sections'}{$section});
 
420
        print "</ul>\n";
 
421
    }
 
422
    print "<hr>\n";
 
423
}
 
424
 
 
425
# output in tex
 
426
sub output_tex {
 
427
    my %args = %{$_[0]};
 
428
    my ($parameter, $section);
 
429
    my $count;
 
430
    my $func = $args{'function'};
 
431
    my $param;
 
432
    my $param2;
 
433
    my $sec;
 
434
    my $check;
 
435
    my $type;
 
436
 
 
437
    $func =~ s/_/\\_/g;
 
438
 
 
439
    print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\
 
440
n";
 
441
 
 
442
    $type = $args{'functiontype'};
 
443
    $type =~ s/_/\\_/g;
 
444
 
 
445
    print "{\\it ".$type."}\n";
 
446
    print "{\\bf ".$func."}\n";
 
447
    print "(";
 
448
    $count = 0;
 
449
    foreach $parameter (@{$args{'parameterlist'}}) {
 
450
        $param = $args{'parametertypes'}{$parameter};
 
451
        $param2 = $parameter;
 
452
        $param =~ s/_/\\_/g;
 
453
        $param2 =~ s/_/\\_/g;
 
454
 
 
455
        print "{\\it ".$param."} {\\bf ".$param2."}";
 
456
        if ($count != $#{$args{'parameterlist'}}) {
 
457
            $count++;
 
458
            print ", ";
 
459
        }
 
460
    }
 
461
    print ")\n";
 
462
 
 
463
    print "\n{\\large{Arguments}}\n";
 
464
 
 
465
    print "\\begin{itemize}\n";
 
466
    $check=0;
 
467
    foreach $parameter (@{$args{'parameterlist'}}) {
 
468
        $param1 = $args{'parametertypes'}{$parameter};
 
469
        $param1 =~ s/_/\\_/g;
 
470
        $param2 = $parameter;
 
471
        $param2 =~ s/_/\\_/g;
 
472
 
 
473
        $check = 1;
 
474
        print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n";
 
475
#       print "\n";
 
476
 
 
477
        $param3 = $args{'parameters'}{$parameter};
 
478
        $param3 =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
 
479
 
 
480
        $out = just_highlight($param3);
 
481
        $out =~ s/_/\\_/g;
 
482
        print $out;
 
483
    }
 
484
    if ($check==0) {
 
485
        print "\\item void\n";
 
486
    }
 
487
    print "\\end{itemize}\n";
 
488
 
 
489
    foreach $section (@{$args{'sectionlist'}}) {
 
490
        $sec = $section;
 
491
        $sec =~ s/_/\\_/g;
 
492
        $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
 
493
 
 
494
        print "\n{\\large{$sec}}\\\\\n";
 
495
        print "\\begin{rmfamily}\n";
 
496
 
 
497
        $sec = $args{'sections'}{$section};
 
498
        $sec =~ s/\\:/:/g;
 
499
        $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
 
500
        $sec =~ s/->/\$\\rightarrow\$/g;
 
501
        $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g;
 
502
 
 
503
        $out = just_highlight($sec);
 
504
        $out =~ s/_/\\_/g;
 
505
 
 
506
        print $out;
 
507
        print "\\end{rmfamily}\n";
 
508
    }
 
509
    print "\n";
 
510
}
 
511
 
 
512
 
 
513
# output in sgml DocBook
 
514
sub output_sgml {
 
515
    my %args = %{$_[0]};
 
516
    my ($parameter, $section);
 
517
    my $count;
 
518
    my $id;
 
519
 
 
520
    $id = $args{'module'}."-".$args{'function'};
 
521
    $id =~ s/[^A-Za-z0-9]/-/g;
 
522
 
 
523
    print "<refentry>\n";
 
524
    print "<refmeta>\n";
 
525
    print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></r
 
526
efentrytitle>\n";
 
527
    print "</refmeta>\n";
 
528
    print "<refnamediv>\n";
 
529
    print " <refname>".$args{'function'}."</refname>\n";
 
530
    print " <refpurpose>\n";
 
531
    print "  ".$args{'purpose'}."\n";
 
532
    print " </refpurpose>\n";
 
533
    print "</refnamediv>\n";
 
534
 
 
535
    print "<refsynopsisdiv>\n";
 
536
    print " <title>Synopsis</title>\n";
 
537
    print "  <funcsynopsis>\n";
 
538
    print "   <funcdef>".$args{'functiontype'}." ";
 
539
    print "<function>".$args{'function'}." ";
 
540
    print "</function></funcdef>\n";
 
541
 
 
542
#    print "<refsect1>\n";
 
543
#    print " <title>Synopsis</title>\n";
 
544
#    print "  <funcsynopsis>\n";
 
545
#    print "   <funcdef>".$args{'functiontype'}." ";
 
546
#    print "<function>".$args{'function'}." ";
 
547
#    print "</function></funcdef>\n";
 
548
 
 
549
    $count = 0;
 
550
    if ($#{$args{'parameterlist'}} >= 0) {
 
551
        foreach $parameter (@{$args{'parameterlist'}}) {
 
552
            print "   <paramdef>".$args{'parametertypes'}{$parameter};
 
553
            print " <parameter>$parameter</parameter></paramdef>\n";
 
554
        }
 
555
    } else {
 
556
        print "  <void>\n";
 
557
    }
 
558
    print "  </funcsynopsis>\n";
 
559
    print "</refsynopsisdiv>\n";
 
560
#    print "</refsect1>\n";
 
561
 
 
562
    # print parameters
 
563
    print "<refsect1>\n <title>Arguments</title>\n";
 
564
#    print "<para>\nArguments\n";
 
565
    if ($#{$args{'parameterlist'}} >= 0) {
 
566
        print " <variablelist>\n";
 
567
        foreach $parameter (@{$args{'parameterlist'}}) {
 
568
            print "  <varlistentry>\n   <term><parameter>$parameter</parameter
 
569
></term>\n";
 
570
            print "   <listitem>\n    <para>\n";
 
571
            $lineprefix="     ";
 
572
            output_highlight($args{'parameters'}{$parameter});
 
573
            print "    </para>\n   </listitem>\n  </varlistentry>\n";
 
574
        }
 
575
        print " </variablelist>\n";
 
576
    } else {
 
577
        print " <para>\n  None\n </para>\n";
 
578
    }
 
579
    print "</refsect1>\n";
 
580
 
 
581
    # print out each section
 
582
    $lineprefix="   ";
 
583
    foreach $section (@{$args{'sectionlist'}}) {
 
584
        print "<refsect1>\n <title>$section</title>\n <para>\n";
 
585
#       print "<para>\n$section\n";
 
586
        if ($section =~ m/EXAMPLE/i) {
 
587
            print "<example><para>\n";
 
588
        }
 
589
        output_highlight($args{'sections'}{$section});
 
590
#       print "</para>";
 
591
        if ($section =~ m/EXAMPLE/i) {
 
592
            print "</para></example>\n";
 
593
        }
 
594
        print " </para>\n</refsect1>\n";
 
595
    }
 
596
 
 
597
    print "\n\n";
 
598
}
 
599
 
 
600
##
 
601
# output in man
 
602
sub output_man {
 
603
    my %args = %{$_[0]};
 
604
    my ($parameter, $section);
 
605
    my $count;
 
606
 
 
607
    print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{'
 
608
module'} . "\" \"". $args{'module'} . "\"\n";
 
609
 
 
610
    print ".SH NAME\n";
 
611
 
 
612
    print $args{'function'}."\n";
 
613
 
 
614
    print ".SH SYNOPSIS\n";
 
615
    print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n"
 
616
        if $args{'includefuncprefix'};
 
617
    print ".sp\n";
 
618
    print ".BI \"".$args{'functiontype'}." ".$args{'function'}."(";
 
619
    $count = 0;
 
620
    foreach $parameter (@{$args{'parameterlist'}}) {
 
621
        print $args{'parametertypes'}{$parameter}." \" ".$parameter." \"";
 
622
        if ($count != $#{$args{'parameterlist'}}) {
 
623
            $count++;
 
624
            print ", ";
 
625
        }
 
626
    }
 
627
    print ");\"\n";
 
628
 
 
629
    print ".SH ARGUMENTS\n";
 
630
    foreach $parameter (@{$args{'parameterlist'}}) {
 
631
        print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 
 
632
12\n";
 
633
        output_highlight($args{'parameters'}{$parameter});
 
634
    }
 
635
    foreach $section (@{$args{'sectionlist'}}) {
 
636
        print ".SH \"" . uc($section) . "\"\n";
 
637
        output_highlight($args{'sections'}{$section});
 
638
    }
 
639
 
 
640
    if ($args{'bugsto'}) {
 
641
        print ".SH \"REPORTING BUGS\"\n";
 
642
        print "Report bugs to <". $args{'bugsto'} . ">.\n";
 
643
    }
 
644
 
 
645
    if ($args{'copyright'}) {
 
646
        print ".SH COPYRIGHT\n";
 
647
        print "Copyright \\(co ". $args{'copyright'} . ".\n";
 
648
        if ($args{'verbatimcopying'}) {
 
649
            print ".br\n";
 
650
            print "Permission is granted to make and distribute verbatim copie
 
651
s of this\n";
 
652
            print "manual provided the copyright notice and this permission no
 
653
tice are\n";
 
654
            print "preserved on all copies.\n";
 
655
        }
 
656
    }
 
657
 
 
658
    if ($args{'seeinfo'}) {
 
659
        print ".SH \"SEE ALSO\"\n";
 
660
        print "The full documentation for\n";
 
661
        print ".B " . $args{'module'} . "\n";
 
662
        print "is maintained as a Texinfo manual.  If the\n";
 
663
        print ".B info\n";
 
664
        print "and\n";
 
665
        print ".B " . $args{'module'} . "\n";
 
666
        print "programs are properly installed at your site, the command\n";
 
667
        print ".IP\n";
 
668
        print ".B info " . $args{'seeinfo'} . "\n";
 
669
        print ".PP\n";
 
670
        print "should give you access to the complete manual.\n";
 
671
    }
 
672
}
 
673
 
 
674
sub output_listfunc {
 
675
    my %args = %{$_[0]};
 
676
    print $args{'function'} . "\n";
 
677
}
 
678
 
 
679
##
 
680
# output in text
 
681
sub output_text {
 
682
    my %args = %{$_[0]};
 
683
    my ($parameter, $section);
 
684
 
 
685
    print "Function = ".$args{'function'}."\n";
 
686
    print "  return type: ".$args{'functiontype'}."\n\n";
 
687
    foreach $parameter (@{$args{'parameterlist'}}) {
 
688
        print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
 
689
        print "    -> ".$args{'parameters'}{$parameter}."\n";
 
690
    }
 
691
    foreach $section (@{$args{'sectionlist'}}) {
 
692
        print " $section:\n";
 
693
        print "    -> ";
 
694
        output_highlight($args{'sections'}{$section});
 
695
    }
 
696
}
 
697
 
 
698
##
 
699
# generic output function - calls the right one based
 
700
# on current output mode.
 
701
sub output_function {
 
702
#    output_html(@_);
 
703
    eval "output_".$output_mode."(\@_);";
 
704
}
 
705
 
 
706
 
 
707
##
 
708
# takes a function prototype and spits out all the details
 
709
# stored in the global arrays/hsahes.
 
710
sub dump_function {
 
711
    my $prototype = shift @_;
 
712
 
 
713
    if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
 
714
        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
 
715
        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
 
716
        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
 
717
        $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/)
 
718
  {
 
719
        $return_type = $1;
 
720
        $function_name = $2;
 
721
        $args = $3;
 
722
 
 
723
#       print STDERR "ARGS = '$args'\n";
 
724
 
 
725
        foreach $arg (split ',', $args) {
 
726
            # strip leading/trailing spaces
 
727
            $arg =~ s/^\s*//;
 
728
            $arg =~ s/\s*$//;
 
729
#           print STDERR "SCAN ARG: '$arg'\n";
 
730
            @args = split('\s', $arg);
 
731
 
 
732
#           print STDERR " -> @args\n";
 
733
            $param = pop @args;
 
734
#           print STDERR " -> @args\n";
 
735
            if ($param =~ m/^(\*+)(.*)/) {
 
736
                $param = $2;
 
737
                push @args, $1;
 
738
            }
 
739
            if ($param =~ m/^(.*)(\[\])$/) {
 
740
                $param = $1;
 
741
                push @args, $2;
 
742
            }
 
743
#           print STDERR " :> @args\n";
 
744
            $type = join " ", @args;
 
745
 
 
746
            if ($parameters{$param} eq "" && $param != "void") {
 
747
                $parameters{$param} = "-- undescribed --";
 
748
                print STDERR "Warning($lineno): Function parameter '$param' no
 
749
t described in '$function_name'\n";
 
750
            }
 
751
 
 
752
            push @parameterlist, $param;
 
753
            $parametertypes{$param} = $type;
 
754
 
 
755
#           print STDERR "param = '$param', type = '$type'\n";
 
756
        }
 
757
    } else {
 
758
        print STDERR "Error($lineno): cannot understand prototype: '$prototype
 
759
'\n";
 
760
        return;
 
761
    }
 
762
 
 
763
    if ($function_only==0 || defined($function_table{$function_name})) {
 
764
        output_function({'function' => $function_name,
 
765
                         'module' => $modulename,
 
766
                         'sourceversion' => $sourceversion,
 
767
                         'includefuncprefix' => $includefuncprefix,
 
768
                         'bugsto' => $bugsto,
 
769
                         'copyright' => $copyright,
 
770
                         'verbatimcopying' => $verbatimcopying,
 
771
                         'seeinfo' => $seeinfo,
 
772
                         'functiontype' => $return_type,
 
773
                         'parameterlist' => \@parameterlist,
 
774
                         'parameters' => \%parameters,
 
775
                         'parametertypes' => \%parametertypes,
 
776
                         'sectionlist' => \@sectionlist,
 
777
                         'sections' => \%sections,
 
778
                         'purpose' => $function_purpose
 
779
                         });
 
780
    }
 
781
}
 
782
 
 
783
######################################################################
 
784
# main
 
785
# states
 
786
# 0 - normal code
 
787
# 1 - looking for function name
 
788
# 2 - scanning field start.
 
789
# 3 - scanning prototype.
 
790
$state = 0;
 
791
$section = "";
 
792
 
 
793
$doc_special = "\@\%\$\&";
 
794
 
 
795
$doc_start = "^/\\*\\*\$";
 
796
$doc_end = "\\*/";
 
797
$doc_com = "\\s*\\*\\s*";
 
798
$doc_func = $doc_com."(\\w+):?";
 
799
$doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):(.*)";
 
800
$doc_content = $doc_com."(.*)";
 
801
 
 
802
%constants = ();
 
803
%parameters = ();
 
804
@parameterlist = ();
 
805
%sections = ();
 
806
@sectionlist = ();
 
807
 
 
808
$contents = "";
 
809
$section_default = "Description";       # default section
 
810
$section = $section_default;
 
811
 
 
812
$lineno = 0;
 
813
foreach $file (@ARGV) {
 
814
    if (!open(IN,"<$file")) {
 
815
        print STDERR "Error: Cannot open file $file\n";
 
816
        next;
 
817
    }
 
818
    while (<IN>) {
 
819
        $lineno++;
 
820
 
 
821
        if ($state == 0) {
 
822
            if (/$doc_start/o) {
 
823
                $state = 1;             # next line is always the function nam
 
824
e
 
825
            }
 
826
        } elsif ($state == 1) { # this line is the function name (always)
 
827
            if (/$doc_func/o) {
 
828
                $function = $1;
 
829
                $state = 2;
 
830
                if (/-(.*)/) {
 
831
                    $function_purpose = $1;
 
832
                } else {
 
833
                    $function_purpose = "";
 
834
                }
 
835
                if ($verbose) {
 
836
                    print STDERR "Info($lineno): Scanning doc for $function\n"
 
837
;
 
838
                }
 
839
            } else {
 
840
                print STDERR "WARN($lineno): Cannot understand $_ on line $lin
 
841
eno",
 
842
                " - I thought it was a doc line\n";
 
843
                $state = 0;
 
844
            }
 
845
        } elsif ($state == 2) { # look for head: lines, and include content
 
846
            if (/$doc_sect/o) {
 
847
                $newsection = $1;
 
848
                $newcontents = $2;
 
849
 
 
850
                if ($contents ne "") {
 
851
                    dump_section($section, $contents);
 
852
                    $section = $section_default;
 
853
                }
 
854
 
 
855
                $contents = $newcontents;
 
856
                if ($contents ne "") {
 
857
                    $contents .= "\n";
 
858
                }
 
859
                $section = $newsection;
 
860
            } elsif (/$doc_end/) {
 
861
 
 
862
                if ($contents ne "") {
 
863
                    dump_section($section, $contents);
 
864
                    $section = $section_default;
 
865
                    $contents = "";
 
866
                }
 
867
 
 
868
#           print STDERR "end of doc comment, looking for prototype\n";
 
869
                $prototype = "";
 
870
                $state = 3;
 
871
            } elsif (/$doc_content/) {
 
872
                # miguel-style comment kludge, look for blank lines after
 
873
                # @parameter line to signify start of description
 
874
                if ($1 eq "" && $section =~ m/^@/) {
 
875
                    dump_section($section, $contents);
 
876
                    $section = $section_default;
 
877
                    $contents = "";
 
878
                } else {
 
879
                    $contents .= $1."\n";
 
880
                }
 
881
            } else {
 
882
                # i dont know - bad line?  ignore.
 
883
                print STDERR "WARNING($lineno): bad line: $_"; 
 
884
            }
 
885
        } elsif ($state == 3) { # scanning for function { (end of prototype)
 
886
            if (m#\s*/\*\s+MACDOC\s*#io) {
 
887
              # do nothing
 
888
            }
 
889
            elsif (/([^\{]*)/) {
 
890
                $prototype .= $1;
 
891
            }
 
892
            if (/\{/) {
 
893
                $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
 
894
                $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
 
895
                $prototype =~ s@^ +@@gos; # strip leading spaces
 
896
                dump_function($prototype);
 
897
 
 
898
                $function = "";
 
899
                %constants = ();
 
900
                %parameters = ();
 
901
                %parametertypes = ();
 
902
                @parameterlist = ();
 
903
                %sections = ();
 
904
                @sectionlist = ();
 
905
                $prototype = "";
 
906
 
 
907
                $state = 0;
 
908
            }
 
909
        }
 
910
    }
 
911
}
 
912
 
 
913
 
 
914