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