OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [scripts/] [kernel-doc] - Blame information for rev 1765

Details | Compare with Previous | View Log

\n";\n";
Line No. Rev Author Line
1 1275 phoenix
#!/usr/bin/perl -w
2
 
3
use strict;
4
 
5
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
6
## Copyright (C) 2000, 1  Tim Waugh           ##
7
## Copyright (C) 2001  Simon Huggins                             ##
8
##                                                               ##
9
## #define enhancements by Armin Kuster          ##
10
## Copyright (c) 2000 MontaVista Software, Inc.                  ##
11
##                                                               ##
12
## This software falls under the GNU General Public License.     ##
13
## Please read the COPYING file for more information             ##
14
 
15
# w.o. 03-11-2000: added the '-filelist' option.
16
 
17
# 18/01/2001 -  Cleanups
18
#               Functions prototyped as foo(void) same as foo()
19
#               Stop eval'ing where we don't need to.
20
# -- huggie@earth.li
21
 
22
# 27/06/2001 -  Allowed whitespace after initial "/**" and
23
#               allowed comments before function declarations.
24
# -- Christian Kreibich 
25
 
26
# Still to do:
27
#       - add perldoc documentation
28
#       - Look more closely at some of the scarier bits :)
29
 
30
# 26/05/2001 -  Support for separate source and object trees.
31
#               Return error code.
32
#               Keith Owens 
33
 
34
# 23/09/2001 - Added support for typedefs, structs, enums and unions
35
#              Support for Context section; can be terminated using empty line
36
#              Small fixes (like spaces vs. \s in regex)
37
# -- Tim Jansen 
38
 
39
 
40
#
41
# This will read a 'c' file and scan for embedded comments in the
42
# style of gnome comments (+minor extensions - see below).
43
#
44
 
45
# Note: This only supports 'c'.
46
 
47
# usage:
48
# kerneldoc [ -docbook | -html | -text | -man ]
49
#           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
50
# or
51
#           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
52
#
53
#  Set output format using one of -docbook -html -text or -man.  Default is man.
54
#
55
#  -function funcname
56
#       If set, then only generate documentation for the given function(s).  All
57
#       other functions are ignored.
58
#
59
#  -nofunction funcname
60
#       If set, then only generate documentation for the other function(s).  All
61
#       other functions are ignored. Cannot be used with -function together
62
#       (yes thats a bug - perl hackers can fix it 8))
63
#
64
#  c files - list of 'c' files to process
65
#
66
#  All output goes to stdout, with errors to stderr.
67
 
68
#
69
# format of comments.
70
# In the following table, (...)? signifies optional structure.
71
#                         (...)* signifies 0 or more structure elements
72
# /**
73
#  * function_name(:)? (- short description)?
74
# (* @parameterx: (description of parameter x)?)*
75
# (* a blank line)?
76
#  * (Description:)? (Description of function)?
77
#  * (section header: (section description)? )*
78
#  (*)?*/
79
#
80
# So .. the trivial example would be:
81
#
82
# /**
83
#  * my_function
84
#  **/
85
#
86
# If the Description: header tag is ommitted, then there must be a blank line
87
# after the last parameter specification.
88
# e.g.
89
# /**
90
#  * my_function - does my stuff
91
#  * @my_arg: its mine damnit
92
#  *
93
#  * Does my stuff explained.
94
#  */
95
#
96
#  or, could also use:
97
# /**
98
#  * my_function - does my stuff
99
#  * @my_arg: its mine damnit
100
#  * Description: Does my stuff explained.
101
#  */
102
# etc.
103
#
104
# Beside functions you can also write documentation for structs, unions,
105
# enums and typedefs. Instead of the function name you must write the name
106
# of the declaration;  the struct/union/enum/typedef must always precede
107
# the name. Nesting of declarations is not supported.
108
# Use the argument mechanism to document members or constants. In
109
# structs and unions you must declare one member per declaration
110
# (comma-separated members are not allowed -  the parser does not support
111
# this).
112
# e.g.
113
# /**
114
#  * struct my_struct - short description
115
#  * @a: first member
116
#  * @b: second member
117
#  *
118
#  * Longer description
119
#  */
120
# struct my_struct {
121
#     int a;
122
#     int b;
123
# };
124
#
125
# All descriptions can be multiline, except the short function description.
126
#
127
# You can also add additional sections. When documenting kernel functions you
128
# should document the "Context:" of the function, e.g. whether the functions
129
# can be called form interrupts. Unlike other sections you can end it with an
130
# empty line.
131
# Example-sections should contain the string EXAMPLE so that they are marked
132
# appropriately in DocBook.
133
#
134
# Example:
135
# /**
136
#  * user_function - function that can only be called in user context
137
#  * @a: some argument
138
#  * Context: !in_interrupt()
139
#  *
140
#  * Some description
141
#  * Example:
142
#  *    user_function(22);
143
#  */
144
# ...
145
#
146
#
147
# All descriptive text is further processed, scanning for the following special
148
# patterns, which are highlighted appropriately.
149
#
150
# 'funcname()' - function
151
# '$ENVVAR' - environmental variable
152
# '&struct_name' - name of a structure (up to two words including 'struct')
153
# '@parameter' - name of a parameter
154
# '%CONST' - name of a constant.
155
 
156
my $errors = 0;
157
 
158
# match expressions used to find embedded type information
159
my $type_constant = '\%([-_\w]+)';
160
my $type_func = '(\w+)\(\)';
161
my $type_param = '\@(\w+)';
162
my $type_struct = '\&((struct\s*)?[_\w]+)';
163
my $type_env = '(\$\w+)';
164
 
165
# Output conversion substitutions.
166
#  One for each output format
167
 
168
# these work fairly well
169
my %highlights_html = ( $type_constant, "\$1",
170
                        $type_func, "\$1",
171
                        $type_struct, "\$1",
172
                        $type_param, "\$1" );
173
my $blankline_html = "

";

174
 
175
# sgml, docbook format
176
my %highlights_sgml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1\$2",
177
                        $type_constant, "\$1",
178
                        $type_func, "\$1",
179
                        $type_struct, "\$1",
180
                        $type_env, "\$1",
181
                        $type_param, "\$1" );
182
my $blankline_sgml = "\n";
183
 
184
# gnome, docbook format
185
my %highlights_gnome = ( $type_constant, "\$1",
186
                         $type_func, "\$1",
187
                         $type_struct, "\$1",
188
                         $type_env, "\$1",
189
                         $type_param, "\$1" );
190
my $blankline_gnome = "\n";
191
 
192
# these are pretty rough
193
my %highlights_man = ( $type_constant, "\$1",
194
                       $type_func, "\\\\fB\$1\\\\fP",
195
                       $type_struct, "\\\\fI\$1\\\\fP",
196
                       $type_param, "\\\\fI\$1\\\\fP" );
197
my $blankline_man = "";
198
 
199
# text-mode
200
my %highlights_text = ( $type_constant, "\$1",
201
                        $type_func, "\$1",
202
                        $type_struct, "\$1",
203
                        $type_param, "\$1" );
204
my $blankline_text = "";
205
 
206
 
207
sub usage {
208
    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
209
    print "         [ -function funcname [ -function funcname ...] ]\n";
210
    print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
211
    print "         c source file(s) > outputfile\n";
212
    exit 1;
213
}
214
 
215
# read arguments
216
if ($#ARGV==-1) {
217
    usage();
218
}
219
 
220
my $verbose = 0;
221
my $output_mode = "man";
222
my %highlights = %highlights_man;
223
my $blankline = $blankline_man;
224
my $modulename = "Kernel API";
225
my $function_only = 0;
226
my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
227
                'July', 'August', 'September', 'October',
228
                'November', 'December')[(localtime)[4]] .
229
  " " . ((localtime)[5]+1900);
230
 
231
# Essentially these are globals
232
# They probably want to be tidied up made more localised or summat.
233
# CAVEAT EMPTOR!  Some of the others I localised may not want to be which
234
# could cause "use of undefined value" or other bugs.
235
my ($function, %function_table,%parametertypes,$declaration_purpose);
236
my ($type,$declaration_name,$return_type);
237
my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
238
 
239
# Generated docbook code is inserted in a template at a point where
240
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
241
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
242
# We keep track of number of generated entries and generate a dummy
243
# if needs be to ensure the expanded template can be postprocessed
244
# into html.
245
my $section_counter = 0;
246
 
247
my $lineprefix="";
248
 
249
# states
250
# 0 - normal code
251
# 1 - looking for function name
252
# 2 - scanning field start.
253
# 3 - scanning prototype.
254
# 4 - documentation block
255
my $state;
256
 
257
#declaration types: can be
258
# 'function', 'struct', 'union', 'enum', 'typedef'
259
my $decl_type;
260
 
261
my $doc_special = "\@\%\$\&";
262
 
263
my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
264
my $doc_end = '\*/';
265
my $doc_com = '\s*\*\s*';
266
my $doc_decl = $doc_com.'(\w+)';
267
my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
268
my $doc_content = $doc_com.'(.*)';
269
my $doc_block = $doc_com.'DOC:\s*(.*)?';
270
 
271
my %constants;
272
my %parameterdescs;
273
my @parameterlist;
274
my %sections;
275
my @sectionlist;
276
 
277
my $contents = "";
278
my $section_default = "Description";    # default section
279
my $section_intro = "Introduction";
280
my $section = $section_default;
281
my $section_context = "Context";
282
 
283
my $undescribed = "-- undescribed --";
284
 
285
reset_state();
286
 
287
while ($ARGV[0] =~ m/^-(.*)/) {
288
    my $cmd = shift @ARGV;
289
    if ($cmd eq "-html") {
290
        $output_mode = "html";
291
        %highlights = %highlights_html;
292
        $blankline = $blankline_html;
293
    } elsif ($cmd eq "-man") {
294
        $output_mode = "man";
295
        %highlights = %highlights_man;
296
        $blankline = $blankline_man;
297
    } elsif ($cmd eq "-text") {
298
        $output_mode = "text";
299
        %highlights = %highlights_text;
300
        $blankline = $blankline_text;
301
    } elsif ($cmd eq "-docbook") {
302
        $output_mode = "sgml";
303
        %highlights = %highlights_sgml;
304
        $blankline = $blankline_sgml;
305
    } elsif ($cmd eq "-gnome") {
306
        $output_mode = "gnome";
307
        %highlights = %highlights_gnome;
308
        $blankline = $blankline_gnome;
309
    } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
310
        $modulename = shift @ARGV;
311
    } elsif ($cmd eq "-function") { # to only output specific functions
312
        $function_only = 1;
313
        $function = shift @ARGV;
314
        $function_table{$function} = 1;
315
    } elsif ($cmd eq "-nofunction") { # to only output specific functions
316
        $function_only = 2;
317
        $function = shift @ARGV;
318
        $function_table{$function} = 1;
319
    } elsif ($cmd eq "-v") {
320
        $verbose = 1;
321
    } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
322
        usage();
323
    } elsif ($cmd eq '-filelist') {
324
            $filelist = shift @ARGV;
325
    }
326
}
327
 
328
 
329
# generate a sequence of code that will splice in highlighting information
330
# using the s// operator.
331
my $dohighlight = "";
332
foreach my $pattern (keys %highlights) {
333
#    print "scanning pattern $pattern ($highlights{$pattern})\n";
334
    $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
335
}
336
 
337
##
338
# dumps section contents to arrays/hashes intended for that purpose.
339
#
340
sub dump_section {
341
    my $name = shift;
342
    my $contents = join "\n", @_;
343
 
344
    if ($name =~ m/$type_constant/) {
345
        $name = $1;
346
#       print STDERR "constant section '$1' = '$contents'\n";
347
        $constants{$name} = $contents;
348
    } elsif ($name =~ m/$type_param/) {
349
#       print STDERR "parameter def '$1' = '$contents'\n";
350
        $name = $1;
351
        $parameterdescs{$name} = $contents;
352
    } else {
353
#       print STDERR "other section '$name' = '$contents'\n";
354
        $sections{$name} = $contents;
355
        push @sectionlist, $name;
356
    }
357
}
358
 
359
##
360
# output function
361
#
362
# parameterdescs, a hash.
363
#  function => "function name"
364
#  parameterlist => @list of parameters
365
#  parameterdescs => %parameter descriptions
366
#  sectionlist => @list of sections
367
#  sections => %descriont descriptions
368
#
369
 
370
sub output_highlight {
371
    my $contents = join "\n",@_;
372
    my $line;
373
 
374
#   DEBUG
375
#   if (!defined $contents) {
376
#       use Carp;
377
#       confess "output_highlight got called with no args?\n";
378
#   }
379
 
380
    eval $dohighlight;
381
    die $@ if $@;
382
    foreach $line (split "\n", $contents) {
383
      if ($line eq ""){
384
            print $lineprefix, $blankline;
385
        } else {
386
            $line =~ s/\\\\\\/\&/g;
387
            print $lineprefix, $line;
388
        }
389
        print "\n";
390
    }
391
}
392
 
393
#output sections in html
394
sub output_section_html(%) {
395
    my %args = %{$_[0]};
396
    my $section;
397
 
398
    foreach $section (@{$args{'sectionlist'}}) {
399
        print "

$section

\n";
400
        print "
\n";
401
        output_highlight($args{'sections'}{$section});
402
        print "\n";
403
    }
404
}
405
 
406
# output enum in html
407
sub output_enum_html(%) {
408
    my %args = %{$_[0]};
409
    my ($parameter);
410
    my $count;
411
    print "

enum ".$args{'enum'}."

\n";
412
 
413
    print "enum ".$args{'enum'}." {
\n";
414
    $count = 0;
415
    foreach $parameter (@{$args{'parameterlist'}}) {
416
        print " ".$parameter."";
417
        if ($count != $#{$args{'parameterlist'}}) {
418
            $count++;
419
            print ",\n";
420
        }
421
        print "
";
422
    }
423
    print "};
\n";
424
 
425
    print "

Constants

\n";
426
    print "
\n";
427
    foreach $parameter (@{$args{'parameterlist'}}) {
428
        print "
".$parameter."\n";
429
        print "
";
430
        output_highlight($args{'parameterdescs'}{$parameter});
431
    }
432
    print "\n";
433
    output_section_html(@_);
434
    print "
\n";
435
}
436
 
437
# output tyepdef in html
438
sub output_typedef_html(%) {
439
    my %args = %{$_[0]};
440
    my ($parameter);
441
    my $count;
442
    print "

typedef ".$args{'typedef'}."

\n";
443
 
444
    print "typedef ".$args{'typedef'}."\n";
445
    output_section_html(@_);
446
    print "
\n";
447
}
448
 
449
# output struct in html
450
sub output_struct_html(%) {
451
    my %args = %{$_[0]};
452
    my ($parameter);
453
 
454
    print "

".$args{'type'}." ".$args{'struct'}."

\n";
455
    print "".$args{'type'}." ".$args{'struct'}." {
\n";
456
    foreach $parameter (@{$args{'parameterlist'}}) {
457
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
458
        $type = $args{'parametertypes'}{$parameter};
459
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
460
            # pointer-to-function
461
            print " $1$parameter) ($2);
\n";
462
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
463
            print " $1 $parameter$2;
\n";
464
        } else {
465
            print " $type $parameter;
\n";
466
        }
467
    }
468
    print "};
\n";
469
 
470
    print "

Members

\n";
471
    print "
\n";
472
    foreach $parameter (@{$args{'parameterlist'}}) {
473
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
474
        print "
".$parameter."\n";
475
        print "
";
476
        output_highlight($args{'parameterdescs'}{$parameter});
477
    }
478
    print "\n";
479
    output_section_html(@_);
480
    print "
\n";
481
}
482
 
483
# output function in html
484
sub output_function_html(%) {
485
    my %args = %{$_[0]};
486
    my ($parameter, $section);
487
    my $count;
488
    print "

Function

\n";
489
 
490
    print "".$args{'functiontype'}."\n";
491
    print "".$args{'function'}."\n";
492
    print "(";
493
    $count = 0;
494
    foreach $parameter (@{$args{'parameterlist'}}) {
495
        $type = $args{'parametertypes'}{$parameter};
496
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
497
            # pointer-to-function
498
            print "$1$parameter) ($2)";
499
        } else {
500
            print "".$type." ".$parameter."";
501
        }
502
        if ($count != $#{$args{'parameterlist'}}) {
503
            $count++;
504
            print ",\n";
505
        }
506
    }
507
    print ")\n";
508
 
509
    print "

Arguments

\n";
510
    print "
\n";
511
    foreach $parameter (@{$args{'parameterlist'}}) {
512
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
513
        print "
".$parameter."\n";
514
        print "
";
515
        output_highlight($args{'parameterdescs'}{$parameter});
516
    }
517
    print "\n";
518
    output_section_html(@_);
519
    print "
\n";
520
}
521
 
522
# output intro in html
523
sub output_intro_html(%) {
524
    my %args = %{$_[0]};
525
    my ($parameter, $section);
526
    my $count;
527
 
528
    foreach $section (@{$args{'sectionlist'}}) {
529
        print "

$section

\n";
530
        print "
    \n";
531
        output_highlight($args{'sections'}{$section});
532
        print "\n";
533
    }
534
    print "
\n";
535
}
536
 
537
sub output_section_sgml(%) {
538
    my %args = %{$_[0]};
539
    my $section;
540
    # print out each section
541
    $lineprefix="   ";
542
    foreach $section (@{$args{'sectionlist'}}) {
543
        print "\n $section\n \n";
544
        if ($section =~ m/EXAMPLE/i) {
545
            print "\n";
546
        }
547
        output_highlight($args{'sections'}{$section});
548
        if ($section =~ m/EXAMPLE/i) {
549
            print "\n";
550
        }
551
        print " \n\n";
552
    }
553
}
554
 
555
# output function in sgml DocBook
556
sub output_function_sgml(%) {
557
    my %args = %{$_[0]};
558
    my ($parameter, $section);
559
    my $count;
560
    my $id;
561
 
562
    $id = "API-".$args{'function'};
563
    $id =~ s/[^A-Za-z0-9]/-/g;
564
 
565
    print "\n";
566
    print "\n";
567
    print "".$args{'function'}."\n";
568
    print "\n";
569
    print "\n";
570
    print " ".$args{'function'}."\n";
571
    print " \n";
572
    print "  ";
573
    output_highlight ($args{'purpose'});
574
    print " \n";
575
    print "\n";
576
 
577
    print "\n";
578
    print " Synopsis\n";
579
    print "  \n";
580
    print "   ".$args{'functiontype'}." ";
581
    print "".$args{'function'}." \n";
582
 
583
    $count = 0;
584
    if ($#{$args{'parameterlist'}} >= 0) {
585
        foreach $parameter (@{$args{'parameterlist'}}) {
586
            $type = $args{'parametertypes'}{$parameter};
587
            if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
588
                # pointer-to-function
589
                print "   $1$parameter)\n";
590
                print "     $2\n";
591
            } else {
592
                print "   ".$type;
593
                print " $parameter\n";
594
            }
595
        }
596
    } else {
597
        print "  \n";
598
    }
599
    print "  \n";
600
    print "\n";
601
 
602
    # print parameters
603
    print "\n Arguments\n";
604
    if ($#{$args{'parameterlist'}} >= 0) {
605
        print " \n";
606
        foreach $parameter (@{$args{'parameterlist'}}) {
607
            print "  \n   $parameter\n";
608
            print "   \n    \n";
609
            $lineprefix="     ";
610
            output_highlight($args{'parameterdescs'}{$parameter});
611
            print "    \n   \n  \n";
612
        }
613
        print " \n";
614
    } else {
615
        print " \n  None\n \n";
616
    }
617
    print "\n";
618
 
619
    output_section_sgml(@_);
620
    print "\n\n";
621
}
622
 
623
# output struct in sgml DocBook
624
sub output_struct_sgml(%) {
625
    my %args = %{$_[0]};
626
    my ($parameter, $section);
627
    my $id;
628
 
629
    $id = "API-struct-".$args{'struct'};
630
    $id =~ s/[^A-Za-z0-9]/-/g;
631
 
632
    print "\n";
633
    print "\n";
634
    print "".$args{'type'}." ".$args{'struct'}."\n";
635
    print "\n";
636
    print "\n";
637
    print " ".$args{'type'}." ".$args{'struct'}."\n";
638
    print " \n";
639
    print "  ";
640
    output_highlight ($args{'purpose'});
641
    print " \n";
642
    print "\n";
643
 
644
    print "\n";
645
    print " Synopsis\n";
646
    print "  \n";
647
    print $args{'type'}." ".$args{'struct'}." {\n";
648
    foreach $parameter (@{$args{'parameterlist'}}) {
649
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
650
        $type = $args{'parametertypes'}{$parameter};
651
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
652
            # pointer-to-function
653
            print "  $1 $parameter ($2);\n";
654
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
655
            print "  $1 $parameter$2;\n";
656
        } else {
657
            print "  ".$type." ".$parameter.";\n";
658
        }
659
    }
660
    print "};";
661
    print "  \n";
662
    print "\n";
663
 
664
    print " \n";
665
    print "  Members\n";
666
 
667
    print "  \n";
668
    foreach $parameter (@{$args{'parameterlist'}}) {
669
      ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
670
      print "    ";
671
      print "      $parameter\n";
672
      print "      \n";
673
      output_highlight($args{'parameterdescs'}{$parameter});
674
      print "      \n";
675
      print "    \n";
676
    }
677
    print "  \n";
678
    print " \n";
679
 
680
    output_section_sgml(@_);
681
 
682
    print "\n\n";
683
}
684
 
685
# output enum in sgml DocBook
686
sub output_enum_sgml(%) {
687
    my %args = %{$_[0]};
688
    my ($parameter, $section);
689
    my $count;
690
    my $id;
691
 
692
    $id = "API-enum-".$args{'enum'};
693
    $id =~ s/[^A-Za-z0-9]/-/g;
694
 
695
    print "\n";
696
    print "\n";
697
    print "enum ".$args{'enum'}."\n";
698
    print "\n";
699
    print "\n";
700
    print " enum ".$args{'enum'}."\n";
701
    print " \n";
702
    print "  ";
703
    output_highlight ($args{'purpose'});
704
    print " \n";
705
    print "\n";
706
 
707
    print "\n";
708
    print " Synopsis\n";
709
    print "  \n";
710
    print "enum ".$args{'enum'}." {\n";
711
    $count = 0;
712
    foreach $parameter (@{$args{'parameterlist'}}) {
713
        print "  $parameter";
714
        if ($count != $#{$args{'parameterlist'}}) {
715
            $count++;
716
            print ",";
717
        }
718
        print "\n";
719
    }
720
    print "};";
721
    print "  \n";
722
    print "\n";
723
 
724
    print "\n";
725
    print " Constants\n";
726
    print "  \n";
727
    foreach $parameter (@{$args{'parameterlist'}}) {
728
      print "    ";
729
      print "      $parameter\n";
730
      print "      \n";
731
      output_highlight($args{'parameterdescs'}{$parameter});
732
      print "      \n";
733
      print "    \n";
734
    }
735
    print "  \n";
736
    print "\n";
737
 
738
    output_section_sgml(@_);
739
 
740
    print "\n\n";
741
}
742
 
743
# output typedef in sgml DocBook
744
sub output_typedef_sgml(%) {
745
    my %args = %{$_[0]};
746
    my ($parameter, $section);
747
    my $id;
748
 
749
    $id = "API-typedef-".$args{'typedef'};
750
    $id =~ s/[^A-Za-z0-9]/-/g;
751
 
752
    print "\n";
753
    print "\n";
754
    print "typedef ".$args{'typedef'}."\n";
755
    print "\n";
756
    print "\n";
757
    print " typedef ".$args{'typedef'}."\n";
758
    print " \n";
759
    print "  ";
760
    output_highlight ($args{'purpose'});
761
    print " \n";
762
    print "\n";
763
 
764
    print "\n";
765
    print " Synopsis\n";
766
    print "  typedef ".$args{'typedef'}.";\n";
767
    print "\n";
768
 
769
    output_section_sgml(@_);
770
 
771
    print "\n\n";
772
}
773
 
774
# output in sgml DocBook
775
sub output_intro_sgml(%) {
776
    my %args = %{$_[0]};
777
    my ($parameter, $section);
778
    my $count;
779
 
780
    my $id = $args{'module'};
781
    $id =~ s/[^A-Za-z0-9]/-/g;
782
 
783
    # print out each section
784
    $lineprefix="   ";
785
    foreach $section (@{$args{'sectionlist'}}) {
786
        print "\n $section\n \n";
787
        if ($section =~ m/EXAMPLE/i) {
788
            print "\n";
789
        }
790
        output_highlight($args{'sections'}{$section});
791
        if ($section =~ m/EXAMPLE/i) {
792
            print "\n";
793
        }
794
        print " \n\n";
795
    }
796
 
797
    print "\n\n";
798
}
799
 
800
# output in sgml DocBook
801
sub output_function_gnome {
802
    my %args = %{$_[0]};
803
    my ($parameter, $section);
804
    my $count;
805
    my $id;
806
 
807
    $id = $args{'module'}."-".$args{'function'};
808
    $id =~ s/[^A-Za-z0-9]/-/g;
809
 
810
    print "\n";
811
    print " ".$args{'function'}."\n";
812
 
813
    print "  \n";
814
    print "   ".$args{'functiontype'}." ";
815
    print "".$args{'function'}." ";
816
    print "\n";
817
 
818
    $count = 0;
819
    if ($#{$args{'parameterlist'}} >= 0) {
820
        foreach $parameter (@{$args{'parameterlist'}}) {
821
            $type = $args{'parametertypes'}{$parameter};
822
            if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
823
                # pointer-to-function
824
                print "   $1 $parameter)\n";
825
                print "     $2\n";
826
            } else {
827
                print "   ".$type;
828
                print " $parameter\n";
829
            }
830
        }
831
    } else {
832
        print "  \n";
833
    }
834
    print "  \n";
835
    if ($#{$args{'parameterlist'}} >= 0) {
836
        print " \n";
837
        print "\n";
838
        print "\n";
839
        print "\n";
840
        print "
841
        foreach $parameter (@{$args{'parameterlist'}}) {
842
            print "  $parameter\n";
843
            print "   \n";
844
            $lineprefix="     ";
845
            output_highlight($args{'parameterdescs'}{$parameter});
846
            print "    \n";
847
        }
848
        print " 
849
    } else {
850
        print " \n  None\n \n";
851
    }
852
 
853
    # print out each section
854
    $lineprefix="   ";
855
    foreach $section (@{$args{'sectionlist'}}) {
856
        print "\n $section\n";
857
        if ($section =~ m/EXAMPLE/i) {
858
            print "\n";
859
        } else {
860
        }
861
        print "\n";
862
        output_highlight($args{'sections'}{$section});
863
        print "\n";
864
        if ($section =~ m/EXAMPLE/i) {
865
            print "\n";
866
        } else {
867
        }
868
        print " \n";
869
    }
870
 
871
    print "\n\n";
872
}
873
 
874
##
875
# output function in man
876
sub output_function_man(%) {
877
    my %args = %{$_[0]};
878
    my ($parameter, $section);
879
    my $count;
880
 
881
    print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"25 May 1998\" \"Kernel Hacker's Manual\" LINUX\n";
882
 
883
    print ".SH NAME\n";
884
    print $args{'function'}." \\- ".$args{'purpose'}."\n";
885
 
886
    print ".SH SYNOPSIS\n";
887
    print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
888
    $count = 0;
889
    my $parenth = "(";
890
    my $post = ",";
891
    foreach my $parameter (@{$args{'parameterlist'}}) {
892
        if ($count == $#{$args{'parameterlist'}}) {
893
            $post = ");";
894
        }
895
        $type = $args{'parametertypes'}{$parameter};
896
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
897
            # pointer-to-function
898
            print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
899
        } else {
900
            $type =~ s/([^\*])$/$1 /;
901
            print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
902
        }
903
        $count++;
904
        $parenth = "";
905
    }
906
 
907
    print ".SH ARGUMENTS\n";
908
    foreach $parameter (@{$args{'parameterlist'}}) {
909
        print ".IP \"".$parameter."\" 12\n";
910
        output_highlight($args{'parameterdescs'}{$parameter});
911
    }
912
    foreach $section (@{$args{'sectionlist'}}) {
913
        print ".SH \"", uc $section, "\"\n";
914
        output_highlight($args{'sections'}{$section});
915
    }
916
}
917
 
918
##
919
# output enum in man
920
sub output_enum_man(%) {
921
    my %args = %{$_[0]};
922
    my ($parameter, $section);
923
    my $count;
924
 
925
    print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
926
 
927
    print ".SH NAME\n";
928
    print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
929
 
930
    print ".SH SYNOPSIS\n";
931
    print "enum ".$args{'enum'}." {\n";
932
    $count = 0;
933
    foreach my $parameter (@{$args{'parameterlist'}}) {
934
        print ".br\n.BI \"    $parameter\"\n";
935
        if ($count == $#{$args{'parameterlist'}}) {
936
            print "\n};\n";
937
            last;
938
        }
939
        else {
940
            print ", \n.br\n";
941
        }
942
        $count++;
943
    }
944
 
945
    print ".SH Constants\n";
946
    foreach $parameter (@{$args{'parameterlist'}}) {
947
        print ".IP \"".$parameter."\" 12\n";
948
        output_highlight($args{'parameterdescs'}{$parameter});
949
    }
950
    foreach $section (@{$args{'sectionlist'}}) {
951
        print ".SH \"$section\"\n";
952
        output_highlight($args{'sections'}{$section});
953
    }
954
}
955
 
956
##
957
# output struct in man
958
sub output_struct_man(%) {
959
    my %args = %{$_[0]};
960
    my ($parameter, $section);
961
 
962
    print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
963
 
964
    print ".SH NAME\n";
965
    print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
966
 
967
    print ".SH SYNOPSIS\n";
968
    print $args{'type'}." ".$args{'struct'}." {\n";
969
 
970
    foreach my $parameter (@{$args{'parameterlist'}}) {
971
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
972
        print "\n.br\n";
973
        $type = $args{'parametertypes'}{$parameter};
974
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
975
            # pointer-to-function
976
            print ".BI \"    ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
977
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
978
            print ".BI \"    ".$1."\" ".$parameter.$2." \""."\"\n;\n";
979
        } else {
980
            $type =~ s/([^\*])$/$1 /;
981
            print ".BI \"    ".$type."\" ".$parameter." \""."\"\n;\n";
982
        }
983
        print "\n.br\n";
984
    }
985
    print "};\n.br\n";
986
 
987
    print ".SH Arguments\n";
988
    foreach $parameter (@{$args{'parameterlist'}}) {
989
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
990
        print ".IP \"".$parameter."\" 12\n";
991
        output_highlight($args{'parameterdescs'}{$parameter});
992
    }
993
    foreach $section (@{$args{'sectionlist'}}) {
994
        print ".SH \"$section\"\n";
995
        output_highlight($args{'sections'}{$section});
996
    }
997
}
998
 
999
##
1000
# output typedef in man
1001
sub output_typedef_man(%) {
1002
    my %args = %{$_[0]};
1003
    my ($parameter, $section);
1004
 
1005
    print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
1006
 
1007
    print ".SH NAME\n";
1008
    print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
1009
 
1010
    foreach $section (@{$args{'sectionlist'}}) {
1011
        print ".SH \"$section\"\n";
1012
        output_highlight($args{'sections'}{$section});
1013
    }
1014
}
1015
 
1016
sub output_intro_man(%) {
1017
    my %args = %{$_[0]};
1018
    my ($parameter, $section);
1019
    my $count;
1020
 
1021
    print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
1022
 
1023
    foreach $section (@{$args{'sectionlist'}}) {
1024
        print ".SH \"$section\"\n";
1025
        output_highlight($args{'sections'}{$section});
1026
    }
1027
}
1028
 
1029
##
1030
# output in text
1031
sub output_function_text(%) {
1032
    my %args = %{$_[0]};
1033
    my ($parameter, $section);
1034
 
1035
    print "Function:\n\n";
1036
    my $start=$args{'functiontype'}." ".$args{'function'}." (";
1037
    print $start;
1038
    my $count = 0;
1039
    foreach my $parameter (@{$args{'parameterlist'}}) {
1040
        $type = $args{'parametertypes'}{$parameter};
1041
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1042
            # pointer-to-function
1043
            print $1.$parameter.") (".$2;
1044
        } else {
1045
            print $type." ".$parameter;
1046
        }
1047
        if ($count != $#{$args{'parameterlist'}}) {
1048
            $count++;
1049
            print ",\n";
1050
            print " " x length($start);
1051
        } else {
1052
            print ");\n\n";
1053
        }
1054
    }
1055
 
1056
    print "Arguments:\n\n";
1057
    foreach $parameter (@{$args{'parameterlist'}}) {
1058
        print $parameter."\n\t".$args{'parameterdescs'}{$parameter}."\n";
1059
    }
1060
    output_section_text(@_);
1061
}
1062
 
1063
#output sections in text
1064
sub output_section_text(%) {
1065
    my %args = %{$_[0]};
1066
    my $section;
1067
 
1068
    print "\n";
1069
    foreach $section (@{$args{'sectionlist'}}) {
1070
        print "$section:\n\n";
1071
        output_highlight($args{'sections'}{$section});
1072
    }
1073
    print "\n\n";
1074
}
1075
 
1076
# output enum in text
1077
sub output_enum_text(%) {
1078
    my %args = %{$_[0]};
1079
    my ($parameter);
1080
    my $count;
1081
    print "Enum:\n\n";
1082
 
1083
    print "enum ".$args{'enum'}." {\n";
1084
    $count = 0;
1085
    foreach $parameter (@{$args{'parameterlist'}}) {
1086
        print "\t$parameter";
1087
        if ($count != $#{$args{'parameterlist'}}) {
1088
            $count++;
1089
            print ",";
1090
        }
1091
        print "\n";
1092
    }
1093
    print "};\n\n";
1094
 
1095
    print "Constants:\n\n";
1096
    foreach $parameter (@{$args{'parameterlist'}}) {
1097
        print "$parameter\n\t";
1098
        print $args{'parameterdescs'}{$parameter}."\n";
1099
    }
1100
 
1101
    output_section_text(@_);
1102
}
1103
 
1104
# output typedef in text
1105
sub output_typedef_text(%) {
1106
    my %args = %{$_[0]};
1107
    my ($parameter);
1108
    my $count;
1109
    print "Typedef:\n\n";
1110
 
1111
    print "typedef ".$args{'typedef'}."\n";
1112
    output_section_text(@_);
1113
}
1114
 
1115
# output struct as text
1116
sub output_struct_text(%) {
1117
    my %args = %{$_[0]};
1118
    my ($parameter);
1119
 
1120
    print $args{'type'}." ".$args{'struct'}.":\n\n";
1121
    print $args{'type'}." ".$args{'struct'}." {\n";
1122
    foreach $parameter (@{$args{'parameterlist'}}) {
1123
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
1124
        $type = $args{'parametertypes'}{$parameter};
1125
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1126
            # pointer-to-function
1127
            print "\t$1 $parameter) ($2);\n";
1128
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1129
            print "\t$1 $parameter$2;\n";
1130
        } else {
1131
            print "\t".$type." ".$parameter.";\n";
1132
        }
1133
    }
1134
    print "};\n\n";
1135
 
1136
    print "Members:\n\n";
1137
    foreach $parameter (@{$args{'parameterlist'}}) {
1138
        ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
1139
        print "$parameter\n\t";
1140
        print $args{'parameterdescs'}{$parameter}."\n";
1141
    }
1142
    print "\n";
1143
    output_section_text(@_);
1144
}
1145
 
1146
sub output_intro_text(%) {
1147
    my %args = %{$_[0]};
1148
    my ($parameter, $section);
1149
 
1150
    foreach $section (@{$args{'sectionlist'}}) {
1151
        print " $section:\n";
1152
        print "    -> ";
1153
        output_highlight($args{'sections'}{$section});
1154
    }
1155
}
1156
 
1157
##
1158
# generic output function for typedefs
1159
sub output_declaration {
1160
    no strict 'refs';
1161
    my $name = shift;
1162
    my $functype = shift;
1163
    my $func = "output_${functype}_$output_mode";
1164
    if (($function_only==0) ||
1165
        ( $function_only == 1 && defined($function_table{$name})) ||
1166
        ( $function_only == 2 && !defined($function_table{$name})))
1167
    {
1168
        &$func(@_);
1169
        $section_counter++;
1170
    }
1171
}
1172
 
1173
##
1174
# generic output function - calls the right one based
1175
# on current output mode.
1176
sub output_intro {
1177
    no strict 'refs';
1178
    my $func = "output_intro_".$output_mode;
1179
    &$func(@_);
1180
    $section_counter++;
1181
}
1182
 
1183
##
1184
# takes a declaration (struct, union, enum, typedef) and
1185
# invokes the right handler. NOT called for functions.
1186
sub dump_declaration($$) {
1187
    no strict 'refs';
1188
    my ($prototype, $file) = @_;
1189
    my $func = "dump_".$decl_type;
1190
    &$func(@_);
1191
}
1192
 
1193
sub dump_union($$) {
1194
    dump_struct(@_);
1195
}
1196
 
1197
sub dump_struct($$) {
1198
    my $x = shift;
1199
    my $file = shift;
1200
 
1201
    if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
1202
        $declaration_name = $2;
1203
        my $members = $3;
1204
 
1205
        # ignore embedded structs or unions
1206
        $members =~ s/{.*}//g;
1207
 
1208
        create_parameterlist($members, ';', $file);
1209
 
1210
        output_declaration($declaration_name,
1211
                           'struct',
1212
                           {'struct' => $declaration_name,
1213
                            'module' => $modulename,
1214
                            'parameterlist' => \@parameterlist,
1215
                            'parameterdescs' => \%parameterdescs,
1216
                            'parametertypes' => \%parametertypes,
1217
                            'sectionlist' => \@sectionlist,
1218
                            'sections' => \%sections,
1219
                            'purpose' => $declaration_purpose,
1220
                            'type' => $decl_type
1221
                           });
1222
    }
1223
    else {
1224
        print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
1225
        ++$errors;
1226
    }
1227
}
1228
 
1229
sub dump_enum($$) {
1230
    my $x = shift;
1231
    my $file = shift;
1232
 
1233
    if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1234
        $declaration_name = $1;
1235
        my $members = $2;
1236
 
1237
        foreach my $arg (split ',', $members) {
1238
            $arg =~ s/^\s*(\w+).*/$1/;
1239
            push @parameterlist, $arg;
1240
            if (!$parameterdescs{$arg}) {
1241
                $parameterdescs{$arg} = $undescribed;
1242
                print STDERR "Warning(${file}:$.): Enum value '$arg' ".
1243
                    "not described in enum '$declaration_name'\n";
1244
            }
1245
 
1246
        }
1247
 
1248
        output_declaration($declaration_name,
1249
                           'enum',
1250
                           {'enum' => $declaration_name,
1251
                            'module' => $modulename,
1252
                            'parameterlist' => \@parameterlist,
1253
                            'parameterdescs' => \%parameterdescs,
1254
                            'sectionlist' => \@sectionlist,
1255
                            'sections' => \%sections,
1256
                            'purpose' => $declaration_purpose
1257
                           });
1258
    }
1259
    else {
1260
        print STDERR "Error(${file}:$.): Cannot parse enum!\n";
1261
        ++$errors;
1262
    }
1263
}
1264
 
1265
sub dump_typedef($$) {
1266
    my $x = shift;
1267
    my $file = shift;
1268
 
1269
    while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
1270
        $x =~ s/\(*.\)\s*;$/;/;
1271
        $x =~ s/\[*.\]\s*;$/;/;
1272
    }
1273
 
1274
    if ($x =~ /typedef.*\s+(\w+)\s*;/) {
1275
        $declaration_name = $1;
1276
 
1277
        output_declaration($declaration_name,
1278
                           'typedef',
1279
                           {'typedef' => $declaration_name,
1280
                            'module' => $modulename,
1281
                            'sectionlist' => \@sectionlist,
1282
                            'sections' => \%sections,
1283
                            'purpose' => $declaration_purpose
1284
                           });
1285
    }
1286
    else {
1287
        print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
1288
        ++$errors;
1289
    }
1290
}
1291
 
1292
sub create_parameterlist($$$) {
1293
    my $args = shift;
1294
    my $splitter = shift;
1295
    my $file = shift;
1296
    my $type;
1297
    my $param;
1298
 
1299
    while ($args =~ /(\([^\),]+),/) {
1300
        $args =~ s/(\([^\),]+),/$1#/g;
1301
    }
1302
 
1303
    foreach my $arg (split($splitter, $args)) {
1304
        # strip leading/trailing spaces
1305
        $arg =~ s/^\s*//;
1306
        $arg =~ s/\s*$//;
1307
        $arg =~ s/\s+/ /;
1308
 
1309
        if ($arg =~ m/\(/) {
1310
            # pointer-to-function
1311
            $arg =~ tr/#/,/;
1312
            $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
1313
            $param = $1;
1314
            $type = $arg;
1315
            $type =~ s/([^\(]+\(\*)$param/$1/;
1316
        } else {
1317
            # evil magic to get fixed array parameters to work
1318
            $arg =~ s/(.+\s+)(.+)\[.*/$1* $2/;
1319
            my @args = split('\s', $arg);
1320
 
1321
            $param = pop @args;
1322
            if ($param =~ m/^(\*+)(.*)/) {
1323
                $param = $2;
1324
                push @args, $1;
1325
            }
1326
            elsif ($param =~ m/(.*?)\s*:\s*(\d+)/) {
1327
                $param = $1;
1328
                push @args, ":$2";
1329
            }
1330
            $type = join " ", @args;
1331
        }
1332
 
1333
        if ($type eq "" && $param eq "...")
1334
        {
1335
            $type="...";
1336
            $param="...";
1337
            $parameterdescs{"..."} = "variable arguments";
1338
        }
1339
        elsif ($type eq "" && ($param eq "" or $param eq "void"))
1340
        {
1341
            $type="";
1342
            $param="void";
1343
            $parameterdescs{void} = "no arguments";
1344
        }
1345
        if (defined $type && $type && !defined $parameterdescs{$param}) {
1346
            $parameterdescs{$param} = $undescribed;
1347
 
1348
            if (($type eq 'function') || ($type eq 'enum')) {
1349
                print STDERR "Warning(${file}:$.): Function parameter ".
1350
                    "or member '$param' not " .
1351
                    "described in '$declaration_name'\n";
1352
            }
1353
            ++$errors;
1354
        }
1355
 
1356
        push @parameterlist, $param;
1357
        $parametertypes{$param} = $type;
1358
    }
1359
}
1360
 
1361
##
1362
# takes a function prototype and the name of the current file being
1363
# processed and spits out all the details stored in the global
1364
# arrays/hashes.
1365
sub dump_function($$) {
1366
    my $prototype = shift;
1367
    my $file = shift;
1368
 
1369
    $prototype =~ s/^static +//;
1370
    $prototype =~ s/^extern +//;
1371
    $prototype =~ s/^inline +//;
1372
    $prototype =~ s/^__inline__ +//;
1373
    $prototype =~ s/^#define +//; #ak added
1374
 
1375
    # Yes, this truly is vile.  We are looking for:
1376
    # 1. Return type (may be nothing if we're looking at a macro)
1377
    # 2. Function name
1378
    # 3. Function parameters.
1379
    #
1380
    # All the while we have to watch out for function pointer parameters
1381
    # (which IIRC is what the two sections are for), C types (these
1382
    # regexps don't even start to express all the possibilities), and
1383
    # so on.
1384
    #
1385
    # If you mess with these regexps, it's a good idea to check that
1386
    # the following functions' documentation still comes out right:
1387
    # - parport_register_device (function pointer parameters)
1388
    # - atomic_set (macro)
1389
    # - pci_match_device (long return type)
1390
 
1391
    if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1392
        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1393
        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1394
        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1395
        $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1396
        $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1397
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1398
        $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1399
        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1400
        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1401
        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1402
        $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1403
        $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1404
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
1405
        $return_type = $1;
1406
        $declaration_name = $2;
1407
        my $args = $3;
1408
 
1409
        create_parameterlist($args, ',', $file);
1410
    } else {
1411
        print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
1412
        ++$errors;
1413
        return;
1414
    }
1415
 
1416
    output_declaration($declaration_name,
1417
                       'function',
1418
                       {'function' => $declaration_name,
1419
                        'module' => $modulename,
1420
                        'functiontype' => $return_type,
1421
                        'parameterlist' => \@parameterlist,
1422
                        'parameterdescs' => \%parameterdescs,
1423
                        'parametertypes' => \%parametertypes,
1424
                        'sectionlist' => \@sectionlist,
1425
                        'sections' => \%sections,
1426
                        'purpose' => $declaration_purpose
1427
                       });
1428
}
1429
 
1430
sub process_file($);
1431
 
1432
# Read the file that maps relative names to absolute names for
1433
# separate source and object directories and for shadow trees.
1434
if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
1435
        my ($relname, $absname);
1436
        while() {
1437
                chop();
1438
                ($relname, $absname) = (split())[0..1];
1439
                $relname =~ s:^/+::;
1440
                $source_map{$relname} = $absname;
1441
        }
1442
        close(SOURCE_MAP);
1443
}
1444
 
1445
if ($filelist) {
1446
        open(FLIST,"<$filelist") or die "Can't open file list $filelist";
1447
        while() {
1448
                chop;
1449
                process_file($_);
1450
        }
1451
}
1452
 
1453
foreach (@ARGV) {
1454
    chomp;
1455
    process_file($_);
1456
}
1457
 
1458
exit($errors);
1459
 
1460
sub reset_state {
1461
    $function = "";
1462
    %constants = ();
1463
    %parameterdescs = ();
1464
    %parametertypes = ();
1465
    @parameterlist = ();
1466
    %sections = ();
1467
    @sectionlist = ();
1468
    $prototype = "";
1469
 
1470
    $state = 0;
1471
}
1472
 
1473
sub process_state3_function($$) {
1474
    my $x = shift;
1475
    my $file = shift;
1476
 
1477
    if ($x =~ m#\s*/\*\s+MACDOC\s*#io) {
1478
        # do nothing
1479
    }
1480
    elsif ($x =~ /([^\{]*)/) {
1481
        $prototype .= $1;
1482
    }
1483
    if (($x =~ /\{/) || ($x =~ /\#/) || ($x =~ /;/)) {
1484
        $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
1485
        $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1486
        $prototype =~ s@^\s+@@gos; # strip leading spaces
1487
        dump_function($prototype,$file);
1488
        reset_state();
1489
    }
1490
}
1491
 
1492
sub process_state3_type($$) {
1493
    my $x = shift;
1494
    my $file = shift;
1495
 
1496
    $x =~ s@/\*.*?\*/@@gos;     # strip comments.
1497
    $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1498
    $x =~ s@^\s+@@gos; # strip leading spaces
1499
    $x =~ s@\s+$@@gos; # strip trailing spaces
1500
 
1501
    while (1) {
1502
        if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
1503
            $prototype .= $1 . $2;
1504
            ($2 eq '{') && $brcount++;
1505
            ($2 eq '}') && $brcount--;
1506
            if (($2 eq ';') && ($brcount == 0)) {
1507
                dump_declaration($prototype,$file);
1508
                reset_state();
1509
                last;
1510
            }
1511
            $x = $3;
1512
        } else {
1513
            $prototype .= $x;
1514
            last;
1515
        }
1516
    }
1517
}
1518
 
1519
sub process_file($) {
1520
    my ($file) = @_;
1521
    my $identifier;
1522
    my $func;
1523
    my $initial_section_counter = $section_counter;
1524
 
1525
    if (defined($source_map{$file})) {
1526
        $file = $source_map{$file};
1527
    }
1528
 
1529
    if (!open(IN,"<$file")) {
1530
        print STDERR "Error: Cannot open file $file\n";
1531
        ++$errors;
1532
        return;
1533
    }
1534
 
1535
    $section_counter = 0;
1536
    while () {
1537
        if ($state == 0) {
1538
            if (/$doc_start/o) {
1539
                $state = 1;             # next line is always the function name
1540
            }
1541
        } elsif ($state == 1) { # this line is the function name (always)
1542
            if (/$doc_block/o) {
1543
                $state = 4;
1544
                $contents = "";
1545
                if ( $1 eq "" ) {
1546
                        $section = $section_intro;
1547
                } else {
1548
                        $section = $1;
1549
                }
1550
            }
1551
            elsif (/$doc_decl/o) {
1552
                $identifier = $1;
1553
                if (/\s*([\w\s]+?)\s*-/) {
1554
                    $identifier = $1;
1555
                }
1556
 
1557
                $state = 2;
1558
                if (/-(.*)/) {
1559
                    $declaration_purpose = $1;
1560
                } else {
1561
                    $declaration_purpose = "";
1562
                }
1563
                if ($identifier =~ m/^struct/) {
1564
                    $decl_type = 'struct';
1565
                } elsif ($identifier =~ m/^union/) {
1566
                    $decl_type = 'union';
1567
                } elsif ($identifier =~ m/^enum/) {
1568
                    $decl_type = 'enum';
1569
                } elsif ($identifier =~ m/^typedef/) {
1570
                    $decl_type = 'typedef';
1571
                } else {
1572
                    $decl_type = 'function';
1573
                }
1574
 
1575
                if ($verbose) {
1576
                    print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
1577
                }
1578
            } else {
1579
                print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
1580
                " - I thought it was a doc line\n";
1581
                ++$errors;
1582
                $state = 0;
1583
            }
1584
        } elsif ($state == 2) { # look for head: lines, and include content
1585
            if (/$doc_sect/o) {
1586
                $newsection = $1;
1587
                $newcontents = $2;
1588
 
1589
                if ($contents ne "") {
1590
                    $contents =~ s/\&/\\\\\\amp;/g;
1591
                    $contents =~ s/\
1592
                    $contents =~ s/\>/\\\\\\gt;/g;
1593
                    dump_section($section, $contents);
1594
                    $section = $section_default;
1595
                }
1596
 
1597
                $contents = $newcontents;
1598
                if ($contents ne "") {
1599
                    $contents .= "\n";
1600
                }
1601
                $section = $newsection;
1602
            } elsif (/$doc_end/) {
1603
 
1604
                if ($contents ne "") {
1605
                    $contents =~ s/\&/\\\\\\amp;/g;
1606
                    $contents =~ s/\
1607
                    $contents =~ s/\>/\\\\\\gt;/g;
1608
                    dump_section($section, $contents);
1609
                    $section = $section_default;
1610
                    $contents = "";
1611
                }
1612
 
1613
                $prototype = "";
1614
                $state = 3;
1615
                $brcount = 0;
1616
#           print STDERR "end of doc comment, looking for prototype\n";
1617
            } elsif (/$doc_content/) {
1618
                # miguel-style comment kludge, look for blank lines after
1619
                # @parameter line to signify start of description
1620
                if ($1 eq "" &&
1621
                        ($section =~ m/^@/ || $section eq $section_context)) {
1622
                    $contents =~ s/\&/\\\\\\amp;/g;
1623
                    $contents =~ s/\
1624
                    $contents =~ s/\>/\\\\\\gt;/g;
1625
                    dump_section($section, $contents);
1626
                    $section = $section_default;
1627
                    $contents = "";
1628
                } else {
1629
                    $contents .= $1."\n";
1630
                }
1631
            } else {
1632
                # i dont know - bad line?  ignore.
1633
                print STDERR "Warning(${file}:$.): bad line: $_";
1634
                ++$errors;
1635
            }
1636
        } elsif ($state == 3) { # scanning for function { (end of prototype)
1637
            if ($decl_type eq 'function') {
1638
                process_state3_function($_, $file);
1639
            } else {
1640
                process_state3_type($_, $file);
1641
            }
1642
        } elsif ($state == 4) {
1643
                # Documentation block
1644
                if (/$doc_block/) {
1645
                        dump_section($section, $contents);
1646
                        output_intro({'sectionlist' => \@sectionlist,
1647
                                      'sections' => \%sections });
1648
                        $contents = "";
1649
                        $function = "";
1650
                        %constants = ();
1651
                        %parameterdescs = ();
1652
                        %parametertypes = ();
1653
                        @parameterlist = ();
1654
                        %sections = ();
1655
                        @sectionlist = ();
1656
                        $prototype = "";
1657
                        if ( $1 eq "" ) {
1658
                                $section = $section_intro;
1659
                        } else {
1660
                                $section = $1;
1661
                        }
1662
                }
1663
                elsif (/$doc_end/)
1664
                {
1665
                        dump_section($section, $contents);
1666
                        output_intro({'sectionlist' => \@sectionlist,
1667
                                      'sections' => \%sections });
1668
                        $contents = "";
1669
                        $function = "";
1670
                        %constants = ();
1671
                        %parameterdescs = ();
1672
                        %parametertypes = ();
1673
                        @parameterlist = ();
1674
                        %sections = ();
1675
                        @sectionlist = ();
1676
                        $prototype = "";
1677
                        $state = 0;
1678
                }
1679
                elsif (/$doc_content/)
1680
                {
1681
                        if ( $1 eq "" )
1682
                        {
1683
                                $contents .= $blankline;
1684
                        }
1685
                        else
1686
                        {
1687
                                $contents .= $1 . "\n";
1688
                        }
1689
                }
1690
          }
1691
    }
1692
    if ($initial_section_counter == $section_counter) {
1693
        print STDERR "Warning(${file}): no structured comments found\n";
1694
        if ($output_mode eq "sgml") {
1695
            # The template wants at least one RefEntry here; make one.
1696
            print "\n";
1697
            print " \n";
1698
            print "  \n";
1699
            print "   ${file}\n";
1700
            print "  \n";
1701
            print "  \n";
1702
            print "   Document generation inconsistency\n";
1703
            print "  \n";
1704
            print " \n";
1705
            print " \n";
1706
            print "  \n";</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>1707</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>            print "   Oops\n";</code></pre></td>
      </tr>
      <tr valign="middle">
         <td>1708</td>
         <td></td>
         <td></td>
         <td class="code"><pre><code>            print "  \n";
1709
            print "  \n";
1710
            print "   \n";
1711
            print "    The template for this document tried to insert\n";
1712
            print "    the structured comment from the file\n";
1713
            print "    ${file} at this point,\n";
1714
            print "    but none was found.\n";
1715
            print "    This dummy section is inserted to allow\n";
1716
            print "    generation to continue.\n";
1717
            print "   \n";
1718
            print "  \n";
1719
            print " \n";
1720
            print "\n";
1721
        }
1722
    }
1723
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.