cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

kernel-doc (67925B)


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