Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'tools-final2' into docs-mw

Our documentation-related tools are spread out over various directories;
several are buried in the scripts/ dumping ground. That makes them harder
to discover and harder to maintain.

Recent work has started accumulating our documentation-related tools in
/tools/docs. This series nearly completes that task, moving most of the
rest of our various utilities there, hopefully fixing up all of the
relevant references in the process.

The one exception is scripts/kernel-doc; that move turned up some other
problems, so I have dropped it until those are ironed out.

At the end, rather than move the old, Perl kernel-doc, I simply removed it.

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