Statistics
| Branch: | Revision:

iof-bird-daemon / doc / kernel-doc @ 371adba6

History | View | Annotate | Download (24.9 KB)

1
#!/usr/bin/perl
2

    
3
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
4
##                                                               ##
5
## This software falls under the GNU Public License. Please read ##
6
##              the COPYING file for more information            ##
7

    
8
#
9
# This will read a 'c' file and scan for embedded comments in the
10
# style of gnome comments (+minor extensions - see below).
11
#
12

    
13
# Note: This only supports 'c'.
14

    
15
# usage:
16
# kerneldoc [ -docbook | -html | -text | -man | -gnome | -bird ]
17
#           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
18
# or
19
#           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
20
#
21
#  Set output format using one of -docbook -html -text -man -gnome or -bird.  Default is man.
22
#
23
#  -function funcname
24
#	If set, then only generate documentation for the given function(s).  All
25
#	other functions are ignored.
26
#
27
#  -nofunction funcname
28
#	If set, then only generate documentation for the other function(s).  All
29
#	other functions are ignored. Cannot be used with -function together
30
#	(yes thats a bug - perl hackers can fix it 8))
31
#
32
#  c files - list of 'c' files to process
33
#
34
#  All output goes to stdout, with errors to stderr.
35

    
36
#
37
# format of comments.
38
# In the following table, (...)? signifies optional structure.
39
#                         (...)* signifies 0 or more structure elements
40
# /**
41
#  * function_name(:)? (- short description)?
42
# (* @parameterx: (description of parameter x)?)*
43
# (* a blank line)?
44
#  * (Description:)? (Description of function)?
45
#  * (section header: (section description)? )*
46
#  (*)?*/
47
#
48
# So .. the trivial example would be:
49
#
50
# /**
51
#  * my_function
52
#  **/
53
#
54
# If the Description: header tag is ommitted, then there must be a blank line
55
# after the last parameter specification.
56
# e.g.
57
# /**
58
#  * my_function - does my stuff
59
#  * @my_arg: its mine damnit
60
#  *
61
#  * Does my stuff explained. 
62
#  */
63
#
64
#  or, could also use:
65
# /**
66
#  * my_function - does my stuff
67
#  * @my_arg: its mine damnit
68
#  * Description: Does my stuff explained. 
69
#  */
70
# etc.
71
#
72
# All descriptions can be multiline, apart from the short function description.
73
#
74
# All descriptive text is further processed, scanning for the following special
75
# patterns, which are highlighted appropriately.
76
#
77
# 'funcname()' - function
78
# '$ENVVAR' - environmental variable
79
# '&struct_name' - name of a structure
80
# '@parameter' - name of a parameter
81
# '%CONST' - name of a constant.
82

    
83
# match expressions used to find embedded type information
84
$type_constant = "\\\%(\\w+)";
85
$type_func = "(\\w+\\(\\))";
86
$type_param = "\\\@(\\w+)";
87
$type_struct = "\\\&(\\w+)";
88
$type_env = "(\\\$\\w+)";
89

    
90

    
91
# Output conversion substitutions.
92
#  One for each output format
93

    
94
# these work fairly well
95
%highlights_html = ( $type_constant, "<i>\$1</i>",
96
		     $type_func, "<b>\$1</b>",
97
		     $type_struct, "<i>\$1</i>",
98
		     $type_param, "<tt><b>\$1</b></tt>" );
99
$blankline_html = "<p>";
100

    
101
# sgml, docbook format
102
%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
103
		     $type_func, "<function>\$1</function>",
104
		     $type_struct, "<structname>\$1</structname>",
105
		     $type_env, "<envar>\$1</envar>",
106
		     $type_param, "<parameter>\$1</parameter>" );
107
$blankline_sgml = "</para><para>\n";
108

    
109
# gnome, docbook format
110
%highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
111
		     $type_func, "<function>\$1</function>",
112
		     $type_struct, "<structname>\$1</structname>",
113
		     $type_env, "<envar>\$1</envar>",
114
		     $type_param, "<parameter>\$1</parameter>" );
115
$blankline_gnome = "</para><para>\n";
116

    
117
# bird documentation
118
%highlights_bird = ( $type_constant, "<const/\$1/",
119
		     $type_func, "<func/\$1/",
120
		     $type_struct, "<struct/\$1/",
121
		     $type_param, "<param/\$1/" );
122
$blankline_bird = "<p>";
123

    
124
# these are pretty rough
125
%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n",
126
		    $type_func, "\\n.B \\\"\$1\\\"\\n",
127
		    $type_struct, "\\n.I \\\"\$1\\\"\\n",
128
		    $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" );
129
$blankline_man = "";
130

    
131
# text-mode
132
%highlights_text = ( $type_constant, "\$1",
133
		     $type_func, "\$1",
134
		     $type_struct, "\$1",
135
		     $type_param, "\$1" );
136
$blankline_text = "";
137

    
138

    
139
sub usage {
140
    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
141
    print "         [ -function funcname [ -function funcname ...] ]\n";
142
    print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
143
    print "         c source file(s) > outputfile\n";
144
    exit 1;
145
}
146

    
147
# read arguments
148
if ($#ARGV==-1) {
149
    usage();
150
}
151

    
152
$verbose = 0;
153
$output_mode = "man";
154
%highlights = %highlights_man;
155
$blankline = $blankline_man;
156
$modulename = "API Documentation";
157
$function_only = 0;
158
while ($ARGV[0] =~ m/^-(.*)/) {
159
    $cmd = shift @ARGV;
160
    if ($cmd eq "-html") {
161
	$output_mode = "html";
162
	%highlights = %highlights_html;
163
	$blankline = $blankline_html;
164
    } elsif ($cmd eq "-man") {
165
	$output_mode = "man";
166
	%highlights = %highlights_man;
167
	$blankline = $blankline_man;
168
    } elsif ($cmd eq "-text") {
169
	$output_mode = "text";
170
	%highlights = %highlights_text;
171
	$blankline = $blankline_text;
172
    } elsif ($cmd eq "-docbook") {
173
	$output_mode = "sgml";
174
	%highlights = %highlights_sgml;
175
	$blankline = $blankline_sgml;
176
    } elsif ($cmd eq "-gnome") {
177
	$output_mode = "gnome";
178
	%highlights = %highlights_gnome;
179
	$blankline = $blankline_gnome;
180
    } elsif ($cmd eq "-bird") {
181
	$output_mode = "bird";
182
	%highlights = %highlights_bird;
183
	$blankline = $blankline_bird;
184
    } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
185
	$modulename = shift @ARGV;
186
    } elsif ($cmd eq "-function") { # to only output specific functions
187
	$function_only = 1;
188
	$function = shift @ARGV;
189
	$function_table{$function} = 1;
190
    } elsif ($cmd eq "-nofunction") { # to only output specific functions
191
	$function_only = 2;
192
	$function = shift @ARGV;
193
	$function_table{$function} = 1;
194
    } elsif ($cmd eq "-v") {
195
	$verbose = 1;
196
    } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
197
	usage();
198
    }
199
}
200

    
201

    
202
# generate a sequence of code that will splice in highlighting information
203
# using the s// operator.
204
$dohighlight = "";
205
foreach $pattern (keys %highlights) {
206
#    print "scanning pattern $pattern ($highlights{$pattern})\n";
207
    $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
208
}
209

    
210
##
211
# dumps section contents to arrays/hashes intended for that purpose.
212
#
213
sub dump_section {
214
    my $name = shift @_;
215
    my $contents = join "\n", @_;
216

    
217
    if ($name =~ m/$type_constant/) {
218
	$name = $1;
219
#	print STDERR "constant section '$1' = '$contents'\n";
220
	$constants{$name} = $contents;
221
    } elsif ($name =~ m/$type_param/) {
222
#	print STDERR "parameter def '$1' = '$contents'\n";
223
	$name = $1;
224
	$parameters{$name} = $contents;
225
    } else {
226
#	print STDERR "other section '$name' = '$contents'\n";
227
	$sections{$name} = $contents;
228
	push @sectionlist, $name;
229
    }
230
}
231

    
232
##
233
# output function
234
#
235
# parameters, a hash.
236
#  function => "function name"
237
#  parameterlist => @list of parameters
238
#  parameters => %parameter descriptions
239
#  sectionlist => @list of sections
240
#  sections => %descriont descriptions
241
#  
242

    
243
sub output_highlight {
244
    my $contents = join "\n", @_;
245
    my $line;
246

    
247
    eval $dohighlight;
248
    foreach $line (split "\n", $contents) {
249
	if ($line eq ""){
250
	    print $lineprefix, $blankline;
251
	} else {
252
            $line =~ s/\\\\\\/\&/g;
253
	    print $lineprefix, $line;
254
	}
255
	print "\n";
256
    }
257
}
258

    
259

    
260
# output in html
261
sub output_html {
262
    my %args = %{$_[0]};
263
    my ($parameter, $section);
264
    my $count;
265
    print "<h2>Function</h2>\n";
266

    
267
    print "<i>".$args{'functiontype'}."</i>\n";
268
    print "<b>".$args{'function'}."</b>\n";
269
    print "(";
270
    $count = 0;
271
    foreach $parameter (@{$args{'parameterlist'}}) {
272
	print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
273
	if ($count != $#{$args{'parameterlist'}}) {
274
	    $count++;
275
	    print ", ";
276
	}
277
    }
278
    print ")\n";
279

    
280
    print "<h3>Arguments</h3>\n";
281
    print "<dl>\n";
282
    foreach $parameter (@{$args{'parameterlist'}}) {
283
	print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
284
	print "<dd>";
285
	output_highlight($args{'parameters'}{$parameter});
286
    }
287
    print "</dl>\n";
288
    foreach $section (@{$args{'sectionlist'}}) {
289
	print "<h1>$section</h1>\n";
290
	print "<ul>\n";
291
	output_highlight($args{'sections'}{$section});
292
	print "</ul>\n";
293
    }
294
    print "<hr>\n";
295
}
296

    
297

    
298
# output in html
299
sub output_intro_html {
300
    my %args = %{$_[0]};
301
    my ($parameter, $section);
302
    my $count;
303

    
304
    foreach $section (@{$args{'sectionlist'}}) {
305
	print "<h1>$section</h1>\n";
306
	print "<ul>\n";
307
	output_highlight($args{'sections'}{$section});
308
	print "</ul>\n";
309
    }
310
    print "<hr>\n";
311
}
312

    
313

    
314

    
315
# output in sgml DocBook
316
sub output_sgml {
317
    my %args = %{$_[0]};
318
    my ($parameter, $section);
319
    my $count;
320
    my $id;
321

    
322
    $id = $args{'module'}."-".$args{'function'};
323
    $id =~ s/[^A-Za-z0-9]/-/g;
324

    
325
    print "<refentry>\n";
326
    print "<refmeta>\n";
327
    print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
328
    print "</refmeta>\n";
329
    print "<refnamediv>\n";
330
    print " <refname>".$args{'function'}."</refname>\n";
331
    print " <refpurpose>\n";
332
    print "  ".$args{'purpose'}."\n";
333
    print " </refpurpose>\n";
334
    print "</refnamediv>\n";
335

    
336
    print "<refsynopsisdiv>\n";
337
    print " <title>Synopsis</title>\n";
338
    print "  <funcsynopsis>\n";
339
    print "   <funcdef>".$args{'functiontype'}." ";
340
    print "<function>".$args{'function'}." ";
341
    print "</function></funcdef>\n";
342

    
343
#    print "<refsect1>\n";
344
#    print " <title>Synopsis</title>\n";
345
#    print "  <funcsynopsis>\n";
346
#    print "   <funcdef>".$args{'functiontype'}." ";
347
#    print "<function>".$args{'function'}." ";
348
#    print "</function></funcdef>\n";
349

    
350
    $count = 0;
351
    if ($#{$args{'parameterlist'}} >= 0) {
352
	foreach $parameter (@{$args{'parameterlist'}}) {
353
	    print "   <paramdef>".$args{'parametertypes'}{$parameter};
354
	    print " <parameter>$parameter</parameter></paramdef>\n";
355
	}
356
    } else {
357
	print "  <void>\n";
358
    }
359
    print "  </funcsynopsis>\n";
360
    print "</refsynopsisdiv>\n";
361
#    print "</refsect1>\n";
362

    
363
    # print parameters
364
    print "<refsect1>\n <title>Arguments</title>\n";
365
#    print "<para>\nArguments\n";
366
    if ($#{$args{'parameterlist'}} >= 0) {
367
	print " <variablelist>\n";
368
	foreach $parameter (@{$args{'parameterlist'}}) {
369
	    print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
370
	    print "   <listitem>\n    <para>\n";
371
	    $lineprefix="     ";
372
	    output_highlight($args{'parameters'}{$parameter});
373
	    print "    </para>\n   </listitem>\n  </varlistentry>\n";
374
	}
375
	print " </variablelist>\n";
376
    } else {
377
	print " <para>\n  None\n </para>\n";
378
    }
379
    print "</refsect1>\n";
380

    
381
    # print out each section
382
    $lineprefix="   ";
383
    foreach $section (@{$args{'sectionlist'}}) {
384
	print "<refsect1>\n <title>$section</title>\n <para>\n";
385
#	print "<para>\n$section\n";
386
	if ($section =~ m/EXAMPLE/i) {
387
	    print "<example><para>\n";
388
	}
389
	output_highlight($args{'sections'}{$section});
390
#	print "</para>";
391
	if ($section =~ m/EXAMPLE/i) {
392
	    print "</para></example>\n";
393
	}
394
	print " </para>\n</refsect1>\n";
395
    }
396

    
397
    print "</refentry>\n\n";
398
}
399

    
400
# output in sgml DocBook
401
sub output_intro_sgml {
402
    my %args = %{$_[0]};
403
    my ($parameter, $section);
404
    my $count;
405
    my $id;
406

    
407
    $id = $args{'module'};
408
    $id =~ s/[^A-Za-z0-9]/-/g;
409

    
410
    # print out each section
411
    $lineprefix="   ";
412
    foreach $section (@{$args{'sectionlist'}}) {
413
	print "<refsect1>\n <title>$section</title>\n <para>\n";
414
#	print "<para>\n$section\n";
415
	if ($section =~ m/EXAMPLE/i) {
416
	    print "<example><para>\n";
417
	}
418
	output_highlight($args{'sections'}{$section});
419
#	print "</para>";
420
	if ($section =~ m/EXAMPLE/i) {
421
	    print "</para></example>\n";
422
	}
423
	print " </para>\n</refsect1>\n";
424
    }
425

    
426
    print "\n\n";
427
}
428

    
429
# output in sgml DocBook
430
sub output_gnome {
431
    my %args = %{$_[0]};
432
    my ($parameter, $section);
433
    my $count;
434
    my $id;
435

    
436
    $id = $args{'module'}."-".$args{'function'};
437
    $id =~ s/[^A-Za-z0-9]/-/g;
438

    
439
    print "<sect2>\n";
440
    print " <title id=\"$id\">".$args{'function'}."</title>\n";
441

    
442
#    print "<simplesect>\n";
443
#    print " <title>Synopsis</title>\n";
444
    print "  <funcsynopsis>\n";
445
    print "   <funcdef>".$args{'functiontype'}." ";
446
    print "<function>".$args{'function'}." ";
447
    print "</function></funcdef>\n";
448

    
449
    $count = 0;
450
    if ($#{$args{'parameterlist'}} >= 0) {
451
	foreach $parameter (@{$args{'parameterlist'}}) {
452
	    print "   <paramdef>".$args{'parametertypes'}{$parameter};
453
	    print " <parameter>$parameter</parameter></paramdef>\n";
454
	}
455
    } else {
456
	print "  <void>\n";
457
    }
458
    print "  </funcsynopsis>\n";
459
#    print "</simplesect>\n";
460
#    print "</refsect1>\n";
461

    
462
    # print parameters
463
#    print "<simplesect>\n <title>Arguments</title>\n";
464
#    if ($#{$args{'parameterlist'}} >= 0) {
465
#	print " <variablelist>\n";
466
#	foreach $parameter (@{$args{'parameterlist'}}) {
467
#	    print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
468
#	    print "   <listitem>\n    <para>\n";
469
#	    $lineprefix="     ";
470
#	    output_highlight($args{'parameters'}{$parameter});
471
#	    print "    </para>\n   </listitem>\n  </varlistentry>\n";
472
#	}
473
#	print " </variablelist>\n";
474
#    } else {
475
#	print " <para>\n  None\n </para>\n";
476
#    }
477
#    print "</simplesect>\n";
478

    
479
#    print "<simplesect>\n <title>Arguments</title>\n";
480
    if ($#{$args{'parameterlist'}} >= 0) {
481
	print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
482
	print "<tgroup cols=\"2\">\n";
483
	print "<colspec colwidth=\"2*\">\n";
484
	print "<colspec colwidth=\"8*\">\n";
485
	print "<tbody>\n";
486
	foreach $parameter (@{$args{'parameterlist'}}) {
487
	    print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
488
	    print "   <entry>\n";
489
	    $lineprefix="     ";
490
	    output_highlight($args{'parameters'}{$parameter});
491
	    print "    </entry></row>\n";
492
	}
493
	print " </tbody></tgroup></informaltable>\n";
494
    } else {
495
	print " <para>\n  None\n </para>\n";
496
    }
497
#    print "</simplesect>\n";
498

    
499
    # print out each section
500
    $lineprefix="   ";
501
    foreach $section (@{$args{'sectionlist'}}) {
502
	print "<simplesect>\n <title>$section</title>\n";
503
#	print "<para>\n$section\n";
504
	if ($section =~ m/EXAMPLE/i) {
505
	    print "<example><programlisting>\n";
506
	} else {
507
	}
508
	print "<para>\n";
509
	output_highlight($args{'sections'}{$section});
510
#	print "</para>";
511
	print "</para>\n";
512
	if ($section =~ m/EXAMPLE/i) {
513
	    print "</programlisting></example>\n";
514
	} else {
515
	}
516
	print " </simplesect>\n";
517
    }
518

    
519
    print "</sect2>\n\n";
520
}
521

    
522
# output in birddoc
523
sub output_bird {
524
    my %args = %{$_[0]};
525
    my ($parameter, $section);
526
    my $count;
527
    print "<function><p><type>".$args{'functiontype'}."</type>\n";
528
    print "<funcdef>".$args{'function'}."</funcdef>\n";
529
    print "(";
530
    $count = 0;
531
    my $ntyped = 0;
532
    foreach $parameter (@{$args{'parameterlist'}}) {
533
	if ($args{'parametertypes'}{$parameter} ne "") {
534
	    print "<type>".$args{'parametertypes'}{$parameter}."</type> ";
535
	    $ntyped++;
536
	}
537
	print "<param>".$parameter."</param>";
538
	if ($count != $#{$args{'parameterlist'}}) {
539
	    $count++;
540
	    print ", ";
541
	}
542
    }
543
    print ")\n";
544

    
545
    if ($ntyped) {
546
	print "<funcsect>Arguments\n";
547
	print "<p><descrip>\n";
548
	foreach $parameter (@{$args{'parameterlist'}}) {
549
	    print "<tagp><type>".$args{'parametertypes'}{$parameter}."</type> <param>".$parameter."</param></tagp>\n";
550
	    output_highlight($args{'parameters'}{$parameter});
551
	}
552
	print "</descrip>\n";
553
    }
554
    foreach $section (@{$args{'sectionlist'}}) {
555
	print "<funcsect>$section\n";
556
	print "<p>\n";
557
	output_highlight($args{'sections'}{$section});
558
    }
559
    print "</function>\n";
560
}
561

    
562
# output in birddoc
563
sub output_intro_bird {
564
    my %args = %{$_[0]};
565
    my ($parameter, $section);
566
    my $count;
567
    my $id;
568

    
569
    $id = $args{'module'};
570
    $id =~ s/[^A-Za-z0-9]/-/g;
571

    
572
    # print out each section
573
    $lineprefix="   ";
574
    foreach $section (@{$args{'sectionlist'}}) {
575
	print "<sect>$section\n<p>\n";
576
	output_highlight($args{'sections'}{$section});
577
    }
578

    
579
    print "\n\n";
580
}
581

    
582
##
583
# output in man
584
sub output_man {
585
    my %args = %{$_[0]};
586
    my ($parameter, $section);
587
    my $count;
588

    
589
    print ".TH \"$args{'module'}\" \"$args{'function'}\" \"25 May 1998\" \"API Manual\" LINUX\n";
590

    
591
    print ".SH Function\n";
592

    
593
    print ".I \"".$args{'functiontype'}."\"\n";
594
    print ".B \"".$args{'function'}."\"\n";
595
    print "(\n";
596
    $count = 0;
597
    foreach $parameter (@{$args{'parameterlist'}}) {
598
	print ".I \"".$args{'parametertypes'}{$parameter}."\"\n.B \"".$parameter."\"\n";
599
	if ($count != $#{$args{'parameterlist'}}) {
600
	    $count++;
601
	    print ",\n";
602
	}
603
    }
604
    print ")\n";
605

    
606
    print ".SH Arguments\n";
607
    foreach $parameter (@{$args{'parameterlist'}}) {
608
	print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 12\n";
609
	output_highlight($args{'parameters'}{$parameter});
610
    }
611
    foreach $section (@{$args{'sectionlist'}}) {
612
	print ".SH \"$section\"\n";
613
	output_highlight($args{'sections'}{$section});
614
    }
615
}
616

    
617
sub output_intro_man {
618
    my %args = %{$_[0]};
619
    my ($parameter, $section);
620
    my $count;
621

    
622
    print ".TH \"$args{'module'}\" \"$args{'module'}\" \"25 May 1998\" \"API Manual\" LINUX\n";
623

    
624
    foreach $section (@{$args{'sectionlist'}}) {
625
	print ".SH \"$section\"\n";
626
	output_highlight($args{'sections'}{$section});
627
    }
628
}
629

    
630
##
631
# output in text
632
sub output_text {
633
    my %args = %{$_[0]};
634
    my ($parameter, $section);
635

    
636
    print "Function = ".$args{'function'}."\n";
637
    print "  return type: ".$args{'functiontype'}."\n\n";
638
    foreach $parameter (@{$args{'parameterlist'}}) {
639
	print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
640
	print "    -> ".$args{'parameters'}{$parameter}."\n";
641
    }
642
    foreach $section (@{$args{'sectionlist'}}) {
643
	print " $section:\n";
644
	print "    -> ";
645
	output_highlight($args{'sections'}{$section});
646
    }
647
}
648

    
649
sub output_intro_text {
650
    my %args = %{$_[0]};
651
    my ($parameter, $section);
652

    
653
    foreach $section (@{$args{'sectionlist'}}) {
654
	print " $section:\n";
655
	print "    -> ";
656
	output_highlight($args{'sections'}{$section});
657
    }
658
}
659

    
660
##
661
# generic output function - calls the right one based
662
# on current output mode.
663
sub output_function {
664
#    output_html(@_);
665
    eval "output_".$output_mode."(\@_);";
666
}
667

    
668
##
669
# generic output function - calls the right one based
670
# on current output mode.
671
sub output_intro {
672
#    output_html(@_);
673
    eval "output_intro_".$output_mode."(\@_);";
674
}
675

    
676

    
677
##
678
# takes a function prototype and spits out all the details
679
# stored in the global arrays/hsahes.
680
sub dump_function {
681
    my $prototype = shift @_;
682

    
683
    $prototype =~ s/^static+ //;
684
    $prototype =~ s/^extern+ //;
685
    $prototype =~ s/^inline+ //;
686
    $prototype =~ s/^__inline__+ //;
687

    
688
    if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
689
	$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
690
	$prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
691
	$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
692
	$prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/)  {
693
	$return_type = $1;
694
	$function_name = $2;
695
	$args = $3;
696

    
697
#	print STDERR "ARGS = '$args'\n";
698

    
699
	foreach $arg (split ',', $args) {
700
	    # strip leading/trailing spaces
701
	    $arg =~ s/^\s*//;
702
	    $arg =~ s/\s*$//;
703
#	    print STDERR "SCAN ARG: '$arg'\n";
704
	    @args = split('\s', $arg);
705

    
706
#	    print STDERR " -> @args\n";
707
	    $param = pop @args;
708
#	    print STDERR " -> @args\n";
709
	    if ($param =~ m/^(\*+)(.*)/) {
710
		$param = $2;
711
		push @args, $1;
712
	    }
713
	    $type = join " ", @args;
714

    
715
	    if ($type eq "" && $param eq "...")
716
	    {
717
		$type="...";
718
		$param="...";
719
		$parameters{"..."} = "variable arguments";
720
	    }
721
	    if ($type eq "")
722
	    {
723
		$type="";
724
		$param="void";
725
		$parameters{void} = "no arguments";
726
	    }
727
            if ($parameters{$param} eq "") {
728
	        $parameters{$param} = "-- undescribed --";
729
	        print STDERR "Warning($lineno): Function parameter '$param' not described in '$function_name'\n";
730
	    }
731

    
732
	    push @parameterlist, $param;
733
	    $parametertypes{$param} = $type;
734
#	    print STDERR "param = '$param', type = '$type'\n";
735
	}
736
    } else {
737
	print STDERR "Error($lineno): cannot understand prototype: '$prototype'\n";
738
	return;
739
    }
740

    
741
    if ($function_only==0 || 
742
     ( $function_only == 1 && defined($function_table{$function_name})) || 
743
     ( $function_only == 2 && !defined($function_table{$function_name})))
744
    {
745
	output_function({'function' => $function_name,
746
			 'module' => $modulename,
747
			 'functiontype' => $return_type,
748
			 'parameterlist' => \@parameterlist,
749
			 'parameters' => \%parameters,
750
			 'parametertypes' => \%parametertypes,
751
			 'sectionlist' => \@sectionlist,
752
			 'sections' => \%sections,
753
			 'purpose' => $function_purpose
754
			 });
755
    }
756
}
757

    
758
######################################################################
759
# main
760
# states
761
# 0 - normal code
762
# 1 - looking for function name
763
# 2 - scanning field start.
764
# 3 - scanning prototype.
765
$state = 0;
766
$section = "";
767

    
768
$doc_special = "\@\%\$\&";
769

    
770
$doc_start = "^/\\*\\*\$";
771
$doc_end = "\\*/";
772
$doc_com = "\\s*\\*\\s*";
773
$doc_func = $doc_com."(\\w+):?";
774
$doc_sect = $doc_com."([".$doc_special."]?[\\w ]+):(.*)";
775
$doc_content = $doc_com."(.*)";
776
$doc_block = $doc_com."DOC:\\s*(.*)?";
777

    
778
%constants = ();
779
%parameters = ();
780
@parameterlist = ();
781
%sections = ();
782
@sectionlist = ();
783

    
784
$contents = "";
785
$section_default = "Description";	# default section
786
$section_intro = "Introduction";
787
$section = $section_default;
788

    
789
$lineno = 0;
790
foreach $file (@ARGV) {
791
    if (!open(IN,"<$file")) {
792
	print STDERR "Error: Cannot open file $file\n";
793
	next;
794
    }
795
    while (<IN>) {
796
	$lineno++;
797

    
798
	if ($state == 0) {
799
	    if (/$doc_start/o) {
800
		$state = 1;		# next line is always the function name
801
	    }
802
	} elsif ($state == 1) {	# this line is the function name (always)
803
	    if (/$doc_block/o) {
804
		$state = 4;
805
		$contents = "";
806
		if ( $1 eq "" ) {
807
			$section = $section_intro;
808
		} else {
809
			$section = $1;
810
		}
811
            }
812
	    elsif (/$doc_func/o) {
813
		$function = $1;
814
		$state = 2;
815
		if (/-(.*)/) {
816
		    $function_purpose = $1;
817
		} else {
818
		    $function_purpose = "";
819
		}
820
		if ($verbose) {
821
		    print STDERR "Info($lineno): Scanning doc for $function\n";
822
		}
823
	    } else {
824
		print STDERR "WARN($lineno): Cannot understand $_ on line $lineno",
825
		" - I thought it was a doc line\n";
826
		$state = 0;
827
	    }
828
	} elsif ($state == 2) {	# look for head: lines, and include content
829
	    if (/$doc_sect/o) {
830
		$newsection = $1;
831
		$newcontents = $2;
832

    
833
		if ($contents ne "") {
834
		    $contents =~ s/\&/\\\\\\amp;/g;
835
		    $contents =~ s/\</\\\\\\lt;/g;
836
		    $contents =~ s/\>/\\\\\\gt;/g;
837
		    dump_section($section, $contents);
838
		    $section = $section_default;
839
		}
840

    
841
		$contents = $newcontents;
842
		if ($contents ne "") {
843
		    $contents .= "\n";
844
		}
845
		$section = $newsection;
846
	    } elsif (/$doc_end/) {
847

    
848
		if ($contents ne "") {
849
		    $contents =~ s/\&/\\\\\\amp;/g;
850
		    $contents =~ s/\</\\\\\\lt;/g;
851
		    $contents =~ s/\>/\\\\\\gt;/g;
852
		    dump_section($section, $contents);
853
		    $section = $section_default;
854
		    $contents = "";
855
		}
856

    
857
#	    print STDERR "end of doc comment, looking for prototype\n";
858
		$prototype = "";
859
		$state = 3;
860
	    } elsif (/$doc_content/) {
861
		# miguel-style comment kludge, look for blank lines after
862
		# @parameter line to signify start of description
863
		if ($1 eq "" && $section =~ m/^@/) {
864
		    $contents =~ s/\&/\\\\\\amp;/g;
865
		    $contents =~ s/\</\\\\\\lt;/g;
866
		    $contents =~ s/\>/\\\\\\gt;/g;
867
		    dump_section($section, $contents);
868
		    $section = $section_default;
869
		    $contents = "";
870
		} else {
871
		    $contents .= $1."\n";
872
		}
873
	    } else {
874
		# i dont know - bad line?  ignore.
875
		print STDERR "WARNING($lineno): bad line: $_"; 
876
	    }
877
	} elsif ($state == 3) {	# scanning for function { (end of prototype)
878
	    if (m#\s*/\*\s+MACDOC\s*#io) {
879
	      # do nothing
880
	    }
881
	    elsif (/([^\{]*)/) {
882
		$prototype .= $1;
883
	    }
884
	    if (/\{/) {
885
		$prototype =~ s@/\*.*?\*/@@gos;	# strip comments.
886
		$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
887
		$prototype =~ s@^ +@@gos; # strip leading spaces
888
		dump_function($prototype);
889

    
890
		$function = "";
891
		%constants = ();
892
		%parameters = ();
893
		%parametertypes = ();
894
		@parameterlist = ();
895
		%sections = ();
896
		@sectionlist = ();
897
		$prototype = "";
898

    
899
		$state = 0;
900
	    }
901
	} elsif ($state == 4) {
902
		# Documentation block
903
	        if (/$doc_block/) {
904
			dump_section($section, $contents);
905
			output_intro({'sectionlist' => \@sectionlist,
906
				      'sections' => \%sections });
907
			$contents = "";
908
			$function = "";
909
			%constants = ();
910
			%parameters = ();
911
			%parametertypes = ();
912
			@parameterlist = ();
913
			%sections = ();
914
			@sectionlist = ();
915
			$prototype = "";
916
			if ( $1 eq "" ) {
917
				$section = $section_intro;
918
			} else {
919
				$section = $1;
920
			}
921
                }
922
		elsif (/$doc_end/)
923
		{
924
			dump_section($section, $contents);
925
			output_intro({'sectionlist' => \@sectionlist,
926
				      'sections' => \%sections });
927
			$contents = "";
928
			$function = "";
929
			%constants = ();
930
			%parameters = ();
931
			%parametertypes = ();
932
			@parameterlist = ();
933
			%sections = ();
934
			@sectionlist = ();
935
			$prototype = "";
936
			$state = 0;
937
		}
938
		elsif (/$doc_content/)
939
		{
940
			if ( $1 eq "" )
941
			{
942
				$contents .= $blankline;
943
			}
944
			else
945
			{
946
				$contents .= $1 . "\n";
947
			}	
948
        	}
949
          }
950
    }
951
}
952