]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - scripts/kernel-doc
blk-mq: remove the error argument to blk_mq_complete_request
[karo-tx-linux.git] / scripts / kernel-doc
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 sub usage {
43     my $message = <<"EOF";
44 Usage: $0 [OPTION ...] FILE ...
45
46 Read C language source or header FILEs, extract embedded documentation comments,
47 and print formatted documentation to standard output.
48
49 The documentation comments are identified by "/**" opening comment mark. See
50 Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax.
51
52 Output format selection (mutually exclusive):
53   -docbook              Output DocBook format.
54   -html                 Output HTML format.
55   -html5                Output HTML5 format.
56   -list                 Output symbol list format. This is for use by docproc.
57   -man                  Output troff manual page format. This is the default.
58   -rst                  Output reStructuredText format.
59   -text                 Output plain text format.
60
61 Output selection (mutually exclusive):
62   -export               Only output documentation for symbols that have been
63                         exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
64                         in any input FILE or -export-file FILE.
65   -internal             Only output documentation for symbols that have NOT been
66                         exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL()
67                         in any input FILE or -export-file FILE.
68   -function NAME        Only output documentation for the given function(s)
69                         or DOC: section title(s). All other functions and DOC:
70                         sections are ignored. May be specified multiple times.
71   -nofunction NAME      Do NOT output documentation for the given function(s);
72                         only output documentation for the other functions and
73                         DOC: sections. May be specified multiple times.
74
75 Output selection modifiers:
76   -no-doc-sections      Do not output DOC: sections.
77   -enable-lineno        Enable output of #define LINENO lines. Only works with
78                         reStructuredText format.
79   -export-file FILE     Specify an additional FILE in which to look for
80                         EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with
81                         -export or -internal. May be specified multiple times.
82
83 Other parameters:
84   -v                    Verbose output, more warnings and other information.
85   -h                    Print this help.
86
87 EOF
88     print $message;
89     exit 1;
90 }
91
92 #
93 # format of comments.
94 # In the following table, (...)? signifies optional structure.
95 #                         (...)* signifies 0 or more structure elements
96 # /**
97 #  * function_name(:)? (- short description)?
98 # (* @parameterx: (description of parameter x)?)*
99 # (* a blank line)?
100 #  * (Description:)? (Description of function)?
101 #  * (section header: (section description)? )*
102 #  (*)?*/
103 #
104 # So .. the trivial example would be:
105 #
106 # /**
107 #  * my_function
108 #  */
109 #
110 # If the Description: header tag is omitted, then there must be a blank line
111 # after the last parameter specification.
112 # e.g.
113 # /**
114 #  * my_function - does my stuff
115 #  * @my_arg: its mine damnit
116 #  *
117 #  * Does my stuff explained.
118 #  */
119 #
120 #  or, could also use:
121 # /**
122 #  * my_function - does my stuff
123 #  * @my_arg: its mine damnit
124 #  * Description: Does my stuff explained.
125 #  */
126 # etc.
127 #
128 # Besides functions you can also write documentation for structs, unions,
129 # enums and typedefs. Instead of the function name you must write the name
130 # of the declaration;  the struct/union/enum/typedef must always precede
131 # the name. Nesting of declarations is not supported.
132 # Use the argument mechanism to document members or constants.
133 # e.g.
134 # /**
135 #  * struct my_struct - short description
136 #  * @a: first member
137 #  * @b: second member
138 #  *
139 #  * Longer description
140 #  */
141 # struct my_struct {
142 #     int a;
143 #     int b;
144 # /* private: */
145 #     int c;
146 # };
147 #
148 # All descriptions can be multiline, except the short function description.
149 #
150 # For really longs structs, you can also describe arguments inside the
151 # body of the struct.
152 # eg.
153 # /**
154 #  * struct my_struct - short description
155 #  * @a: first member
156 #  * @b: second member
157 #  *
158 #  * Longer description
159 #  */
160 # struct my_struct {
161 #     int a;
162 #     int b;
163 #     /**
164 #      * @c: This is longer description of C
165 #      *
166 #      * You can use paragraphs to describe arguments
167 #      * using this method.
168 #      */
169 #     int c;
170 # };
171 #
172 # This should be use only for struct/enum members.
173 #
174 # You can also add additional sections. When documenting kernel functions you
175 # should document the "Context:" of the function, e.g. whether the functions
176 # can be called form interrupts. Unlike other sections you can end it with an
177 # empty line.
178 # A non-void function should have a "Return:" section describing the return
179 # value(s).
180 # Example-sections should contain the string EXAMPLE so that they are marked
181 # appropriately in DocBook.
182 #
183 # Example:
184 # /**
185 #  * user_function - function that can only be called in user context
186 #  * @a: some argument
187 #  * Context: !in_interrupt()
188 #  *
189 #  * Some description
190 #  * Example:
191 #  *    user_function(22);
192 #  */
193 # ...
194 #
195 #
196 # All descriptive text is further processed, scanning for the following special
197 # patterns, which are highlighted appropriately.
198 #
199 # 'funcname()' - function
200 # '$ENVVAR' - environmental variable
201 # '&struct_name' - name of a structure (up to two words including 'struct')
202 # '&struct_name.member' - name of a structure member
203 # '@parameter' - name of a parameter
204 # '%CONST' - name of a constant.
205
206 ## init lots of data
207
208 my $errors = 0;
209 my $warnings = 0;
210 my $anon_struct_union = 0;
211
212 # match expressions used to find embedded type information
213 my $type_constant = '\%([-_\w]+)';
214 my $type_func = '(\w+)\(\)';
215 my $type_param = '\@(\w+(\.\.\.)?)';
216 my $type_fp_param = '\@(\w+)\(\)';  # Special RST handling for func ptr params
217 my $type_env = '(\$\w+)';
218 my $type_enum = '\&(enum\s*([_\w]+))';
219 my $type_struct = '\&(struct\s*([_\w]+))';
220 my $type_typedef = '\&(typedef\s*([_\w]+))';
221 my $type_union = '\&(union\s*([_\w]+))';
222 my $type_member = '\&([_\w]+)(\.|->)([_\w]+)';
223 my $type_fallback = '\&([_\w]+)';
224 my $type_enum_xml = '\&amp;(enum\s*([_\w]+))';
225 my $type_struct_xml = '\&amp;(struct\s*([_\w]+))';
226 my $type_typedef_xml = '\&amp;(typedef\s*([_\w]+))';
227 my $type_union_xml = '\&amp;(union\s*([_\w]+))';
228 my $type_member_xml = '\&amp;([_\w]+)(\.|-\&gt;)([_\w]+)';
229 my $type_fallback_xml = '\&amp([_\w]+)';
230 my $type_member_func = $type_member . '\(\)';
231
232 # Output conversion substitutions.
233 #  One for each output format
234
235 # these work fairly well
236 my @highlights_html = (
237                        [$type_constant, "<i>\$1</i>"],
238                        [$type_func, "<b>\$1</b>"],
239                        [$type_enum_xml, "<i>\$1</i>"],
240                        [$type_struct_xml, "<i>\$1</i>"],
241                        [$type_typedef_xml, "<i>\$1</i>"],
242                        [$type_union_xml, "<i>\$1</i>"],
243                        [$type_env, "<b><i>\$1</i></b>"],
244                        [$type_param, "<tt><b>\$1</b></tt>"],
245                        [$type_member_xml, "<tt><i>\$1</i>\$2\$3</tt>"],
246                        [$type_fallback_xml, "<i>\$1</i>"]
247                       );
248 my $local_lt = "\\\\\\\\lt:";
249 my $local_gt = "\\\\\\\\gt:";
250 my $blankline_html = $local_lt . "p" . $local_gt;       # was "<p>"
251
252 # html version 5
253 my @highlights_html5 = (
254                         [$type_constant, "<span class=\"const\">\$1</span>"],
255                         [$type_func, "<span class=\"func\">\$1</span>"],
256                         [$type_enum_xml, "<span class=\"enum\">\$1</span>"],
257                         [$type_struct_xml, "<span class=\"struct\">\$1</span>"],
258                         [$type_typedef_xml, "<span class=\"typedef\">\$1</span>"],
259                         [$type_union_xml, "<span class=\"union\">\$1</span>"],
260                         [$type_env, "<span class=\"env\">\$1</span>"],
261                         [$type_param, "<span class=\"param\">\$1</span>]"],
262                         [$type_member_xml, "<span class=\"literal\"><span class=\"struct\">\$1</span>\$2<span class=\"member\">\$3</span></span>"],
263                         [$type_fallback_xml, "<span class=\"struct\">\$1</span>"]
264                        );
265 my $blankline_html5 = $local_lt . "br /" . $local_gt;
266
267 # XML, docbook format
268 my @highlights_xml = (
269                       ["([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>"],
270                       [$type_constant, "<constant>\$1</constant>"],
271                       [$type_enum_xml, "<type>\$1</type>"],
272                       [$type_struct_xml, "<structname>\$1</structname>"],
273                       [$type_typedef_xml, "<type>\$1</type>"],
274                       [$type_union_xml, "<structname>\$1</structname>"],
275                       [$type_param, "<parameter>\$1</parameter>"],
276                       [$type_func, "<function>\$1</function>"],
277                       [$type_env, "<envar>\$1</envar>"],
278                       [$type_member_xml, "<literal><structname>\$1</structname>\$2<structfield>\$3</structfield></literal>"],
279                       [$type_fallback_xml, "<structname>\$1</structname>"]
280                      );
281 my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
282
283 # gnome, docbook format
284 my @highlights_gnome = (
285                         [$type_constant, "<replaceable class=\"option\">\$1</replaceable>"],
286                         [$type_func, "<function>\$1</function>"],
287                         [$type_enum, "<type>\$1</type>"],
288                         [$type_struct, "<structname>\$1</structname>"],
289                         [$type_typedef, "<type>\$1</type>"],
290                         [$type_union, "<structname>\$1</structname>"],
291                         [$type_env, "<envar>\$1</envar>"],
292                         [$type_param, "<parameter>\$1</parameter>" ],
293                         [$type_member, "<literal><structname>\$1</structname>\$2<structfield>\$3</structfield></literal>"],
294                         [$type_fallback, "<structname>\$1</structname>"]
295                        );
296 my $blankline_gnome = "</para><para>\n";
297
298 # these are pretty rough
299 my @highlights_man = (
300                       [$type_constant, "\$1"],
301                       [$type_func, "\\\\fB\$1\\\\fP"],
302                       [$type_enum, "\\\\fI\$1\\\\fP"],
303                       [$type_struct, "\\\\fI\$1\\\\fP"],
304                       [$type_typedef, "\\\\fI\$1\\\\fP"],
305                       [$type_union, "\\\\fI\$1\\\\fP"],
306                       [$type_param, "\\\\fI\$1\\\\fP"],
307                       [$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
308                       [$type_fallback, "\\\\fI\$1\\\\fP"]
309                      );
310 my $blankline_man = "";
311
312 # text-mode
313 my @highlights_text = (
314                        [$type_constant, "\$1"],
315                        [$type_func, "\$1"],
316                        [$type_enum, "\$1"],
317                        [$type_struct, "\$1"],
318                        [$type_typedef, "\$1"],
319                        [$type_union, "\$1"],
320                        [$type_param, "\$1"],
321                        [$type_member, "\$1\$2\$3"],
322                        [$type_fallback, "\$1"]
323                       );
324 my $blankline_text = "";
325
326 # rst-mode
327 my @highlights_rst = (
328                        [$type_constant, "``\$1``"],
329                        # Note: need to escape () to avoid func matching later
330                        [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
331                        [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
332                        [$type_fp_param, "**\$1\\\\(\\\\)**"],
333                        [$type_func, "\\:c\\:func\\:`\$1()`"],
334                        [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
335                        [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
336                        [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"],
337                        [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
338                        # in rst this can refer to any type
339                        [$type_fallback, "\\:c\\:type\\:`\$1`"],
340                        [$type_param, "**\$1**"]
341                       );
342 my $blankline_rst = "\n";
343
344 # list mode
345 my @highlights_list = (
346                        [$type_constant, "\$1"],
347                        [$type_func, "\$1"],
348                        [$type_enum, "\$1"],
349                        [$type_struct, "\$1"],
350                        [$type_typedef, "\$1"],
351                        [$type_union, "\$1"],
352                        [$type_param, "\$1"],
353                        [$type_member, "\$1"],
354                        [$type_fallback, "\$1"]
355                       );
356 my $blankline_list = "";
357
358 # read arguments
359 if ($#ARGV == -1) {
360     usage();
361 }
362
363 my $kernelversion;
364 my $dohighlight = "";
365
366 my $verbose = 0;
367 my $output_mode = "man";
368 my $output_preformatted = 0;
369 my $no_doc_sections = 0;
370 my $enable_lineno = 0;
371 my @highlights = @highlights_man;
372 my $blankline = $blankline_man;
373 my $modulename = "Kernel API";
374
375 use constant {
376     OUTPUT_ALL          => 0, # output all symbols and doc sections
377     OUTPUT_INCLUDE      => 1, # output only specified symbols
378     OUTPUT_EXCLUDE      => 2, # output everything except specified symbols
379     OUTPUT_EXPORTED     => 3, # output exported symbols
380     OUTPUT_INTERNAL     => 4, # output non-exported symbols
381 };
382 my $output_selection = OUTPUT_ALL;
383 my $show_not_found = 0;
384
385 my @export_file_list;
386
387 my @build_time;
388 if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
389     (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
390     @build_time = gmtime($seconds);
391 } else {
392     @build_time = localtime;
393 }
394
395 my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
396                 'July', 'August', 'September', 'October',
397                 'November', 'December')[$build_time[4]] .
398   " " . ($build_time[5]+1900);
399
400 # Essentially these are globals.
401 # They probably want to be tidied up, made more localised or something.
402 # CAVEAT EMPTOR!  Some of the others I localised may not want to be, which
403 # could cause "use of undefined value" or other bugs.
404 my ($function, %function_table, %parametertypes, $declaration_purpose);
405 my $declaration_start_line;
406 my ($type, $declaration_name, $return_type);
407 my ($newsection, $newcontents, $prototype, $brcount, %source_map);
408
409 if (defined($ENV{'KBUILD_VERBOSE'})) {
410         $verbose = "$ENV{'KBUILD_VERBOSE'}";
411 }
412
413 # Generated docbook code is inserted in a template at a point where
414 # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
415 # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
416 # We keep track of number of generated entries and generate a dummy
417 # if needs be to ensure the expanded template can be postprocessed
418 # into html.
419 my $section_counter = 0;
420
421 my $lineprefix="";
422
423 # Parser states
424 use constant {
425     STATE_NORMAL        => 0, # normal code
426     STATE_NAME          => 1, # looking for function name
427     STATE_FIELD         => 2, # scanning field start
428     STATE_PROTO         => 3, # scanning prototype
429     STATE_DOCBLOCK      => 4, # documentation block
430     STATE_INLINE        => 5, # gathering documentation outside main block
431 };
432 my $state;
433 my $in_doc_sect;
434
435 # Inline documentation state
436 use constant {
437     STATE_INLINE_NA     => 0, # not applicable ($state != STATE_INLINE)
438     STATE_INLINE_NAME   => 1, # looking for member name (@foo:)
439     STATE_INLINE_TEXT   => 2, # looking for member documentation
440     STATE_INLINE_END    => 3, # done
441     STATE_INLINE_ERROR  => 4, # error - Comment without header was found.
442                               # Spit a warning as it's not
443                               # proper kernel-doc and ignore the rest.
444 };
445 my $inline_doc_state;
446
447 #declaration types: can be
448 # 'function', 'struct', 'union', 'enum', 'typedef'
449 my $decl_type;
450
451 my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
452 my $doc_end = '\*/';
453 my $doc_com = '\s*\*\s*';
454 my $doc_com_body = '\s*\* ?';
455 my $doc_decl = $doc_com . '(\w+)';
456 # @params and a strictly limited set of supported section names
457 my $doc_sect = $doc_com . 
458     '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)';
459 my $doc_content = $doc_com_body . '(.*)';
460 my $doc_block = $doc_com . 'DOC:\s*(.*)?';
461 my $doc_inline_start = '^\s*/\*\*\s*$';
462 my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)';
463 my $doc_inline_end = '^\s*\*/\s*$';
464 my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$';
465 my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
466
467 my %parameterdescs;
468 my %parameterdesc_start_lines;
469 my @parameterlist;
470 my %sections;
471 my @sectionlist;
472 my %section_start_lines;
473 my $sectcheck;
474 my $struct_actual;
475
476 my $contents = "";
477 my $new_start_line = 0;
478
479 # the canonical section names. see also $doc_sect above.
480 my $section_default = "Description";    # default section
481 my $section_intro = "Introduction";
482 my $section = $section_default;
483 my $section_context = "Context";
484 my $section_return = "Return";
485
486 my $undescribed = "-- undescribed --";
487
488 reset_state();
489
490 while ($ARGV[0] =~ m/^-(.*)/) {
491     my $cmd = shift @ARGV;
492     if ($cmd eq "-html") {
493         $output_mode = "html";
494         @highlights = @highlights_html;
495         $blankline = $blankline_html;
496     } elsif ($cmd eq "-html5") {
497         $output_mode = "html5";
498         @highlights = @highlights_html5;
499         $blankline = $blankline_html5;
500     } elsif ($cmd eq "-man") {
501         $output_mode = "man";
502         @highlights = @highlights_man;
503         $blankline = $blankline_man;
504     } elsif ($cmd eq "-text") {
505         $output_mode = "text";
506         @highlights = @highlights_text;
507         $blankline = $blankline_text;
508     } elsif ($cmd eq "-rst") {
509         $output_mode = "rst";
510         @highlights = @highlights_rst;
511         $blankline = $blankline_rst;
512     } elsif ($cmd eq "-docbook") {
513         $output_mode = "xml";
514         @highlights = @highlights_xml;
515         $blankline = $blankline_xml;
516     } elsif ($cmd eq "-list") {
517         $output_mode = "list";
518         @highlights = @highlights_list;
519         $blankline = $blankline_list;
520     } elsif ($cmd eq "-gnome") {
521         $output_mode = "gnome";
522         @highlights = @highlights_gnome;
523         $blankline = $blankline_gnome;
524     } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
525         $modulename = shift @ARGV;
526     } elsif ($cmd eq "-function") { # to only output specific functions
527         $output_selection = OUTPUT_INCLUDE;
528         $function = shift @ARGV;
529         $function_table{$function} = 1;
530     } elsif ($cmd eq "-nofunction") { # output all except specific functions
531         $output_selection = OUTPUT_EXCLUDE;
532         $function = shift @ARGV;
533         $function_table{$function} = 1;
534     } elsif ($cmd eq "-export") { # only exported symbols
535         $output_selection = OUTPUT_EXPORTED;
536         %function_table = ();
537     } elsif ($cmd eq "-internal") { # only non-exported symbols
538         $output_selection = OUTPUT_INTERNAL;
539         %function_table = ();
540     } elsif ($cmd eq "-export-file") {
541         my $file = shift @ARGV;
542         push(@export_file_list, $file);
543     } elsif ($cmd eq "-v") {
544         $verbose = 1;
545     } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
546         usage();
547     } elsif ($cmd eq '-no-doc-sections') {
548             $no_doc_sections = 1;
549     } elsif ($cmd eq '-enable-lineno') {
550             $enable_lineno = 1;
551     } elsif ($cmd eq '-show-not-found') {
552         $show_not_found = 1;
553     }
554 }
555
556 # continue execution near EOF;
557
558 # get kernel version from env
559 sub get_kernel_version() {
560     my $version = 'unknown kernel version';
561
562     if (defined($ENV{'KERNELVERSION'})) {
563         $version = $ENV{'KERNELVERSION'};
564     }
565     return $version;
566 }
567
568 #
569 sub print_lineno {
570     my $lineno = shift;
571     if ($enable_lineno && defined($lineno)) {
572         print "#define LINENO " . $lineno . "\n";
573     }
574 }
575 ##
576 # dumps section contents to arrays/hashes intended for that purpose.
577 #
578 sub dump_section {
579     my $file = shift;
580     my $name = shift;
581     my $contents = join "\n", @_;
582
583     if ($name =~ m/$type_param/) {
584         $name = $1;
585         $parameterdescs{$name} = $contents;
586         $sectcheck = $sectcheck . $name . " ";
587         $parameterdesc_start_lines{$name} = $new_start_line;
588         $new_start_line = 0;
589     } elsif ($name eq "@\.\.\.") {
590         $name = "...";
591         $parameterdescs{$name} = $contents;
592         $sectcheck = $sectcheck . $name . " ";
593         $parameterdesc_start_lines{$name} = $new_start_line;
594         $new_start_line = 0;
595     } else {
596         if (defined($sections{$name}) && ($sections{$name} ne "")) {
597             # Only warn on user specified duplicate section names.
598             if ($name ne $section_default) {
599                 print STDERR "${file}:$.: warning: duplicate section name '$name'\n";
600                 ++$warnings;
601             }
602             $sections{$name} .= $contents;
603         } else {
604             $sections{$name} = $contents;
605             push @sectionlist, $name;
606             $section_start_lines{$name} = $new_start_line;
607             $new_start_line = 0;
608         }
609     }
610 }
611
612 ##
613 # dump DOC: section after checking that it should go out
614 #
615 sub dump_doc_section {
616     my $file = shift;
617     my $name = shift;
618     my $contents = join "\n", @_;
619
620     if ($no_doc_sections) {
621         return;
622     }
623
624     if (($output_selection == OUTPUT_ALL) ||
625         ($output_selection == OUTPUT_INCLUDE &&
626          defined($function_table{$name})) ||
627         ($output_selection == OUTPUT_EXCLUDE &&
628          !defined($function_table{$name})))
629     {
630         dump_section($file, $name, $contents);
631         output_blockhead({'sectionlist' => \@sectionlist,
632                           'sections' => \%sections,
633                           'module' => $modulename,
634                           'content-only' => ($output_selection != OUTPUT_ALL), });
635     }
636 }
637
638 ##
639 # output function
640 #
641 # parameterdescs, a hash.
642 #  function => "function name"
643 #  parameterlist => @list of parameters
644 #  parameterdescs => %parameter descriptions
645 #  sectionlist => @list of sections
646 #  sections => %section descriptions
647 #
648
649 sub output_highlight {
650     my $contents = join "\n",@_;
651     my $line;
652
653 #   DEBUG
654 #   if (!defined $contents) {
655 #       use Carp;
656 #       confess "output_highlight got called with no args?\n";
657 #   }
658
659     if ($output_mode eq "html" || $output_mode eq "html5" ||
660         $output_mode eq "xml") {
661         $contents = local_unescape($contents);
662         # convert data read & converted thru xml_escape() into &xyz; format:
663         $contents =~ s/\\\\\\/\&/g;
664     }
665 #   print STDERR "contents b4:$contents\n";
666     eval $dohighlight;
667     die $@ if $@;
668 #   print STDERR "contents af:$contents\n";
669
670 #   strip whitespaces when generating html5
671     if ($output_mode eq "html5") {
672         $contents =~ s/^\s+//;
673         $contents =~ s/\s+$//;
674     }
675     foreach $line (split "\n", $contents) {
676         if (! $output_preformatted) {
677             $line =~ s/^\s*//;
678         }
679         if ($line eq ""){
680             if (! $output_preformatted) {
681                 print $lineprefix, local_unescape($blankline);
682             }
683         } else {
684             $line =~ s/\\\\\\/\&/g;
685             if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
686                 print "\\&$line";
687             } else {
688                 print $lineprefix, $line;
689             }
690         }
691         print "\n";
692     }
693 }
694
695 # output sections in html
696 sub output_section_html(%) {
697     my %args = %{$_[0]};
698     my $section;
699
700     foreach $section (@{$args{'sectionlist'}}) {
701         print "<h3>$section</h3>\n";
702         print "<blockquote>\n";
703         output_highlight($args{'sections'}{$section});
704         print "</blockquote>\n";
705     }
706 }
707
708 # output enum in html
709 sub output_enum_html(%) {
710     my %args = %{$_[0]};
711     my ($parameter);
712     my $count;
713     print "<h2>enum " . $args{'enum'} . "</h2>\n";
714
715     print "<b>enum " . $args{'enum'} . "</b> {<br>\n";
716     $count = 0;
717     foreach $parameter (@{$args{'parameterlist'}}) {
718         print " <b>" . $parameter . "</b>";
719         if ($count != $#{$args{'parameterlist'}}) {
720             $count++;
721             print ",\n";
722         }
723         print "<br>";
724     }
725     print "};<br>\n";
726
727     print "<h3>Constants</h3>\n";
728     print "<dl>\n";
729     foreach $parameter (@{$args{'parameterlist'}}) {
730         print "<dt><b>" . $parameter . "</b>\n";
731         print "<dd>";
732         output_highlight($args{'parameterdescs'}{$parameter});
733     }
734     print "</dl>\n";
735     output_section_html(@_);
736     print "<hr>\n";
737 }
738
739 # output typedef in html
740 sub output_typedef_html(%) {
741     my %args = %{$_[0]};
742     my ($parameter);
743     my $count;
744     print "<h2>typedef " . $args{'typedef'} . "</h2>\n";
745
746     print "<b>typedef " . $args{'typedef'} . "</b>\n";
747     output_section_html(@_);
748     print "<hr>\n";
749 }
750
751 # output struct in html
752 sub output_struct_html(%) {
753     my %args = %{$_[0]};
754     my ($parameter);
755
756     print "<h2>" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "</h2>\n";
757     print "<b>" . $args{'type'} . " " . $args{'struct'} . "</b> {<br>\n";
758     foreach $parameter (@{$args{'parameterlist'}}) {
759         if ($parameter =~ /^#/) {
760                 print "$parameter<br>\n";
761                 next;
762         }
763         my $parameter_name = $parameter;
764         $parameter_name =~ s/\[.*//;
765
766         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
767         $type = $args{'parametertypes'}{$parameter};
768         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
769             # pointer-to-function
770             print "&nbsp; &nbsp; <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
771         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
772             # bitfield
773             print "&nbsp; &nbsp; <i>$1</i> <b>$parameter</b>$2;<br>\n";
774         } else {
775             print "&nbsp; &nbsp; <i>$type</i> <b>$parameter</b>;<br>\n";
776         }
777     }
778     print "};<br>\n";
779
780     print "<h3>Members</h3>\n";
781     print "<dl>\n";
782     foreach $parameter (@{$args{'parameterlist'}}) {
783         ($parameter =~ /^#/) && next;
784
785         my $parameter_name = $parameter;
786         $parameter_name =~ s/\[.*//;
787
788         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
789         print "<dt><b>" . $parameter . "</b>\n";
790         print "<dd>";
791         output_highlight($args{'parameterdescs'}{$parameter_name});
792     }
793     print "</dl>\n";
794     output_section_html(@_);
795     print "<hr>\n";
796 }
797
798 # output function in html
799 sub output_function_html(%) {
800     my %args = %{$_[0]};
801     my ($parameter, $section);
802     my $count;
803
804     print "<h2>" . $args{'function'} . " - " . $args{'purpose'} . "</h2>\n";
805     print "<i>" . $args{'functiontype'} . "</i>\n";
806     print "<b>" . $args{'function'} . "</b>\n";
807     print "(";
808     $count = 0;
809     foreach $parameter (@{$args{'parameterlist'}}) {
810         $type = $args{'parametertypes'}{$parameter};
811         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
812             # pointer-to-function
813             print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
814         } else {
815             print "<i>" . $type . "</i> <b>" . $parameter . "</b>";
816         }
817         if ($count != $#{$args{'parameterlist'}}) {
818             $count++;
819             print ",\n";
820         }
821     }
822     print ")\n";
823
824     print "<h3>Arguments</h3>\n";
825     print "<dl>\n";
826     foreach $parameter (@{$args{'parameterlist'}}) {
827         my $parameter_name = $parameter;
828         $parameter_name =~ s/\[.*//;
829
830         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
831         print "<dt><b>" . $parameter . "</b>\n";
832         print "<dd>";
833         output_highlight($args{'parameterdescs'}{$parameter_name});
834     }
835     print "</dl>\n";
836     output_section_html(@_);
837     print "<hr>\n";
838 }
839
840 # output DOC: block header in html
841 sub output_blockhead_html(%) {
842     my %args = %{$_[0]};
843     my ($parameter, $section);
844     my $count;
845
846     foreach $section (@{$args{'sectionlist'}}) {
847         print "<h3>$section</h3>\n";
848         print "<ul>\n";
849         output_highlight($args{'sections'}{$section});
850         print "</ul>\n";
851     }
852     print "<hr>\n";
853 }
854
855 # output sections in html5
856 sub output_section_html5(%) {
857     my %args = %{$_[0]};
858     my $section;
859
860     foreach $section (@{$args{'sectionlist'}}) {
861         print "<section>\n";
862         print "<h1>$section</h1>\n";
863         print "<p>\n";
864         output_highlight($args{'sections'}{$section});
865         print "</p>\n";
866         print "</section>\n";
867     }
868 }
869
870 # output enum in html5
871 sub output_enum_html5(%) {
872     my %args = %{$_[0]};
873     my ($parameter);
874     my $count;
875     my $html5id;
876
877     $html5id = $args{'enum'};
878     $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
879     print "<article class=\"enum\" id=\"enum:". $html5id . "\">";
880     print "<h1>enum " . $args{'enum'} . "</h1>\n";
881     print "<ol class=\"code\">\n";
882     print "<li>";
883     print "<span class=\"keyword\">enum</span> ";
884     print "<span class=\"identifier\">" . $args{'enum'} . "</span> {";
885     print "</li>\n";
886     $count = 0;
887     foreach $parameter (@{$args{'parameterlist'}}) {
888         print "<li class=\"indent\">";
889         print "<span class=\"param\">" . $parameter . "</span>";
890         if ($count != $#{$args{'parameterlist'}}) {
891             $count++;
892             print ",";
893         }
894         print "</li>\n";
895     }
896     print "<li>};</li>\n";
897     print "</ol>\n";
898
899     print "<section>\n";
900     print "<h1>Constants</h1>\n";
901     print "<dl>\n";
902     foreach $parameter (@{$args{'parameterlist'}}) {
903         print "<dt>" . $parameter . "</dt>\n";
904         print "<dd>";
905         output_highlight($args{'parameterdescs'}{$parameter});
906         print "</dd>\n";
907     }
908     print "</dl>\n";
909     print "</section>\n";
910     output_section_html5(@_);
911     print "</article>\n";
912 }
913
914 # output typedef in html5
915 sub output_typedef_html5(%) {
916     my %args = %{$_[0]};
917     my ($parameter);
918     my $count;
919     my $html5id;
920
921     $html5id = $args{'typedef'};
922     $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
923     print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n";
924     print "<h1>typedef " . $args{'typedef'} . "</h1>\n";
925
926     print "<ol class=\"code\">\n";
927     print "<li>";
928     print "<span class=\"keyword\">typedef</span> ";
929     print "<span class=\"identifier\">" . $args{'typedef'} . "</span>";
930     print "</li>\n";
931     print "</ol>\n";
932     output_section_html5(@_);
933     print "</article>\n";
934 }
935
936 # output struct in html5
937 sub output_struct_html5(%) {
938     my %args = %{$_[0]};
939     my ($parameter);
940     my $html5id;
941
942     $html5id = $args{'struct'};
943     $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
944     print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n";
945     print "<hgroup>\n";
946     print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>";
947     print "<h2>". $args{'purpose'} . "</h2>\n";
948     print "</hgroup>\n";
949     print "<ol class=\"code\">\n";
950     print "<li>";
951     print "<span class=\"type\">" . $args{'type'} . "</span> ";
952     print "<span class=\"identifier\">" . $args{'struct'} . "</span> {";
953     print "</li>\n";
954     foreach $parameter (@{$args{'parameterlist'}}) {
955         print "<li class=\"indent\">";
956         if ($parameter =~ /^#/) {
957                 print "<span class=\"param\">" . $parameter ."</span>\n";
958                 print "</li>\n";
959                 next;
960         }
961         my $parameter_name = $parameter;
962         $parameter_name =~ s/\[.*//;
963
964         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
965         $type = $args{'parametertypes'}{$parameter};
966         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
967             # pointer-to-function
968             print "<span class=\"type\">$1</span> ";
969             print "<span class=\"param\">$parameter</span>";
970             print "<span class=\"type\">)</span> ";
971             print "(<span class=\"args\">$2</span>);";
972         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
973             # bitfield
974             print "<span class=\"type\">$1</span> ";
975             print "<span class=\"param\">$parameter</span>";
976             print "<span class=\"bits\">$2</span>;";
977         } else {
978             print "<span class=\"type\">$type</span> ";
979             print "<span class=\"param\">$parameter</span>;";
980         }
981         print "</li>\n";
982     }
983     print "<li>};</li>\n";
984     print "</ol>\n";
985
986     print "<section>\n";
987     print "<h1>Members</h1>\n";
988     print "<dl>\n";
989     foreach $parameter (@{$args{'parameterlist'}}) {
990         ($parameter =~ /^#/) && next;
991
992         my $parameter_name = $parameter;
993         $parameter_name =~ s/\[.*//;
994
995         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
996         print "<dt>" . $parameter . "</dt>\n";
997         print "<dd>";
998         output_highlight($args{'parameterdescs'}{$parameter_name});
999         print "</dd>\n";
1000     }
1001     print "</dl>\n";
1002     print "</section>\n";
1003     output_section_html5(@_);
1004     print "</article>\n";
1005 }
1006
1007 # output function in html5
1008 sub output_function_html5(%) {
1009     my %args = %{$_[0]};
1010     my ($parameter, $section);
1011     my $count;
1012     my $html5id;
1013
1014     $html5id = $args{'function'};
1015     $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
1016     print "<article class=\"function\" id=\"func:". $html5id . "\">\n";
1017     print "<hgroup>\n";
1018     print "<h1>" . $args{'function'} . "</h1>";
1019     print "<h2>" . $args{'purpose'} . "</h2>\n";
1020     print "</hgroup>\n";
1021     print "<ol class=\"code\">\n";
1022     print "<li>";
1023     print "<span class=\"type\">" . $args{'functiontype'} . "</span> ";
1024     print "<span class=\"identifier\">" . $args{'function'} . "</span> (";
1025     print "</li>";
1026     $count = 0;
1027     foreach $parameter (@{$args{'parameterlist'}}) {
1028         print "<li class=\"indent\">";
1029         $type = $args{'parametertypes'}{$parameter};
1030         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1031             # pointer-to-function
1032             print "<span class=\"type\">$1</span> ";
1033             print "<span class=\"param\">$parameter</span>";
1034             print "<span class=\"type\">)</span> ";
1035             print "(<span class=\"args\">$2</span>)";
1036         } else {
1037             print "<span class=\"type\">$type</span> ";
1038             print "<span class=\"param\">$parameter</span>";
1039         }
1040         if ($count != $#{$args{'parameterlist'}}) {
1041             $count++;
1042             print ",";
1043         }
1044         print "</li>\n";
1045     }
1046     print "<li>)</li>\n";
1047     print "</ol>\n";
1048
1049     print "<section>\n";
1050     print "<h1>Arguments</h1>\n";
1051     print "<p>\n";
1052     print "<dl>\n";
1053     foreach $parameter (@{$args{'parameterlist'}}) {
1054         my $parameter_name = $parameter;
1055         $parameter_name =~ s/\[.*//;
1056
1057         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1058         print "<dt>" . $parameter . "</dt>\n";
1059         print "<dd>";
1060         output_highlight($args{'parameterdescs'}{$parameter_name});
1061         print "</dd>\n";
1062     }
1063     print "</dl>\n";
1064     print "</section>\n";
1065     output_section_html5(@_);
1066     print "</article>\n";
1067 }
1068
1069 # output DOC: block header in html5
1070 sub output_blockhead_html5(%) {
1071     my %args = %{$_[0]};
1072     my ($parameter, $section);
1073     my $count;
1074     my $html5id;
1075
1076     foreach $section (@{$args{'sectionlist'}}) {
1077         $html5id = $section;
1078         $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
1079         print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n";
1080         print "<h1>$section</h1>\n";
1081         print "<p>\n";
1082         output_highlight($args{'sections'}{$section});
1083         print "</p>\n";
1084     }
1085     print "</article>\n";
1086 }
1087
1088 sub output_section_xml(%) {
1089     my %args = %{$_[0]};
1090     my $section;
1091     # print out each section
1092     $lineprefix="   ";
1093     foreach $section (@{$args{'sectionlist'}}) {
1094         print "<refsect1>\n";
1095         print "<title>$section</title>\n";
1096         if ($section =~ m/EXAMPLE/i) {
1097             print "<informalexample><programlisting>\n";
1098             $output_preformatted = 1;
1099         } else {
1100             print "<para>\n";
1101         }
1102         output_highlight($args{'sections'}{$section});
1103         $output_preformatted = 0;
1104         if ($section =~ m/EXAMPLE/i) {
1105             print "</programlisting></informalexample>\n";
1106         } else {
1107             print "</para>\n";
1108         }
1109         print "</refsect1>\n";
1110     }
1111 }
1112
1113 # output function in XML DocBook
1114 sub output_function_xml(%) {
1115     my %args = %{$_[0]};
1116     my ($parameter, $section);
1117     my $count;
1118     my $id;
1119
1120     $id = "API-" . $args{'function'};
1121     $id =~ s/[^A-Za-z0-9]/-/g;
1122
1123     print "<refentry id=\"$id\">\n";
1124     print "<refentryinfo>\n";
1125     print " <title>LINUX</title>\n";
1126     print " <productname>Kernel Hackers Manual</productname>\n";
1127     print " <date>$man_date</date>\n";
1128     print "</refentryinfo>\n";
1129     print "<refmeta>\n";
1130     print " <refentrytitle><phrase>" . $args{'function'} . "</phrase></refentrytitle>\n";
1131     print " <manvolnum>9</manvolnum>\n";
1132     print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
1133     print "</refmeta>\n";
1134     print "<refnamediv>\n";
1135     print " <refname>" . $args{'function'} . "</refname>\n";
1136     print " <refpurpose>\n";
1137     print "  ";
1138     output_highlight ($args{'purpose'});
1139     print " </refpurpose>\n";
1140     print "</refnamediv>\n";
1141
1142     print "<refsynopsisdiv>\n";
1143     print " <title>Synopsis</title>\n";
1144     print "  <funcsynopsis><funcprototype>\n";
1145     print "   <funcdef>" . $args{'functiontype'} . " ";
1146     print "<function>" . $args{'function'} . " </function></funcdef>\n";
1147
1148     $count = 0;
1149     if ($#{$args{'parameterlist'}} >= 0) {
1150         foreach $parameter (@{$args{'parameterlist'}}) {
1151             $type = $args{'parametertypes'}{$parameter};
1152             if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1153                 # pointer-to-function
1154                 print "   <paramdef>$1<parameter>$parameter</parameter>)\n";
1155                 print "     <funcparams>$2</funcparams></paramdef>\n";
1156             } else {
1157                 print "   <paramdef>" . $type;
1158                 print " <parameter>$parameter</parameter></paramdef>\n";
1159             }
1160         }
1161     } else {
1162         print "  <void/>\n";
1163     }
1164     print "  </funcprototype></funcsynopsis>\n";
1165     print "</refsynopsisdiv>\n";
1166
1167     # print parameters
1168     print "<refsect1>\n <title>Arguments</title>\n";
1169     if ($#{$args{'parameterlist'}} >= 0) {
1170         print " <variablelist>\n";
1171         foreach $parameter (@{$args{'parameterlist'}}) {
1172             my $parameter_name = $parameter;
1173             $parameter_name =~ s/\[.*//;
1174             $type = $args{'parametertypes'}{$parameter};
1175
1176             print "  <varlistentry>\n   <term><parameter>$type $parameter</parameter></term>\n";
1177             print "   <listitem>\n    <para>\n";
1178             $lineprefix="     ";
1179             output_highlight($args{'parameterdescs'}{$parameter_name});
1180             print "    </para>\n   </listitem>\n  </varlistentry>\n";
1181         }
1182         print " </variablelist>\n";
1183     } else {
1184         print " <para>\n  None\n </para>\n";
1185     }
1186     print "</refsect1>\n";
1187
1188     output_section_xml(@_);
1189     print "</refentry>\n\n";
1190 }
1191
1192 # output struct in XML DocBook
1193 sub output_struct_xml(%) {
1194     my %args = %{$_[0]};
1195     my ($parameter, $section);
1196     my $id;
1197
1198     $id = "API-struct-" . $args{'struct'};
1199     $id =~ s/[^A-Za-z0-9]/-/g;
1200
1201     print "<refentry id=\"$id\">\n";
1202     print "<refentryinfo>\n";
1203     print " <title>LINUX</title>\n";
1204     print " <productname>Kernel Hackers Manual</productname>\n";
1205     print " <date>$man_date</date>\n";
1206     print "</refentryinfo>\n";
1207     print "<refmeta>\n";
1208     print " <refentrytitle><phrase>" . $args{'type'} . " " . $args{'struct'} . "</phrase></refentrytitle>\n";
1209     print " <manvolnum>9</manvolnum>\n";
1210     print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
1211     print "</refmeta>\n";
1212     print "<refnamediv>\n";
1213     print " <refname>" . $args{'type'} . " " . $args{'struct'} . "</refname>\n";
1214     print " <refpurpose>\n";
1215     print "  ";
1216     output_highlight ($args{'purpose'});
1217     print " </refpurpose>\n";
1218     print "</refnamediv>\n";
1219
1220     print "<refsynopsisdiv>\n";
1221     print " <title>Synopsis</title>\n";
1222     print "  <programlisting>\n";
1223     print $args{'type'} . " " . $args{'struct'} . " {\n";
1224     foreach $parameter (@{$args{'parameterlist'}}) {
1225         if ($parameter =~ /^#/) {
1226             my $prm = $parameter;
1227             # convert data read & converted thru xml_escape() into &xyz; format:
1228             # This allows us to have #define macros interspersed in a struct.
1229             $prm =~ s/\\\\\\/\&/g;
1230             print "$prm\n";
1231             next;
1232         }
1233
1234         my $parameter_name = $parameter;
1235         $parameter_name =~ s/\[.*//;
1236
1237         defined($args{'parameterdescs'}{$parameter_name}) || next;
1238         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1239         $type = $args{'parametertypes'}{$parameter};
1240         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1241             # pointer-to-function
1242             print "  $1 $parameter) ($2);\n";
1243         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1244             # bitfield
1245             print "  $1 $parameter$2;\n";
1246         } else {
1247             print "  " . $type . " " . $parameter . ";\n";
1248         }
1249     }
1250     print "};";
1251     print "  </programlisting>\n";
1252     print "</refsynopsisdiv>\n";
1253
1254     print " <refsect1>\n";
1255     print "  <title>Members</title>\n";
1256
1257     if ($#{$args{'parameterlist'}} >= 0) {
1258     print "  <variablelist>\n";
1259     foreach $parameter (@{$args{'parameterlist'}}) {
1260       ($parameter =~ /^#/) && next;
1261
1262       my $parameter_name = $parameter;
1263       $parameter_name =~ s/\[.*//;
1264
1265       defined($args{'parameterdescs'}{$parameter_name}) || next;
1266       ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1267       $type = $args{'parametertypes'}{$parameter};
1268       print "    <varlistentry>";
1269       print "      <term><literal>$type $parameter</literal></term>\n";
1270       print "      <listitem><para>\n";
1271       output_highlight($args{'parameterdescs'}{$parameter_name});
1272       print "      </para></listitem>\n";
1273       print "    </varlistentry>\n";
1274     }
1275     print "  </variablelist>\n";
1276     } else {
1277         print " <para>\n  None\n </para>\n";
1278     }
1279     print " </refsect1>\n";
1280
1281     output_section_xml(@_);
1282
1283     print "</refentry>\n\n";
1284 }
1285
1286 # output enum in XML DocBook
1287 sub output_enum_xml(%) {
1288     my %args = %{$_[0]};
1289     my ($parameter, $section);
1290     my $count;
1291     my $id;
1292
1293     $id = "API-enum-" . $args{'enum'};
1294     $id =~ s/[^A-Za-z0-9]/-/g;
1295
1296     print "<refentry id=\"$id\">\n";
1297     print "<refentryinfo>\n";
1298     print " <title>LINUX</title>\n";
1299     print " <productname>Kernel Hackers Manual</productname>\n";
1300     print " <date>$man_date</date>\n";
1301     print "</refentryinfo>\n";
1302     print "<refmeta>\n";
1303     print " <refentrytitle><phrase>enum " . $args{'enum'} . "</phrase></refentrytitle>\n";
1304     print " <manvolnum>9</manvolnum>\n";
1305     print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n";
1306     print "</refmeta>\n";
1307     print "<refnamediv>\n";
1308     print " <refname>enum " . $args{'enum'} . "</refname>\n";
1309     print " <refpurpose>\n";
1310     print "  ";
1311     output_highlight ($args{'purpose'});
1312     print " </refpurpose>\n";
1313     print "</refnamediv>\n";
1314
1315     print "<refsynopsisdiv>\n";
1316     print " <title>Synopsis</title>\n";
1317     print "  <programlisting>\n";
1318     print "enum " . $args{'enum'} . " {\n";
1319     $count = 0;
1320     foreach $parameter (@{$args{'parameterlist'}}) {
1321         print "  $parameter";
1322         if ($count != $#{$args{'parameterlist'}}) {
1323             $count++;
1324             print ",";
1325         }
1326         print "\n";
1327     }
1328     print "};";
1329     print "  </programlisting>\n";
1330     print "</refsynopsisdiv>\n";
1331
1332     print "<refsect1>\n";
1333     print " <title>Constants</title>\n";
1334     print "  <variablelist>\n";
1335     foreach $parameter (@{$args{'parameterlist'}}) {
1336       my $parameter_name = $parameter;
1337       $parameter_name =~ s/\[.*//;
1338
1339       print "    <varlistentry>";
1340       print "      <term>$parameter</term>\n";
1341       print "      <listitem><para>\n";
1342       output_highlight($args{'parameterdescs'}{$parameter_name});
1343       print "      </para></listitem>\n";
1344       print "    </varlistentry>\n";
1345     }
1346     print "  </variablelist>\n";
1347     print "</refsect1>\n";
1348
1349     output_section_xml(@_);
1350
1351     print "</refentry>\n\n";
1352 }
1353
1354 # output typedef in XML DocBook
1355 sub output_typedef_xml(%) {
1356     my %args = %{$_[0]};
1357     my ($parameter, $section);
1358     my $id;
1359
1360     $id = "API-typedef-" . $args{'typedef'};
1361     $id =~ s/[^A-Za-z0-9]/-/g;
1362
1363     print "<refentry id=\"$id\">\n";
1364     print "<refentryinfo>\n";
1365     print " <title>LINUX</title>\n";
1366     print " <productname>Kernel Hackers Manual</productname>\n";
1367     print " <date>$man_date</date>\n";
1368     print "</refentryinfo>\n";
1369     print "<refmeta>\n";
1370     print " <refentrytitle><phrase>typedef " . $args{'typedef'} . "</phrase></refentrytitle>\n";
1371     print " <manvolnum>9</manvolnum>\n";
1372     print "</refmeta>\n";
1373     print "<refnamediv>\n";
1374     print " <refname>typedef " . $args{'typedef'} . "</refname>\n";
1375     print " <refpurpose>\n";
1376     print "  ";
1377     output_highlight ($args{'purpose'});
1378     print " </refpurpose>\n";
1379     print "</refnamediv>\n";
1380
1381     print "<refsynopsisdiv>\n";
1382     print " <title>Synopsis</title>\n";
1383     print "  <synopsis>typedef " . $args{'typedef'} . ";</synopsis>\n";
1384     print "</refsynopsisdiv>\n";
1385
1386     output_section_xml(@_);
1387
1388     print "</refentry>\n\n";
1389 }
1390
1391 # output in XML DocBook
1392 sub output_blockhead_xml(%) {
1393     my %args = %{$_[0]};
1394     my ($parameter, $section);
1395     my $count;
1396
1397     my $id = $args{'module'};
1398     $id =~ s/[^A-Za-z0-9]/-/g;
1399
1400     # print out each section
1401     $lineprefix="   ";
1402     foreach $section (@{$args{'sectionlist'}}) {
1403         if (!$args{'content-only'}) {
1404                 print "<refsect1>\n <title>$section</title>\n";
1405         }
1406         if ($section =~ m/EXAMPLE/i) {
1407             print "<example><para>\n";
1408             $output_preformatted = 1;
1409         } else {
1410             print "<para>\n";
1411         }
1412         output_highlight($args{'sections'}{$section});
1413         $output_preformatted = 0;
1414         if ($section =~ m/EXAMPLE/i) {
1415             print "</para></example>\n";
1416         } else {
1417             print "</para>";
1418         }
1419         if (!$args{'content-only'}) {
1420                 print "\n</refsect1>\n";
1421         }
1422     }
1423
1424     print "\n\n";
1425 }
1426
1427 # output in XML DocBook
1428 sub output_function_gnome {
1429     my %args = %{$_[0]};
1430     my ($parameter, $section);
1431     my $count;
1432     my $id;
1433
1434     $id = $args{'module'} . "-" . $args{'function'};
1435     $id =~ s/[^A-Za-z0-9]/-/g;
1436
1437     print "<sect2>\n";
1438     print " <title id=\"$id\">" . $args{'function'} . "</title>\n";
1439
1440     print "  <funcsynopsis>\n";
1441     print "   <funcdef>" . $args{'functiontype'} . " ";
1442     print "<function>" . $args{'function'} . " ";
1443     print "</function></funcdef>\n";
1444
1445     $count = 0;
1446     if ($#{$args{'parameterlist'}} >= 0) {
1447         foreach $parameter (@{$args{'parameterlist'}}) {
1448             $type = $args{'parametertypes'}{$parameter};
1449             if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1450                 # pointer-to-function
1451                 print "   <paramdef>$1 <parameter>$parameter</parameter>)\n";
1452                 print "     <funcparams>$2</funcparams></paramdef>\n";
1453             } else {
1454                 print "   <paramdef>" . $type;
1455                 print " <parameter>$parameter</parameter></paramdef>\n";
1456             }
1457         }
1458     } else {
1459         print "  <void>\n";
1460     }
1461     print "  </funcsynopsis>\n";
1462     if ($#{$args{'parameterlist'}} >= 0) {
1463         print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
1464         print "<tgroup cols=\"2\">\n";
1465         print "<colspec colwidth=\"2*\">\n";
1466         print "<colspec colwidth=\"8*\">\n";
1467         print "<tbody>\n";
1468         foreach $parameter (@{$args{'parameterlist'}}) {
1469             my $parameter_name = $parameter;
1470             $parameter_name =~ s/\[.*//;
1471
1472             print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
1473             print "   <entry>\n";
1474             $lineprefix="     ";
1475             output_highlight($args{'parameterdescs'}{$parameter_name});
1476             print "    </entry></row>\n";
1477         }
1478         print " </tbody></tgroup></informaltable>\n";
1479     } else {
1480         print " <para>\n  None\n </para>\n";
1481     }
1482
1483     # print out each section
1484     $lineprefix="   ";
1485     foreach $section (@{$args{'sectionlist'}}) {
1486         print "<simplesect>\n <title>$section</title>\n";
1487         if ($section =~ m/EXAMPLE/i) {
1488             print "<example><programlisting>\n";
1489             $output_preformatted = 1;
1490         } else {
1491         }
1492         print "<para>\n";
1493         output_highlight($args{'sections'}{$section});
1494         $output_preformatted = 0;
1495         print "</para>\n";
1496         if ($section =~ m/EXAMPLE/i) {
1497             print "</programlisting></example>\n";
1498         } else {
1499         }
1500         print " </simplesect>\n";
1501     }
1502
1503     print "</sect2>\n\n";
1504 }
1505
1506 ##
1507 # output function in man
1508 sub output_function_man(%) {
1509     my %args = %{$_[0]};
1510     my ($parameter, $section);
1511     my $count;
1512
1513     print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
1514
1515     print ".SH NAME\n";
1516     print $args{'function'} . " \\- " . $args{'purpose'} . "\n";
1517
1518     print ".SH SYNOPSIS\n";
1519     if ($args{'functiontype'} ne "") {
1520         print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n";
1521     } else {
1522         print ".B \"" . $args{'function'} . "\n";
1523     }
1524     $count = 0;
1525     my $parenth = "(";
1526     my $post = ",";
1527     foreach my $parameter (@{$args{'parameterlist'}}) {
1528         if ($count == $#{$args{'parameterlist'}}) {
1529             $post = ");";
1530         }
1531         $type = $args{'parametertypes'}{$parameter};
1532         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1533             # pointer-to-function
1534             print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n";
1535         } else {
1536             $type =~ s/([^\*])$/$1 /;
1537             print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n";
1538         }
1539         $count++;
1540         $parenth = "";
1541     }
1542
1543     print ".SH ARGUMENTS\n";
1544     foreach $parameter (@{$args{'parameterlist'}}) {
1545         my $parameter_name = $parameter;
1546         $parameter_name =~ s/\[.*//;
1547
1548         print ".IP \"" . $parameter . "\" 12\n";
1549         output_highlight($args{'parameterdescs'}{$parameter_name});
1550     }
1551     foreach $section (@{$args{'sectionlist'}}) {
1552         print ".SH \"", uc $section, "\"\n";
1553         output_highlight($args{'sections'}{$section});
1554     }
1555 }
1556
1557 ##
1558 # output enum in man
1559 sub output_enum_man(%) {
1560     my %args = %{$_[0]};
1561     my ($parameter, $section);
1562     my $count;
1563
1564     print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
1565
1566     print ".SH NAME\n";
1567     print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n";
1568
1569     print ".SH SYNOPSIS\n";
1570     print "enum " . $args{'enum'} . " {\n";
1571     $count = 0;
1572     foreach my $parameter (@{$args{'parameterlist'}}) {
1573         print ".br\n.BI \"    $parameter\"\n";
1574         if ($count == $#{$args{'parameterlist'}}) {
1575             print "\n};\n";
1576             last;
1577         }
1578         else {
1579             print ", \n.br\n";
1580         }
1581         $count++;
1582     }
1583
1584     print ".SH Constants\n";
1585     foreach $parameter (@{$args{'parameterlist'}}) {
1586         my $parameter_name = $parameter;
1587         $parameter_name =~ s/\[.*//;
1588
1589         print ".IP \"" . $parameter . "\" 12\n";
1590         output_highlight($args{'parameterdescs'}{$parameter_name});
1591     }
1592     foreach $section (@{$args{'sectionlist'}}) {
1593         print ".SH \"$section\"\n";
1594         output_highlight($args{'sections'}{$section});
1595     }
1596 }
1597
1598 ##
1599 # output struct in man
1600 sub output_struct_man(%) {
1601     my %args = %{$_[0]};
1602     my ($parameter, $section);
1603
1604     print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n";
1605
1606     print ".SH NAME\n";
1607     print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n";
1608
1609     print ".SH SYNOPSIS\n";
1610     print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
1611
1612     foreach my $parameter (@{$args{'parameterlist'}}) {
1613         if ($parameter =~ /^#/) {
1614             print ".BI \"$parameter\"\n.br\n";
1615             next;
1616         }
1617         my $parameter_name = $parameter;
1618         $parameter_name =~ s/\[.*//;
1619
1620         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1621         $type = $args{'parametertypes'}{$parameter};
1622         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1623             # pointer-to-function
1624             print ".BI \"    " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n";
1625         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1626             # bitfield
1627             print ".BI \"    " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n";
1628         } else {
1629             $type =~ s/([^\*])$/$1 /;
1630             print ".BI \"    " . $type . "\" " . $parameter . " \"" . "\"\n;\n";
1631         }
1632         print "\n.br\n";
1633     }
1634     print "};\n.br\n";
1635
1636     print ".SH Members\n";
1637     foreach $parameter (@{$args{'parameterlist'}}) {
1638         ($parameter =~ /^#/) && next;
1639
1640         my $parameter_name = $parameter;
1641         $parameter_name =~ s/\[.*//;
1642
1643         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1644         print ".IP \"" . $parameter . "\" 12\n";
1645         output_highlight($args{'parameterdescs'}{$parameter_name});
1646     }
1647     foreach $section (@{$args{'sectionlist'}}) {
1648         print ".SH \"$section\"\n";
1649         output_highlight($args{'sections'}{$section});
1650     }
1651 }
1652
1653 ##
1654 # output typedef in man
1655 sub output_typedef_man(%) {
1656     my %args = %{$_[0]};
1657     my ($parameter, $section);
1658
1659     print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
1660
1661     print ".SH NAME\n";
1662     print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n";
1663
1664     foreach $section (@{$args{'sectionlist'}}) {
1665         print ".SH \"$section\"\n";
1666         output_highlight($args{'sections'}{$section});
1667     }
1668 }
1669
1670 sub output_blockhead_man(%) {
1671     my %args = %{$_[0]};
1672     my ($parameter, $section);
1673     my $count;
1674
1675     print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
1676
1677     foreach $section (@{$args{'sectionlist'}}) {
1678         print ".SH \"$section\"\n";
1679         output_highlight($args{'sections'}{$section});
1680     }
1681 }
1682
1683 ##
1684 # output in text
1685 sub output_function_text(%) {
1686     my %args = %{$_[0]};
1687     my ($parameter, $section);
1688     my $start;
1689
1690     print "Name:\n\n";
1691     print $args{'function'} . " - " . $args{'purpose'} . "\n";
1692
1693     print "\nSynopsis:\n\n";
1694     if ($args{'functiontype'} ne "") {
1695         $start = $args{'functiontype'} . " " . $args{'function'} . " (";
1696     } else {
1697         $start = $args{'function'} . " (";
1698     }
1699     print $start;
1700
1701     my $count = 0;
1702     foreach my $parameter (@{$args{'parameterlist'}}) {
1703         $type = $args{'parametertypes'}{$parameter};
1704         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1705             # pointer-to-function
1706             print $1 . $parameter . ") (" . $2;
1707         } else {
1708             print $type . " " . $parameter;
1709         }
1710         if ($count != $#{$args{'parameterlist'}}) {
1711             $count++;
1712             print ",\n";
1713             print " " x length($start);
1714         } else {
1715             print ");\n\n";
1716         }
1717     }
1718
1719     print "Arguments:\n\n";
1720     foreach $parameter (@{$args{'parameterlist'}}) {
1721         my $parameter_name = $parameter;
1722         $parameter_name =~ s/\[.*//;
1723
1724         print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n";
1725     }
1726     output_section_text(@_);
1727 }
1728
1729 #output sections in text
1730 sub output_section_text(%) {
1731     my %args = %{$_[0]};
1732     my $section;
1733
1734     print "\n";
1735     foreach $section (@{$args{'sectionlist'}}) {
1736         print "$section:\n\n";
1737         output_highlight($args{'sections'}{$section});
1738     }
1739     print "\n\n";
1740 }
1741
1742 # output enum in text
1743 sub output_enum_text(%) {
1744     my %args = %{$_[0]};
1745     my ($parameter);
1746     my $count;
1747     print "Enum:\n\n";
1748
1749     print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n";
1750     print "enum " . $args{'enum'} . " {\n";
1751     $count = 0;
1752     foreach $parameter (@{$args{'parameterlist'}}) {
1753         print "\t$parameter";
1754         if ($count != $#{$args{'parameterlist'}}) {
1755             $count++;
1756             print ",";
1757         }
1758         print "\n";
1759     }
1760     print "};\n\n";
1761
1762     print "Constants:\n\n";
1763     foreach $parameter (@{$args{'parameterlist'}}) {
1764         print "$parameter\n\t";
1765         print $args{'parameterdescs'}{$parameter} . "\n";
1766     }
1767
1768     output_section_text(@_);
1769 }
1770
1771 # output typedef in text
1772 sub output_typedef_text(%) {
1773     my %args = %{$_[0]};
1774     my ($parameter);
1775     my $count;
1776     print "Typedef:\n\n";
1777
1778     print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n";
1779     output_section_text(@_);
1780 }
1781
1782 # output struct as text
1783 sub output_struct_text(%) {
1784     my %args = %{$_[0]};
1785     my ($parameter);
1786
1787     print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n";
1788     print $args{'type'} . " " . $args{'struct'} . " {\n";
1789     foreach $parameter (@{$args{'parameterlist'}}) {
1790         if ($parameter =~ /^#/) {
1791             print "$parameter\n";
1792             next;
1793         }
1794
1795         my $parameter_name = $parameter;
1796         $parameter_name =~ s/\[.*//;
1797
1798         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1799         $type = $args{'parametertypes'}{$parameter};
1800         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1801             # pointer-to-function
1802             print "\t$1 $parameter) ($2);\n";
1803         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1804             # bitfield
1805             print "\t$1 $parameter$2;\n";
1806         } else {
1807             print "\t" . $type . " " . $parameter . ";\n";
1808         }
1809     }
1810     print "};\n\n";
1811
1812     print "Members:\n\n";
1813     foreach $parameter (@{$args{'parameterlist'}}) {
1814         ($parameter =~ /^#/) && next;
1815
1816         my $parameter_name = $parameter;
1817         $parameter_name =~ s/\[.*//;
1818
1819         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1820         print "$parameter\n\t";
1821         print $args{'parameterdescs'}{$parameter_name} . "\n";
1822     }
1823     print "\n";
1824     output_section_text(@_);
1825 }
1826
1827 sub output_blockhead_text(%) {
1828     my %args = %{$_[0]};
1829     my ($parameter, $section);
1830
1831     foreach $section (@{$args{'sectionlist'}}) {
1832         print " $section:\n";
1833         print "    -> ";
1834         output_highlight($args{'sections'}{$section});
1835     }
1836 }
1837
1838 ##
1839 # output in restructured text
1840 #
1841
1842 #
1843 # This could use some work; it's used to output the DOC: sections, and
1844 # starts by putting out the name of the doc section itself, but that tends
1845 # to duplicate a header already in the template file.
1846 #
1847 sub output_blockhead_rst(%) {
1848     my %args = %{$_[0]};
1849     my ($parameter, $section);
1850
1851     foreach $section (@{$args{'sectionlist'}}) {
1852         if ($output_selection != OUTPUT_INCLUDE) {
1853             print "**$section**\n\n";
1854         }
1855         print_lineno($section_start_lines{$section});
1856         output_highlight_rst($args{'sections'}{$section});
1857         print "\n";
1858     }
1859 }
1860
1861 sub output_highlight_rst {
1862     my $contents = join "\n",@_;
1863     my $line;
1864
1865     # undo the evil effects of xml_escape() earlier
1866     $contents = xml_unescape($contents);
1867
1868     eval $dohighlight;
1869     die $@ if $@;
1870
1871     foreach $line (split "\n", $contents) {
1872         print $lineprefix . $line . "\n";
1873     }
1874 }
1875
1876 sub output_function_rst(%) {
1877     my %args = %{$_[0]};
1878     my ($parameter, $section);
1879     my $oldprefix = $lineprefix;
1880     my $start = "";
1881
1882     if ($args{'typedef'}) {
1883         print ".. c:type:: ". $args{'function'} . "\n\n";
1884         print_lineno($declaration_start_line);
1885         print "   **Typedef**: ";
1886         $lineprefix = "";
1887         output_highlight_rst($args{'purpose'});
1888         $start = "\n\n**Syntax**\n\n  ``";
1889     } else {
1890         print ".. c:function:: ";
1891     }
1892     if ($args{'functiontype'} ne "") {
1893         $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
1894     } else {
1895         $start .= $args{'function'} . " (";
1896     }
1897     print $start;
1898
1899     my $count = 0;
1900     foreach my $parameter (@{$args{'parameterlist'}}) {
1901         if ($count ne 0) {
1902             print ", ";
1903         }
1904         $count++;
1905         $type = $args{'parametertypes'}{$parameter};
1906
1907         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1908             # pointer-to-function
1909             print $1 . $parameter . ") (" . $2;
1910         } else {
1911             print $type . " " . $parameter;
1912         }
1913     }
1914     if ($args{'typedef'}) {
1915         print ");``\n\n";
1916     } else {
1917         print ")\n\n";
1918         print_lineno($declaration_start_line);
1919         $lineprefix = "   ";
1920         output_highlight_rst($args{'purpose'});
1921         print "\n";
1922     }
1923
1924     print "**Parameters**\n\n";
1925     $lineprefix = "  ";
1926     foreach $parameter (@{$args{'parameterlist'}}) {
1927         my $parameter_name = $parameter;
1928         $parameter_name =~ s/\[.*//;
1929         $type = $args{'parametertypes'}{$parameter};
1930
1931         if ($type ne "") {
1932             print "``$type $parameter``\n";
1933         } else {
1934             print "``$parameter``\n";
1935         }
1936
1937         print_lineno($parameterdesc_start_lines{$parameter_name});
1938
1939         if (defined($args{'parameterdescs'}{$parameter_name}) &&
1940             $args{'parameterdescs'}{$parameter_name} ne $undescribed) {
1941             output_highlight_rst($args{'parameterdescs'}{$parameter_name});
1942         } else {
1943             print "  *undescribed*\n";
1944         }
1945         print "\n";
1946     }
1947
1948     $lineprefix = $oldprefix;
1949     output_section_rst(@_);
1950 }
1951
1952 sub output_section_rst(%) {
1953     my %args = %{$_[0]};
1954     my $section;
1955     my $oldprefix = $lineprefix;
1956     $lineprefix = "";
1957
1958     foreach $section (@{$args{'sectionlist'}}) {
1959         print "**$section**\n\n";
1960         print_lineno($section_start_lines{$section});
1961         output_highlight_rst($args{'sections'}{$section});
1962         print "\n";
1963     }
1964     print "\n";
1965     $lineprefix = $oldprefix;
1966 }
1967
1968 sub output_enum_rst(%) {
1969     my %args = %{$_[0]};
1970     my ($parameter);
1971     my $oldprefix = $lineprefix;
1972     my $count;
1973     my $name = "enum " . $args{'enum'};
1974
1975     print "\n\n.. c:type:: " . $name . "\n\n";
1976     print_lineno($declaration_start_line);
1977     $lineprefix = "   ";
1978     output_highlight_rst($args{'purpose'});
1979     print "\n";
1980
1981     print "**Constants**\n\n";
1982     $lineprefix = "  ";
1983     foreach $parameter (@{$args{'parameterlist'}}) {
1984         print "``$parameter``\n";
1985         if ($args{'parameterdescs'}{$parameter} ne $undescribed) {
1986             output_highlight_rst($args{'parameterdescs'}{$parameter});
1987         } else {
1988             print "  *undescribed*\n";
1989         }
1990         print "\n";
1991     }
1992
1993     $lineprefix = $oldprefix;
1994     output_section_rst(@_);
1995 }
1996
1997 sub output_typedef_rst(%) {
1998     my %args = %{$_[0]};
1999     my ($parameter);
2000     my $oldprefix = $lineprefix;
2001     my $name = "typedef " . $args{'typedef'};
2002
2003     print "\n\n.. c:type:: " . $name . "\n\n";
2004     print_lineno($declaration_start_line);
2005     $lineprefix = "   ";
2006     output_highlight_rst($args{'purpose'});
2007     print "\n";
2008
2009     $lineprefix = $oldprefix;
2010     output_section_rst(@_);
2011 }
2012
2013 sub output_struct_rst(%) {
2014     my %args = %{$_[0]};
2015     my ($parameter);
2016     my $oldprefix = $lineprefix;
2017     my $name = $args{'type'} . " " . $args{'struct'};
2018
2019     print "\n\n.. c:type:: " . $name . "\n\n";
2020     print_lineno($declaration_start_line);
2021     $lineprefix = "   ";
2022     output_highlight_rst($args{'purpose'});
2023     print "\n";
2024
2025     print "**Definition**\n\n";
2026     print "::\n\n";
2027     print "  " . $args{'type'} . " " . $args{'struct'} . " {\n";
2028     foreach $parameter (@{$args{'parameterlist'}}) {
2029         if ($parameter =~ /^#/) {
2030             print "  " . "$parameter\n";
2031             next;
2032         }
2033
2034         my $parameter_name = $parameter;
2035         $parameter_name =~ s/\[.*//;
2036
2037         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
2038         $type = $args{'parametertypes'}{$parameter};
2039         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
2040             # pointer-to-function
2041             print "    $1 $parameter) ($2);\n";
2042         } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
2043             # bitfield
2044             print "    $1 $parameter$2;\n";
2045         } else {
2046             print "    " . $type . " " . $parameter . ";\n";
2047         }
2048     }
2049     print "  };\n\n";
2050
2051     print "**Members**\n\n";
2052     $lineprefix = "  ";
2053     foreach $parameter (@{$args{'parameterlist'}}) {
2054         ($parameter =~ /^#/) && next;
2055
2056         my $parameter_name = $parameter;
2057         $parameter_name =~ s/\[.*//;
2058
2059         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
2060         $type = $args{'parametertypes'}{$parameter};
2061         print_lineno($parameterdesc_start_lines{$parameter_name});
2062         print "``" . $parameter . "``\n";
2063         output_highlight_rst($args{'parameterdescs'}{$parameter_name});
2064         print "\n";
2065     }
2066     print "\n";
2067
2068     $lineprefix = $oldprefix;
2069     output_section_rst(@_);
2070 }
2071
2072
2073 ## list mode output functions
2074
2075 sub output_function_list(%) {
2076     my %args = %{$_[0]};
2077
2078     print $args{'function'} . "\n";
2079 }
2080
2081 # output enum in list
2082 sub output_enum_list(%) {
2083     my %args = %{$_[0]};
2084     print $args{'enum'} . "\n";
2085 }
2086
2087 # output typedef in list
2088 sub output_typedef_list(%) {
2089     my %args = %{$_[0]};
2090     print $args{'typedef'} . "\n";
2091 }
2092
2093 # output struct as list
2094 sub output_struct_list(%) {
2095     my %args = %{$_[0]};
2096
2097     print $args{'struct'} . "\n";
2098 }
2099
2100 sub output_blockhead_list(%) {
2101     my %args = %{$_[0]};
2102     my ($parameter, $section);
2103
2104     foreach $section (@{$args{'sectionlist'}}) {
2105         print "DOC: $section\n";
2106     }
2107 }
2108
2109 ##
2110 # generic output function for all types (function, struct/union, typedef, enum);
2111 # calls the generated, variable output_ function name based on
2112 # functype and output_mode
2113 sub output_declaration {
2114     no strict 'refs';
2115     my $name = shift;
2116     my $functype = shift;
2117     my $func = "output_${functype}_$output_mode";
2118     if (($output_selection == OUTPUT_ALL) ||
2119         (($output_selection == OUTPUT_INCLUDE ||
2120           $output_selection == OUTPUT_EXPORTED) &&
2121          defined($function_table{$name})) ||
2122         (($output_selection == OUTPUT_EXCLUDE ||
2123           $output_selection == OUTPUT_INTERNAL) &&
2124          !($functype eq "function" && defined($function_table{$name}))))
2125     {
2126         &$func(@_);
2127         $section_counter++;
2128     }
2129 }
2130
2131 ##
2132 # generic output function - calls the right one based on current output mode.
2133 sub output_blockhead {
2134     no strict 'refs';
2135     my $func = "output_blockhead_" . $output_mode;
2136     &$func(@_);
2137     $section_counter++;
2138 }
2139
2140 ##
2141 # takes a declaration (struct, union, enum, typedef) and
2142 # invokes the right handler. NOT called for functions.
2143 sub dump_declaration($$) {
2144     no strict 'refs';
2145     my ($prototype, $file) = @_;
2146     my $func = "dump_" . $decl_type;
2147     &$func(@_);
2148 }
2149
2150 sub dump_union($$) {
2151     dump_struct(@_);
2152 }
2153
2154 sub dump_struct($$) {
2155     my $x = shift;
2156     my $file = shift;
2157     my $nested;
2158
2159     if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) {
2160         #my $decl_type = $1;
2161         $declaration_name = $2;
2162         my $members = $3;
2163
2164         # ignore embedded structs or unions
2165         $members =~ s/({.*})//g;
2166         $nested = $1;
2167
2168         # ignore members marked private:
2169         $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
2170         $members =~ s/\/\*\s*private:.*//gosi;
2171         # strip comments:
2172         $members =~ s/\/\*.*?\*\///gos;
2173         $nested =~ s/\/\*.*?\*\///gos;
2174         # strip kmemcheck_bitfield_{begin,end}.*;
2175         $members =~ s/kmemcheck_bitfield_.*?;//gos;
2176         # strip attributes
2177         $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
2178         $members =~ s/__aligned\s*\([^;]*\)//gos;
2179         $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos;
2180         # replace DECLARE_BITMAP
2181         $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
2182
2183         create_parameterlist($members, ';', $file);
2184         check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
2185
2186         output_declaration($declaration_name,
2187                            'struct',
2188                            {'struct' => $declaration_name,
2189                             'module' => $modulename,
2190                             'parameterlist' => \@parameterlist,
2191                             'parameterdescs' => \%parameterdescs,
2192                             'parametertypes' => \%parametertypes,
2193                             'sectionlist' => \@sectionlist,
2194                             'sections' => \%sections,
2195                             'purpose' => $declaration_purpose,
2196                             'type' => $decl_type
2197                            });
2198     }
2199     else {
2200         print STDERR "${file}:$.: error: Cannot parse struct or union!\n";
2201         ++$errors;
2202     }
2203 }
2204
2205 sub dump_enum($$) {
2206     my $x = shift;
2207     my $file = shift;
2208
2209     $x =~ s@/\*.*?\*/@@gos;     # strip comments.
2210     # strip #define macros inside enums
2211     $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos;
2212
2213     if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
2214         $declaration_name = $1;
2215         my $members = $2;
2216
2217         foreach my $arg (split ',', $members) {
2218             $arg =~ s/^\s*(\w+).*/$1/;
2219             push @parameterlist, $arg;
2220             if (!$parameterdescs{$arg}) {
2221                 $parameterdescs{$arg} = $undescribed;
2222                 print STDERR "${file}:$.: warning: Enum value '$arg' ".
2223                     "not described in enum '$declaration_name'\n";
2224             }
2225
2226         }
2227
2228         output_declaration($declaration_name,
2229                            'enum',
2230                            {'enum' => $declaration_name,
2231                             'module' => $modulename,
2232                             'parameterlist' => \@parameterlist,
2233                             'parameterdescs' => \%parameterdescs,
2234                             'sectionlist' => \@sectionlist,
2235                             'sections' => \%sections,
2236                             'purpose' => $declaration_purpose
2237                            });
2238     }
2239     else {
2240         print STDERR "${file}:$.: error: Cannot parse enum!\n";
2241         ++$errors;
2242     }
2243 }
2244
2245 sub dump_typedef($$) {
2246     my $x = shift;
2247     my $file = shift;
2248
2249     $x =~ s@/\*.*?\*/@@gos;     # strip comments.
2250
2251     # Parse function prototypes
2252     if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
2253         $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) {
2254
2255         # Function typedefs
2256         $return_type = $1;
2257         $declaration_name = $2;
2258         my $args = $3;
2259
2260         create_parameterlist($args, ',', $file);
2261
2262         output_declaration($declaration_name,
2263                            'function',
2264                            {'function' => $declaration_name,
2265                             'typedef' => 1,
2266                             'module' => $modulename,
2267                             'functiontype' => $return_type,
2268                             'parameterlist' => \@parameterlist,
2269                             'parameterdescs' => \%parameterdescs,
2270                             'parametertypes' => \%parametertypes,
2271                             'sectionlist' => \@sectionlist,
2272                             'sections' => \%sections,
2273                             'purpose' => $declaration_purpose
2274                            });
2275         return;
2276     }
2277
2278     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
2279         $x =~ s/\(*.\)\s*;$/;/;
2280         $x =~ s/\[*.\]\s*;$/;/;
2281     }
2282
2283     if ($x =~ /typedef.*\s+(\w+)\s*;/) {
2284         $declaration_name = $1;
2285
2286         output_declaration($declaration_name,
2287                            'typedef',
2288                            {'typedef' => $declaration_name,
2289                             'module' => $modulename,
2290                             'sectionlist' => \@sectionlist,
2291                             'sections' => \%sections,
2292                             'purpose' => $declaration_purpose
2293                            });
2294     }
2295     else {
2296         print STDERR "${file}:$.: error: Cannot parse typedef!\n";
2297         ++$errors;
2298     }
2299 }
2300
2301 sub save_struct_actual($) {
2302     my $actual = shift;
2303
2304     # strip all spaces from the actual param so that it looks like one string item
2305     $actual =~ s/\s*//g;
2306     $struct_actual = $struct_actual . $actual . " ";
2307 }
2308
2309 sub create_parameterlist($$$) {
2310     my $args = shift;
2311     my $splitter = shift;
2312     my $file = shift;
2313     my $type;
2314     my $param;
2315
2316     # temporarily replace commas inside function pointer definition
2317     while ($args =~ /(\([^\),]+),/) {
2318         $args =~ s/(\([^\),]+),/$1#/g;
2319     }
2320
2321     foreach my $arg (split($splitter, $args)) {
2322         # strip comments
2323         $arg =~ s/\/\*.*\*\///;
2324         # strip leading/trailing spaces
2325         $arg =~ s/^\s*//;
2326         $arg =~ s/\s*$//;
2327         $arg =~ s/\s+/ /;
2328
2329         if ($arg =~ /^#/) {
2330             # Treat preprocessor directive as a typeless variable just to fill
2331             # corresponding data structures "correctly". Catch it later in
2332             # output_* subs.
2333             push_parameter($arg, "", $file);
2334         } elsif ($arg =~ m/\(.+\)\s*\(/) {
2335             # pointer-to-function
2336             $arg =~ tr/#/,/;
2337             $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/;
2338             $param = $1;
2339             $type = $arg;
2340             $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
2341             save_struct_actual($param);
2342             push_parameter($param, $type, $file);
2343         } elsif ($arg) {
2344             $arg =~ s/\s*:\s*/:/g;
2345             $arg =~ s/\s*\[/\[/g;
2346
2347             my @args = split('\s*,\s*', $arg);
2348             if ($args[0] =~ m/\*/) {
2349                 $args[0] =~ s/(\*+)\s*/ $1/;
2350             }
2351
2352             my @first_arg;
2353             if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
2354                     shift @args;
2355                     push(@first_arg, split('\s+', $1));
2356                     push(@first_arg, $2);
2357             } else {
2358                     @first_arg = split('\s+', shift @args);
2359             }
2360
2361             unshift(@args, pop @first_arg);
2362             $type = join " ", @first_arg;
2363
2364             foreach $param (@args) {
2365                 if ($param =~ m/^(\*+)\s*(.*)/) {
2366                     save_struct_actual($2);
2367                     push_parameter($2, "$type $1", $file);
2368                 }
2369                 elsif ($param =~ m/(.*?):(\d+)/) {
2370                     if ($type ne "") { # skip unnamed bit-fields
2371                         save_struct_actual($1);
2372                         push_parameter($1, "$type:$2", $file)
2373                     }
2374                 }
2375                 else {
2376                     save_struct_actual($param);
2377                     push_parameter($param, $type, $file);
2378                 }
2379             }
2380         }
2381     }
2382 }
2383
2384 sub push_parameter($$$) {
2385         my $param = shift;
2386         my $type = shift;
2387         my $file = shift;
2388
2389         if (($anon_struct_union == 1) && ($type eq "") &&
2390             ($param eq "}")) {
2391                 return;         # ignore the ending }; from anon. struct/union
2392         }
2393
2394         $anon_struct_union = 0;
2395         my $param_name = $param;
2396         $param_name =~ s/\[.*//;
2397
2398         if ($type eq "" && $param =~ /\.\.\.$/)
2399         {
2400             if (!$param =~ /\w\.\.\.$/) {
2401               # handles unnamed variable parameters
2402               $param = "...";
2403             }
2404             if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
2405                 $parameterdescs{$param} = "variable arguments";
2406             }
2407         }
2408         elsif ($type eq "" && ($param eq "" or $param eq "void"))
2409         {
2410             $param="void";
2411             $parameterdescs{void} = "no arguments";
2412         }
2413         elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
2414         # handle unnamed (anonymous) union or struct:
2415         {
2416                 $type = $param;
2417                 $param = "{unnamed_" . $param . "}";
2418                 $parameterdescs{$param} = "anonymous\n";
2419                 $anon_struct_union = 1;
2420         }
2421
2422         # warn if parameter has no description
2423         # (but ignore ones starting with # as these are not parameters
2424         # but inline preprocessor statements);
2425         # also ignore unnamed structs/unions;
2426         if (!$anon_struct_union) {
2427         if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
2428
2429             $parameterdescs{$param_name} = $undescribed;
2430
2431             if (($type eq 'function') || ($type eq 'enum')) {
2432                 print STDERR "${file}:$.: warning: Function parameter ".
2433                     "or member '$param' not " .
2434                     "described in '$declaration_name'\n";
2435             }
2436             print STDERR "${file}:$.: warning:" .
2437                          " No description found for parameter '$param'\n";
2438             ++$warnings;
2439         }
2440         }
2441
2442         $param = xml_escape($param);
2443
2444         # strip spaces from $param so that it is one continuous string
2445         # on @parameterlist;
2446         # this fixes a problem where check_sections() cannot find
2447         # a parameter like "addr[6 + 2]" because it actually appears
2448         # as "addr[6", "+", "2]" on the parameter list;
2449         # but it's better to maintain the param string unchanged for output,
2450         # so just weaken the string compare in check_sections() to ignore
2451         # "[blah" in a parameter string;
2452         ###$param =~ s/\s*//g;
2453         push @parameterlist, $param;
2454         $type =~ s/\s\s+/ /g;
2455         $parametertypes{$param} = $type;
2456 }
2457
2458 sub check_sections($$$$$$) {
2459         my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
2460         my @sects = split ' ', $sectcheck;
2461         my @prms = split ' ', $prmscheck;
2462         my $err;
2463         my ($px, $sx);
2464         my $prm_clean;          # strip trailing "[array size]" and/or beginning "*"
2465
2466         foreach $sx (0 .. $#sects) {
2467                 $err = 1;
2468                 foreach $px (0 .. $#prms) {
2469                         $prm_clean = $prms[$px];
2470                         $prm_clean =~ s/\[.*\]//;
2471                         $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
2472                         # ignore array size in a parameter string;
2473                         # however, the original param string may contain
2474                         # spaces, e.g.:  addr[6 + 2]
2475                         # and this appears in @prms as "addr[6" since the
2476                         # parameter list is split at spaces;
2477                         # hence just ignore "[..." for the sections check;
2478                         $prm_clean =~ s/\[.*//;
2479
2480                         ##$prm_clean =~ s/^\**//;
2481                         if ($prm_clean eq $sects[$sx]) {
2482                                 $err = 0;
2483                                 last;
2484                         }
2485                 }
2486                 if ($err) {
2487                         if ($decl_type eq "function") {
2488                                 print STDERR "${file}:$.: warning: " .
2489                                         "Excess function parameter " .
2490                                         "'$sects[$sx]' " .
2491                                         "description in '$decl_name'\n";
2492                                 ++$warnings;
2493                         } else {
2494                                 if ($nested !~ m/\Q$sects[$sx]\E/) {
2495                                     print STDERR "${file}:$.: warning: " .
2496                                         "Excess struct/union/enum/typedef member " .
2497                                         "'$sects[$sx]' " .
2498                                         "description in '$decl_name'\n";
2499                                     ++$warnings;
2500                                 }
2501                         }
2502                 }
2503         }
2504 }
2505
2506 ##
2507 # Checks the section describing the return value of a function.
2508 sub check_return_section {
2509         my $file = shift;
2510         my $declaration_name = shift;
2511         my $return_type = shift;
2512
2513         # Ignore an empty return type (It's a macro)
2514         # Ignore functions with a "void" return type. (But don't ignore "void *")
2515         if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) {
2516                 return;
2517         }
2518
2519         if (!defined($sections{$section_return}) ||
2520             $sections{$section_return} eq "") {
2521                 print STDERR "${file}:$.: warning: " .
2522                         "No description found for return value of " .
2523                         "'$declaration_name'\n";
2524                 ++$warnings;
2525         }
2526 }
2527
2528 ##
2529 # takes a function prototype and the name of the current file being
2530 # processed and spits out all the details stored in the global
2531 # arrays/hashes.
2532 sub dump_function($$) {
2533     my $prototype = shift;
2534     my $file = shift;
2535     my $noret = 0;
2536
2537     $prototype =~ s/^static +//;
2538     $prototype =~ s/^extern +//;
2539     $prototype =~ s/^asmlinkage +//;
2540     $prototype =~ s/^inline +//;
2541     $prototype =~ s/^__inline__ +//;
2542     $prototype =~ s/^__inline +//;
2543     $prototype =~ s/^__always_inline +//;
2544     $prototype =~ s/^noinline +//;
2545     $prototype =~ s/__init +//;
2546     $prototype =~ s/__init_or_module +//;
2547     $prototype =~ s/__meminit +//;
2548     $prototype =~ s/__must_check +//;
2549     $prototype =~ s/__weak +//;
2550     my $define = $prototype =~ s/^#\s*define\s+//; #ak added
2551     $prototype =~ s/__attribute__\s*\(\(
2552             (?:
2553                  [\w\s]++          # attribute name
2554                  (?:\([^)]*+\))?   # attribute arguments
2555                  \s*+,?            # optional comma at the end
2556             )+
2557           \)\)\s+//x;
2558
2559     # Yes, this truly is vile.  We are looking for:
2560     # 1. Return type (may be nothing if we're looking at a macro)
2561     # 2. Function name
2562     # 3. Function parameters.
2563     #
2564     # All the while we have to watch out for function pointer parameters
2565     # (which IIRC is what the two sections are for), C types (these
2566     # regexps don't even start to express all the possibilities), and
2567     # so on.
2568     #
2569     # If you mess with these regexps, it's a good idea to check that
2570     # the following functions' documentation still comes out right:
2571     # - parport_register_device (function pointer parameters)
2572     # - atomic_set (macro)
2573     # - pci_match_device, __copy_to_user (long return type)
2574
2575     if ($define && $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s+/) {
2576         # This is an object-like macro, it has no return type and no parameter
2577         # list.
2578         # Function-like macros are not allowed to have spaces between
2579         # declaration_name and opening parenthesis (notice the \s+).
2580         $return_type = $1;
2581         $declaration_name = $2;
2582         $noret = 1;
2583     } elsif ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2584         $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2585         $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2586         $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2587         $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2588         $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2589         $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
2590         $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2591         $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2592         $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2593         $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2594         $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2595         $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2596         $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2597         $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2598         $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
2599         $prototype =~ m/^(\w+\s+\w+\s*\*+\s*\w+\s*\*+\s*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
2600         $return_type = $1;
2601         $declaration_name = $2;
2602         my $args = $3;
2603
2604         create_parameterlist($args, ',', $file);
2605     } else {
2606         print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n";
2607         return;
2608     }
2609
2610         my $prms = join " ", @parameterlist;
2611         check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
2612
2613         # This check emits a lot of warnings at the moment, because many
2614         # functions don't have a 'Return' doc section. So until the number
2615         # of warnings goes sufficiently down, the check is only performed in
2616         # verbose mode.
2617         # TODO: always perform the check.
2618         if ($verbose && !$noret) {
2619                 check_return_section($file, $declaration_name, $return_type);
2620         }
2621
2622     output_declaration($declaration_name,
2623                        'function',
2624                        {'function' => $declaration_name,
2625                         'module' => $modulename,
2626                         'functiontype' => $return_type,
2627                         'parameterlist' => \@parameterlist,
2628                         'parameterdescs' => \%parameterdescs,
2629                         'parametertypes' => \%parametertypes,
2630                         'sectionlist' => \@sectionlist,
2631                         'sections' => \%sections,
2632                         'purpose' => $declaration_purpose
2633                        });
2634 }
2635
2636 sub reset_state {
2637     $function = "";
2638     %parameterdescs = ();
2639     %parametertypes = ();
2640     @parameterlist = ();
2641     %sections = ();
2642     @sectionlist = ();
2643     $sectcheck = "";
2644     $struct_actual = "";
2645     $prototype = "";
2646
2647     $state = STATE_NORMAL;
2648     $inline_doc_state = STATE_INLINE_NA;
2649 }
2650
2651 sub tracepoint_munge($) {
2652         my $file = shift;
2653         my $tracepointname = 0;
2654         my $tracepointargs = 0;
2655
2656         if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
2657                 $tracepointname = $1;
2658         }
2659         if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
2660                 $tracepointname = $1;
2661         }
2662         if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
2663                 $tracepointname = $2;
2664         }
2665         $tracepointname =~ s/^\s+//; #strip leading whitespace
2666         if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
2667                 $tracepointargs = $1;
2668         }
2669         if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
2670                 print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n".
2671                              "$prototype\n";
2672         } else {
2673                 $prototype = "static inline void trace_$tracepointname($tracepointargs)";
2674         }
2675 }
2676
2677 sub syscall_munge() {
2678         my $void = 0;
2679
2680         $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs
2681 ##      if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) {
2682         if ($prototype =~ m/SYSCALL_DEFINE0/) {
2683                 $void = 1;
2684 ##              $prototype = "long sys_$1(void)";
2685         }
2686
2687         $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name
2688         if ($prototype =~ m/long (sys_.*?),/) {
2689                 $prototype =~ s/,/\(/;
2690         } elsif ($void) {
2691                 $prototype =~ s/\)/\(void\)/;
2692         }
2693
2694         # now delete all of the odd-number commas in $prototype
2695         # so that arg types & arg names don't have a comma between them
2696         my $count = 0;
2697         my $len = length($prototype);
2698         if ($void) {
2699                 $len = 0;       # skip the for-loop
2700         }
2701         for (my $ix = 0; $ix < $len; $ix++) {
2702                 if (substr($prototype, $ix, 1) eq ',') {
2703                         $count++;
2704                         if ($count % 2 == 1) {
2705                                 substr($prototype, $ix, 1) = ' ';
2706                         }
2707                 }
2708         }
2709 }
2710
2711 sub process_proto_function($$) {
2712     my $x = shift;
2713     my $file = shift;
2714
2715     $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
2716
2717     if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) {
2718         # do nothing
2719     }
2720     elsif ($x =~ /([^\{]*)/) {
2721         $prototype .= $1;
2722     }
2723
2724     if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) {
2725         $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
2726         $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
2727         $prototype =~ s@^\s+@@gos; # strip leading spaces
2728         if ($prototype =~ /SYSCALL_DEFINE/) {
2729                 syscall_munge();
2730         }
2731         if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
2732             $prototype =~ /DEFINE_SINGLE_EVENT/)
2733         {
2734                 tracepoint_munge($file);
2735         }
2736         dump_function($prototype, $file);
2737         reset_state();
2738     }
2739 }
2740
2741 sub process_proto_type($$) {
2742     my $x = shift;
2743     my $file = shift;
2744
2745     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
2746     $x =~ s@^\s+@@gos; # strip leading spaces
2747     $x =~ s@\s+$@@gos; # strip trailing spaces
2748     $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
2749
2750     if ($x =~ /^#/) {
2751         # To distinguish preprocessor directive from regular declaration later.
2752         $x .= ";";
2753     }
2754
2755     while (1) {
2756         if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
2757             $prototype .= $1 . $2;
2758             ($2 eq '{') && $brcount++;
2759             ($2 eq '}') && $brcount--;
2760             if (($2 eq ';') && ($brcount == 0)) {
2761                 dump_declaration($prototype, $file);
2762                 reset_state();
2763                 last;
2764             }
2765             $x = $3;
2766         } else {
2767             $prototype .= $x;
2768             last;
2769         }
2770     }
2771 }
2772
2773 # xml_escape: replace <, >, and & in the text stream;
2774 #
2775 # however, formatting controls that are generated internally/locally in the
2776 # kernel-doc script are not escaped here; instead, they begin life like
2777 # $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings
2778 # are converted to their mnemonic-expected output, without the 4 * '\' & ':',
2779 # just before actual output; (this is done by local_unescape())
2780 sub xml_escape($) {
2781         my $text = shift;
2782         if (($output_mode eq "text") || ($output_mode eq "man")) {
2783                 return $text;
2784         }
2785         $text =~ s/\&/\\\\\\amp;/g;
2786         $text =~ s/\</\\\\\\lt;/g;
2787         $text =~ s/\>/\\\\\\gt;/g;
2788         return $text;
2789 }
2790
2791 # xml_unescape: reverse the effects of xml_escape
2792 sub xml_unescape($) {
2793         my $text = shift;
2794         if (($output_mode eq "text") || ($output_mode eq "man")) {
2795                 return $text;
2796         }
2797         $text =~ s/\\\\\\amp;/\&/g;
2798         $text =~ s/\\\\\\lt;/</g;
2799         $text =~ s/\\\\\\gt;/>/g;
2800         return $text;
2801 }
2802
2803 # convert local escape strings to html
2804 # local escape strings look like:  '\\\\menmonic:' (that's 4 backslashes)
2805 sub local_unescape($) {
2806         my $text = shift;
2807         if (($output_mode eq "text") || ($output_mode eq "man")) {
2808                 return $text;
2809         }
2810         $text =~ s/\\\\\\\\lt:/</g;
2811         $text =~ s/\\\\\\\\gt:/>/g;
2812         return $text;
2813 }
2814
2815 sub map_filename($) {
2816     my $file;
2817     my ($orig_file) = @_;
2818
2819     if (defined($ENV{'SRCTREE'})) {
2820         $file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
2821     } else {
2822         $file = $orig_file;
2823     }
2824
2825     if (defined($source_map{$file})) {
2826         $file = $source_map{$file};
2827     }
2828
2829     return $file;
2830 }
2831
2832 sub process_export_file($) {
2833     my ($orig_file) = @_;
2834     my $file = map_filename($orig_file);
2835
2836     if (!open(IN,"<$file")) {
2837         print STDERR "Error: Cannot open file $file\n";
2838         ++$errors;
2839         return;
2840     }
2841
2842     while (<IN>) {
2843         if (/$export_symbol/) {
2844             $function_table{$2} = 1;
2845         }
2846     }
2847
2848     close(IN);
2849 }
2850
2851 sub process_file($) {
2852     my $file;
2853     my $identifier;
2854     my $func;
2855     my $descr;
2856     my $in_purpose = 0;
2857     my $initial_section_counter = $section_counter;
2858     my ($orig_file) = @_;
2859     my $leading_space;
2860
2861     $file = map_filename($orig_file);
2862
2863     if (!open(IN,"<$file")) {
2864         print STDERR "Error: Cannot open file $file\n";
2865         ++$errors;
2866         return;
2867     }
2868
2869     $. = 1;
2870
2871     $section_counter = 0;
2872     while (<IN>) {
2873         while (s/\\\s*$//) {
2874             $_ .= <IN>;
2875         }
2876         if ($state == STATE_NORMAL) {
2877             if (/$doc_start/o) {
2878                 $state = STATE_NAME;    # next line is always the function name
2879                 $in_doc_sect = 0;
2880                 $declaration_start_line = $. + 1;
2881             }
2882         } elsif ($state == STATE_NAME) {# this line is the function name (always)
2883             if (/$doc_block/o) {
2884                 $state = STATE_DOCBLOCK;
2885                 $contents = "";
2886                 $new_start_line = $. + 1;
2887
2888                 if ( $1 eq "" ) {
2889                         $section = $section_intro;
2890                 } else {
2891                         $section = $1;
2892                 }
2893             }
2894             elsif (/$doc_decl/o) {
2895                 $identifier = $1;
2896                 if (/\s*([\w\s]+?)\s*-/) {
2897                     $identifier = $1;
2898                 }
2899
2900                 $state = STATE_FIELD;
2901                 # if there's no @param blocks need to set up default section
2902                 # here
2903                 $contents = "";
2904                 $section = $section_default;
2905                 $new_start_line = $. + 1;
2906                 if (/-(.*)/) {
2907                     # strip leading/trailing/multiple spaces
2908                     $descr= $1;
2909                     $descr =~ s/^\s*//;
2910                     $descr =~ s/\s*$//;
2911                     $descr =~ s/\s+/ /g;
2912                     $declaration_purpose = xml_escape($descr);
2913                     $in_purpose = 1;
2914                 } else {
2915                     $declaration_purpose = "";
2916                 }
2917
2918                 if (($declaration_purpose eq "") && $verbose) {
2919                         print STDERR "${file}:$.: warning: missing initial short description on line:\n";
2920                         print STDERR $_;
2921                         ++$warnings;
2922                 }
2923
2924                 if ($identifier =~ m/^struct/) {
2925                     $decl_type = 'struct';
2926                 } elsif ($identifier =~ m/^union/) {
2927                     $decl_type = 'union';
2928                 } elsif ($identifier =~ m/^enum/) {
2929                     $decl_type = 'enum';
2930                 } elsif ($identifier =~ m/^typedef/) {
2931                     $decl_type = 'typedef';
2932                 } else {
2933                     $decl_type = 'function';
2934                 }
2935
2936                 if ($verbose) {
2937                     print STDERR "${file}:$.: info: Scanning doc for $identifier\n";
2938                 }
2939             } else {
2940                 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
2941                 " - I thought it was a doc line\n";
2942                 ++$warnings;
2943                 $state = STATE_NORMAL;
2944             }
2945         } elsif ($state == STATE_FIELD) {       # look for head: lines, and include content
2946             if (/$doc_sect/i) { # case insensitive for supported section names
2947                 $newsection = $1;
2948                 $newcontents = $2;
2949
2950                 # map the supported section names to the canonical names
2951                 if ($newsection =~ m/^description$/i) {
2952                     $newsection = $section_default;
2953                 } elsif ($newsection =~ m/^context$/i) {
2954                     $newsection = $section_context;
2955                 } elsif ($newsection =~ m/^returns?$/i) {
2956                     $newsection = $section_return;
2957                 } elsif ($newsection =~ m/^\@return$/) {
2958                     # special: @return is a section, not a param description
2959                     $newsection = $section_return;
2960                 }
2961
2962                 if (($contents ne "") && ($contents ne "\n")) {
2963                     if (!$in_doc_sect && $verbose) {
2964                         print STDERR "${file}:$.: warning: contents before sections\n";
2965                         ++$warnings;
2966                     }
2967                     dump_section($file, $section, xml_escape($contents));
2968                     $section = $section_default;
2969                 }
2970
2971                 $in_doc_sect = 1;
2972                 $in_purpose = 0;
2973                 $contents = $newcontents;
2974                 $new_start_line = $.;
2975                 while ((substr($contents, 0, 1) eq " ") ||
2976                        substr($contents, 0, 1) eq "\t") {
2977                     $contents = substr($contents, 1);
2978                 }
2979                 if ($contents ne "") {
2980                     $contents .= "\n";
2981                 }
2982                 $section = $newsection;
2983                 $leading_space = undef;
2984             } elsif (/$doc_end/) {
2985                 if (($contents ne "") && ($contents ne "\n")) {
2986                     dump_section($file, $section, xml_escape($contents));
2987                     $section = $section_default;
2988                     $contents = "";
2989                 }
2990                 # look for doc_com + <text> + doc_end:
2991                 if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
2992                     print STDERR "${file}:$.: warning: suspicious ending line: $_";
2993                     ++$warnings;
2994                 }
2995
2996                 $prototype = "";
2997                 $state = STATE_PROTO;
2998                 $brcount = 0;
2999 #               print STDERR "end of doc comment, looking for prototype\n";
3000             } elsif (/$doc_content/) {
3001                 # miguel-style comment kludge, look for blank lines after
3002                 # @parameter line to signify start of description
3003                 if ($1 eq "") {
3004                     if ($section =~ m/^@/ || $section eq $section_context) {
3005                         dump_section($file, $section, xml_escape($contents));
3006                         $section = $section_default;
3007                         $contents = "";
3008                         $new_start_line = $.;
3009                     } else {
3010                         $contents .= "\n";
3011                     }
3012                     $in_purpose = 0;
3013                 } elsif ($in_purpose == 1) {
3014                     # Continued declaration purpose
3015                     chomp($declaration_purpose);
3016                     $declaration_purpose .= " " . xml_escape($1);
3017                     $declaration_purpose =~ s/\s+/ /g;
3018                 } else {
3019                     my $cont = $1;
3020                     if ($section =~ m/^@/ || $section eq $section_context) {
3021                         if (!defined $leading_space) {
3022                             if ($cont =~ m/^(\s+)/) {
3023                                 $leading_space = $1;
3024                             } else {
3025                                 $leading_space = "";
3026                             }
3027                         }
3028
3029                         $cont =~ s/^$leading_space//;
3030                     }
3031                     $contents .= $cont . "\n";
3032                 }
3033             } else {
3034                 # i dont know - bad line?  ignore.
3035                 print STDERR "${file}:$.: warning: bad line: $_";
3036                 ++$warnings;
3037             }
3038         } elsif ($state == STATE_INLINE) { # scanning for inline parameters
3039             # First line (state 1) needs to be a @parameter
3040             if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
3041                 $section = $1;
3042                 $contents = $2;
3043                 $new_start_line = $.;
3044                 if ($contents ne "") {
3045                     while ((substr($contents, 0, 1) eq " ") ||
3046                            substr($contents, 0, 1) eq "\t") {
3047                         $contents = substr($contents, 1);
3048                     }
3049                     $contents .= "\n";
3050                 }
3051                 $inline_doc_state = STATE_INLINE_TEXT;
3052             # Documentation block end */
3053             } elsif (/$doc_inline_end/) {
3054                 if (($contents ne "") && ($contents ne "\n")) {
3055                     dump_section($file, $section, xml_escape($contents));
3056                     $section = $section_default;
3057                     $contents = "";
3058                 }
3059                 $state = STATE_PROTO;
3060                 $inline_doc_state = STATE_INLINE_NA;
3061             # Regular text
3062             } elsif (/$doc_content/) {
3063                 if ($inline_doc_state == STATE_INLINE_TEXT) {
3064                     $contents .= $1 . "\n";
3065                     # nuke leading blank lines
3066                     if ($contents =~ /^\s*$/) {
3067                         $contents = "";
3068                     }
3069                 } elsif ($inline_doc_state == STATE_INLINE_NAME) {
3070                     $inline_doc_state = STATE_INLINE_ERROR;
3071                     print STDERR "${file}:$.: warning: ";
3072                     print STDERR "Incorrect use of kernel-doc format: $_";
3073                     ++$warnings;
3074                 }
3075             }
3076         } elsif ($state == STATE_PROTO) {       # scanning for function '{' (end of prototype)
3077             if (/$doc_inline_oneline/) {
3078                 $section = $1;
3079                 $contents = $2;
3080                 if ($contents ne "") {
3081                     $contents .= "\n";
3082                     dump_section($file, $section, xml_escape($contents));
3083                     $section = $section_default;
3084                     $contents = "";
3085                 }
3086             } elsif (/$doc_inline_start/) {
3087                 $state = STATE_INLINE;
3088                 $inline_doc_state = STATE_INLINE_NAME;
3089             } elsif ($decl_type eq 'function') {
3090                 process_proto_function($_, $file);
3091             } else {
3092                 process_proto_type($_, $file);
3093             }
3094         } elsif ($state == STATE_DOCBLOCK) {
3095                 if (/$doc_end/)
3096                 {
3097                         dump_doc_section($file, $section, xml_escape($contents));
3098                         $section = $section_default;
3099                         $contents = "";
3100                         $function = "";
3101                         %parameterdescs = ();
3102                         %parametertypes = ();
3103                         @parameterlist = ();
3104                         %sections = ();
3105                         @sectionlist = ();
3106                         $prototype = "";
3107                         $state = STATE_NORMAL;
3108                 }
3109                 elsif (/$doc_content/)
3110                 {
3111                         if ( $1 eq "" )
3112                         {
3113                                 $contents .= $blankline;
3114                         }
3115                         else
3116                         {
3117                                 $contents .= $1 . "\n";
3118                         }
3119                 }
3120         }
3121     }
3122     if ($initial_section_counter == $section_counter) {
3123         print STDERR "${file}:1: warning: no structured comments found\n";
3124         if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) {
3125             print STDERR "    Was looking for '$_'.\n" for keys %function_table;
3126         }
3127         if ($output_mode eq "xml") {
3128             # The template wants at least one RefEntry here; make one.
3129             print "<refentry>\n";
3130             print " <refnamediv>\n";
3131             print "  <refname>\n";
3132             print "   ${orig_file}\n";
3133             print "  </refname>\n";
3134             print "  <refpurpose>\n";
3135             print "   Document generation inconsistency\n";
3136             print "  </refpurpose>\n";
3137             print " </refnamediv>\n";
3138             print " <refsect1>\n";
3139             print "  <title>\n";
3140             print "   Oops\n";
3141             print "  </title>\n";
3142             print "  <warning>\n";
3143             print "   <para>\n";
3144             print "    The template for this document tried to insert\n";
3145             print "    the structured comment from the file\n";
3146             print "    <filename>${orig_file}</filename> at this point,\n";
3147             print "    but none was found.\n";
3148             print "    This dummy section is inserted to allow\n";
3149             print "    generation to continue.\n";
3150             print "   </para>\n";
3151             print "  </warning>\n";
3152             print " </refsect1>\n";
3153             print "</refentry>\n";
3154         }
3155     }
3156 }
3157
3158
3159 $kernelversion = get_kernel_version();
3160
3161 # generate a sequence of code that will splice in highlighting information
3162 # using the s// operator.
3163 for (my $k = 0; $k < @highlights; $k++) {
3164     my $pattern = $highlights[$k][0];
3165     my $result = $highlights[$k][1];
3166 #   print STDERR "scanning pattern:$pattern, highlight:($result)\n";
3167     $dohighlight .=  "\$contents =~ s:$pattern:$result:gs;\n";
3168 }
3169
3170 # Read the file that maps relative names to absolute names for
3171 # separate source and object directories and for shadow trees.
3172 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
3173         my ($relname, $absname);
3174         while(<SOURCE_MAP>) {
3175                 chop();
3176                 ($relname, $absname) = (split())[0..1];
3177                 $relname =~ s:^/+::;
3178                 $source_map{$relname} = $absname;
3179         }
3180         close(SOURCE_MAP);
3181 }
3182
3183 if ($output_selection == OUTPUT_EXPORTED ||
3184     $output_selection == OUTPUT_INTERNAL) {
3185
3186     push(@export_file_list, @ARGV);
3187
3188     foreach (@export_file_list) {
3189         chomp;
3190         process_export_file($_);
3191     }
3192 }
3193
3194 foreach (@ARGV) {
3195     chomp;
3196     process_file($_);
3197 }
3198 if ($verbose && $errors) {
3199   print STDERR "$errors errors\n";
3200 }
3201 if ($verbose && $warnings) {
3202   print STDERR "$warnings warnings\n";
3203 }
3204
3205 exit($errors);