~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/scripts/kernel-doc

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/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 <twaugh@redhat.com>          ##
 
7
## Copyright (C) 2001  Simon Huggins                             ##
 
8
## Copyright (C) 2005-2012  Randy Dunlap                         ##
 
9
## Copyright (C) 2012  Dan Luedtke                               ##
 
10
##                                                               ##
 
11
## #define enhancements by Armin Kuster <akuster@mvista.com>     ##
 
12
## Copyright (c) 2000 MontaVista Software, Inc.                  ##
 
13
##                                                               ##
 
14
## This software falls under the GNU General Public License.     ##
 
15
## Please read the COPYING file for more information             ##
 
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 <ck@whoop.org>
 
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 <kaos@ocs.com.au>
 
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 <tim@tjansen.de>
 
38
 
 
39
# 25/07/2012 - Added support for HTML5
 
40
# -- Dan Luedtke <mail@danrl.de>
 
41
 
 
42
#
 
43
# This will read a 'c' file and scan for embedded comments in the
 
44
# style of gnome comments (+minor extensions - see below).
 
45
#
 
46
 
 
47
# Note: This only supports 'c'.
 
48
 
 
49
# usage:
 
50
# kernel-doc [ -docbook | -html | -html5 | -text | -man | -list ]
 
51
#            [ -no-doc-sections ]
 
52
#            [ -function funcname [ -function funcname ...] ]
 
53
#            c file(s)s > outputfile
 
54
# or
 
55
#            [ -nofunction funcname [ -function funcname ...] ]
 
56
#            c file(s)s > outputfile
 
57
#
 
58
#  Set output format using one of -docbook -html -html5 -text or -man.
 
59
#  Default is man.
 
60
#  The -list format is for internal use by docproc.
 
61
#
 
62
#  -no-doc-sections
 
63
#       Do not output DOC: sections
 
64
#
 
65
#  -function funcname
 
66
#       If set, then only generate documentation for the given function(s) or
 
67
#       DOC: section titles.  All other functions and DOC: sections are ignored.
 
68
#
 
69
#  -nofunction funcname
 
70
#       If set, then only generate documentation for the other function(s)/DOC:
 
71
#       sections. Cannot be used together with -function (yes, that's a bug --
 
72
#       perl hackers can fix it 8))
 
73
#
 
74
#  c files - list of 'c' files to process
 
75
#
 
76
#  All output goes to stdout, with errors to stderr.
 
77
 
 
78
#
 
79
# format of comments.
 
80
# In the following table, (...)? signifies optional structure.
 
81
#                         (...)* signifies 0 or more structure elements
 
82
# /**
 
83
#  * function_name(:)? (- short description)?
 
84
# (* @parameterx: (description of parameter x)?)*
 
85
# (* a blank line)?
 
86
#  * (Description:)? (Description of function)?
 
87
#  * (section header: (section description)? )*
 
88
#  (*)?*/
 
89
#
 
90
# So .. the trivial example would be:
 
91
#
 
92
# /**
 
93
#  * my_function
 
94
#  */
 
95
#
 
96
# If the Description: header tag is omitted, then there must be a blank line
 
97
# after the last parameter specification.
 
98
# e.g.
 
99
# /**
 
100
#  * my_function - does my stuff
 
101
#  * @my_arg: its mine damnit
 
102
#  *
 
103
#  * Does my stuff explained.
 
104
#  */
 
105
#
 
106
#  or, could also use:
 
107
# /**
 
108
#  * my_function - does my stuff
 
109
#  * @my_arg: its mine damnit
 
110
#  * Description: Does my stuff explained.
 
111
#  */
 
112
# etc.
 
113
#
 
114
# Besides functions you can also write documentation for structs, unions,
 
115
# enums and typedefs. Instead of the function name you must write the name
 
116
# of the declaration;  the struct/union/enum/typedef must always precede
 
117
# the name. Nesting of declarations is not supported.
 
118
# Use the argument mechanism to document members or constants.
 
119
# e.g.
 
120
# /**
 
121
#  * struct my_struct - short description
 
122
#  * @a: first member
 
123
#  * @b: second member
 
124
#  *
 
125
#  * Longer description
 
126
#  */
 
127
# struct my_struct {
 
128
#     int a;
 
129
#     int b;
 
130
# /* private: */
 
131
#     int c;
 
132
# };
 
133
#
 
134
# All descriptions can be multiline, except the short function description.
 
135
#
 
136
# You can also add additional sections. When documenting kernel functions you
 
137
# should document the "Context:" of the function, e.g. whether the functions
 
138
# can be called form interrupts. Unlike other sections you can end it with an
 
139
# empty line.
 
140
# A non-void function should have a "Return:" section describing the return
 
141
# value(s).
 
142
# Example-sections should contain the string EXAMPLE so that they are marked
 
143
# appropriately in DocBook.
 
144
#
 
145
# Example:
 
146
# /**
 
147
#  * user_function - function that can only be called in user context
 
148
#  * @a: some argument
 
149
#  * Context: !in_interrupt()
 
150
#  *
 
151
#  * Some description
 
152
#  * Example:
 
153
#  *    user_function(22);
 
154
#  */
 
155
# ...
 
156
#
 
157
#
 
158
# All descriptive text is further processed, scanning for the following special
 
159
# patterns, which are highlighted appropriately.
 
160
#
 
161
# 'funcname()' - function
 
162
# '$ENVVAR' - environmental variable
 
163
# '&struct_name' - name of a structure (up to two words including 'struct')
 
164
# '@parameter' - name of a parameter
 
165
# '%CONST' - name of a constant.
 
166
 
 
167
## init lots of data
 
168
 
 
169
my $errors = 0;
 
170
my $warnings = 0;
 
171
my $anon_struct_union = 0;
 
172
 
 
173
# match expressions used to find embedded type information
 
174
my $type_constant = '\%([-_\w]+)';
 
175
my $type_func = '(\w+)\(\)';
 
176
my $type_param = '\@(\w+)';
 
177
my $type_struct = '\&((struct\s*)*[_\w]+)';
 
178
my $type_struct_xml = '\\&amp;((struct\s*)*[_\w]+)';
 
179
my $type_env = '(\$\w+)';
 
180
 
 
181
# Output conversion substitutions.
 
182
#  One for each output format
 
183
 
 
184
# these work fairly well
 
185
my %highlights_html = ( $type_constant, "<i>\$1</i>",
 
186
                        $type_func, "<b>\$1</b>",
 
187
                        $type_struct_xml, "<i>\$1</i>",
 
188
                        $type_env, "<b><i>\$1</i></b>",
 
189
                        $type_param, "<tt><b>\$1</b></tt>" );
 
190
my $local_lt = "\\\\\\\\lt:";
 
191
my $local_gt = "\\\\\\\\gt:";
 
192
my $blankline_html = $local_lt . "p" . $local_gt;       # was "<p>"
 
193
 
 
194
# html version 5
 
195
my %highlights_html5 = ( $type_constant, "<span class=\"const\">\$1</span>",
 
196
                        $type_func, "<span class=\"func\">\$1</span>",
 
197
                        $type_struct_xml, "<span class=\"struct\">\$1</span>",
 
198
                        $type_env, "<span class=\"env\">\$1</span>",
 
199
                        $type_param, "<span class=\"param\">\$1</span>" );
 
200
my $blankline_html5 = $local_lt . "br /" . $local_gt;
 
201
 
 
202
# XML, docbook format
 
203
my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
 
204
                        $type_constant, "<constant>\$1</constant>",
 
205
                        $type_func, "<function>\$1</function>",
 
206
                        $type_struct_xml, "<structname>\$1</structname>",
 
207
                        $type_env, "<envar>\$1</envar>",
 
208
                        $type_param, "<parameter>\$1</parameter>" );
 
209
my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
 
210
 
 
211
# gnome, docbook format
 
212
my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
 
213
                         $type_func, "<function>\$1</function>",
 
214
                         $type_struct, "<structname>\$1</structname>",
 
215
                         $type_env, "<envar>\$1</envar>",
 
216
                         $type_param, "<parameter>\$1</parameter>" );
 
217
my $blankline_gnome = "</para><para>\n";
 
218
 
 
219
# these are pretty rough
 
220
my %highlights_man = ( $type_constant, "\$1",
 
221
                       $type_func, "\\\\fB\$1\\\\fP",
 
222
                       $type_struct, "\\\\fI\$1\\\\fP",
 
223
                       $type_param, "\\\\fI\$1\\\\fP" );
 
224
my $blankline_man = "";
 
225
 
 
226
# text-mode
 
227
my %highlights_text = ( $type_constant, "\$1",
 
228
                        $type_func, "\$1",
 
229
                        $type_struct, "\$1",
 
230
                        $type_param, "\$1" );
 
231
my $blankline_text = "";
 
232
 
 
233
# list mode
 
234
my %highlights_list = ( $type_constant, "\$1",
 
235
                        $type_func, "\$1",
 
236
                        $type_struct, "\$1",
 
237
                        $type_param, "\$1" );
 
238
my $blankline_list = "";
 
239
 
 
240
# read arguments
 
241
if ($#ARGV == -1) {
 
242
    usage();
 
243
}
 
244
 
 
245
my $kernelversion;
 
246
my $dohighlight = "";
 
247
 
 
248
my $verbose = 0;
 
249
my $output_mode = "man";
 
250
my $output_preformatted = 0;
 
251
my $no_doc_sections = 0;
 
252
my %highlights = %highlights_man;
 
253
my $blankline = $blankline_man;
 
254
my $modulename = "Bootloader API";
 
255
my $function_only = 0;
 
256
my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
 
257
                'July', 'August', 'September', 'October',
 
258
                'November', 'December')[(localtime)[4]] .
 
259
  " " . ((localtime)[5]+1900);
 
260
my $show_not_found = 0;
 
261
 
 
262
# Essentially these are globals.
 
263
# They probably want to be tidied up, made more localised or something.
 
264
# CAVEAT EMPTOR!  Some of the others I localised may not want to be, which
 
265
# could cause "use of undefined value" or other bugs.
 
266
my ($function, %function_table, %parametertypes, $declaration_purpose);
 
267
my ($type, $declaration_name, $return_type);
 
268
my ($newsection, $newcontents, $prototype, $brcount, %source_map);
 
269
 
 
270
if (defined($ENV{'KBUILD_VERBOSE'})) {
 
271
        $verbose = "$ENV{'KBUILD_VERBOSE'}";
 
272
}
 
273
 
 
274
# Generated docbook code is inserted in a template at a point where
 
275
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
 
276
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
 
277
# We keep track of number of generated entries and generate a dummy
 
278
# if needs be to ensure the expanded template can be postprocessed
 
279
# into html.
 
280
my $section_counter = 0;
 
281
 
 
282
my $lineprefix="";
 
283
 
 
284
# states
 
285
# 0 - normal code
 
286
# 1 - looking for function name
 
287
# 2 - scanning field start.
 
288
# 3 - scanning prototype.
 
289
# 4 - documentation block
 
290
my $state;
 
291
my $in_doc_sect;
 
292
 
 
293
#declaration types: can be
 
294
# 'function', 'struct', 'union', 'enum', 'typedef'
 
295
my $decl_type;
 
296
 
 
297
my $doc_special = "\@\%\$\&";
 
298
 
 
299
my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
 
300
my $doc_end = '\*/';
 
301
my $doc_com = '\s*\*\s*';
 
302
my $doc_com_body = '\s*\* ?';
 
303
my $doc_decl = $doc_com . '(\w+)';
 
304
my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)';
 
305
my $doc_content = $doc_com_body . '(.*)';
 
306
my $doc_block = $doc_com . 'DOC:\s*(.*)?';
 
307
 
 
308
my %constants;
 
309
my %parameterdescs;
 
310
my @parameterlist;
 
311
my %sections;
 
312
my @sectionlist;
 
313
my $sectcheck;
 
314
my $struct_actual;
 
315
 
 
316
my $contents = "";
 
317
my $section_default = "Description";    # default section
 
318
my $section_intro = "Introduction";
 
319
my $section = $section_default;
 
320
my $section_context = "Context";
 
321
my $section_return = "Return";
 
322
 
 
323
my $undescribed = "-- undescribed --";
 
324
 
 
325
reset_state();
 
326
 
 
327
while ($ARGV[0] =~ m/^-(.*)/) {
 
328
    my $cmd = shift @ARGV;
 
329
    if ($cmd eq "-html") {
 
330
        $output_mode = "html";
 
331
        %highlights = %highlights_html;
 
332
        $blankline = $blankline_html;
 
333
    } elsif ($cmd eq "-html5") {
 
334
        $output_mode = "html5";
 
335
        %highlights = %highlights_html5;
 
336
        $blankline = $blankline_html5;
 
337
    } elsif ($cmd eq "-man") {
 
338
        $output_mode = "man";
 
339
        %highlights = %highlights_man;
 
340
        $blankline = $blankline_man;
 
341
    } elsif ($cmd eq "-text") {
 
342
        $output_mode = "text";
 
343
        %highlights = %highlights_text;
 
344
        $blankline = $blankline_text;
 
345
    } elsif ($cmd eq "-docbook") {
 
346
        $output_mode = "xml";
 
347
        %highlights = %highlights_xml;
 
348
        $blankline = $blankline_xml;
 
349
    } elsif ($cmd eq "-list") {
 
350
        $output_mode = "list";
 
351
        %highlights = %highlights_list;
 
352
        $blankline = $blankline_list;
 
353
    } elsif ($cmd eq "-gnome") {
 
354
        $output_mode = "gnome";
 
355
        %highlights = %highlights_gnome;
 
356
        $blankline = $blankline_gnome;
 
357
    } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
 
358
        $modulename = shift @ARGV;
 
359
    } elsif ($cmd eq "-function") { # to only output specific functions
 
360
        $function_only = 1;
 
361
        $function = shift @ARGV;
 
362
        $function_table{$function} = 1;
 
363
    } elsif ($cmd eq "-nofunction") { # to only output specific functions
 
364
        $function_only = 2;
 
365
        $function = shift @ARGV;
 
366
        $function_table{$function} = 1;
 
367
    } elsif ($cmd eq "-v") {
 
368
        $verbose = 1;
 
369
    } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
 
370
        usage();
 
371
    } elsif ($cmd eq '-no-doc-sections') {
 
372
            $no_doc_sections = 1;
 
373
    } elsif ($cmd eq '-show-not-found') {
 
374
        $show_not_found = 1;
 
375
    }
 
376
}
 
377
 
 
378
# continue execution near EOF;
 
379
 
 
380
sub usage {
 
381
    print "Usage: $0 [ -docbook | -html | -html5 | -text | -man | -list ]\n";
 
382
    print "         [ -no-doc-sections ]\n";
 
383
    print "         [ -function funcname [ -function funcname ...] ]\n";
 
384
    print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
 
385
    print "         [ -v ]\n";
 
386
    print "         c source file(s) > outputfile\n";
 
387
    print "         -v : verbose output, more warnings & other info listed\n";
 
388
    exit 1;
 
389
}
 
390
 
 
391
# get kernel version from env
 
392
sub get_kernel_version() {
 
393
    my $version = 'unknown kernel version';
 
394
 
 
395
    if (defined($ENV{'UBOOTVERSION'})) {
 
396
        $version = $ENV{'UBOOTVERSION'};
 
397
    }
 
398
    return $version;
 
399
}
 
400
 
 
401
##
 
402
# dumps section contents to arrays/hashes intended for that purpose.
 
403
#
 
404
sub dump_section {
 
405
    my $file = shift;
 
406
    my $name = shift;
 
407
    my $contents = join "\n", @_;
 
408
 
 
409
    if ($name =~ m/$type_constant/) {
 
410
        $name = $1;
 
411
#       print STDERR "constant section '$1' = '$contents'\n";
 
412
        $constants{$name} = $contents;
 
413
    } elsif ($name =~ m/$type_param/) {
 
414
#       print STDERR "parameter def '$1' = '$contents'\n";
 
415
        $name = $1;
 
416
        $parameterdescs{$name} = $contents;
 
417
        $sectcheck = $sectcheck . $name . " ";
 
418
    } elsif ($name eq "@\.\.\.") {
 
419
#       print STDERR "parameter def '...' = '$contents'\n";
 
420
        $name = "...";
 
421
        $parameterdescs{$name} = $contents;
 
422
        $sectcheck = $sectcheck . $name . " ";
 
423
    } else {
 
424
#       print STDERR "other section '$name' = '$contents'\n";
 
425
        if (defined($sections{$name}) && ($sections{$name} ne "")) {
 
426
                print STDERR "Error(${file}:$.): duplicate section name '$name'\n";
 
427
                ++$errors;
 
428
        }
 
429
        $sections{$name} = $contents;
 
430
        push @sectionlist, $name;
 
431
    }
 
432
}
 
433
 
 
434
##
 
435
# dump DOC: section after checking that it should go out
 
436
#
 
437
sub dump_doc_section {
 
438
    my $file = shift;
 
439
    my $name = shift;
 
440
    my $contents = join "\n", @_;
 
441
 
 
442
    if ($no_doc_sections) {
 
443
        return;
 
444
    }
 
445
 
 
446
    if (($function_only == 0) ||
 
447
        ( $function_only == 1 && defined($function_table{$name})) ||
 
448
        ( $function_only == 2 && !defined($function_table{$name})))
 
449
    {
 
450
        dump_section($file, $name, $contents);
 
451
        output_blockhead({'sectionlist' => \@sectionlist,
 
452
                          'sections' => \%sections,
 
453
                          'module' => $modulename,
 
454
                          'content-only' => ($function_only != 0), });
 
455
    }
 
456
}
 
457
 
 
458
##
 
459
# output function
 
460
#
 
461
# parameterdescs, a hash.
 
462
#  function => "function name"
 
463
#  parameterlist => @list of parameters
 
464
#  parameterdescs => %parameter descriptions
 
465
#  sectionlist => @list of sections
 
466
#  sections => %section descriptions
 
467
#
 
468
 
 
469
sub output_highlight {
 
470
    my $contents = join "\n",@_;
 
471
    my $line;
 
472
 
 
473
#   DEBUG
 
474
#   if (!defined $contents) {
 
475
#       use Carp;
 
476
#       confess "output_highlight got called with no args?\n";
 
477
#   }
 
478
 
 
479
    if ($output_mode eq "html" || $output_mode eq "html5" ||
 
480
        $output_mode eq "xml") {
 
481
        $contents = local_unescape($contents);
 
482
        # convert data read & converted thru xml_escape() into &xyz; format:
 
483
        $contents =~ s/\\\\\\/\&/g;
 
484
    }
 
485
#   print STDERR "contents b4:$contents\n";
 
486
    eval $dohighlight;
 
487
    die $@ if $@;
 
488
#   print STDERR "contents af:$contents\n";
 
489
 
 
490
#   strip whitespaces when generating html5
 
491
    if ($output_mode eq "html5") {
 
492
        $contents =~ s/^\s+//;
 
493
        $contents =~ s/\s+$//;
 
494
    }
 
495
    foreach $line (split "\n", $contents) {
 
496
        if (! $output_preformatted) {
 
497
            $line =~ s/^\s*//;
 
498
        }
 
499
        if ($line eq ""){
 
500
            if (! $output_preformatted) {
 
501
                print $lineprefix, local_unescape($blankline);
 
502
            }
 
503
        } else {
 
504
            $line =~ s/\\\\\\/\&/g;
 
505
            if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
 
506
                print "\\&$line";
 
507
            } else {
 
508
                print $lineprefix, $line;
 
509
            }
 
510
        }
 
511
        print "\n";
 
512
    }
 
513
}
 
514
 
 
515
# output sections in html
 
516
sub output_section_html(%) {
 
517
    my %args = %{$_[0]};
 
518
    my $section;
 
519
 
 
520
    foreach $section (@{$args{'sectionlist'}}) {
 
521
        print "<h3>$section</h3>\n";
 
522
        print "<blockquote>\n";
 
523
        output_highlight($args{'sections'}{$section});
 
524
        print "</blockquote>\n";
 
525
    }
 
526
}
 
527
 
 
528
# output enum in html
 
529
sub output_enum_html(%) {
 
530
    my %args = %{$_[0]};
 
531
    my ($parameter);
 
532
    my $count;
 
533
    print "<h2>enum " . $args{'enum'} . "</h2>\n";
 
534
 
 
535
    print "<b>enum " . $args{'enum'} . "</b> {<br>\n";
 
536
    $count = 0;
 
537
    foreach $parameter (@{$args{'parameterlist'}}) {
 
538
        print " <b>" . $parameter . "</b>";
 
539
        if ($count != $#{$args{'parameterlist'}}) {
 
540
            $count++;
 
541
            print ",\n";
 
542
        }
 
543
        print "<br>";
 
544
    }
 
545
    print "};<br>\n";
 
546
 
 
547
    print "<h3>Constants</h3>\n";
 
548
    print "<dl>\n";
 
549
    foreach $parameter (@{$args{'parameterlist'}}) {
 
550
        print "<dt><b>" . $parameter . "</b>\n";
 
551
        print "<dd>";
 
552
        output_highlight($args{'parameterdescs'}{$parameter});
 
553
    }
 
554
    print "</dl>\n";
 
555
    output_section_html(@_);
 
556
    print "<hr>\n";
 
557
}
 
558
 
 
559
# output typedef in html
 
560
sub output_typedef_html(%) {
 
561
    my %args = %{$_[0]};
 
562
    my ($parameter);
 
563
    my $count;
 
564
    print "<h2>typedef " . $args{'typedef'} . "</h2>\n";
 
565
 
 
566
    print "<b>typedef " . $args{'typedef'} . "</b>\n";
 
567
    output_section_html(@_);
 
568
    print "<hr>\n";
 
569
}
 
570
 
 
571
# output struct in html
 
572
sub output_struct_html(%) {
 
573
    my %args = %{$_[0]};
 
574
    my ($parameter);
 
575
 
 
576
    print "<h2>" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "</h2>\n";
 
577
    print "<b>" . $args{'type'} . " " . $args{'struct'} . "</b> {<br>\n";
 
578
    foreach $parameter (@{$args{'parameterlist'}}) {
 
579
        if ($parameter =~ /^#/) {
 
580
                print "$parameter<br>\n";
 
581
                next;
 
582
        }
 
583
        my $parameter_name = $parameter;
 
584
        $parameter_name =~ s/\[.*//;
 
585
 
 
586
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
587
        $type = $args{'parametertypes'}{$parameter};
 
588
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
589
            # pointer-to-function
 
590
            print "&nbsp; &nbsp; <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
 
591
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
 
592
            # bitfield
 
593
            print "&nbsp; &nbsp; <i>$1</i> <b>$parameter</b>$2;<br>\n";
 
594
        } else {
 
595
            print "&nbsp; &nbsp; <i>$type</i> <b>$parameter</b>;<br>\n";
 
596
        }
 
597
    }
 
598
    print "};<br>\n";
 
599
 
 
600
    print "<h3>Members</h3>\n";
 
601
    print "<dl>\n";
 
602
    foreach $parameter (@{$args{'parameterlist'}}) {
 
603
        ($parameter =~ /^#/) && next;
 
604
 
 
605
        my $parameter_name = $parameter;
 
606
        $parameter_name =~ s/\[.*//;
 
607
 
 
608
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
609
        print "<dt><b>" . $parameter . "</b>\n";
 
610
        print "<dd>";
 
611
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
612
    }
 
613
    print "</dl>\n";
 
614
    output_section_html(@_);
 
615
    print "<hr>\n";
 
616
}
 
617
 
 
618
# output function in html
 
619
sub output_function_html(%) {
 
620
    my %args = %{$_[0]};
 
621
    my ($parameter, $section);
 
622
    my $count;
 
623
 
 
624
    print "<h2>" . $args{'function'} . " - " . $args{'purpose'} . "</h2>\n";
 
625
    print "<i>" . $args{'functiontype'} . "</i>\n";
 
626
    print "<b>" . $args{'function'} . "</b>\n";
 
627
    print "(";
 
628
    $count = 0;
 
629
    foreach $parameter (@{$args{'parameterlist'}}) {
 
630
        $type = $args{'parametertypes'}{$parameter};
 
631
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
632
            # pointer-to-function
 
633
            print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
 
634
        } else {
 
635
            print "<i>" . $type . "</i> <b>" . $parameter . "</b>";
 
636
        }
 
637
        if ($count != $#{$args{'parameterlist'}}) {
 
638
            $count++;
 
639
            print ",\n";
 
640
        }
 
641
    }
 
642
    print ")\n";
 
643
 
 
644
    print "<h3>Arguments</h3>\n";
 
645
    print "<dl>\n";
 
646
    foreach $parameter (@{$args{'parameterlist'}}) {
 
647
        my $parameter_name = $parameter;
 
648
        $parameter_name =~ s/\[.*//;
 
649
 
 
650
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
651
        print "<dt><b>" . $parameter . "</b>\n";
 
652
        print "<dd>";
 
653
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
654
    }
 
655
    print "</dl>\n";
 
656
    output_section_html(@_);
 
657
    print "<hr>\n";
 
658
}
 
659
 
 
660
# output DOC: block header in html
 
661
sub output_blockhead_html(%) {
 
662
    my %args = %{$_[0]};
 
663
    my ($parameter, $section);
 
664
    my $count;
 
665
 
 
666
    foreach $section (@{$args{'sectionlist'}}) {
 
667
        print "<h3>$section</h3>\n";
 
668
        print "<ul>\n";
 
669
        output_highlight($args{'sections'}{$section});
 
670
        print "</ul>\n";
 
671
    }
 
672
    print "<hr>\n";
 
673
}
 
674
 
 
675
# output sections in html5
 
676
sub output_section_html5(%) {
 
677
    my %args = %{$_[0]};
 
678
    my $section;
 
679
 
 
680
    foreach $section (@{$args{'sectionlist'}}) {
 
681
        print "<section>\n";
 
682
        print "<h1>$section</h1>\n";
 
683
        print "<p>\n";
 
684
        output_highlight($args{'sections'}{$section});
 
685
        print "</p>\n";
 
686
        print "</section>\n";
 
687
    }
 
688
}
 
689
 
 
690
# output enum in html5
 
691
sub output_enum_html5(%) {
 
692
    my %args = %{$_[0]};
 
693
    my ($parameter);
 
694
    my $count;
 
695
    my $html5id;
 
696
 
 
697
    $html5id = $args{'enum'};
 
698
    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
 
699
    print "<article class=\"enum\" id=\"enum:". $html5id . "\">";
 
700
    print "<h1>enum " . $args{'enum'} . "</h1>\n";
 
701
    print "<ol class=\"code\">\n";
 
702
    print "<li>";
 
703
    print "<span class=\"keyword\">enum</span> ";
 
704
    print "<span class=\"identifier\">" . $args{'enum'} . "</span> {";
 
705
    print "</li>\n";
 
706
    $count = 0;
 
707
    foreach $parameter (@{$args{'parameterlist'}}) {
 
708
        print "<li class=\"indent\">";
 
709
        print "<span class=\"param\">" . $parameter . "</span>";
 
710
        if ($count != $#{$args{'parameterlist'}}) {
 
711
            $count++;
 
712
            print ",";
 
713
        }
 
714
        print "</li>\n";
 
715
    }
 
716
    print "<li>};</li>\n";
 
717
    print "</ol>\n";
 
718
 
 
719
    print "<section>\n";
 
720
    print "<h1>Constants</h1>\n";
 
721
    print "<dl>\n";
 
722
    foreach $parameter (@{$args{'parameterlist'}}) {
 
723
        print "<dt>" . $parameter . "</dt>\n";
 
724
        print "<dd>";
 
725
        output_highlight($args{'parameterdescs'}{$parameter});
 
726
        print "</dd>\n";
 
727
    }
 
728
    print "</dl>\n";
 
729
    print "</section>\n";
 
730
    output_section_html5(@_);
 
731
    print "</article>\n";
 
732
}
 
733
 
 
734
# output typedef in html5
 
735
sub output_typedef_html5(%) {
 
736
    my %args = %{$_[0]};
 
737
    my ($parameter);
 
738
    my $count;
 
739
    my $html5id;
 
740
 
 
741
    $html5id = $args{'typedef'};
 
742
    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
 
743
    print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n";
 
744
    print "<h1>typedef " . $args{'typedef'} . "</h1>\n";
 
745
 
 
746
    print "<ol class=\"code\">\n";
 
747
    print "<li>";
 
748
    print "<span class=\"keyword\">typedef</span> ";
 
749
    print "<span class=\"identifier\">" . $args{'typedef'} . "</span>";
 
750
    print "</li>\n";
 
751
    print "</ol>\n";
 
752
    output_section_html5(@_);
 
753
    print "</article>\n";
 
754
}
 
755
 
 
756
# output struct in html5
 
757
sub output_struct_html5(%) {
 
758
    my %args = %{$_[0]};
 
759
    my ($parameter);
 
760
    my $html5id;
 
761
 
 
762
    $html5id = $args{'struct'};
 
763
    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
 
764
    print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n";
 
765
    print "<hgroup>\n";
 
766
    print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>";
 
767
    print "<h2>". $args{'purpose'} . "</h2>\n";
 
768
    print "</hgroup>\n";
 
769
    print "<ol class=\"code\">\n";
 
770
    print "<li>";
 
771
    print "<span class=\"type\">" . $args{'type'} . "</span> ";
 
772
    print "<span class=\"identifier\">" . $args{'struct'} . "</span> {";
 
773
    print "</li>\n";
 
774
    foreach $parameter (@{$args{'parameterlist'}}) {
 
775
        print "<li class=\"indent\">";
 
776
        if ($parameter =~ /^#/) {
 
777
                print "<span class=\"param\">" . $parameter ."</span>\n";
 
778
                print "</li>\n";
 
779
                next;
 
780
        }
 
781
        my $parameter_name = $parameter;
 
782
        $parameter_name =~ s/\[.*//;
 
783
 
 
784
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
785
        $type = $args{'parametertypes'}{$parameter};
 
786
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
787
            # pointer-to-function
 
788
            print "<span class=\"type\">$1</span> ";
 
789
            print "<span class=\"param\">$parameter</span>";
 
790
            print "<span class=\"type\">)</span> ";
 
791
            print "(<span class=\"args\">$2</span>);";
 
792
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
 
793
            # bitfield
 
794
            print "<span class=\"type\">$1</span> ";
 
795
            print "<span class=\"param\">$parameter</span>";
 
796
            print "<span class=\"bits\">$2</span>;";
 
797
        } else {
 
798
            print "<span class=\"type\">$type</span> ";
 
799
            print "<span class=\"param\">$parameter</span>;";
 
800
        }
 
801
        print "</li>\n";
 
802
    }
 
803
    print "<li>};</li>\n";
 
804
    print "</ol>\n";
 
805
 
 
806
    print "<section>\n";
 
807
    print "<h1>Members</h1>\n";
 
808
    print "<dl>\n";
 
809
    foreach $parameter (@{$args{'parameterlist'}}) {
 
810
        ($parameter =~ /^#/) && next;
 
811
 
 
812
        my $parameter_name = $parameter;
 
813
        $parameter_name =~ s/\[.*//;
 
814
 
 
815
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
816
        print "<dt>" . $parameter . "</dt>\n";
 
817
        print "<dd>";
 
818
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
819
        print "</dd>\n";
 
820
    }
 
821
    print "</dl>\n";
 
822
    print "</section>\n";
 
823
    output_section_html5(@_);
 
824
    print "</article>\n";
 
825
}
 
826
 
 
827
# output function in html5
 
828
sub output_function_html5(%) {
 
829
    my %args = %{$_[0]};
 
830
    my ($parameter, $section);
 
831
    my $count;
 
832
    my $html5id;
 
833
 
 
834
    $html5id = $args{'function'};
 
835
    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
 
836
    print "<article class=\"function\" id=\"func:". $html5id . "\">\n";
 
837
    print "<hgroup>\n";
 
838
    print "<h1>" . $args{'function'} . "</h1>";
 
839
    print "<h2>" . $args{'purpose'} . "</h2>\n";
 
840
    print "</hgroup>\n";
 
841
    print "<ol class=\"code\">\n";
 
842
    print "<li>";
 
843
    print "<span class=\"type\">" . $args{'functiontype'} . "</span> ";
 
844
    print "<span class=\"identifier\">" . $args{'function'} . "</span> (";
 
845
    print "</li>";
 
846
    $count = 0;
 
847
    foreach $parameter (@{$args{'parameterlist'}}) {
 
848
        print "<li class=\"indent\">";
 
849
        $type = $args{'parametertypes'}{$parameter};
 
850
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
851
            # pointer-to-function
 
852
            print "<span class=\"type\">$1</span> ";
 
853
            print "<span class=\"param\">$parameter</span>";
 
854
            print "<span class=\"type\">)</span> ";
 
855
            print "(<span class=\"args\">$2</span>)";
 
856
        } else {
 
857
            print "<span class=\"type\">$type</span> ";
 
858
            print "<span class=\"param\">$parameter</span>";
 
859
        }
 
860
        if ($count != $#{$args{'parameterlist'}}) {
 
861
            $count++;
 
862
            print ",";
 
863
        }
 
864
        print "</li>\n";
 
865
    }
 
866
    print "<li>)</li>\n";
 
867
    print "</ol>\n";
 
868
 
 
869
    print "<section>\n";
 
870
    print "<h1>Arguments</h1>\n";
 
871
    print "<p>\n";
 
872
    print "<dl>\n";
 
873
    foreach $parameter (@{$args{'parameterlist'}}) {
 
874
        my $parameter_name = $parameter;
 
875
        $parameter_name =~ s/\[.*//;
 
876
 
 
877
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
878
        print "<dt>" . $parameter . "</dt>\n";
 
879
        print "<dd>";
 
880
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
881
        print "</dd>\n";
 
882
    }
 
883
    print "</dl>\n";
 
884
    print "</section>\n";
 
885
    output_section_html5(@_);
 
886
    print "</article>\n";
 
887
}
 
888
 
 
889
# output DOC: block header in html5
 
890
sub output_blockhead_html5(%) {
 
891
    my %args = %{$_[0]};
 
892
    my ($parameter, $section);
 
893
    my $count;
 
894
    my $html5id;
 
895
 
 
896
    foreach $section (@{$args{'sectionlist'}}) {
 
897
        $html5id = $section;
 
898
        $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
 
899
        print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n";
 
900
        print "<h1>$section</h1>\n";
 
901
        print "<p>\n";
 
902
        output_highlight($args{'sections'}{$section});
 
903
        print "</p>\n";
 
904
    }
 
905
    print "</article>\n";
 
906
}
 
907
 
 
908
sub output_section_xml(%) {
 
909
    my %args = %{$_[0]};
 
910
    my $section;
 
911
    # print out each section
 
912
    $lineprefix="   ";
 
913
    foreach $section (@{$args{'sectionlist'}}) {
 
914
        print "<refsect1>\n";
 
915
        print "<title>$section</title>\n";
 
916
        if ($section =~ m/EXAMPLE/i) {
 
917
            print "<informalexample><programlisting>\n";
 
918
            $output_preformatted = 1;
 
919
        } else {
 
920
            print "<para>\n";
 
921
        }
 
922
        output_highlight($args{'sections'}{$section});
 
923
        $output_preformatted = 0;
 
924
        if ($section =~ m/EXAMPLE/i) {
 
925
            print "</programlisting></informalexample>\n";
 
926
        } else {
 
927
            print "</para>\n";
 
928
        }
 
929
        print "</refsect1>\n";
 
930
    }
 
931
}
 
932
 
 
933
# output function in XML DocBook
 
934
sub output_function_xml(%) {
 
935
    my %args = %{$_[0]};
 
936
    my ($parameter, $section);
 
937
    my $count;
 
938
    my $id;
 
939
 
 
940
    $id = "API-" . $args{'function'};
 
941
    $id =~ s/[^A-Za-z0-9]/-/g;
 
942
 
 
943
    print "<refentry id=\"$id\">\n";
 
944
    print "<refentryinfo>\n";
 
945
    print " <title>U-BOOT</title>\n";
 
946
    print " <productname>Bootloader Hackers Manual</productname>\n";
 
947
    print " <date>$man_date</date>\n";
 
948
    print "</refentryinfo>\n";
 
949
    print "<refmeta>\n";
 
950
    print " <refentrytitle><phrase>" . $args{'function'} . "</phrase></refentrytitle>\n";
 
951
    print " <manvolnum>9</manvolnum>\n";
 
952
    print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
 
953
    print "</refmeta>\n";
 
954
    print "<refnamediv>\n";
 
955
    print " <refname>" . $args{'function'} . "</refname>\n";
 
956
    print " <refpurpose>\n";
 
957
    print "  ";
 
958
    output_highlight ($args{'purpose'});
 
959
    print " </refpurpose>\n";
 
960
    print "</refnamediv>\n";
 
961
 
 
962
    print "<refsynopsisdiv>\n";
 
963
    print " <title>Synopsis</title>\n";
 
964
    print "  <funcsynopsis><funcprototype>\n";
 
965
    print "   <funcdef>" . $args{'functiontype'} . " ";
 
966
    print "<function>" . $args{'function'} . " </function></funcdef>\n";
 
967
 
 
968
    $count = 0;
 
969
    if ($#{$args{'parameterlist'}} >= 0) {
 
970
        foreach $parameter (@{$args{'parameterlist'}}) {
 
971
            $type = $args{'parametertypes'}{$parameter};
 
972
            if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
973
                # pointer-to-function
 
974
                print "   <paramdef>$1<parameter>$parameter</parameter>)\n";
 
975
                print "     <funcparams>$2</funcparams></paramdef>\n";
 
976
            } else {
 
977
                print "   <paramdef>" . $type;
 
978
                print " <parameter>$parameter</parameter></paramdef>\n";
 
979
            }
 
980
        }
 
981
    } else {
 
982
        print "  <void/>\n";
 
983
    }
 
984
    print "  </funcprototype></funcsynopsis>\n";
 
985
    print "</refsynopsisdiv>\n";
 
986
 
 
987
    # print parameters
 
988
    print "<refsect1>\n <title>Arguments</title>\n";
 
989
    if ($#{$args{'parameterlist'}} >= 0) {
 
990
        print " <variablelist>\n";
 
991
        foreach $parameter (@{$args{'parameterlist'}}) {
 
992
            my $parameter_name = $parameter;
 
993
            $parameter_name =~ s/\[.*//;
 
994
 
 
995
            print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
 
996
            print "   <listitem>\n    <para>\n";
 
997
            $lineprefix="     ";
 
998
            output_highlight($args{'parameterdescs'}{$parameter_name});
 
999
            print "    </para>\n   </listitem>\n  </varlistentry>\n";
 
1000
        }
 
1001
        print " </variablelist>\n";
 
1002
    } else {
 
1003
        print " <para>\n  None\n </para>\n";
 
1004
    }
 
1005
    print "</refsect1>\n";
 
1006
 
 
1007
    output_section_xml(@_);
 
1008
    print "</refentry>\n\n";
 
1009
}
 
1010
 
 
1011
# output struct in XML DocBook
 
1012
sub output_struct_xml(%) {
 
1013
    my %args = %{$_[0]};
 
1014
    my ($parameter, $section);
 
1015
    my $id;
 
1016
 
 
1017
    $id = "API-struct-" . $args{'struct'};
 
1018
    $id =~ s/[^A-Za-z0-9]/-/g;
 
1019
 
 
1020
    print "<refentry id=\"$id\">\n";
 
1021
    print "<refentryinfo>\n";
 
1022
    print " <title>U-BOOT</title>\n";
 
1023
    print " <productname>Bootloader Hackers Manual</productname>\n";
 
1024
    print " <date>$man_date</date>\n";
 
1025
    print "</refentryinfo>\n";
 
1026
    print "<refmeta>\n";
 
1027
    print " <refentrytitle><phrase>" . $args{'type'} . " " . $args{'struct'} . "</phrase></refentrytitle>\n";
 
1028
    print " <manvolnum>9</manvolnum>\n";
 
1029
    print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
 
1030
    print "</refmeta>\n";
 
1031
    print "<refnamediv>\n";
 
1032
    print " <refname>" . $args{'type'} . " " . $args{'struct'} . "</refname>\n";
 
1033
    print " <refpurpose>\n";
 
1034
    print "  ";
 
1035
    output_highlight ($args{'purpose'});
 
1036
    print " </refpurpose>\n";
 
1037
    print "</refnamediv>\n";
 
1038
 
 
1039
    print "<refsynopsisdiv>\n";
 
1040
    print " <title>Synopsis</title>\n";
 
1041
    print "  <programlisting>\n";
 
1042
    print $args{'type'} . " " . $args{'struct'} . " {\n";
 
1043
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1044
        if ($parameter =~ /^#/) {
 
1045
            my $prm = $parameter;
 
1046
            # convert data read & converted thru xml_escape() into &xyz; format:
 
1047
            # This allows us to have #define macros interspersed in a struct.
 
1048
            $prm =~ s/\\\\\\/\&/g;
 
1049
            print "$prm\n";
 
1050
            next;
 
1051
        }
 
1052
 
 
1053
        my $parameter_name = $parameter;
 
1054
        $parameter_name =~ s/\[.*//;
 
1055
 
 
1056
        defined($args{'parameterdescs'}{$parameter_name}) || next;
 
1057
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1058
        $type = $args{'parametertypes'}{$parameter};
 
1059
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1060
            # pointer-to-function
 
1061
            print "  $1 $parameter) ($2);\n";
 
1062
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
 
1063
            # bitfield
 
1064
            print "  $1 $parameter$2;\n";
 
1065
        } else {
 
1066
            print "  " . $type . " " . $parameter . ";\n";
 
1067
        }
 
1068
    }
 
1069
    print "};";
 
1070
    print "  </programlisting>\n";
 
1071
    print "</refsynopsisdiv>\n";
 
1072
 
 
1073
    print " <refsect1>\n";
 
1074
    print "  <title>Members</title>\n";
 
1075
 
 
1076
    if ($#{$args{'parameterlist'}} >= 0) {
 
1077
    print "  <variablelist>\n";
 
1078
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1079
      ($parameter =~ /^#/) && next;
 
1080
 
 
1081
      my $parameter_name = $parameter;
 
1082
      $parameter_name =~ s/\[.*//;
 
1083
 
 
1084
      defined($args{'parameterdescs'}{$parameter_name}) || next;
 
1085
      ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1086
      print "    <varlistentry>";
 
1087
      print "      <term>$parameter</term>\n";
 
1088
      print "      <listitem><para>\n";
 
1089
      output_highlight($args{'parameterdescs'}{$parameter_name});
 
1090
      print "      </para></listitem>\n";
 
1091
      print "    </varlistentry>\n";
 
1092
    }
 
1093
    print "  </variablelist>\n";
 
1094
    } else {
 
1095
        print " <para>\n  None\n </para>\n";
 
1096
    }
 
1097
    print " </refsect1>\n";
 
1098
 
 
1099
    output_section_xml(@_);
 
1100
 
 
1101
    print "</refentry>\n\n";
 
1102
}
 
1103
 
 
1104
# output enum in XML DocBook
 
1105
sub output_enum_xml(%) {
 
1106
    my %args = %{$_[0]};
 
1107
    my ($parameter, $section);
 
1108
    my $count;
 
1109
    my $id;
 
1110
 
 
1111
    $id = "API-enum-" . $args{'enum'};
 
1112
    $id =~ s/[^A-Za-z0-9]/-/g;
 
1113
 
 
1114
    print "<refentry id=\"$id\">\n";
 
1115
    print "<refentryinfo>\n";
 
1116
    print " <title>U-BOOT</title>\n";
 
1117
    print " <productname>Bootloader Hackers Manual</productname>\n";
 
1118
    print " <date>$man_date</date>\n";
 
1119
    print "</refentryinfo>\n";
 
1120
    print "<refmeta>\n";
 
1121
    print " <refentrytitle><phrase>enum " . $args{'enum'} . "</phrase></refentrytitle>\n";
 
1122
    print " <manvolnum>9</manvolnum>\n";
 
1123
    print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
 
1124
    print "</refmeta>\n";
 
1125
    print "<refnamediv>\n";
 
1126
    print " <refname>enum " . $args{'enum'} . "</refname>\n";
 
1127
    print " <refpurpose>\n";
 
1128
    print "  ";
 
1129
    output_highlight ($args{'purpose'});
 
1130
    print " </refpurpose>\n";
 
1131
    print "</refnamediv>\n";
 
1132
 
 
1133
    print "<refsynopsisdiv>\n";
 
1134
    print " <title>Synopsis</title>\n";
 
1135
    print "  <programlisting>\n";
 
1136
    print "enum " . $args{'enum'} . " {\n";
 
1137
    $count = 0;
 
1138
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1139
        print "  $parameter";
 
1140
        if ($count != $#{$args{'parameterlist'}}) {
 
1141
            $count++;
 
1142
            print ",";
 
1143
        }
 
1144
        print "\n";
 
1145
    }
 
1146
    print "};";
 
1147
    print "  </programlisting>\n";
 
1148
    print "</refsynopsisdiv>\n";
 
1149
 
 
1150
    print "<refsect1>\n";
 
1151
    print " <title>Constants</title>\n";
 
1152
    print "  <variablelist>\n";
 
1153
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1154
      my $parameter_name = $parameter;
 
1155
      $parameter_name =~ s/\[.*//;
 
1156
 
 
1157
      print "    <varlistentry>";
 
1158
      print "      <term>$parameter</term>\n";
 
1159
      print "      <listitem><para>\n";
 
1160
      output_highlight($args{'parameterdescs'}{$parameter_name});
 
1161
      print "      </para></listitem>\n";
 
1162
      print "    </varlistentry>\n";
 
1163
    }
 
1164
    print "  </variablelist>\n";
 
1165
    print "</refsect1>\n";
 
1166
 
 
1167
    output_section_xml(@_);
 
1168
 
 
1169
    print "</refentry>\n\n";
 
1170
}
 
1171
 
 
1172
# output typedef in XML DocBook
 
1173
sub output_typedef_xml(%) {
 
1174
    my %args = %{$_[0]};
 
1175
    my ($parameter, $section);
 
1176
    my $id;
 
1177
 
 
1178
    $id = "API-typedef-" . $args{'typedef'};
 
1179
    $id =~ s/[^A-Za-z0-9]/-/g;
 
1180
 
 
1181
    print "<refentry id=\"$id\">\n";
 
1182
    print "<refentryinfo>\n";
 
1183
    print " <title>U-BOOT</title>\n";
 
1184
    print " <productname>Bootloader Hackers Manual</productname>\n";
 
1185
    print " <date>$man_date</date>\n";
 
1186
    print "</refentryinfo>\n";
 
1187
    print "<refmeta>\n";
 
1188
    print " <refentrytitle><phrase>typedef " . $args{'typedef'} . "</phrase></refentrytitle>\n";
 
1189
    print " <manvolnum>9</manvolnum>\n";
 
1190
    print "</refmeta>\n";
 
1191
    print "<refnamediv>\n";
 
1192
    print " <refname>typedef " . $args{'typedef'} . "</refname>\n";
 
1193
    print " <refpurpose>\n";
 
1194
    print "  ";
 
1195
    output_highlight ($args{'purpose'});
 
1196
    print " </refpurpose>\n";
 
1197
    print "</refnamediv>\n";
 
1198
 
 
1199
    print "<refsynopsisdiv>\n";
 
1200
    print " <title>Synopsis</title>\n";
 
1201
    print "  <synopsis>typedef " . $args{'typedef'} . ";</synopsis>\n";
 
1202
    print "</refsynopsisdiv>\n";
 
1203
 
 
1204
    output_section_xml(@_);
 
1205
 
 
1206
    print "</refentry>\n\n";
 
1207
}
 
1208
 
 
1209
# output in XML DocBook
 
1210
sub output_blockhead_xml(%) {
 
1211
    my %args = %{$_[0]};
 
1212
    my ($parameter, $section);
 
1213
    my $count;
 
1214
 
 
1215
    my $id = $args{'module'};
 
1216
    $id =~ s/[^A-Za-z0-9]/-/g;
 
1217
 
 
1218
    # print out each section
 
1219
    $lineprefix="   ";
 
1220
    foreach $section (@{$args{'sectionlist'}}) {
 
1221
        if (!$args{'content-only'}) {
 
1222
                print "<refsect1>\n <title>$section</title>\n";
 
1223
        }
 
1224
        if ($section =~ m/EXAMPLE/i) {
 
1225
            print "<example><para>\n";
 
1226
            $output_preformatted = 1;
 
1227
        } else {
 
1228
            print "<para>\n";
 
1229
        }
 
1230
        output_highlight($args{'sections'}{$section});
 
1231
        $output_preformatted = 0;
 
1232
        if ($section =~ m/EXAMPLE/i) {
 
1233
            print "</para></example>\n";
 
1234
        } else {
 
1235
            print "</para>";
 
1236
        }
 
1237
        if (!$args{'content-only'}) {
 
1238
                print "\n</refsect1>\n";
 
1239
        }
 
1240
    }
 
1241
 
 
1242
    print "\n\n";
 
1243
}
 
1244
 
 
1245
# output in XML DocBook
 
1246
sub output_function_gnome {
 
1247
    my %args = %{$_[0]};
 
1248
    my ($parameter, $section);
 
1249
    my $count;
 
1250
    my $id;
 
1251
 
 
1252
    $id = $args{'module'} . "-" . $args{'function'};
 
1253
    $id =~ s/[^A-Za-z0-9]/-/g;
 
1254
 
 
1255
    print "<sect2>\n";
 
1256
    print " <title id=\"$id\">" . $args{'function'} . "</title>\n";
 
1257
 
 
1258
    print "  <funcsynopsis>\n";
 
1259
    print "   <funcdef>" . $args{'functiontype'} . " ";
 
1260
    print "<function>" . $args{'function'} . " ";
 
1261
    print "</function></funcdef>\n";
 
1262
 
 
1263
    $count = 0;
 
1264
    if ($#{$args{'parameterlist'}} >= 0) {
 
1265
        foreach $parameter (@{$args{'parameterlist'}}) {
 
1266
            $type = $args{'parametertypes'}{$parameter};
 
1267
            if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1268
                # pointer-to-function
 
1269
                print "   <paramdef>$1 <parameter>$parameter</parameter>)\n";
 
1270
                print "     <funcparams>$2</funcparams></paramdef>\n";
 
1271
            } else {
 
1272
                print "   <paramdef>" . $type;
 
1273
                print " <parameter>$parameter</parameter></paramdef>\n";
 
1274
            }
 
1275
        }
 
1276
    } else {
 
1277
        print "  <void>\n";
 
1278
    }
 
1279
    print "  </funcsynopsis>\n";
 
1280
    if ($#{$args{'parameterlist'}} >= 0) {
 
1281
        print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
 
1282
        print "<tgroup cols=\"2\">\n";
 
1283
        print "<colspec colwidth=\"2*\">\n";
 
1284
        print "<colspec colwidth=\"8*\">\n";
 
1285
        print "<tbody>\n";
 
1286
        foreach $parameter (@{$args{'parameterlist'}}) {
 
1287
            my $parameter_name = $parameter;
 
1288
            $parameter_name =~ s/\[.*//;
 
1289
 
 
1290
            print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
 
1291
            print "   <entry>\n";
 
1292
            $lineprefix="     ";
 
1293
            output_highlight($args{'parameterdescs'}{$parameter_name});
 
1294
            print "    </entry></row>\n";
 
1295
        }
 
1296
        print " </tbody></tgroup></informaltable>\n";
 
1297
    } else {
 
1298
        print " <para>\n  None\n </para>\n";
 
1299
    }
 
1300
 
 
1301
    # print out each section
 
1302
    $lineprefix="   ";
 
1303
    foreach $section (@{$args{'sectionlist'}}) {
 
1304
        print "<simplesect>\n <title>$section</title>\n";
 
1305
        if ($section =~ m/EXAMPLE/i) {
 
1306
            print "<example><programlisting>\n";
 
1307
            $output_preformatted = 1;
 
1308
        } else {
 
1309
        }
 
1310
        print "<para>\n";
 
1311
        output_highlight($args{'sections'}{$section});
 
1312
        $output_preformatted = 0;
 
1313
        print "</para>\n";
 
1314
        if ($section =~ m/EXAMPLE/i) {
 
1315
            print "</programlisting></example>\n";
 
1316
        } else {
 
1317
        }
 
1318
        print " </simplesect>\n";
 
1319
    }
 
1320
 
 
1321
    print "</sect2>\n\n";
 
1322
}
 
1323
 
 
1324
##
 
1325
# output function in man
 
1326
sub output_function_man(%) {
 
1327
    my %args = %{$_[0]};
 
1328
    my ($parameter, $section);
 
1329
    my $count;
 
1330
 
 
1331
    print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Bootloader Hacker's Manual\" U-BOOT\n";
 
1332
 
 
1333
    print ".SH NAME\n";
 
1334
    print $args{'function'} . " \\- " . $args{'purpose'} . "\n";
 
1335
 
 
1336
    print ".SH SYNOPSIS\n";
 
1337
    if ($args{'functiontype'} ne "") {
 
1338
        print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n";
 
1339
    } else {
 
1340
        print ".B \"" . $args{'function'} . "\n";
 
1341
    }
 
1342
    $count = 0;
 
1343
    my $parenth = "(";
 
1344
    my $post = ",";
 
1345
    foreach my $parameter (@{$args{'parameterlist'}}) {
 
1346
        if ($count == $#{$args{'parameterlist'}}) {
 
1347
            $post = ");";
 
1348
        }
 
1349
        $type = $args{'parametertypes'}{$parameter};
 
1350
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1351
            # pointer-to-function
 
1352
            print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n";
 
1353
        } else {
 
1354
            $type =~ s/([^\*])$/$1 /;
 
1355
            print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n";
 
1356
        }
 
1357
        $count++;
 
1358
        $parenth = "";
 
1359
    }
 
1360
 
 
1361
    print ".SH ARGUMENTS\n";
 
1362
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1363
        my $parameter_name = $parameter;
 
1364
        $parameter_name =~ s/\[.*//;
 
1365
 
 
1366
        print ".IP \"" . $parameter . "\" 12\n";
 
1367
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
1368
    }
 
1369
    foreach $section (@{$args{'sectionlist'}}) {
 
1370
        print ".SH \"", uc $section, "\"\n";
 
1371
        output_highlight($args{'sections'}{$section});
 
1372
    }
 
1373
}
 
1374
 
 
1375
##
 
1376
# output enum in man
 
1377
sub output_enum_man(%) {
 
1378
    my %args = %{$_[0]};
 
1379
    my ($parameter, $section);
 
1380
    my $count;
 
1381
 
 
1382
    print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" U-BOOT\n";
 
1383
 
 
1384
    print ".SH NAME\n";
 
1385
    print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n";
 
1386
 
 
1387
    print ".SH SYNOPSIS\n";
 
1388
    print "enum " . $args{'enum'} . " {\n";
 
1389
    $count = 0;
 
1390
    foreach my $parameter (@{$args{'parameterlist'}}) {
 
1391
        print ".br\n.BI \"    $parameter\"\n";
 
1392
        if ($count == $#{$args{'parameterlist'}}) {
 
1393
            print "\n};\n";
 
1394
            last;
 
1395
        }
 
1396
        else {
 
1397
            print ", \n.br\n";
 
1398
        }
 
1399
        $count++;
 
1400
    }
 
1401
 
 
1402
    print ".SH Constants\n";
 
1403
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1404
        my $parameter_name = $parameter;
 
1405
        $parameter_name =~ s/\[.*//;
 
1406
 
 
1407
        print ".IP \"" . $parameter . "\" 12\n";
 
1408
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
1409
    }
 
1410
    foreach $section (@{$args{'sectionlist'}}) {
 
1411
        print ".SH \"$section\"\n";
 
1412
        output_highlight($args{'sections'}{$section});
 
1413
    }
 
1414
}
 
1415
 
 
1416
##
 
1417
# output struct in man
 
1418
sub output_struct_man(%) {
 
1419
    my %args = %{$_[0]};
 
1420
    my ($parameter, $section);
 
1421
 
 
1422
    print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" U-BOOT\n";
 
1423
 
 
1424
    print ".SH NAME\n";
 
1425
    print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n";
 
1426
 
 
1427
    print ".SH SYNOPSIS\n";
 
1428
    print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
 
1429
 
 
1430
    foreach my $parameter (@{$args{'parameterlist'}}) {
 
1431
        if ($parameter =~ /^#/) {
 
1432
            print ".BI \"$parameter\"\n.br\n";
 
1433
            next;
 
1434
        }
 
1435
        my $parameter_name = $parameter;
 
1436
        $parameter_name =~ s/\[.*//;
 
1437
 
 
1438
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1439
        $type = $args{'parametertypes'}{$parameter};
 
1440
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1441
            # pointer-to-function
 
1442
            print ".BI \"    " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n";
 
1443
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
 
1444
            # bitfield
 
1445
            print ".BI \"    " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n";
 
1446
        } else {
 
1447
            $type =~ s/([^\*])$/$1 /;
 
1448
            print ".BI \"    " . $type . "\" " . $parameter . " \"" . "\"\n;\n";
 
1449
        }
 
1450
        print "\n.br\n";
 
1451
    }
 
1452
    print "};\n.br\n";
 
1453
 
 
1454
    print ".SH Members\n";
 
1455
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1456
        ($parameter =~ /^#/) && next;
 
1457
 
 
1458
        my $parameter_name = $parameter;
 
1459
        $parameter_name =~ s/\[.*//;
 
1460
 
 
1461
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1462
        print ".IP \"" . $parameter . "\" 12\n";
 
1463
        output_highlight($args{'parameterdescs'}{$parameter_name});
 
1464
    }
 
1465
    foreach $section (@{$args{'sectionlist'}}) {
 
1466
        print ".SH \"$section\"\n";
 
1467
        output_highlight($args{'sections'}{$section});
 
1468
    }
 
1469
}
 
1470
 
 
1471
##
 
1472
# output typedef in man
 
1473
sub output_typedef_man(%) {
 
1474
    my %args = %{$_[0]};
 
1475
    my ($parameter, $section);
 
1476
 
 
1477
    print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" U-BOOT\n";
 
1478
 
 
1479
    print ".SH NAME\n";
 
1480
    print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n";
 
1481
 
 
1482
    foreach $section (@{$args{'sectionlist'}}) {
 
1483
        print ".SH \"$section\"\n";
 
1484
        output_highlight($args{'sections'}{$section});
 
1485
    }
 
1486
}
 
1487
 
 
1488
sub output_blockhead_man(%) {
 
1489
    my %args = %{$_[0]};
 
1490
    my ($parameter, $section);
 
1491
    my $count;
 
1492
 
 
1493
    print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" U-BOOT\n";
 
1494
 
 
1495
    foreach $section (@{$args{'sectionlist'}}) {
 
1496
        print ".SH \"$section\"\n";
 
1497
        output_highlight($args{'sections'}{$section});
 
1498
    }
 
1499
}
 
1500
 
 
1501
##
 
1502
# output in text
 
1503
sub output_function_text(%) {
 
1504
    my %args = %{$_[0]};
 
1505
    my ($parameter, $section);
 
1506
    my $start;
 
1507
 
 
1508
    print "Name:\n\n";
 
1509
    print $args{'function'} . " - " . $args{'purpose'} . "\n";
 
1510
 
 
1511
    print "\nSynopsis:\n\n";
 
1512
    if ($args{'functiontype'} ne "") {
 
1513
        $start = $args{'functiontype'} . " " . $args{'function'} . " (";
 
1514
    } else {
 
1515
        $start = $args{'function'} . " (";
 
1516
    }
 
1517
    print $start;
 
1518
 
 
1519
    my $count = 0;
 
1520
    foreach my $parameter (@{$args{'parameterlist'}}) {
 
1521
        $type = $args{'parametertypes'}{$parameter};
 
1522
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1523
            # pointer-to-function
 
1524
            print $1 . $parameter . ") (" . $2;
 
1525
        } else {
 
1526
            print $type . " " . $parameter;
 
1527
        }
 
1528
        if ($count != $#{$args{'parameterlist'}}) {
 
1529
            $count++;
 
1530
            print ",\n";
 
1531
            print " " x length($start);
 
1532
        } else {
 
1533
            print ");\n\n";
 
1534
        }
 
1535
    }
 
1536
 
 
1537
    print "Arguments:\n\n";
 
1538
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1539
        my $parameter_name = $parameter;
 
1540
        $parameter_name =~ s/\[.*//;
 
1541
 
 
1542
        print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n";
 
1543
    }
 
1544
    output_section_text(@_);
 
1545
}
 
1546
 
 
1547
#output sections in text
 
1548
sub output_section_text(%) {
 
1549
    my %args = %{$_[0]};
 
1550
    my $section;
 
1551
 
 
1552
    print "\n";
 
1553
    foreach $section (@{$args{'sectionlist'}}) {
 
1554
        print "$section:\n\n";
 
1555
        output_highlight($args{'sections'}{$section});
 
1556
    }
 
1557
    print "\n\n";
 
1558
}
 
1559
 
 
1560
# output enum in text
 
1561
sub output_enum_text(%) {
 
1562
    my %args = %{$_[0]};
 
1563
    my ($parameter);
 
1564
    my $count;
 
1565
    print "Enum:\n\n";
 
1566
 
 
1567
    print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n";
 
1568
    print "enum " . $args{'enum'} . " {\n";
 
1569
    $count = 0;
 
1570
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1571
        print "\t$parameter";
 
1572
        if ($count != $#{$args{'parameterlist'}}) {
 
1573
            $count++;
 
1574
            print ",";
 
1575
        }
 
1576
        print "\n";
 
1577
    }
 
1578
    print "};\n\n";
 
1579
 
 
1580
    print "Constants:\n\n";
 
1581
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1582
        print "$parameter\n\t";
 
1583
        print $args{'parameterdescs'}{$parameter} . "\n";
 
1584
    }
 
1585
 
 
1586
    output_section_text(@_);
 
1587
}
 
1588
 
 
1589
# output typedef in text
 
1590
sub output_typedef_text(%) {
 
1591
    my %args = %{$_[0]};
 
1592
    my ($parameter);
 
1593
    my $count;
 
1594
    print "Typedef:\n\n";
 
1595
 
 
1596
    print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n";
 
1597
    output_section_text(@_);
 
1598
}
 
1599
 
 
1600
# output struct as text
 
1601
sub output_struct_text(%) {
 
1602
    my %args = %{$_[0]};
 
1603
    my ($parameter);
 
1604
 
 
1605
    print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n";
 
1606
    print $args{'type'} . " " . $args{'struct'} . " {\n";
 
1607
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1608
        if ($parameter =~ /^#/) {
 
1609
            print "$parameter\n";
 
1610
            next;
 
1611
        }
 
1612
 
 
1613
        my $parameter_name = $parameter;
 
1614
        $parameter_name =~ s/\[.*//;
 
1615
 
 
1616
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1617
        $type = $args{'parametertypes'}{$parameter};
 
1618
        if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
 
1619
            # pointer-to-function
 
1620
            print "\t$1 $parameter) ($2);\n";
 
1621
        } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
 
1622
            # bitfield
 
1623
            print "\t$1 $parameter$2;\n";
 
1624
        } else {
 
1625
            print "\t" . $type . " " . $parameter . ";\n";
 
1626
        }
 
1627
    }
 
1628
    print "};\n\n";
 
1629
 
 
1630
    print "Members:\n\n";
 
1631
    foreach $parameter (@{$args{'parameterlist'}}) {
 
1632
        ($parameter =~ /^#/) && next;
 
1633
 
 
1634
        my $parameter_name = $parameter;
 
1635
        $parameter_name =~ s/\[.*//;
 
1636
 
 
1637
        ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
 
1638
        print "$parameter\n\t";
 
1639
        print $args{'parameterdescs'}{$parameter_name} . "\n";
 
1640
    }
 
1641
    print "\n";
 
1642
    output_section_text(@_);
 
1643
}
 
1644
 
 
1645
sub output_blockhead_text(%) {
 
1646
    my %args = %{$_[0]};
 
1647
    my ($parameter, $section);
 
1648
 
 
1649
    foreach $section (@{$args{'sectionlist'}}) {
 
1650
        print " $section:\n";
 
1651
        print "    -> ";
 
1652
        output_highlight($args{'sections'}{$section});
 
1653
    }
 
1654
}
 
1655
 
 
1656
## list mode output functions
 
1657
 
 
1658
sub output_function_list(%) {
 
1659
    my %args = %{$_[0]};
 
1660
 
 
1661
    print $args{'function'} . "\n";
 
1662
}
 
1663
 
 
1664
# output enum in list
 
1665
sub output_enum_list(%) {
 
1666
    my %args = %{$_[0]};
 
1667
    print $args{'enum'} . "\n";
 
1668
}
 
1669
 
 
1670
# output typedef in list
 
1671
sub output_typedef_list(%) {
 
1672
    my %args = %{$_[0]};
 
1673
    print $args{'typedef'} . "\n";
 
1674
}
 
1675
 
 
1676
# output struct as list
 
1677
sub output_struct_list(%) {
 
1678
    my %args = %{$_[0]};
 
1679
 
 
1680
    print $args{'struct'} . "\n";
 
1681
}
 
1682
 
 
1683
sub output_blockhead_list(%) {
 
1684
    my %args = %{$_[0]};
 
1685
    my ($parameter, $section);
 
1686
 
 
1687
    foreach $section (@{$args{'sectionlist'}}) {
 
1688
        print "DOC: $section\n";
 
1689
    }
 
1690
}
 
1691
 
 
1692
##
 
1693
# generic output function for all types (function, struct/union, typedef, enum);
 
1694
# calls the generated, variable output_ function name based on
 
1695
# functype and output_mode
 
1696
sub output_declaration {
 
1697
    no strict 'refs';
 
1698
    my $name = shift;
 
1699
    my $functype = shift;
 
1700
    my $func = "output_${functype}_$output_mode";
 
1701
    if (($function_only==0) ||
 
1702
        ( $function_only == 1 && defined($function_table{$name})) ||
 
1703
        ( $function_only == 2 && !defined($function_table{$name})))
 
1704
    {
 
1705
        &$func(@_);
 
1706
        $section_counter++;
 
1707
    }
 
1708
}
 
1709
 
 
1710
##
 
1711
# generic output function - calls the right one based on current output mode.
 
1712
sub output_blockhead {
 
1713
    no strict 'refs';
 
1714
    my $func = "output_blockhead_" . $output_mode;
 
1715
    &$func(@_);
 
1716
    $section_counter++;
 
1717
}
 
1718
 
 
1719
##
 
1720
# takes a declaration (struct, union, enum, typedef) and
 
1721
# invokes the right handler. NOT called for functions.
 
1722
sub dump_declaration($$) {
 
1723
    no strict 'refs';
 
1724
    my ($prototype, $file) = @_;
 
1725
    my $func = "dump_" . $decl_type;
 
1726
    &$func(@_);
 
1727
}
 
1728
 
 
1729
sub dump_union($$) {
 
1730
    dump_struct(@_);
 
1731
}
 
1732
 
 
1733
sub dump_struct($$) {
 
1734
    my $x = shift;
 
1735
    my $file = shift;
 
1736
    my $nested;
 
1737
 
 
1738
    if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) {
 
1739
        #my $decl_type = $1;
 
1740
        $declaration_name = $2;
 
1741
        my $members = $3;
 
1742
 
 
1743
        # ignore embedded structs or unions
 
1744
        $members =~ s/({.*})//g;
 
1745
        $nested = $1;
 
1746
 
 
1747
        # ignore members marked private:
 
1748
        $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gos;
 
1749
        $members =~ s/\/\*\s*private:.*//gos;
 
1750
        # strip comments:
 
1751
        $members =~ s/\/\*.*?\*\///gos;
 
1752
        $nested =~ s/\/\*.*?\*\///gos;
 
1753
        # strip kmemcheck_bitfield_{begin,end}.*;
 
1754
        $members =~ s/kmemcheck_bitfield_.*?;//gos;
 
1755
        # strip attributes
 
1756
        $members =~ s/__aligned\s*\(.+\)//gos;
 
1757
 
 
1758
        create_parameterlist($members, ';', $file);
 
1759
        check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
 
1760
 
 
1761
        output_declaration($declaration_name,
 
1762
                           'struct',
 
1763
                           {'struct' => $declaration_name,
 
1764
                            'module' => $modulename,
 
1765
                            'parameterlist' => \@parameterlist,
 
1766
                            'parameterdescs' => \%parameterdescs,
 
1767
                            'parametertypes' => \%parametertypes,
 
1768
                            'sectionlist' => \@sectionlist,
 
1769
                            'sections' => \%sections,
 
1770
                            'purpose' => $declaration_purpose,
 
1771
                            'type' => $decl_type
 
1772
                           });
 
1773
    }
 
1774
    else {
 
1775
        print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
 
1776
        ++$errors;
 
1777
    }
 
1778
}
 
1779
 
 
1780
sub dump_enum($$) {
 
1781
    my $x = shift;
 
1782
    my $file = shift;
 
1783
 
 
1784
    $x =~ s@/\*.*?\*/@@gos;     # strip comments.
 
1785
    $x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
 
1786
 
 
1787
    if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
 
1788
        $declaration_name = $1;
 
1789
        my $members = $2;
 
1790
 
 
1791
        foreach my $arg (split ',', $members) {
 
1792
            $arg =~ s/^\s*(\w+).*/$1/;
 
1793
            push @parameterlist, $arg;
 
1794
            if (!$parameterdescs{$arg}) {
 
1795
                $parameterdescs{$arg} = $undescribed;
 
1796
                print STDERR "Warning(${file}:$.): Enum value '$arg' ".
 
1797
                    "not described in enum '$declaration_name'\n";
 
1798
            }
 
1799
 
 
1800
        }
 
1801
 
 
1802
        output_declaration($declaration_name,
 
1803
                           'enum',
 
1804
                           {'enum' => $declaration_name,
 
1805
                            'module' => $modulename,
 
1806
                            'parameterlist' => \@parameterlist,
 
1807
                            'parameterdescs' => \%parameterdescs,
 
1808
                            'sectionlist' => \@sectionlist,
 
1809
                            'sections' => \%sections,
 
1810
                            'purpose' => $declaration_purpose
 
1811
                           });
 
1812
    }
 
1813
    else {
 
1814
        print STDERR "Error(${file}:$.): Cannot parse enum!\n";
 
1815
        ++$errors;
 
1816
    }
 
1817
}
 
1818
 
 
1819
sub dump_typedef($$) {
 
1820
    my $x = shift;
 
1821
    my $file = shift;
 
1822
 
 
1823
    $x =~ s@/\*.*?\*/@@gos;     # strip comments.
 
1824
    while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
 
1825
        $x =~ s/\(*.\)\s*;$/;/;
 
1826
        $x =~ s/\[*.\]\s*;$/;/;
 
1827
    }
 
1828
 
 
1829
    if ($x =~ /typedef.*\s+(\w+)\s*;/) {
 
1830
        $declaration_name = $1;
 
1831
 
 
1832
        output_declaration($declaration_name,
 
1833
                           'typedef',
 
1834
                           {'typedef' => $declaration_name,
 
1835
                            'module' => $modulename,
 
1836
                            'sectionlist' => \@sectionlist,
 
1837
                            'sections' => \%sections,
 
1838
                            'purpose' => $declaration_purpose
 
1839
                           });
 
1840
    }
 
1841
    else {
 
1842
        print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
 
1843
        ++$errors;
 
1844
    }
 
1845
}
 
1846
 
 
1847
sub save_struct_actual($) {
 
1848
    my $actual = shift;
 
1849
 
 
1850
    # strip all spaces from the actual param so that it looks like one string item
 
1851
    $actual =~ s/\s*//g;
 
1852
    $struct_actual = $struct_actual . $actual . " ";
 
1853
}
 
1854
 
 
1855
sub create_parameterlist($$$) {
 
1856
    my $args = shift;
 
1857
    my $splitter = shift;
 
1858
    my $file = shift;
 
1859
    my $type;
 
1860
    my $param;
 
1861
 
 
1862
    # temporarily replace commas inside function pointer definition
 
1863
    while ($args =~ /(\([^\),]+),/) {
 
1864
        $args =~ s/(\([^\),]+),/$1#/g;
 
1865
    }
 
1866
 
 
1867
    foreach my $arg (split($splitter, $args)) {
 
1868
        # strip comments
 
1869
        $arg =~ s/\/\*.*\*\///;
 
1870
        # strip leading/trailing spaces
 
1871
        $arg =~ s/^\s*//;
 
1872
        $arg =~ s/\s*$//;
 
1873
        $arg =~ s/\s+/ /;
 
1874
 
 
1875
        if ($arg =~ /^#/) {
 
1876
            # Treat preprocessor directive as a typeless variable just to fill
 
1877
            # corresponding data structures "correctly". Catch it later in
 
1878
            # output_* subs.
 
1879
            push_parameter($arg, "", $file);
 
1880
        } elsif ($arg =~ m/\(.+\)\s*\(/) {
 
1881
            # pointer-to-function
 
1882
            $arg =~ tr/#/,/;
 
1883
            $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/;
 
1884
            $param = $1;
 
1885
            $type = $arg;
 
1886
            $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
 
1887
            save_struct_actual($param);
 
1888
            push_parameter($param, $type, $file);
 
1889
        } elsif ($arg) {
 
1890
            $arg =~ s/\s*:\s*/:/g;
 
1891
            $arg =~ s/\s*\[/\[/g;
 
1892
 
 
1893
            my @args = split('\s*,\s*', $arg);
 
1894
            if ($args[0] =~ m/\*/) {
 
1895
                $args[0] =~ s/(\*+)\s*/ $1/;
 
1896
            }
 
1897
 
 
1898
            my @first_arg;
 
1899
            if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
 
1900
                    shift @args;
 
1901
                    push(@first_arg, split('\s+', $1));
 
1902
                    push(@first_arg, $2);
 
1903
            } else {
 
1904
                    @first_arg = split('\s+', shift @args);
 
1905
            }
 
1906
 
 
1907
            unshift(@args, pop @first_arg);
 
1908
            $type = join " ", @first_arg;
 
1909
 
 
1910
            foreach $param (@args) {
 
1911
                if ($param =~ m/^(\*+)\s*(.*)/) {
 
1912
                    save_struct_actual($2);
 
1913
                    push_parameter($2, "$type $1", $file);
 
1914
                }
 
1915
                elsif ($param =~ m/(.*?):(\d+)/) {
 
1916
                    if ($type ne "") { # skip unnamed bit-fields
 
1917
                        save_struct_actual($1);
 
1918
                        push_parameter($1, "$type:$2", $file)
 
1919
                    }
 
1920
                }
 
1921
                else {
 
1922
                    save_struct_actual($param);
 
1923
                    push_parameter($param, $type, $file);
 
1924
                }
 
1925
            }
 
1926
        }
 
1927
    }
 
1928
}
 
1929
 
 
1930
sub push_parameter($$$) {
 
1931
        my $param = shift;
 
1932
        my $type = shift;
 
1933
        my $file = shift;
 
1934
 
 
1935
        if (($anon_struct_union == 1) && ($type eq "") &&
 
1936
            ($param eq "}")) {
 
1937
                return;         # ignore the ending }; from anon. struct/union
 
1938
        }
 
1939
 
 
1940
        $anon_struct_union = 0;
 
1941
        my $param_name = $param;
 
1942
        $param_name =~ s/\[.*//;
 
1943
 
 
1944
        if ($type eq "" && $param =~ /\.\.\.$/)
 
1945
        {
 
1946
            if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
 
1947
                $parameterdescs{$param} = "variable arguments";
 
1948
            }
 
1949
        }
 
1950
        elsif ($type eq "" && ($param eq "" or $param eq "void"))
 
1951
        {
 
1952
            $param="void";
 
1953
            $parameterdescs{void} = "no arguments";
 
1954
        }
 
1955
        elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
 
1956
        # handle unnamed (anonymous) union or struct:
 
1957
        {
 
1958
                $type = $param;
 
1959
                $param = "{unnamed_" . $param . "}";
 
1960
                $parameterdescs{$param} = "anonymous\n";
 
1961
                $anon_struct_union = 1;
 
1962
        }
 
1963
 
 
1964
        # warn if parameter has no description
 
1965
        # (but ignore ones starting with # as these are not parameters
 
1966
        # but inline preprocessor statements);
 
1967
        # also ignore unnamed structs/unions;
 
1968
        if (!$anon_struct_union) {
 
1969
        if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
 
1970
 
 
1971
            $parameterdescs{$param_name} = $undescribed;
 
1972
 
 
1973
            if (($type eq 'function') || ($type eq 'enum')) {
 
1974
                print STDERR "Warning(${file}:$.): Function parameter ".
 
1975
                    "or member '$param' not " .
 
1976
                    "described in '$declaration_name'\n";
 
1977
            }
 
1978
            print STDERR "Warning(${file}:$.):" .
 
1979
                         " No description found for parameter '$param'\n";
 
1980
            ++$warnings;
 
1981
        }
 
1982
        }
 
1983
 
 
1984
        $param = xml_escape($param);
 
1985
 
 
1986
        # strip spaces from $param so that it is one continuous string
 
1987
        # on @parameterlist;
 
1988
        # this fixes a problem where check_sections() cannot find
 
1989
        # a parameter like "addr[6 + 2]" because it actually appears
 
1990
        # as "addr[6", "+", "2]" on the parameter list;
 
1991
        # but it's better to maintain the param string unchanged for output,
 
1992
        # so just weaken the string compare in check_sections() to ignore
 
1993
        # "[blah" in a parameter string;
 
1994
        ###$param =~ s/\s*//g;
 
1995
        push @parameterlist, $param;
 
1996
        $parametertypes{$param} = $type;
 
1997
}
 
1998
 
 
1999
sub check_sections($$$$$$) {
 
2000
        my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
 
2001
        my @sects = split ' ', $sectcheck;
 
2002
        my @prms = split ' ', $prmscheck;
 
2003
        my $err;
 
2004
        my ($px, $sx);
 
2005
        my $prm_clean;          # strip trailing "[array size]" and/or beginning "*"
 
2006
 
 
2007
        foreach $sx (0 .. $#sects) {
 
2008
                $err = 1;
 
2009
                foreach $px (0 .. $#prms) {
 
2010
                        $prm_clean = $prms[$px];
 
2011
                        $prm_clean =~ s/\[.*\]//;
 
2012
                        $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
 
2013
                        # ignore array size in a parameter string;
 
2014
                        # however, the original param string may contain
 
2015
                        # spaces, e.g.:  addr[6 + 2]
 
2016
                        # and this appears in @prms as "addr[6" since the
 
2017
                        # parameter list is split at spaces;
 
2018
                        # hence just ignore "[..." for the sections check;
 
2019
                        $prm_clean =~ s/\[.*//;
 
2020
 
 
2021
                        ##$prm_clean =~ s/^\**//;
 
2022
                        if ($prm_clean eq $sects[$sx]) {
 
2023
                                $err = 0;
 
2024
                                last;
 
2025
                        }
 
2026
                }
 
2027
                if ($err) {
 
2028
                        if ($decl_type eq "function") {
 
2029
                                print STDERR "Warning(${file}:$.): " .
 
2030
                                        "Excess function parameter " .
 
2031
                                        "'$sects[$sx]' " .
 
2032
                                        "description in '$decl_name'\n";
 
2033
                                ++$warnings;
 
2034
                        } else {
 
2035
                                if ($nested !~ m/\Q$sects[$sx]\E/) {
 
2036
                                    print STDERR "Warning(${file}:$.): " .
 
2037
                                        "Excess struct/union/enum/typedef member " .
 
2038
                                        "'$sects[$sx]' " .
 
2039
                                        "description in '$decl_name'\n";
 
2040
                                    ++$warnings;
 
2041
                                }
 
2042
                        }
 
2043
                }
 
2044
        }
 
2045
}
 
2046
 
 
2047
##
 
2048
# Checks the section describing the return value of a function.
 
2049
sub check_return_section {
 
2050
        my $file = shift;
 
2051
        my $declaration_name = shift;
 
2052
        my $return_type = shift;
 
2053
 
 
2054
        # Ignore an empty return type (It's a macro)
 
2055
        # Ignore functions with a "void" return type. (But don't ignore "void *")
 
2056
        if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) {
 
2057
                return;
 
2058
        }
 
2059
 
 
2060
        if (!defined($sections{$section_return}) ||
 
2061
            $sections{$section_return} eq "") {
 
2062
                print STDERR "Warning(${file}:$.): " .
 
2063
                        "No description found for return value of " .
 
2064
                        "'$declaration_name'\n";
 
2065
                ++$warnings;
 
2066
        }
 
2067
}
 
2068
 
 
2069
##
 
2070
# takes a function prototype and the name of the current file being
 
2071
# processed and spits out all the details stored in the global
 
2072
# arrays/hashes.
 
2073
sub dump_function($$) {
 
2074
    my $prototype = shift;
 
2075
    my $file = shift;
 
2076
 
 
2077
    $prototype =~ s/^static +//;
 
2078
    $prototype =~ s/^extern +//;
 
2079
    $prototype =~ s/^asmlinkage +//;
 
2080
    $prototype =~ s/^inline +//;
 
2081
    $prototype =~ s/^__inline__ +//;
 
2082
    $prototype =~ s/^__inline +//;
 
2083
    $prototype =~ s/^__always_inline +//;
 
2084
    $prototype =~ s/^noinline +//;
 
2085
    $prototype =~ s/__init +//;
 
2086
    $prototype =~ s/__init_or_module +//;
 
2087
    $prototype =~ s/__must_check +//;
 
2088
    $prototype =~ s/__weak +//;
 
2089
    $prototype =~ s/^#\s*define\s+//; #ak added
 
2090
    $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//;
 
2091
 
 
2092
    # Yes, this truly is vile.  We are looking for:
 
2093
    # 1. Return type (may be nothing if we're looking at a macro)
 
2094
    # 2. Function name
 
2095
    # 3. Function parameters.
 
2096
    #
 
2097
    # All the while we have to watch out for function pointer parameters
 
2098
    # (which IIRC is what the two sections are for), C types (these
 
2099
    # regexps don't even start to express all the possibilities), and
 
2100
    # so on.
 
2101
    #
 
2102
    # If you mess with these regexps, it's a good idea to check that
 
2103
    # the following functions' documentation still comes out right:
 
2104
    # - parport_register_device (function pointer parameters)
 
2105
    # - atomic_set (macro)
 
2106
    # - pci_match_device, __copy_to_user (long return type)
 
2107
 
 
2108
    if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2109
        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2110
        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2111
        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2112
        $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2113
        $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2114
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
 
2115
        $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2116
        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2117
        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2118
        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2119
        $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2120
        $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2121
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2122
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2123
        $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
 
2124
        $prototype =~ m/^(\w+\s+\w+\s*\*\s*\w+\s*\*\s*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
 
2125
        $return_type = $1;
 
2126
        $declaration_name = $2;
 
2127
        my $args = $3;
 
2128
 
 
2129
        create_parameterlist($args, ',', $file);
 
2130
    } else {
 
2131
        print STDERR "Warning(${file}:$.): cannot understand function prototype: '$prototype'\n";
 
2132
        return;
 
2133
    }
 
2134
 
 
2135
        my $prms = join " ", @parameterlist;
 
2136
        check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
 
2137
 
 
2138
        # This check emits a lot of warnings at the moment, because many
 
2139
        # functions don't have a 'Return' doc section. So until the number
 
2140
        # of warnings goes sufficiently down, the check is only performed in
 
2141
        # verbose mode.
 
2142
        # TODO: always perform the check.
 
2143
        if ($verbose) {
 
2144
                check_return_section($file, $declaration_name, $return_type);
 
2145
        }
 
2146
 
 
2147
    output_declaration($declaration_name,
 
2148
                       'function',
 
2149
                       {'function' => $declaration_name,
 
2150
                        'module' => $modulename,
 
2151
                        'functiontype' => $return_type,
 
2152
                        'parameterlist' => \@parameterlist,
 
2153
                        'parameterdescs' => \%parameterdescs,
 
2154
                        'parametertypes' => \%parametertypes,
 
2155
                        'sectionlist' => \@sectionlist,
 
2156
                        'sections' => \%sections,
 
2157
                        'purpose' => $declaration_purpose
 
2158
                       });
 
2159
}
 
2160
 
 
2161
sub reset_state {
 
2162
    $function = "";
 
2163
    %constants = ();
 
2164
    %parameterdescs = ();
 
2165
    %parametertypes = ();
 
2166
    @parameterlist = ();
 
2167
    %sections = ();
 
2168
    @sectionlist = ();
 
2169
    $sectcheck = "";
 
2170
    $struct_actual = "";
 
2171
    $prototype = "";
 
2172
 
 
2173
    $state = 0;
 
2174
}
 
2175
 
 
2176
sub tracepoint_munge($) {
 
2177
        my $file = shift;
 
2178
        my $tracepointname = 0;
 
2179
        my $tracepointargs = 0;
 
2180
 
 
2181
        if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
 
2182
                $tracepointname = $1;
 
2183
        }
 
2184
        if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
 
2185
                $tracepointname = $1;
 
2186
        }
 
2187
        if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
 
2188
                $tracepointname = $2;
 
2189
        }
 
2190
        $tracepointname =~ s/^\s+//; #strip leading whitespace
 
2191
        if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
 
2192
                $tracepointargs = $1;
 
2193
        }
 
2194
        if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
 
2195
                print STDERR "Warning(${file}:$.): Unrecognized tracepoint format: \n".
 
2196
                             "$prototype\n";
 
2197
        } else {
 
2198
                $prototype = "static inline void trace_$tracepointname($tracepointargs)";
 
2199
        }
 
2200
}
 
2201
 
 
2202
sub syscall_munge() {
 
2203
        my $void = 0;
 
2204
 
 
2205
        $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs
 
2206
##      if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) {
 
2207
        if ($prototype =~ m/SYSCALL_DEFINE0/) {
 
2208
                $void = 1;
 
2209
##              $prototype = "long sys_$1(void)";
 
2210
        }
 
2211
 
 
2212
        $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name
 
2213
        if ($prototype =~ m/long (sys_.*?),/) {
 
2214
                $prototype =~ s/,/\(/;
 
2215
        } elsif ($void) {
 
2216
                $prototype =~ s/\)/\(void\)/;
 
2217
        }
 
2218
 
 
2219
        # now delete all of the odd-number commas in $prototype
 
2220
        # so that arg types & arg names don't have a comma between them
 
2221
        my $count = 0;
 
2222
        my $len = length($prototype);
 
2223
        if ($void) {
 
2224
                $len = 0;       # skip the for-loop
 
2225
        }
 
2226
        for (my $ix = 0; $ix < $len; $ix++) {
 
2227
                if (substr($prototype, $ix, 1) eq ',') {
 
2228
                        $count++;
 
2229
                        if ($count % 2 == 1) {
 
2230
                                substr($prototype, $ix, 1) = ' ';
 
2231
                        }
 
2232
                }
 
2233
        }
 
2234
}
 
2235
 
 
2236
sub process_state3_function($$) {
 
2237
    my $x = shift;
 
2238
    my $file = shift;
 
2239
 
 
2240
    $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
 
2241
 
 
2242
    if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) {
 
2243
        # do nothing
 
2244
    }
 
2245
    elsif ($x =~ /([^\{]*)/) {
 
2246
        $prototype .= $1;
 
2247
    }
 
2248
 
 
2249
    if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) {
 
2250
        $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
 
2251
        $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
 
2252
        $prototype =~ s@^\s+@@gos; # strip leading spaces
 
2253
        if ($prototype =~ /SYSCALL_DEFINE/) {
 
2254
                syscall_munge();
 
2255
        }
 
2256
        if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
 
2257
            $prototype =~ /DEFINE_SINGLE_EVENT/)
 
2258
        {
 
2259
                tracepoint_munge($file);
 
2260
        }
 
2261
        dump_function($prototype, $file);
 
2262
        reset_state();
 
2263
    }
 
2264
}
 
2265
 
 
2266
sub process_state3_type($$) {
 
2267
    my $x = shift;
 
2268
    my $file = shift;
 
2269
 
 
2270
    $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
 
2271
    $x =~ s@^\s+@@gos; # strip leading spaces
 
2272
    $x =~ s@\s+$@@gos; # strip trailing spaces
 
2273
    $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
 
2274
 
 
2275
    if ($x =~ /^#/) {
 
2276
        # To distinguish preprocessor directive from regular declaration later.
 
2277
        $x .= ";";
 
2278
    }
 
2279
 
 
2280
    while (1) {
 
2281
        if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
 
2282
            $prototype .= $1 . $2;
 
2283
            ($2 eq '{') && $brcount++;
 
2284
            ($2 eq '}') && $brcount--;
 
2285
            if (($2 eq ';') && ($brcount == 0)) {
 
2286
                dump_declaration($prototype, $file);
 
2287
                reset_state();
 
2288
                last;
 
2289
            }
 
2290
            $x = $3;
 
2291
        } else {
 
2292
            $prototype .= $x;
 
2293
            last;
 
2294
        }
 
2295
    }
 
2296
}
 
2297
 
 
2298
# xml_escape: replace <, >, and & in the text stream;
 
2299
#
 
2300
# however, formatting controls that are generated internally/locally in the
 
2301
# kernel-doc script are not escaped here; instead, they begin life like
 
2302
# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings
 
2303
# are converted to their mnemonic-expected output, without the 4 * '\' & ':',
 
2304
# just before actual output; (this is done by local_unescape())
 
2305
sub xml_escape($) {
 
2306
        my $text = shift;
 
2307
        if (($output_mode eq "text") || ($output_mode eq "man")) {
 
2308
                return $text;
 
2309
        }
 
2310
        $text =~ s/\&/\\\\\\amp;/g;
 
2311
        $text =~ s/\</\\\\\\lt;/g;
 
2312
        $text =~ s/\>/\\\\\\gt;/g;
 
2313
        return $text;
 
2314
}
 
2315
 
 
2316
# convert local escape strings to html
 
2317
# local escape strings look like:  '\\\\menmonic:' (that's 4 backslashes)
 
2318
sub local_unescape($) {
 
2319
        my $text = shift;
 
2320
        if (($output_mode eq "text") || ($output_mode eq "man")) {
 
2321
                return $text;
 
2322
        }
 
2323
        $text =~ s/\\\\\\\\lt:/</g;
 
2324
        $text =~ s/\\\\\\\\gt:/>/g;
 
2325
        return $text;
 
2326
}
 
2327
 
 
2328
sub process_file($) {
 
2329
    my $file;
 
2330
    my $identifier;
 
2331
    my $func;
 
2332
    my $descr;
 
2333
    my $in_purpose = 0;
 
2334
    my $initial_section_counter = $section_counter;
 
2335
 
 
2336
    if (defined($ENV{'SRCTREE'})) {
 
2337
        $file = "$ENV{'SRCTREE'}" . "/" . "@_";
 
2338
    }
 
2339
    else {
 
2340
        $file = "@_";
 
2341
    }
 
2342
    if (defined($source_map{$file})) {
 
2343
        $file = $source_map{$file};
 
2344
    }
 
2345
 
 
2346
    if (!open(IN,"<$file")) {
 
2347
        print STDERR "Error: Cannot open file $file\n";
 
2348
        ++$errors;
 
2349
        return;
 
2350
    }
 
2351
 
 
2352
    $. = 1;
 
2353
 
 
2354
    $section_counter = 0;
 
2355
    while (<IN>) {
 
2356
        while (s/\\\s*$//) {
 
2357
            $_ .= <IN>;
 
2358
        }
 
2359
        if ($state == 0) {
 
2360
            if (/$doc_start/o) {
 
2361
                $state = 1;             # next line is always the function name
 
2362
                $in_doc_sect = 0;
 
2363
            }
 
2364
        } elsif ($state == 1) { # this line is the function name (always)
 
2365
            if (/$doc_block/o) {
 
2366
                $state = 4;
 
2367
                $contents = "";
 
2368
                if ( $1 eq "" ) {
 
2369
                        $section = $section_intro;
 
2370
                } else {
 
2371
                        $section = $1;
 
2372
                }
 
2373
            }
 
2374
            elsif (/$doc_decl/o) {
 
2375
                $identifier = $1;
 
2376
                if (/\s*([\w\s]+?)\s*-/) {
 
2377
                    $identifier = $1;
 
2378
                }
 
2379
 
 
2380
                $state = 2;
 
2381
                if (/-(.*)/) {
 
2382
                    # strip leading/trailing/multiple spaces
 
2383
                    $descr= $1;
 
2384
                    $descr =~ s/^\s*//;
 
2385
                    $descr =~ s/\s*$//;
 
2386
                    $descr =~ s/\s+/ /g;
 
2387
                    $declaration_purpose = xml_escape($descr);
 
2388
                    $in_purpose = 1;
 
2389
                } else {
 
2390
                    $declaration_purpose = "";
 
2391
                }
 
2392
 
 
2393
                if (($declaration_purpose eq "") && $verbose) {
 
2394
                        print STDERR "Warning(${file}:$.): missing initial short description on line:\n";
 
2395
                        print STDERR $_;
 
2396
                        ++$warnings;
 
2397
                }
 
2398
 
 
2399
                if ($identifier =~ m/^struct/) {
 
2400
                    $decl_type = 'struct';
 
2401
                } elsif ($identifier =~ m/^union/) {
 
2402
                    $decl_type = 'union';
 
2403
                } elsif ($identifier =~ m/^enum/) {
 
2404
                    $decl_type = 'enum';
 
2405
                } elsif ($identifier =~ m/^typedef/) {
 
2406
                    $decl_type = 'typedef';
 
2407
                } else {
 
2408
                    $decl_type = 'function';
 
2409
                }
 
2410
 
 
2411
                if ($verbose) {
 
2412
                    print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
 
2413
                }
 
2414
            } else {
 
2415
                print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
 
2416
                " - I thought it was a doc line\n";
 
2417
                ++$warnings;
 
2418
                $state = 0;
 
2419
            }
 
2420
        } elsif ($state == 2) { # look for head: lines, and include content
 
2421
            if (/$doc_sect/o) {
 
2422
                $newsection = $1;
 
2423
                $newcontents = $2;
 
2424
 
 
2425
                if (($contents ne "") && ($contents ne "\n")) {
 
2426
                    if (!$in_doc_sect && $verbose) {
 
2427
                        print STDERR "Warning(${file}:$.): contents before sections\n";
 
2428
                        ++$warnings;
 
2429
                    }
 
2430
                    dump_section($file, $section, xml_escape($contents));
 
2431
                    $section = $section_default;
 
2432
                }
 
2433
 
 
2434
                $in_doc_sect = 1;
 
2435
                $in_purpose = 0;
 
2436
                $contents = $newcontents;
 
2437
                if ($contents ne "") {
 
2438
                    while ((substr($contents, 0, 1) eq " ") ||
 
2439
                        substr($contents, 0, 1) eq "\t") {
 
2440
                            $contents = substr($contents, 1);
 
2441
                    }
 
2442
                    $contents .= "\n";
 
2443
                }
 
2444
                $section = $newsection;
 
2445
            } elsif (/$doc_end/) {
 
2446
 
 
2447
                if (($contents ne "") && ($contents ne "\n")) {
 
2448
                    dump_section($file, $section, xml_escape($contents));
 
2449
                    $section = $section_default;
 
2450
                    $contents = "";
 
2451
                }
 
2452
                # look for doc_com + <text> + doc_end:
 
2453
                if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
 
2454
                    print STDERR "Warning(${file}:$.): suspicious ending line: $_";
 
2455
                    ++$warnings;
 
2456
                }
 
2457
 
 
2458
                $prototype = "";
 
2459
                $state = 3;
 
2460
                $brcount = 0;
 
2461
#               print STDERR "end of doc comment, looking for prototype\n";
 
2462
            } elsif (/$doc_content/) {
 
2463
                # miguel-style comment kludge, look for blank lines after
 
2464
                # @parameter line to signify start of description
 
2465
                if ($1 eq "") {
 
2466
                    if ($section =~ m/^@/ || $section eq $section_context) {
 
2467
                        dump_section($file, $section, xml_escape($contents));
 
2468
                        $section = $section_default;
 
2469
                        $contents = "";
 
2470
                    } else {
 
2471
                        $contents .= "\n";
 
2472
                    }
 
2473
                    $in_purpose = 0;
 
2474
                } elsif ($in_purpose == 1) {
 
2475
                    # Continued declaration purpose
 
2476
                    chomp($declaration_purpose);
 
2477
                    $declaration_purpose .= " " . xml_escape($1);
 
2478
                    $declaration_purpose =~ s/\s+/ /g;
 
2479
                } else {
 
2480
                    $contents .= $1 . "\n";
 
2481
                }
 
2482
            } else {
 
2483
                # i dont know - bad line?  ignore.
 
2484
                print STDERR "Warning(${file}:$.): bad line: $_";
 
2485
                ++$warnings;
 
2486
            }
 
2487
        } elsif ($state == 3) { # scanning for function '{' (end of prototype)
 
2488
            if ($decl_type eq 'function') {
 
2489
                process_state3_function($_, $file);
 
2490
            } else {
 
2491
                process_state3_type($_, $file);
 
2492
            }
 
2493
        } elsif ($state == 4) {
 
2494
                # Documentation block
 
2495
                if (/$doc_block/) {
 
2496
                        dump_doc_section($file, $section, xml_escape($contents));
 
2497
                        $contents = "";
 
2498
                        $function = "";
 
2499
                        %constants = ();
 
2500
                        %parameterdescs = ();
 
2501
                        %parametertypes = ();
 
2502
                        @parameterlist = ();
 
2503
                        %sections = ();
 
2504
                        @sectionlist = ();
 
2505
                        $prototype = "";
 
2506
                        if ( $1 eq "" ) {
 
2507
                                $section = $section_intro;
 
2508
                        } else {
 
2509
                                $section = $1;
 
2510
                        }
 
2511
                }
 
2512
                elsif (/$doc_end/)
 
2513
                {
 
2514
                        dump_doc_section($file, $section, xml_escape($contents));
 
2515
                        $contents = "";
 
2516
                        $function = "";
 
2517
                        %constants = ();
 
2518
                        %parameterdescs = ();
 
2519
                        %parametertypes = ();
 
2520
                        @parameterlist = ();
 
2521
                        %sections = ();
 
2522
                        @sectionlist = ();
 
2523
                        $prototype = "";
 
2524
                        $state = 0;
 
2525
                }
 
2526
                elsif (/$doc_content/)
 
2527
                {
 
2528
                        if ( $1 eq "" )
 
2529
                        {
 
2530
                                $contents .= $blankline;
 
2531
                        }
 
2532
                        else
 
2533
                        {
 
2534
                                $contents .= $1 . "\n";
 
2535
                        }
 
2536
                }
 
2537
        }
 
2538
    }
 
2539
    if ($initial_section_counter == $section_counter) {
 
2540
        print STDERR "Warning(${file}): no structured comments found\n";
 
2541
        if (($function_only == 1) && ($show_not_found == 1)) {
 
2542
            print STDERR "    Was looking for '$_'.\n" for keys %function_table;
 
2543
        }
 
2544
        if ($output_mode eq "xml") {
 
2545
            # The template wants at least one RefEntry here; make one.
 
2546
            print "<refentry>\n";
 
2547
            print " <refnamediv>\n";
 
2548
            print "  <refname>\n";
 
2549
            print "   ${file}\n";
 
2550
            print "  </refname>\n";
 
2551
            print "  <refpurpose>\n";
 
2552
            print "   Document generation inconsistency\n";
 
2553
            print "  </refpurpose>\n";
 
2554
            print " </refnamediv>\n";
 
2555
            print " <refsect1>\n";
 
2556
            print "  <title>\n";
 
2557
            print "   Oops\n";
 
2558
            print "  </title>\n";
 
2559
            print "  <warning>\n";
 
2560
            print "   <para>\n";
 
2561
            print "    The template for this document tried to insert\n";
 
2562
            print "    the structured comment from the file\n";
 
2563
            print "    <filename>${file}</filename> at this point,\n";
 
2564
            print "    but none was found.\n";
 
2565
            print "    This dummy section is inserted to allow\n";
 
2566
            print "    generation to continue.\n";
 
2567
            print "   </para>\n";
 
2568
            print "  </warning>\n";
 
2569
            print " </refsect1>\n";
 
2570
            print "</refentry>\n";
 
2571
        }
 
2572
    }
 
2573
}
 
2574
 
 
2575
 
 
2576
$kernelversion = get_kernel_version();
 
2577
 
 
2578
# generate a sequence of code that will splice in highlighting information
 
2579
# using the s// operator.
 
2580
foreach my $pattern (keys %highlights) {
 
2581
#   print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
 
2582
    $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
 
2583
}
 
2584
 
 
2585
# Read the file that maps relative names to absolute names for
 
2586
# separate source and object directories and for shadow trees.
 
2587
if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
 
2588
        my ($relname, $absname);
 
2589
        while(<SOURCE_MAP>) {
 
2590
                chop();
 
2591
                ($relname, $absname) = (split())[0..1];
 
2592
                $relname =~ s:^/+::;
 
2593
                $source_map{$relname} = $absname;
 
2594
        }
 
2595
        close(SOURCE_MAP);
 
2596
}
 
2597
 
 
2598
foreach (@ARGV) {
 
2599
    chomp;
 
2600
    process_file($_);
 
2601
}
 
2602
if ($verbose && $errors) {
 
2603
  print STDERR "$errors errors\n";
 
2604
}
 
2605
if ($verbose && $warnings) {
 
2606
  print STDERR "$warnings warnings\n";
 
2607
}
 
2608
 
 
2609
exit($errors);