18c2ecf20Sopenharmony_ci#!/usr/bin/env perl 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ciuse warnings; 58c2ecf20Sopenharmony_ciuse strict; 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 88c2ecf20Sopenharmony_ci## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 98c2ecf20Sopenharmony_ci## Copyright (C) 2001 Simon Huggins ## 108c2ecf20Sopenharmony_ci## Copyright (C) 2005-2012 Randy Dunlap ## 118c2ecf20Sopenharmony_ci## Copyright (C) 2012 Dan Luedtke ## 128c2ecf20Sopenharmony_ci## ## 138c2ecf20Sopenharmony_ci## #define enhancements by Armin Kuster <akuster@mvista.com> ## 148c2ecf20Sopenharmony_ci## Copyright (c) 2000 MontaVista Software, Inc. ## 158c2ecf20Sopenharmony_ci## ## 168c2ecf20Sopenharmony_ci## This software falls under the GNU General Public License. ## 178c2ecf20Sopenharmony_ci## Please read the COPYING file for more information ## 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci# 18/01/2001 - Cleanups 208c2ecf20Sopenharmony_ci# Functions prototyped as foo(void) same as foo() 218c2ecf20Sopenharmony_ci# Stop eval'ing where we don't need to. 228c2ecf20Sopenharmony_ci# -- huggie@earth.li 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci# 27/06/2001 - Allowed whitespace after initial "/**" and 258c2ecf20Sopenharmony_ci# allowed comments before function declarations. 268c2ecf20Sopenharmony_ci# -- Christian Kreibich <ck@whoop.org> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci# Still to do: 298c2ecf20Sopenharmony_ci# - add perldoc documentation 308c2ecf20Sopenharmony_ci# - Look more closely at some of the scarier bits :) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci# 26/05/2001 - Support for separate source and object trees. 338c2ecf20Sopenharmony_ci# Return error code. 348c2ecf20Sopenharmony_ci# Keith Owens <kaos@ocs.com.au> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci# 23/09/2001 - Added support for typedefs, structs, enums and unions 378c2ecf20Sopenharmony_ci# Support for Context section; can be terminated using empty line 388c2ecf20Sopenharmony_ci# Small fixes (like spaces vs. \s in regex) 398c2ecf20Sopenharmony_ci# -- Tim Jansen <tim@tjansen.de> 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci# 25/07/2012 - Added support for HTML5 428c2ecf20Sopenharmony_ci# -- Dan Luedtke <mail@danrl.de> 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cisub usage { 458c2ecf20Sopenharmony_ci my $message = <<"EOF"; 468c2ecf20Sopenharmony_ciUsage: $0 [OPTION ...] FILE ... 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciRead C language source or header FILEs, extract embedded documentation comments, 498c2ecf20Sopenharmony_ciand print formatted documentation to standard output. 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ciThe documentation comments are identified by "/**" opening comment mark. See 528c2ecf20Sopenharmony_ciDocumentation/doc-guide/kernel-doc.rst for the documentation comment syntax. 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciOutput format selection (mutually exclusive): 558c2ecf20Sopenharmony_ci -man Output troff manual page format. This is the default. 568c2ecf20Sopenharmony_ci -rst Output reStructuredText format. 578c2ecf20Sopenharmony_ci -none Do not output documentation, only warnings. 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ciOutput format selection modifier (affects only ReST output): 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci -sphinx-version Use the ReST C domain dialect compatible with an 628c2ecf20Sopenharmony_ci specific Sphinx Version. 638c2ecf20Sopenharmony_ci If not specified, kernel-doc will auto-detect using 648c2ecf20Sopenharmony_ci the sphinx-build version found on PATH. 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ciOutput selection (mutually exclusive): 678c2ecf20Sopenharmony_ci -export Only output documentation for symbols that have been 688c2ecf20Sopenharmony_ci exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 698c2ecf20Sopenharmony_ci in any input FILE or -export-file FILE. 708c2ecf20Sopenharmony_ci -internal Only output documentation for symbols that have NOT been 718c2ecf20Sopenharmony_ci exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 728c2ecf20Sopenharmony_ci in any input FILE or -export-file FILE. 738c2ecf20Sopenharmony_ci -function NAME Only output documentation for the given function(s) 748c2ecf20Sopenharmony_ci or DOC: section title(s). All other functions and DOC: 758c2ecf20Sopenharmony_ci sections are ignored. May be specified multiple times. 768c2ecf20Sopenharmony_ci -nosymbol NAME Exclude the specified symbols from the output 778c2ecf20Sopenharmony_ci documentation. May be specified multiple times. 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ciOutput selection modifiers: 808c2ecf20Sopenharmony_ci -no-doc-sections Do not output DOC: sections. 818c2ecf20Sopenharmony_ci -enable-lineno Enable output of #define LINENO lines. Only works with 828c2ecf20Sopenharmony_ci reStructuredText format. 838c2ecf20Sopenharmony_ci -export-file FILE Specify an additional FILE in which to look for 848c2ecf20Sopenharmony_ci EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with 858c2ecf20Sopenharmony_ci -export or -internal. May be specified multiple times. 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ciOther parameters: 888c2ecf20Sopenharmony_ci -v Verbose output, more warnings and other information. 898c2ecf20Sopenharmony_ci -h Print this help. 908c2ecf20Sopenharmony_ci -Werror Treat warnings as errors. 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciEOF 938c2ecf20Sopenharmony_ci print $message; 948c2ecf20Sopenharmony_ci exit 1; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci# 988c2ecf20Sopenharmony_ci# format of comments. 998c2ecf20Sopenharmony_ci# In the following table, (...)? signifies optional structure. 1008c2ecf20Sopenharmony_ci# (...)* signifies 0 or more structure elements 1018c2ecf20Sopenharmony_ci# /** 1028c2ecf20Sopenharmony_ci# * function_name(:)? (- short description)? 1038c2ecf20Sopenharmony_ci# (* @parameterx: (description of parameter x)?)* 1048c2ecf20Sopenharmony_ci# (* a blank line)? 1058c2ecf20Sopenharmony_ci# * (Description:)? (Description of function)? 1068c2ecf20Sopenharmony_ci# * (section header: (section description)? )* 1078c2ecf20Sopenharmony_ci# (*)?*/ 1088c2ecf20Sopenharmony_ci# 1098c2ecf20Sopenharmony_ci# So .. the trivial example would be: 1108c2ecf20Sopenharmony_ci# 1118c2ecf20Sopenharmony_ci# /** 1128c2ecf20Sopenharmony_ci# * my_function 1138c2ecf20Sopenharmony_ci# */ 1148c2ecf20Sopenharmony_ci# 1158c2ecf20Sopenharmony_ci# If the Description: header tag is omitted, then there must be a blank line 1168c2ecf20Sopenharmony_ci# after the last parameter specification. 1178c2ecf20Sopenharmony_ci# e.g. 1188c2ecf20Sopenharmony_ci# /** 1198c2ecf20Sopenharmony_ci# * my_function - does my stuff 1208c2ecf20Sopenharmony_ci# * @my_arg: its mine damnit 1218c2ecf20Sopenharmony_ci# * 1228c2ecf20Sopenharmony_ci# * Does my stuff explained. 1238c2ecf20Sopenharmony_ci# */ 1248c2ecf20Sopenharmony_ci# 1258c2ecf20Sopenharmony_ci# or, could also use: 1268c2ecf20Sopenharmony_ci# /** 1278c2ecf20Sopenharmony_ci# * my_function - does my stuff 1288c2ecf20Sopenharmony_ci# * @my_arg: its mine damnit 1298c2ecf20Sopenharmony_ci# * Description: Does my stuff explained. 1308c2ecf20Sopenharmony_ci# */ 1318c2ecf20Sopenharmony_ci# etc. 1328c2ecf20Sopenharmony_ci# 1338c2ecf20Sopenharmony_ci# Besides functions you can also write documentation for structs, unions, 1348c2ecf20Sopenharmony_ci# enums and typedefs. Instead of the function name you must write the name 1358c2ecf20Sopenharmony_ci# of the declaration; the struct/union/enum/typedef must always precede 1368c2ecf20Sopenharmony_ci# the name. Nesting of declarations is not supported. 1378c2ecf20Sopenharmony_ci# Use the argument mechanism to document members or constants. 1388c2ecf20Sopenharmony_ci# e.g. 1398c2ecf20Sopenharmony_ci# /** 1408c2ecf20Sopenharmony_ci# * struct my_struct - short description 1418c2ecf20Sopenharmony_ci# * @a: first member 1428c2ecf20Sopenharmony_ci# * @b: second member 1438c2ecf20Sopenharmony_ci# * 1448c2ecf20Sopenharmony_ci# * Longer description 1458c2ecf20Sopenharmony_ci# */ 1468c2ecf20Sopenharmony_ci# struct my_struct { 1478c2ecf20Sopenharmony_ci# int a; 1488c2ecf20Sopenharmony_ci# int b; 1498c2ecf20Sopenharmony_ci# /* private: */ 1508c2ecf20Sopenharmony_ci# int c; 1518c2ecf20Sopenharmony_ci# }; 1528c2ecf20Sopenharmony_ci# 1538c2ecf20Sopenharmony_ci# All descriptions can be multiline, except the short function description. 1548c2ecf20Sopenharmony_ci# 1558c2ecf20Sopenharmony_ci# For really longs structs, you can also describe arguments inside the 1568c2ecf20Sopenharmony_ci# body of the struct. 1578c2ecf20Sopenharmony_ci# eg. 1588c2ecf20Sopenharmony_ci# /** 1598c2ecf20Sopenharmony_ci# * struct my_struct - short description 1608c2ecf20Sopenharmony_ci# * @a: first member 1618c2ecf20Sopenharmony_ci# * @b: second member 1628c2ecf20Sopenharmony_ci# * 1638c2ecf20Sopenharmony_ci# * Longer description 1648c2ecf20Sopenharmony_ci# */ 1658c2ecf20Sopenharmony_ci# struct my_struct { 1668c2ecf20Sopenharmony_ci# int a; 1678c2ecf20Sopenharmony_ci# int b; 1688c2ecf20Sopenharmony_ci# /** 1698c2ecf20Sopenharmony_ci# * @c: This is longer description of C 1708c2ecf20Sopenharmony_ci# * 1718c2ecf20Sopenharmony_ci# * You can use paragraphs to describe arguments 1728c2ecf20Sopenharmony_ci# * using this method. 1738c2ecf20Sopenharmony_ci# */ 1748c2ecf20Sopenharmony_ci# int c; 1758c2ecf20Sopenharmony_ci# }; 1768c2ecf20Sopenharmony_ci# 1778c2ecf20Sopenharmony_ci# This should be use only for struct/enum members. 1788c2ecf20Sopenharmony_ci# 1798c2ecf20Sopenharmony_ci# You can also add additional sections. When documenting kernel functions you 1808c2ecf20Sopenharmony_ci# should document the "Context:" of the function, e.g. whether the functions 1818c2ecf20Sopenharmony_ci# can be called form interrupts. Unlike other sections you can end it with an 1828c2ecf20Sopenharmony_ci# empty line. 1838c2ecf20Sopenharmony_ci# A non-void function should have a "Return:" section describing the return 1848c2ecf20Sopenharmony_ci# value(s). 1858c2ecf20Sopenharmony_ci# Example-sections should contain the string EXAMPLE so that they are marked 1868c2ecf20Sopenharmony_ci# appropriately in DocBook. 1878c2ecf20Sopenharmony_ci# 1888c2ecf20Sopenharmony_ci# Example: 1898c2ecf20Sopenharmony_ci# /** 1908c2ecf20Sopenharmony_ci# * user_function - function that can only be called in user context 1918c2ecf20Sopenharmony_ci# * @a: some argument 1928c2ecf20Sopenharmony_ci# * Context: !in_interrupt() 1938c2ecf20Sopenharmony_ci# * 1948c2ecf20Sopenharmony_ci# * Some description 1958c2ecf20Sopenharmony_ci# * Example: 1968c2ecf20Sopenharmony_ci# * user_function(22); 1978c2ecf20Sopenharmony_ci# */ 1988c2ecf20Sopenharmony_ci# ... 1998c2ecf20Sopenharmony_ci# 2008c2ecf20Sopenharmony_ci# 2018c2ecf20Sopenharmony_ci# All descriptive text is further processed, scanning for the following special 2028c2ecf20Sopenharmony_ci# patterns, which are highlighted appropriately. 2038c2ecf20Sopenharmony_ci# 2048c2ecf20Sopenharmony_ci# 'funcname()' - function 2058c2ecf20Sopenharmony_ci# '$ENVVAR' - environmental variable 2068c2ecf20Sopenharmony_ci# '&struct_name' - name of a structure (up to two words including 'struct') 2078c2ecf20Sopenharmony_ci# '&struct_name.member' - name of a structure member 2088c2ecf20Sopenharmony_ci# '@parameter' - name of a parameter 2098c2ecf20Sopenharmony_ci# '%CONST' - name of a constant. 2108c2ecf20Sopenharmony_ci# '``LITERAL``' - literal string without any spaces on it. 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci## init lots of data 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cimy $errors = 0; 2158c2ecf20Sopenharmony_cimy $warnings = 0; 2168c2ecf20Sopenharmony_cimy $anon_struct_union = 0; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci# match expressions used to find embedded type information 2198c2ecf20Sopenharmony_cimy $type_constant = '\b``([^\`]+)``\b'; 2208c2ecf20Sopenharmony_cimy $type_constant2 = '\%([-_\w]+)'; 2218c2ecf20Sopenharmony_cimy $type_func = '(\w+)\(\)'; 2228c2ecf20Sopenharmony_cimy $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; 2238c2ecf20Sopenharmony_cimy $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; 2248c2ecf20Sopenharmony_cimy $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params 2258c2ecf20Sopenharmony_cimy $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params 2268c2ecf20Sopenharmony_cimy $type_env = '(\$\w+)'; 2278c2ecf20Sopenharmony_cimy $type_enum = '\&(enum\s*([_\w]+))'; 2288c2ecf20Sopenharmony_cimy $type_struct = '\&(struct\s*([_\w]+))'; 2298c2ecf20Sopenharmony_cimy $type_typedef = '\&(typedef\s*([_\w]+))'; 2308c2ecf20Sopenharmony_cimy $type_union = '\&(union\s*([_\w]+))'; 2318c2ecf20Sopenharmony_cimy $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; 2328c2ecf20Sopenharmony_cimy $type_fallback = '\&([_\w]+)'; 2338c2ecf20Sopenharmony_cimy $type_member_func = $type_member . '\(\)'; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci# Output conversion substitutions. 2368c2ecf20Sopenharmony_ci# One for each output format 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci# these are pretty rough 2398c2ecf20Sopenharmony_cimy @highlights_man = ( 2408c2ecf20Sopenharmony_ci [$type_constant, "\$1"], 2418c2ecf20Sopenharmony_ci [$type_constant2, "\$1"], 2428c2ecf20Sopenharmony_ci [$type_func, "\\\\fB\$1\\\\fP"], 2438c2ecf20Sopenharmony_ci [$type_enum, "\\\\fI\$1\\\\fP"], 2448c2ecf20Sopenharmony_ci [$type_struct, "\\\\fI\$1\\\\fP"], 2458c2ecf20Sopenharmony_ci [$type_typedef, "\\\\fI\$1\\\\fP"], 2468c2ecf20Sopenharmony_ci [$type_union, "\\\\fI\$1\\\\fP"], 2478c2ecf20Sopenharmony_ci [$type_param, "\\\\fI\$1\\\\fP"], 2488c2ecf20Sopenharmony_ci [$type_param_ref, "\\\\fI\$1\$2\\\\fP"], 2498c2ecf20Sopenharmony_ci [$type_member, "\\\\fI\$1\$2\$3\\\\fP"], 2508c2ecf20Sopenharmony_ci [$type_fallback, "\\\\fI\$1\\\\fP"] 2518c2ecf20Sopenharmony_ci ); 2528c2ecf20Sopenharmony_cimy $blankline_man = ""; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci# rst-mode 2558c2ecf20Sopenharmony_cimy @highlights_rst = ( 2568c2ecf20Sopenharmony_ci [$type_constant, "``\$1``"], 2578c2ecf20Sopenharmony_ci [$type_constant2, "``\$1``"], 2588c2ecf20Sopenharmony_ci # Note: need to escape () to avoid func matching later 2598c2ecf20Sopenharmony_ci [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"], 2608c2ecf20Sopenharmony_ci [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"], 2618c2ecf20Sopenharmony_ci [$type_fp_param, "**\$1\\\\(\\\\)**"], 2628c2ecf20Sopenharmony_ci [$type_fp_param2, "**\$1\\\\(\\\\)**"], 2638c2ecf20Sopenharmony_ci [$type_func, "\$1()"], 2648c2ecf20Sopenharmony_ci [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], 2658c2ecf20Sopenharmony_ci [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"], 2668c2ecf20Sopenharmony_ci [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"], 2678c2ecf20Sopenharmony_ci [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"], 2688c2ecf20Sopenharmony_ci # in rst this can refer to any type 2698c2ecf20Sopenharmony_ci [$type_fallback, "\\:c\\:type\\:`\$1`"], 2708c2ecf20Sopenharmony_ci [$type_param_ref, "**\$1\$2**"] 2718c2ecf20Sopenharmony_ci ); 2728c2ecf20Sopenharmony_cimy $blankline_rst = "\n"; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci# read arguments 2758c2ecf20Sopenharmony_ciif ($#ARGV == -1) { 2768c2ecf20Sopenharmony_ci usage(); 2778c2ecf20Sopenharmony_ci} 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_cimy $kernelversion; 2808c2ecf20Sopenharmony_cimy ($sphinx_major, $sphinx_minor, $sphinx_patch); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_cimy $dohighlight = ""; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_cimy $verbose = 0; 2858c2ecf20Sopenharmony_cimy $Werror = 0; 2868c2ecf20Sopenharmony_cimy $output_mode = "rst"; 2878c2ecf20Sopenharmony_cimy $output_preformatted = 0; 2888c2ecf20Sopenharmony_cimy $no_doc_sections = 0; 2898c2ecf20Sopenharmony_cimy $enable_lineno = 0; 2908c2ecf20Sopenharmony_cimy @highlights = @highlights_rst; 2918c2ecf20Sopenharmony_cimy $blankline = $blankline_rst; 2928c2ecf20Sopenharmony_cimy $modulename = "Kernel API"; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ciuse constant { 2958c2ecf20Sopenharmony_ci OUTPUT_ALL => 0, # output all symbols and doc sections 2968c2ecf20Sopenharmony_ci OUTPUT_INCLUDE => 1, # output only specified symbols 2978c2ecf20Sopenharmony_ci OUTPUT_EXPORTED => 2, # output exported symbols 2988c2ecf20Sopenharmony_ci OUTPUT_INTERNAL => 3, # output non-exported symbols 2998c2ecf20Sopenharmony_ci}; 3008c2ecf20Sopenharmony_cimy $output_selection = OUTPUT_ALL; 3018c2ecf20Sopenharmony_cimy $show_not_found = 0; # No longer used 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cimy @export_file_list; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cimy @build_time; 3068c2ecf20Sopenharmony_ciif (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 3078c2ecf20Sopenharmony_ci (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { 3088c2ecf20Sopenharmony_ci @build_time = gmtime($seconds); 3098c2ecf20Sopenharmony_ci} else { 3108c2ecf20Sopenharmony_ci @build_time = localtime; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cimy $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 3148c2ecf20Sopenharmony_ci 'July', 'August', 'September', 'October', 3158c2ecf20Sopenharmony_ci 'November', 'December')[$build_time[4]] . 3168c2ecf20Sopenharmony_ci " " . ($build_time[5]+1900); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci# Essentially these are globals. 3198c2ecf20Sopenharmony_ci# They probably want to be tidied up, made more localised or something. 3208c2ecf20Sopenharmony_ci# CAVEAT EMPTOR! Some of the others I localised may not want to be, which 3218c2ecf20Sopenharmony_ci# could cause "use of undefined value" or other bugs. 3228c2ecf20Sopenharmony_cimy ($function, %function_table, %parametertypes, $declaration_purpose); 3238c2ecf20Sopenharmony_cimy %nosymbol_table = (); 3248c2ecf20Sopenharmony_cimy $declaration_start_line; 3258c2ecf20Sopenharmony_cimy ($type, $declaration_name, $return_type); 3268c2ecf20Sopenharmony_cimy ($newsection, $newcontents, $prototype, $brcount, %source_map); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ciif (defined($ENV{'KBUILD_VERBOSE'})) { 3298c2ecf20Sopenharmony_ci $verbose = "$ENV{'KBUILD_VERBOSE'}"; 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ciif (defined($ENV{'KDOC_WERROR'})) { 3338c2ecf20Sopenharmony_ci $Werror = "$ENV{'KDOC_WERROR'}"; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ciif (defined($ENV{'KCFLAGS'})) { 3378c2ecf20Sopenharmony_ci my $kcflags = "$ENV{'KCFLAGS'}"; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if ($kcflags =~ /Werror/) { 3408c2ecf20Sopenharmony_ci $Werror = 1; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci# Generated docbook code is inserted in a template at a point where 3458c2ecf20Sopenharmony_ci# docbook v3.1 requires a non-zero sequence of RefEntry's; see: 3468c2ecf20Sopenharmony_ci# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html 3478c2ecf20Sopenharmony_ci# We keep track of number of generated entries and generate a dummy 3488c2ecf20Sopenharmony_ci# if needs be to ensure the expanded template can be postprocessed 3498c2ecf20Sopenharmony_ci# into html. 3508c2ecf20Sopenharmony_cimy $section_counter = 0; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cimy $lineprefix=""; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci# Parser states 3558c2ecf20Sopenharmony_ciuse constant { 3568c2ecf20Sopenharmony_ci STATE_NORMAL => 0, # normal code 3578c2ecf20Sopenharmony_ci STATE_NAME => 1, # looking for function name 3588c2ecf20Sopenharmony_ci STATE_BODY_MAYBE => 2, # body - or maybe more description 3598c2ecf20Sopenharmony_ci STATE_BODY => 3, # the body of the comment 3608c2ecf20Sopenharmony_ci STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line 3618c2ecf20Sopenharmony_ci STATE_PROTO => 5, # scanning prototype 3628c2ecf20Sopenharmony_ci STATE_DOCBLOCK => 6, # documentation block 3638c2ecf20Sopenharmony_ci STATE_INLINE => 7, # gathering doc outside main block 3648c2ecf20Sopenharmony_ci}; 3658c2ecf20Sopenharmony_cimy $state; 3668c2ecf20Sopenharmony_cimy $in_doc_sect; 3678c2ecf20Sopenharmony_cimy $leading_space; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci# Inline documentation state 3708c2ecf20Sopenharmony_ciuse constant { 3718c2ecf20Sopenharmony_ci STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) 3728c2ecf20Sopenharmony_ci STATE_INLINE_NAME => 1, # looking for member name (@foo:) 3738c2ecf20Sopenharmony_ci STATE_INLINE_TEXT => 2, # looking for member documentation 3748c2ecf20Sopenharmony_ci STATE_INLINE_END => 3, # done 3758c2ecf20Sopenharmony_ci STATE_INLINE_ERROR => 4, # error - Comment without header was found. 3768c2ecf20Sopenharmony_ci # Spit a warning as it's not 3778c2ecf20Sopenharmony_ci # proper kernel-doc and ignore the rest. 3788c2ecf20Sopenharmony_ci}; 3798c2ecf20Sopenharmony_cimy $inline_doc_state; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci#declaration types: can be 3828c2ecf20Sopenharmony_ci# 'function', 'struct', 'union', 'enum', 'typedef' 3838c2ecf20Sopenharmony_cimy $decl_type; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_cimy $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 3868c2ecf20Sopenharmony_cimy $doc_end = '\*/'; 3878c2ecf20Sopenharmony_cimy $doc_com = '\s*\*\s*'; 3888c2ecf20Sopenharmony_cimy $doc_com_body = '\s*\* ?'; 3898c2ecf20Sopenharmony_cimy $doc_decl = $doc_com . '(\w+)'; 3908c2ecf20Sopenharmony_ci# @params and a strictly limited set of supported section names 3918c2ecf20Sopenharmony_cimy $doc_sect = $doc_com . 3928c2ecf20Sopenharmony_ci '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)'; 3938c2ecf20Sopenharmony_cimy $doc_content = $doc_com_body . '(.*)'; 3948c2ecf20Sopenharmony_cimy $doc_block = $doc_com . 'DOC:\s*(.*)?'; 3958c2ecf20Sopenharmony_cimy $doc_inline_start = '^\s*/\*\*\s*$'; 3968c2ecf20Sopenharmony_cimy $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; 3978c2ecf20Sopenharmony_cimy $doc_inline_end = '^\s*\*/\s*$'; 3988c2ecf20Sopenharmony_cimy $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; 3998c2ecf20Sopenharmony_cimy $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_cimy %parameterdescs; 4028c2ecf20Sopenharmony_cimy %parameterdesc_start_lines; 4038c2ecf20Sopenharmony_cimy @parameterlist; 4048c2ecf20Sopenharmony_cimy %sections; 4058c2ecf20Sopenharmony_cimy @sectionlist; 4068c2ecf20Sopenharmony_cimy %section_start_lines; 4078c2ecf20Sopenharmony_cimy $sectcheck; 4088c2ecf20Sopenharmony_cimy $struct_actual; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_cimy $contents = ""; 4118c2ecf20Sopenharmony_cimy $new_start_line = 0; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci# the canonical section names. see also $doc_sect above. 4148c2ecf20Sopenharmony_cimy $section_default = "Description"; # default section 4158c2ecf20Sopenharmony_cimy $section_intro = "Introduction"; 4168c2ecf20Sopenharmony_cimy $section = $section_default; 4178c2ecf20Sopenharmony_cimy $section_context = "Context"; 4188c2ecf20Sopenharmony_cimy $section_return = "Return"; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_cimy $undescribed = "-- undescribed --"; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_cireset_state(); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ciwhile ($ARGV[0] =~ m/^--?(.*)/) { 4258c2ecf20Sopenharmony_ci my $cmd = $1; 4268c2ecf20Sopenharmony_ci shift @ARGV; 4278c2ecf20Sopenharmony_ci if ($cmd eq "man") { 4288c2ecf20Sopenharmony_ci $output_mode = "man"; 4298c2ecf20Sopenharmony_ci @highlights = @highlights_man; 4308c2ecf20Sopenharmony_ci $blankline = $blankline_man; 4318c2ecf20Sopenharmony_ci } elsif ($cmd eq "rst") { 4328c2ecf20Sopenharmony_ci $output_mode = "rst"; 4338c2ecf20Sopenharmony_ci @highlights = @highlights_rst; 4348c2ecf20Sopenharmony_ci $blankline = $blankline_rst; 4358c2ecf20Sopenharmony_ci } elsif ($cmd eq "none") { 4368c2ecf20Sopenharmony_ci $output_mode = "none"; 4378c2ecf20Sopenharmony_ci } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document 4388c2ecf20Sopenharmony_ci $modulename = shift @ARGV; 4398c2ecf20Sopenharmony_ci } elsif ($cmd eq "function") { # to only output specific functions 4408c2ecf20Sopenharmony_ci $output_selection = OUTPUT_INCLUDE; 4418c2ecf20Sopenharmony_ci $function = shift @ARGV; 4428c2ecf20Sopenharmony_ci $function_table{$function} = 1; 4438c2ecf20Sopenharmony_ci } elsif ($cmd eq "nosymbol") { # Exclude specific symbols 4448c2ecf20Sopenharmony_ci my $symbol = shift @ARGV; 4458c2ecf20Sopenharmony_ci $nosymbol_table{$symbol} = 1; 4468c2ecf20Sopenharmony_ci } elsif ($cmd eq "export") { # only exported symbols 4478c2ecf20Sopenharmony_ci $output_selection = OUTPUT_EXPORTED; 4488c2ecf20Sopenharmony_ci %function_table = (); 4498c2ecf20Sopenharmony_ci } elsif ($cmd eq "internal") { # only non-exported symbols 4508c2ecf20Sopenharmony_ci $output_selection = OUTPUT_INTERNAL; 4518c2ecf20Sopenharmony_ci %function_table = (); 4528c2ecf20Sopenharmony_ci } elsif ($cmd eq "export-file") { 4538c2ecf20Sopenharmony_ci my $file = shift @ARGV; 4548c2ecf20Sopenharmony_ci push(@export_file_list, $file); 4558c2ecf20Sopenharmony_ci } elsif ($cmd eq "v") { 4568c2ecf20Sopenharmony_ci $verbose = 1; 4578c2ecf20Sopenharmony_ci } elsif ($cmd eq "Werror") { 4588c2ecf20Sopenharmony_ci $Werror = 1; 4598c2ecf20Sopenharmony_ci } elsif (($cmd eq "h") || ($cmd eq "help")) { 4608c2ecf20Sopenharmony_ci usage(); 4618c2ecf20Sopenharmony_ci } elsif ($cmd eq 'no-doc-sections') { 4628c2ecf20Sopenharmony_ci $no_doc_sections = 1; 4638c2ecf20Sopenharmony_ci } elsif ($cmd eq 'enable-lineno') { 4648c2ecf20Sopenharmony_ci $enable_lineno = 1; 4658c2ecf20Sopenharmony_ci } elsif ($cmd eq 'show-not-found') { 4668c2ecf20Sopenharmony_ci $show_not_found = 1; # A no-op but don't fail 4678c2ecf20Sopenharmony_ci } elsif ($cmd eq "sphinx-version") { 4688c2ecf20Sopenharmony_ci my $ver_string = shift @ARGV; 4698c2ecf20Sopenharmony_ci if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) { 4708c2ecf20Sopenharmony_ci $sphinx_major = $1; 4718c2ecf20Sopenharmony_ci if (defined($2)) { 4728c2ecf20Sopenharmony_ci $sphinx_minor = substr($2,1); 4738c2ecf20Sopenharmony_ci } else { 4748c2ecf20Sopenharmony_ci $sphinx_minor = 0; 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci if (defined($3)) { 4778c2ecf20Sopenharmony_ci $sphinx_patch = substr($3,1) 4788c2ecf20Sopenharmony_ci } else { 4798c2ecf20Sopenharmony_ci $sphinx_patch = 0; 4808c2ecf20Sopenharmony_ci } 4818c2ecf20Sopenharmony_ci } else { 4828c2ecf20Sopenharmony_ci die "Sphinx version should either major.minor or major.minor.patch format\n"; 4838c2ecf20Sopenharmony_ci } 4848c2ecf20Sopenharmony_ci } else { 4858c2ecf20Sopenharmony_ci # Unknown argument 4868c2ecf20Sopenharmony_ci usage(); 4878c2ecf20Sopenharmony_ci } 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci# continue execution near EOF; 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci# The C domain dialect changed on Sphinx 3. So, we need to check the 4938c2ecf20Sopenharmony_ci# version in order to produce the right tags. 4948c2ecf20Sopenharmony_cisub findprog($) 4958c2ecf20Sopenharmony_ci{ 4968c2ecf20Sopenharmony_ci foreach(split(/:/, $ENV{PATH})) { 4978c2ecf20Sopenharmony_ci return "$_/$_[0]" if(-x "$_/$_[0]"); 4988c2ecf20Sopenharmony_ci } 4998c2ecf20Sopenharmony_ci} 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_cisub get_sphinx_version() 5028c2ecf20Sopenharmony_ci{ 5038c2ecf20Sopenharmony_ci my $ver; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci my $cmd = "sphinx-build"; 5068c2ecf20Sopenharmony_ci if (!findprog($cmd)) { 5078c2ecf20Sopenharmony_ci my $cmd = "sphinx-build3"; 5088c2ecf20Sopenharmony_ci if (!findprog($cmd)) { 5098c2ecf20Sopenharmony_ci $sphinx_major = 1; 5108c2ecf20Sopenharmony_ci $sphinx_minor = 2; 5118c2ecf20Sopenharmony_ci $sphinx_patch = 0; 5128c2ecf20Sopenharmony_ci printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n", 5138c2ecf20Sopenharmony_ci $sphinx_major, $sphinx_minor, $sphinx_patch; 5148c2ecf20Sopenharmony_ci return; 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci } 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci open IN, "$cmd --version 2>&1 |"; 5198c2ecf20Sopenharmony_ci while (<IN>) { 5208c2ecf20Sopenharmony_ci if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) { 5218c2ecf20Sopenharmony_ci $sphinx_major = $1; 5228c2ecf20Sopenharmony_ci $sphinx_minor = $2; 5238c2ecf20Sopenharmony_ci $sphinx_patch = $3; 5248c2ecf20Sopenharmony_ci last; 5258c2ecf20Sopenharmony_ci } 5268c2ecf20Sopenharmony_ci # Sphinx 1.2.x uses a different format 5278c2ecf20Sopenharmony_ci if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) { 5288c2ecf20Sopenharmony_ci $sphinx_major = $1; 5298c2ecf20Sopenharmony_ci $sphinx_minor = $2; 5308c2ecf20Sopenharmony_ci $sphinx_patch = $3; 5318c2ecf20Sopenharmony_ci last; 5328c2ecf20Sopenharmony_ci } 5338c2ecf20Sopenharmony_ci } 5348c2ecf20Sopenharmony_ci close IN; 5358c2ecf20Sopenharmony_ci} 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci# get kernel version from env 5388c2ecf20Sopenharmony_cisub get_kernel_version() { 5398c2ecf20Sopenharmony_ci my $version = 'unknown kernel version'; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci if (defined($ENV{'KERNELVERSION'})) { 5428c2ecf20Sopenharmony_ci $version = $ENV{'KERNELVERSION'}; 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci return $version; 5458c2ecf20Sopenharmony_ci} 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci# 5488c2ecf20Sopenharmony_cisub print_lineno { 5498c2ecf20Sopenharmony_ci my $lineno = shift; 5508c2ecf20Sopenharmony_ci if ($enable_lineno && defined($lineno)) { 5518c2ecf20Sopenharmony_ci print "#define LINENO " . $lineno . "\n"; 5528c2ecf20Sopenharmony_ci } 5538c2ecf20Sopenharmony_ci} 5548c2ecf20Sopenharmony_ci## 5558c2ecf20Sopenharmony_ci# dumps section contents to arrays/hashes intended for that purpose. 5568c2ecf20Sopenharmony_ci# 5578c2ecf20Sopenharmony_cisub dump_section { 5588c2ecf20Sopenharmony_ci my $file = shift; 5598c2ecf20Sopenharmony_ci my $name = shift; 5608c2ecf20Sopenharmony_ci my $contents = join "\n", @_; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci if ($name =~ m/$type_param/) { 5638c2ecf20Sopenharmony_ci $name = $1; 5648c2ecf20Sopenharmony_ci $parameterdescs{$name} = $contents; 5658c2ecf20Sopenharmony_ci $sectcheck = $sectcheck . $name . " "; 5668c2ecf20Sopenharmony_ci $parameterdesc_start_lines{$name} = $new_start_line; 5678c2ecf20Sopenharmony_ci $new_start_line = 0; 5688c2ecf20Sopenharmony_ci } elsif ($name eq "@\.\.\.") { 5698c2ecf20Sopenharmony_ci $name = "..."; 5708c2ecf20Sopenharmony_ci $parameterdescs{$name} = $contents; 5718c2ecf20Sopenharmony_ci $sectcheck = $sectcheck . $name . " "; 5728c2ecf20Sopenharmony_ci $parameterdesc_start_lines{$name} = $new_start_line; 5738c2ecf20Sopenharmony_ci $new_start_line = 0; 5748c2ecf20Sopenharmony_ci } else { 5758c2ecf20Sopenharmony_ci if (defined($sections{$name}) && ($sections{$name} ne "")) { 5768c2ecf20Sopenharmony_ci # Only warn on user specified duplicate section names. 5778c2ecf20Sopenharmony_ci if ($name ne $section_default) { 5788c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; 5798c2ecf20Sopenharmony_ci ++$warnings; 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci $sections{$name} .= $contents; 5828c2ecf20Sopenharmony_ci } else { 5838c2ecf20Sopenharmony_ci $sections{$name} = $contents; 5848c2ecf20Sopenharmony_ci push @sectionlist, $name; 5858c2ecf20Sopenharmony_ci $section_start_lines{$name} = $new_start_line; 5868c2ecf20Sopenharmony_ci $new_start_line = 0; 5878c2ecf20Sopenharmony_ci } 5888c2ecf20Sopenharmony_ci } 5898c2ecf20Sopenharmony_ci} 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci## 5928c2ecf20Sopenharmony_ci# dump DOC: section after checking that it should go out 5938c2ecf20Sopenharmony_ci# 5948c2ecf20Sopenharmony_cisub dump_doc_section { 5958c2ecf20Sopenharmony_ci my $file = shift; 5968c2ecf20Sopenharmony_ci my $name = shift; 5978c2ecf20Sopenharmony_ci my $contents = join "\n", @_; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci if ($no_doc_sections) { 6008c2ecf20Sopenharmony_ci return; 6018c2ecf20Sopenharmony_ci } 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci return if (defined($nosymbol_table{$name})); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (($output_selection == OUTPUT_ALL) || 6068c2ecf20Sopenharmony_ci (($output_selection == OUTPUT_INCLUDE) && 6078c2ecf20Sopenharmony_ci defined($function_table{$name}))) 6088c2ecf20Sopenharmony_ci { 6098c2ecf20Sopenharmony_ci dump_section($file, $name, $contents); 6108c2ecf20Sopenharmony_ci output_blockhead({'sectionlist' => \@sectionlist, 6118c2ecf20Sopenharmony_ci 'sections' => \%sections, 6128c2ecf20Sopenharmony_ci 'module' => $modulename, 6138c2ecf20Sopenharmony_ci 'content-only' => ($output_selection != OUTPUT_ALL), }); 6148c2ecf20Sopenharmony_ci } 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci## 6188c2ecf20Sopenharmony_ci# output function 6198c2ecf20Sopenharmony_ci# 6208c2ecf20Sopenharmony_ci# parameterdescs, a hash. 6218c2ecf20Sopenharmony_ci# function => "function name" 6228c2ecf20Sopenharmony_ci# parameterlist => @list of parameters 6238c2ecf20Sopenharmony_ci# parameterdescs => %parameter descriptions 6248c2ecf20Sopenharmony_ci# sectionlist => @list of sections 6258c2ecf20Sopenharmony_ci# sections => %section descriptions 6268c2ecf20Sopenharmony_ci# 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_cisub output_highlight { 6298c2ecf20Sopenharmony_ci my $contents = join "\n",@_; 6308c2ecf20Sopenharmony_ci my $line; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci# DEBUG 6338c2ecf20Sopenharmony_ci# if (!defined $contents) { 6348c2ecf20Sopenharmony_ci# use Carp; 6358c2ecf20Sopenharmony_ci# confess "output_highlight got called with no args?\n"; 6368c2ecf20Sopenharmony_ci# } 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci# print STDERR "contents b4:$contents\n"; 6398c2ecf20Sopenharmony_ci eval $dohighlight; 6408c2ecf20Sopenharmony_ci die $@ if $@; 6418c2ecf20Sopenharmony_ci# print STDERR "contents af:$contents\n"; 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci foreach $line (split "\n", $contents) { 6448c2ecf20Sopenharmony_ci if (! $output_preformatted) { 6458c2ecf20Sopenharmony_ci $line =~ s/^\s*//; 6468c2ecf20Sopenharmony_ci } 6478c2ecf20Sopenharmony_ci if ($line eq ""){ 6488c2ecf20Sopenharmony_ci if (! $output_preformatted) { 6498c2ecf20Sopenharmony_ci print $lineprefix, $blankline; 6508c2ecf20Sopenharmony_ci } 6518c2ecf20Sopenharmony_ci } else { 6528c2ecf20Sopenharmony_ci if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { 6538c2ecf20Sopenharmony_ci print "\\&$line"; 6548c2ecf20Sopenharmony_ci } else { 6558c2ecf20Sopenharmony_ci print $lineprefix, $line; 6568c2ecf20Sopenharmony_ci } 6578c2ecf20Sopenharmony_ci } 6588c2ecf20Sopenharmony_ci print "\n"; 6598c2ecf20Sopenharmony_ci } 6608c2ecf20Sopenharmony_ci} 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci## 6638c2ecf20Sopenharmony_ci# output function in man 6648c2ecf20Sopenharmony_cisub output_function_man(%) { 6658c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 6668c2ecf20Sopenharmony_ci my ($parameter, $section); 6678c2ecf20Sopenharmony_ci my $count; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n"; 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci print ".SH NAME\n"; 6728c2ecf20Sopenharmony_ci print $args{'function'} . " \\- " . $args{'purpose'} . "\n"; 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci print ".SH SYNOPSIS\n"; 6758c2ecf20Sopenharmony_ci if ($args{'functiontype'} ne "") { 6768c2ecf20Sopenharmony_ci print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n"; 6778c2ecf20Sopenharmony_ci } else { 6788c2ecf20Sopenharmony_ci print ".B \"" . $args{'function'} . "\n"; 6798c2ecf20Sopenharmony_ci } 6808c2ecf20Sopenharmony_ci $count = 0; 6818c2ecf20Sopenharmony_ci my $parenth = "("; 6828c2ecf20Sopenharmony_ci my $post = ","; 6838c2ecf20Sopenharmony_ci foreach my $parameter (@{$args{'parameterlist'}}) { 6848c2ecf20Sopenharmony_ci if ($count == $#{$args{'parameterlist'}}) { 6858c2ecf20Sopenharmony_ci $post = ");"; 6868c2ecf20Sopenharmony_ci } 6878c2ecf20Sopenharmony_ci $type = $args{'parametertypes'}{$parameter}; 6888c2ecf20Sopenharmony_ci if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 6898c2ecf20Sopenharmony_ci # pointer-to-function 6908c2ecf20Sopenharmony_ci print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n"; 6918c2ecf20Sopenharmony_ci } else { 6928c2ecf20Sopenharmony_ci $type =~ s/([^\*])$/$1 /; 6938c2ecf20Sopenharmony_ci print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n"; 6948c2ecf20Sopenharmony_ci } 6958c2ecf20Sopenharmony_ci $count++; 6968c2ecf20Sopenharmony_ci $parenth = ""; 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci print ".SH ARGUMENTS\n"; 7008c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 7018c2ecf20Sopenharmony_ci my $parameter_name = $parameter; 7028c2ecf20Sopenharmony_ci $parameter_name =~ s/\[.*//; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci print ".IP \"" . $parameter . "\" 12\n"; 7058c2ecf20Sopenharmony_ci output_highlight($args{'parameterdescs'}{$parameter_name}); 7068c2ecf20Sopenharmony_ci } 7078c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 7088c2ecf20Sopenharmony_ci print ".SH \"", uc $section, "\"\n"; 7098c2ecf20Sopenharmony_ci output_highlight($args{'sections'}{$section}); 7108c2ecf20Sopenharmony_ci } 7118c2ecf20Sopenharmony_ci} 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci## 7148c2ecf20Sopenharmony_ci# output enum in man 7158c2ecf20Sopenharmony_cisub output_enum_man(%) { 7168c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 7178c2ecf20Sopenharmony_ci my ($parameter, $section); 7188c2ecf20Sopenharmony_ci my $count; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci print ".SH NAME\n"; 7238c2ecf20Sopenharmony_ci print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n"; 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci print ".SH SYNOPSIS\n"; 7268c2ecf20Sopenharmony_ci print "enum " . $args{'enum'} . " {\n"; 7278c2ecf20Sopenharmony_ci $count = 0; 7288c2ecf20Sopenharmony_ci foreach my $parameter (@{$args{'parameterlist'}}) { 7298c2ecf20Sopenharmony_ci print ".br\n.BI \" $parameter\"\n"; 7308c2ecf20Sopenharmony_ci if ($count == $#{$args{'parameterlist'}}) { 7318c2ecf20Sopenharmony_ci print "\n};\n"; 7328c2ecf20Sopenharmony_ci last; 7338c2ecf20Sopenharmony_ci } 7348c2ecf20Sopenharmony_ci else { 7358c2ecf20Sopenharmony_ci print ", \n.br\n"; 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci $count++; 7388c2ecf20Sopenharmony_ci } 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci print ".SH Constants\n"; 7418c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 7428c2ecf20Sopenharmony_ci my $parameter_name = $parameter; 7438c2ecf20Sopenharmony_ci $parameter_name =~ s/\[.*//; 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci print ".IP \"" . $parameter . "\" 12\n"; 7468c2ecf20Sopenharmony_ci output_highlight($args{'parameterdescs'}{$parameter_name}); 7478c2ecf20Sopenharmony_ci } 7488c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 7498c2ecf20Sopenharmony_ci print ".SH \"$section\"\n"; 7508c2ecf20Sopenharmony_ci output_highlight($args{'sections'}{$section}); 7518c2ecf20Sopenharmony_ci } 7528c2ecf20Sopenharmony_ci} 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci## 7558c2ecf20Sopenharmony_ci# output struct in man 7568c2ecf20Sopenharmony_cisub output_struct_man(%) { 7578c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 7588c2ecf20Sopenharmony_ci my ($parameter, $section); 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n"; 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci print ".SH NAME\n"; 7638c2ecf20Sopenharmony_ci print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci my $declaration = $args{'definition'}; 7668c2ecf20Sopenharmony_ci $declaration =~ s/\t/ /g; 7678c2ecf20Sopenharmony_ci $declaration =~ s/\n/"\n.br\n.BI \"/g; 7688c2ecf20Sopenharmony_ci print ".SH SYNOPSIS\n"; 7698c2ecf20Sopenharmony_ci print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; 7708c2ecf20Sopenharmony_ci print ".BI \"$declaration\n};\n.br\n\n"; 7718c2ecf20Sopenharmony_ci 7728c2ecf20Sopenharmony_ci print ".SH Members\n"; 7738c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 7748c2ecf20Sopenharmony_ci ($parameter =~ /^#/) && next; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci my $parameter_name = $parameter; 7778c2ecf20Sopenharmony_ci $parameter_name =~ s/\[.*//; 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 7808c2ecf20Sopenharmony_ci print ".IP \"" . $parameter . "\" 12\n"; 7818c2ecf20Sopenharmony_ci output_highlight($args{'parameterdescs'}{$parameter_name}); 7828c2ecf20Sopenharmony_ci } 7838c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 7848c2ecf20Sopenharmony_ci print ".SH \"$section\"\n"; 7858c2ecf20Sopenharmony_ci output_highlight($args{'sections'}{$section}); 7868c2ecf20Sopenharmony_ci } 7878c2ecf20Sopenharmony_ci} 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci## 7908c2ecf20Sopenharmony_ci# output typedef in man 7918c2ecf20Sopenharmony_cisub output_typedef_man(%) { 7928c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 7938c2ecf20Sopenharmony_ci my ($parameter, $section); 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_ci print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci print ".SH NAME\n"; 7988c2ecf20Sopenharmony_ci print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n"; 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 8018c2ecf20Sopenharmony_ci print ".SH \"$section\"\n"; 8028c2ecf20Sopenharmony_ci output_highlight($args{'sections'}{$section}); 8038c2ecf20Sopenharmony_ci } 8048c2ecf20Sopenharmony_ci} 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_cisub output_blockhead_man(%) { 8078c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 8088c2ecf20Sopenharmony_ci my ($parameter, $section); 8098c2ecf20Sopenharmony_ci my $count; 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_ci print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 8148c2ecf20Sopenharmony_ci print ".SH \"$section\"\n"; 8158c2ecf20Sopenharmony_ci output_highlight($args{'sections'}{$section}); 8168c2ecf20Sopenharmony_ci } 8178c2ecf20Sopenharmony_ci} 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci## 8208c2ecf20Sopenharmony_ci# output in restructured text 8218c2ecf20Sopenharmony_ci# 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_ci# 8248c2ecf20Sopenharmony_ci# This could use some work; it's used to output the DOC: sections, and 8258c2ecf20Sopenharmony_ci# starts by putting out the name of the doc section itself, but that tends 8268c2ecf20Sopenharmony_ci# to duplicate a header already in the template file. 8278c2ecf20Sopenharmony_ci# 8288c2ecf20Sopenharmony_cisub output_blockhead_rst(%) { 8298c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 8308c2ecf20Sopenharmony_ci my ($parameter, $section); 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 8338c2ecf20Sopenharmony_ci next if (defined($nosymbol_table{$section})); 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ci if ($output_selection != OUTPUT_INCLUDE) { 8368c2ecf20Sopenharmony_ci print "**$section**\n\n"; 8378c2ecf20Sopenharmony_ci } 8388c2ecf20Sopenharmony_ci print_lineno($section_start_lines{$section}); 8398c2ecf20Sopenharmony_ci output_highlight_rst($args{'sections'}{$section}); 8408c2ecf20Sopenharmony_ci print "\n"; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci} 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci# 8458c2ecf20Sopenharmony_ci# Apply the RST highlights to a sub-block of text. 8468c2ecf20Sopenharmony_ci# 8478c2ecf20Sopenharmony_cisub highlight_block($) { 8488c2ecf20Sopenharmony_ci # The dohighlight kludge requires the text be called $contents 8498c2ecf20Sopenharmony_ci my $contents = shift; 8508c2ecf20Sopenharmony_ci eval $dohighlight; 8518c2ecf20Sopenharmony_ci die $@ if $@; 8528c2ecf20Sopenharmony_ci return $contents; 8538c2ecf20Sopenharmony_ci} 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci# 8568c2ecf20Sopenharmony_ci# Regexes used only here. 8578c2ecf20Sopenharmony_ci# 8588c2ecf20Sopenharmony_cimy $sphinx_literal = '^[^.].*::$'; 8598c2ecf20Sopenharmony_cimy $sphinx_cblock = '^\.\.\ +code-block::'; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_cisub output_highlight_rst { 8628c2ecf20Sopenharmony_ci my $input = join "\n",@_; 8638c2ecf20Sopenharmony_ci my $output = ""; 8648c2ecf20Sopenharmony_ci my $line; 8658c2ecf20Sopenharmony_ci my $in_literal = 0; 8668c2ecf20Sopenharmony_ci my $litprefix; 8678c2ecf20Sopenharmony_ci my $block = ""; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci foreach $line (split "\n",$input) { 8708c2ecf20Sopenharmony_ci # 8718c2ecf20Sopenharmony_ci # If we're in a literal block, see if we should drop out 8728c2ecf20Sopenharmony_ci # of it. Otherwise pass the line straight through unmunged. 8738c2ecf20Sopenharmony_ci # 8748c2ecf20Sopenharmony_ci if ($in_literal) { 8758c2ecf20Sopenharmony_ci if (! ($line =~ /^\s*$/)) { 8768c2ecf20Sopenharmony_ci # 8778c2ecf20Sopenharmony_ci # If this is the first non-blank line in a literal 8788c2ecf20Sopenharmony_ci # block we need to figure out what the proper indent is. 8798c2ecf20Sopenharmony_ci # 8808c2ecf20Sopenharmony_ci if ($litprefix eq "") { 8818c2ecf20Sopenharmony_ci $line =~ /^(\s*)/; 8828c2ecf20Sopenharmony_ci $litprefix = '^' . $1; 8838c2ecf20Sopenharmony_ci $output .= $line . "\n"; 8848c2ecf20Sopenharmony_ci } elsif (! ($line =~ /$litprefix/)) { 8858c2ecf20Sopenharmony_ci $in_literal = 0; 8868c2ecf20Sopenharmony_ci } else { 8878c2ecf20Sopenharmony_ci $output .= $line . "\n"; 8888c2ecf20Sopenharmony_ci } 8898c2ecf20Sopenharmony_ci } else { 8908c2ecf20Sopenharmony_ci $output .= $line . "\n"; 8918c2ecf20Sopenharmony_ci } 8928c2ecf20Sopenharmony_ci } 8938c2ecf20Sopenharmony_ci # 8948c2ecf20Sopenharmony_ci # Not in a literal block (or just dropped out) 8958c2ecf20Sopenharmony_ci # 8968c2ecf20Sopenharmony_ci if (! $in_literal) { 8978c2ecf20Sopenharmony_ci $block .= $line . "\n"; 8988c2ecf20Sopenharmony_ci if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { 8998c2ecf20Sopenharmony_ci $in_literal = 1; 9008c2ecf20Sopenharmony_ci $litprefix = ""; 9018c2ecf20Sopenharmony_ci $output .= highlight_block($block); 9028c2ecf20Sopenharmony_ci $block = "" 9038c2ecf20Sopenharmony_ci } 9048c2ecf20Sopenharmony_ci } 9058c2ecf20Sopenharmony_ci } 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_ci if ($block) { 9088c2ecf20Sopenharmony_ci $output .= highlight_block($block); 9098c2ecf20Sopenharmony_ci } 9108c2ecf20Sopenharmony_ci foreach $line (split "\n", $output) { 9118c2ecf20Sopenharmony_ci print $lineprefix . $line . "\n"; 9128c2ecf20Sopenharmony_ci } 9138c2ecf20Sopenharmony_ci} 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_cisub output_function_rst(%) { 9168c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 9178c2ecf20Sopenharmony_ci my ($parameter, $section); 9188c2ecf20Sopenharmony_ci my $oldprefix = $lineprefix; 9198c2ecf20Sopenharmony_ci my $start = ""; 9208c2ecf20Sopenharmony_ci my $is_macro = 0; 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci if ($sphinx_major < 3) { 9238c2ecf20Sopenharmony_ci if ($args{'typedef'}) { 9248c2ecf20Sopenharmony_ci print ".. c:type:: ". $args{'function'} . "\n\n"; 9258c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 9268c2ecf20Sopenharmony_ci print " **Typedef**: "; 9278c2ecf20Sopenharmony_ci $lineprefix = ""; 9288c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 9298c2ecf20Sopenharmony_ci $start = "\n\n**Syntax**\n\n ``"; 9308c2ecf20Sopenharmony_ci $is_macro = 1; 9318c2ecf20Sopenharmony_ci } else { 9328c2ecf20Sopenharmony_ci print ".. c:function:: "; 9338c2ecf20Sopenharmony_ci } 9348c2ecf20Sopenharmony_ci } else { 9358c2ecf20Sopenharmony_ci if ($args{'typedef'} || $args{'functiontype'} eq "") { 9368c2ecf20Sopenharmony_ci $is_macro = 1; 9378c2ecf20Sopenharmony_ci print ".. c:macro:: ". $args{'function'} . "\n\n"; 9388c2ecf20Sopenharmony_ci } else { 9398c2ecf20Sopenharmony_ci print ".. c:function:: "; 9408c2ecf20Sopenharmony_ci } 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci if ($args{'typedef'}) { 9438c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 9448c2ecf20Sopenharmony_ci print " **Typedef**: "; 9458c2ecf20Sopenharmony_ci $lineprefix = ""; 9468c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 9478c2ecf20Sopenharmony_ci $start = "\n\n**Syntax**\n\n ``"; 9488c2ecf20Sopenharmony_ci } else { 9498c2ecf20Sopenharmony_ci print "``" if ($is_macro); 9508c2ecf20Sopenharmony_ci } 9518c2ecf20Sopenharmony_ci } 9528c2ecf20Sopenharmony_ci if ($args{'functiontype'} ne "") { 9538c2ecf20Sopenharmony_ci $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; 9548c2ecf20Sopenharmony_ci } else { 9558c2ecf20Sopenharmony_ci $start .= $args{'function'} . " ("; 9568c2ecf20Sopenharmony_ci } 9578c2ecf20Sopenharmony_ci print $start; 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci my $count = 0; 9608c2ecf20Sopenharmony_ci foreach my $parameter (@{$args{'parameterlist'}}) { 9618c2ecf20Sopenharmony_ci if ($count ne 0) { 9628c2ecf20Sopenharmony_ci print ", "; 9638c2ecf20Sopenharmony_ci } 9648c2ecf20Sopenharmony_ci $count++; 9658c2ecf20Sopenharmony_ci $type = $args{'parametertypes'}{$parameter}; 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 9688c2ecf20Sopenharmony_ci # pointer-to-function 9698c2ecf20Sopenharmony_ci print $1 . $parameter . ") (" . $2 . ")"; 9708c2ecf20Sopenharmony_ci } else { 9718c2ecf20Sopenharmony_ci print $type; 9728c2ecf20Sopenharmony_ci } 9738c2ecf20Sopenharmony_ci } 9748c2ecf20Sopenharmony_ci if ($is_macro) { 9758c2ecf20Sopenharmony_ci print ")``\n\n"; 9768c2ecf20Sopenharmony_ci } else { 9778c2ecf20Sopenharmony_ci print ")\n\n"; 9788c2ecf20Sopenharmony_ci } 9798c2ecf20Sopenharmony_ci if (!$args{'typedef'}) { 9808c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 9818c2ecf20Sopenharmony_ci $lineprefix = " "; 9828c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 9838c2ecf20Sopenharmony_ci print "\n"; 9848c2ecf20Sopenharmony_ci } 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci print "**Parameters**\n\n"; 9878c2ecf20Sopenharmony_ci $lineprefix = " "; 9888c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 9898c2ecf20Sopenharmony_ci my $parameter_name = $parameter; 9908c2ecf20Sopenharmony_ci $parameter_name =~ s/\[.*//; 9918c2ecf20Sopenharmony_ci $type = $args{'parametertypes'}{$parameter}; 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci if ($type ne "") { 9948c2ecf20Sopenharmony_ci print "``$type``\n"; 9958c2ecf20Sopenharmony_ci } else { 9968c2ecf20Sopenharmony_ci print "``$parameter``\n"; 9978c2ecf20Sopenharmony_ci } 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci print_lineno($parameterdesc_start_lines{$parameter_name}); 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci if (defined($args{'parameterdescs'}{$parameter_name}) && 10028c2ecf20Sopenharmony_ci $args{'parameterdescs'}{$parameter_name} ne $undescribed) { 10038c2ecf20Sopenharmony_ci output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 10048c2ecf20Sopenharmony_ci } else { 10058c2ecf20Sopenharmony_ci print " *undescribed*\n"; 10068c2ecf20Sopenharmony_ci } 10078c2ecf20Sopenharmony_ci print "\n"; 10088c2ecf20Sopenharmony_ci } 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci $lineprefix = $oldprefix; 10118c2ecf20Sopenharmony_ci output_section_rst(@_); 10128c2ecf20Sopenharmony_ci} 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_cisub output_section_rst(%) { 10158c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 10168c2ecf20Sopenharmony_ci my $section; 10178c2ecf20Sopenharmony_ci my $oldprefix = $lineprefix; 10188c2ecf20Sopenharmony_ci $lineprefix = ""; 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci foreach $section (@{$args{'sectionlist'}}) { 10218c2ecf20Sopenharmony_ci print "**$section**\n\n"; 10228c2ecf20Sopenharmony_ci print_lineno($section_start_lines{$section}); 10238c2ecf20Sopenharmony_ci output_highlight_rst($args{'sections'}{$section}); 10248c2ecf20Sopenharmony_ci print "\n"; 10258c2ecf20Sopenharmony_ci } 10268c2ecf20Sopenharmony_ci print "\n"; 10278c2ecf20Sopenharmony_ci $lineprefix = $oldprefix; 10288c2ecf20Sopenharmony_ci} 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_cisub output_enum_rst(%) { 10318c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 10328c2ecf20Sopenharmony_ci my ($parameter); 10338c2ecf20Sopenharmony_ci my $oldprefix = $lineprefix; 10348c2ecf20Sopenharmony_ci my $count; 10358c2ecf20Sopenharmony_ci 10368c2ecf20Sopenharmony_ci if ($sphinx_major < 3) { 10378c2ecf20Sopenharmony_ci my $name = "enum " . $args{'enum'}; 10388c2ecf20Sopenharmony_ci print "\n\n.. c:type:: " . $name . "\n\n"; 10398c2ecf20Sopenharmony_ci } else { 10408c2ecf20Sopenharmony_ci my $name = $args{'enum'}; 10418c2ecf20Sopenharmony_ci print "\n\n.. c:enum:: " . $name . "\n\n"; 10428c2ecf20Sopenharmony_ci } 10438c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 10448c2ecf20Sopenharmony_ci $lineprefix = " "; 10458c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 10468c2ecf20Sopenharmony_ci print "\n"; 10478c2ecf20Sopenharmony_ci 10488c2ecf20Sopenharmony_ci print "**Constants**\n\n"; 10498c2ecf20Sopenharmony_ci $lineprefix = " "; 10508c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 10518c2ecf20Sopenharmony_ci print "``$parameter``\n"; 10528c2ecf20Sopenharmony_ci if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 10538c2ecf20Sopenharmony_ci output_highlight_rst($args{'parameterdescs'}{$parameter}); 10548c2ecf20Sopenharmony_ci } else { 10558c2ecf20Sopenharmony_ci print " *undescribed*\n"; 10568c2ecf20Sopenharmony_ci } 10578c2ecf20Sopenharmony_ci print "\n"; 10588c2ecf20Sopenharmony_ci } 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci $lineprefix = $oldprefix; 10618c2ecf20Sopenharmony_ci output_section_rst(@_); 10628c2ecf20Sopenharmony_ci} 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_cisub output_typedef_rst(%) { 10658c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 10668c2ecf20Sopenharmony_ci my ($parameter); 10678c2ecf20Sopenharmony_ci my $oldprefix = $lineprefix; 10688c2ecf20Sopenharmony_ci my $name; 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_ci if ($sphinx_major < 3) { 10718c2ecf20Sopenharmony_ci $name = "typedef " . $args{'typedef'}; 10728c2ecf20Sopenharmony_ci } else { 10738c2ecf20Sopenharmony_ci $name = $args{'typedef'}; 10748c2ecf20Sopenharmony_ci } 10758c2ecf20Sopenharmony_ci print "\n\n.. c:type:: " . $name . "\n\n"; 10768c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 10778c2ecf20Sopenharmony_ci $lineprefix = " "; 10788c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 10798c2ecf20Sopenharmony_ci print "\n"; 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci $lineprefix = $oldprefix; 10828c2ecf20Sopenharmony_ci output_section_rst(@_); 10838c2ecf20Sopenharmony_ci} 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_cisub output_struct_rst(%) { 10868c2ecf20Sopenharmony_ci my %args = %{$_[0]}; 10878c2ecf20Sopenharmony_ci my ($parameter); 10888c2ecf20Sopenharmony_ci my $oldprefix = $lineprefix; 10898c2ecf20Sopenharmony_ci 10908c2ecf20Sopenharmony_ci if ($sphinx_major < 3) { 10918c2ecf20Sopenharmony_ci my $name = $args{'type'} . " " . $args{'struct'}; 10928c2ecf20Sopenharmony_ci print "\n\n.. c:type:: " . $name . "\n\n"; 10938c2ecf20Sopenharmony_ci } else { 10948c2ecf20Sopenharmony_ci my $name = $args{'struct'}; 10958c2ecf20Sopenharmony_ci if ($args{'type'} eq 'union') { 10968c2ecf20Sopenharmony_ci print "\n\n.. c:union:: " . $name . "\n\n"; 10978c2ecf20Sopenharmony_ci } else { 10988c2ecf20Sopenharmony_ci print "\n\n.. c:struct:: " . $name . "\n\n"; 10998c2ecf20Sopenharmony_ci } 11008c2ecf20Sopenharmony_ci } 11018c2ecf20Sopenharmony_ci print_lineno($declaration_start_line); 11028c2ecf20Sopenharmony_ci $lineprefix = " "; 11038c2ecf20Sopenharmony_ci output_highlight_rst($args{'purpose'}); 11048c2ecf20Sopenharmony_ci print "\n"; 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_ci print "**Definition**\n\n"; 11078c2ecf20Sopenharmony_ci print "::\n\n"; 11088c2ecf20Sopenharmony_ci my $declaration = $args{'definition'}; 11098c2ecf20Sopenharmony_ci $declaration =~ s/\t/ /g; 11108c2ecf20Sopenharmony_ci print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_ci print "**Members**\n\n"; 11138c2ecf20Sopenharmony_ci $lineprefix = " "; 11148c2ecf20Sopenharmony_ci foreach $parameter (@{$args{'parameterlist'}}) { 11158c2ecf20Sopenharmony_ci ($parameter =~ /^#/) && next; 11168c2ecf20Sopenharmony_ci 11178c2ecf20Sopenharmony_ci my $parameter_name = $parameter; 11188c2ecf20Sopenharmony_ci $parameter_name =~ s/\[.*//; 11198c2ecf20Sopenharmony_ci 11208c2ecf20Sopenharmony_ci ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 11218c2ecf20Sopenharmony_ci $type = $args{'parametertypes'}{$parameter}; 11228c2ecf20Sopenharmony_ci print_lineno($parameterdesc_start_lines{$parameter_name}); 11238c2ecf20Sopenharmony_ci print "``" . $parameter . "``\n"; 11248c2ecf20Sopenharmony_ci output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 11258c2ecf20Sopenharmony_ci print "\n"; 11268c2ecf20Sopenharmony_ci } 11278c2ecf20Sopenharmony_ci print "\n"; 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ci $lineprefix = $oldprefix; 11308c2ecf20Sopenharmony_ci output_section_rst(@_); 11318c2ecf20Sopenharmony_ci} 11328c2ecf20Sopenharmony_ci 11338c2ecf20Sopenharmony_ci## none mode output functions 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_cisub output_function_none(%) { 11368c2ecf20Sopenharmony_ci} 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_cisub output_enum_none(%) { 11398c2ecf20Sopenharmony_ci} 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_cisub output_typedef_none(%) { 11428c2ecf20Sopenharmony_ci} 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_cisub output_struct_none(%) { 11458c2ecf20Sopenharmony_ci} 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_cisub output_blockhead_none(%) { 11488c2ecf20Sopenharmony_ci} 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_ci## 11518c2ecf20Sopenharmony_ci# generic output function for all types (function, struct/union, typedef, enum); 11528c2ecf20Sopenharmony_ci# calls the generated, variable output_ function name based on 11538c2ecf20Sopenharmony_ci# functype and output_mode 11548c2ecf20Sopenharmony_cisub output_declaration { 11558c2ecf20Sopenharmony_ci no strict 'refs'; 11568c2ecf20Sopenharmony_ci my $name = shift; 11578c2ecf20Sopenharmony_ci my $functype = shift; 11588c2ecf20Sopenharmony_ci my $func = "output_${functype}_$output_mode"; 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_ci return if (defined($nosymbol_table{$name})); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci if (($output_selection == OUTPUT_ALL) || 11638c2ecf20Sopenharmony_ci (($output_selection == OUTPUT_INCLUDE || 11648c2ecf20Sopenharmony_ci $output_selection == OUTPUT_EXPORTED) && 11658c2ecf20Sopenharmony_ci defined($function_table{$name})) || 11668c2ecf20Sopenharmony_ci ($output_selection == OUTPUT_INTERNAL && 11678c2ecf20Sopenharmony_ci !($functype eq "function" && defined($function_table{$name})))) 11688c2ecf20Sopenharmony_ci { 11698c2ecf20Sopenharmony_ci &$func(@_); 11708c2ecf20Sopenharmony_ci $section_counter++; 11718c2ecf20Sopenharmony_ci } 11728c2ecf20Sopenharmony_ci} 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_ci## 11758c2ecf20Sopenharmony_ci# generic output function - calls the right one based on current output mode. 11768c2ecf20Sopenharmony_cisub output_blockhead { 11778c2ecf20Sopenharmony_ci no strict 'refs'; 11788c2ecf20Sopenharmony_ci my $func = "output_blockhead_" . $output_mode; 11798c2ecf20Sopenharmony_ci &$func(@_); 11808c2ecf20Sopenharmony_ci $section_counter++; 11818c2ecf20Sopenharmony_ci} 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_ci## 11848c2ecf20Sopenharmony_ci# takes a declaration (struct, union, enum, typedef) and 11858c2ecf20Sopenharmony_ci# invokes the right handler. NOT called for functions. 11868c2ecf20Sopenharmony_cisub dump_declaration($$) { 11878c2ecf20Sopenharmony_ci no strict 'refs'; 11888c2ecf20Sopenharmony_ci my ($prototype, $file) = @_; 11898c2ecf20Sopenharmony_ci my $func = "dump_" . $decl_type; 11908c2ecf20Sopenharmony_ci &$func(@_); 11918c2ecf20Sopenharmony_ci} 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_cisub dump_union($$) { 11948c2ecf20Sopenharmony_ci dump_struct(@_); 11958c2ecf20Sopenharmony_ci} 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_cisub dump_struct($$) { 11988c2ecf20Sopenharmony_ci my $x = shift; 11998c2ecf20Sopenharmony_ci my $file = shift; 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) { 12028c2ecf20Sopenharmony_ci my $decl_type = $1; 12038c2ecf20Sopenharmony_ci $declaration_name = $2; 12048c2ecf20Sopenharmony_ci my $members = $3; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci # ignore members marked private: 12078c2ecf20Sopenharmony_ci $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; 12088c2ecf20Sopenharmony_ci $members =~ s/\/\*\s*private:.*//gosi; 12098c2ecf20Sopenharmony_ci # strip comments: 12108c2ecf20Sopenharmony_ci $members =~ s/\/\*.*?\*\///gos; 12118c2ecf20Sopenharmony_ci # strip attributes 12128c2ecf20Sopenharmony_ci $members =~ s/\s*__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)/ /gi; 12138c2ecf20Sopenharmony_ci $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos; 12148c2ecf20Sopenharmony_ci $members =~ s/\s*__packed\s*/ /gos; 12158c2ecf20Sopenharmony_ci $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos; 12168c2ecf20Sopenharmony_ci $members =~ s/\s*____cacheline_aligned_in_smp/ /gos; 12178c2ecf20Sopenharmony_ci $members =~ s/\s*____cacheline_aligned/ /gos; 12188c2ecf20Sopenharmony_ci # unwrap struct_group(): 12198c2ecf20Sopenharmony_ci # - first eat non-declaration parameters and rewrite for final match 12208c2ecf20Sopenharmony_ci # - then remove macro, outer parens, and trailing semicolon 12218c2ecf20Sopenharmony_ci $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos; 12228c2ecf20Sopenharmony_ci $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos; 12238c2ecf20Sopenharmony_ci $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos; 12248c2ecf20Sopenharmony_ci $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci # replace DECLARE_BITMAP 12278c2ecf20Sopenharmony_ci $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos; 12288c2ecf20Sopenharmony_ci $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; 12298c2ecf20Sopenharmony_ci # replace DECLARE_HASHTABLE 12308c2ecf20Sopenharmony_ci $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; 12318c2ecf20Sopenharmony_ci # replace DECLARE_KFIFO 12328c2ecf20Sopenharmony_ci $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; 12338c2ecf20Sopenharmony_ci # replace DECLARE_KFIFO_PTR 12348c2ecf20Sopenharmony_ci $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; 12358c2ecf20Sopenharmony_ci # replace DECLARE_FLEX_ARRAY 12368c2ecf20Sopenharmony_ci $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos; 12378c2ecf20Sopenharmony_ci my $declaration = $members; 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci # Split nested struct/union elements as newer ones 12408c2ecf20Sopenharmony_ci while ($members =~ m/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/) { 12418c2ecf20Sopenharmony_ci my $newmember; 12428c2ecf20Sopenharmony_ci my $maintype = $1; 12438c2ecf20Sopenharmony_ci my $ids = $4; 12448c2ecf20Sopenharmony_ci my $content = $3; 12458c2ecf20Sopenharmony_ci foreach my $id(split /,/, $ids) { 12468c2ecf20Sopenharmony_ci $newmember .= "$maintype $id; "; 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci $id =~ s/[:\[].*//; 12498c2ecf20Sopenharmony_ci $id =~ s/^\s*\**(\S+)\s*/$1/; 12508c2ecf20Sopenharmony_ci foreach my $arg (split /;/, $content) { 12518c2ecf20Sopenharmony_ci next if ($arg =~ m/^\s*$/); 12528c2ecf20Sopenharmony_ci if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { 12538c2ecf20Sopenharmony_ci # pointer-to-function 12548c2ecf20Sopenharmony_ci my $type = $1; 12558c2ecf20Sopenharmony_ci my $name = $2; 12568c2ecf20Sopenharmony_ci my $extra = $3; 12578c2ecf20Sopenharmony_ci next if (!$name); 12588c2ecf20Sopenharmony_ci if ($id =~ m/^\s*$/) { 12598c2ecf20Sopenharmony_ci # anonymous struct/union 12608c2ecf20Sopenharmony_ci $newmember .= "$type$name$extra; "; 12618c2ecf20Sopenharmony_ci } else { 12628c2ecf20Sopenharmony_ci $newmember .= "$type$id.$name$extra; "; 12638c2ecf20Sopenharmony_ci } 12648c2ecf20Sopenharmony_ci } else { 12658c2ecf20Sopenharmony_ci my $type; 12668c2ecf20Sopenharmony_ci my $names; 12678c2ecf20Sopenharmony_ci $arg =~ s/^\s+//; 12688c2ecf20Sopenharmony_ci $arg =~ s/\s+$//; 12698c2ecf20Sopenharmony_ci # Handle bitmaps 12708c2ecf20Sopenharmony_ci $arg =~ s/:\s*\d+\s*//g; 12718c2ecf20Sopenharmony_ci # Handle arrays 12728c2ecf20Sopenharmony_ci $arg =~ s/\[.*\]//g; 12738c2ecf20Sopenharmony_ci # The type may have multiple words, 12748c2ecf20Sopenharmony_ci # and multiple IDs can be defined, like: 12758c2ecf20Sopenharmony_ci # const struct foo, *bar, foobar 12768c2ecf20Sopenharmony_ci # So, we remove spaces when parsing the 12778c2ecf20Sopenharmony_ci # names, in order to match just names 12788c2ecf20Sopenharmony_ci # and commas for the names 12798c2ecf20Sopenharmony_ci $arg =~ s/\s*,\s*/,/g; 12808c2ecf20Sopenharmony_ci if ($arg =~ m/(.*)\s+([\S+,]+)/) { 12818c2ecf20Sopenharmony_ci $type = $1; 12828c2ecf20Sopenharmony_ci $names = $2; 12838c2ecf20Sopenharmony_ci } else { 12848c2ecf20Sopenharmony_ci $newmember .= "$arg; "; 12858c2ecf20Sopenharmony_ci next; 12868c2ecf20Sopenharmony_ci } 12878c2ecf20Sopenharmony_ci foreach my $name (split /,/, $names) { 12888c2ecf20Sopenharmony_ci $name =~ s/^\s*\**(\S+)\s*/$1/; 12898c2ecf20Sopenharmony_ci next if (($name =~ m/^\s*$/)); 12908c2ecf20Sopenharmony_ci if ($id =~ m/^\s*$/) { 12918c2ecf20Sopenharmony_ci # anonymous struct/union 12928c2ecf20Sopenharmony_ci $newmember .= "$type $name; "; 12938c2ecf20Sopenharmony_ci } else { 12948c2ecf20Sopenharmony_ci $newmember .= "$type $id.$name; "; 12958c2ecf20Sopenharmony_ci } 12968c2ecf20Sopenharmony_ci } 12978c2ecf20Sopenharmony_ci } 12988c2ecf20Sopenharmony_ci } 12998c2ecf20Sopenharmony_ci } 13008c2ecf20Sopenharmony_ci $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/$newmember/; 13018c2ecf20Sopenharmony_ci } 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci # Ignore other nested elements, like enums 13048c2ecf20Sopenharmony_ci $members =~ s/(\{[^\{\}]*\})//g; 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_ci create_parameterlist($members, ';', $file, $declaration_name); 13078c2ecf20Sopenharmony_ci check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); 13088c2ecf20Sopenharmony_ci 13098c2ecf20Sopenharmony_ci # Adjust declaration for better display 13108c2ecf20Sopenharmony_ci $declaration =~ s/([\{;])/$1\n/g; 13118c2ecf20Sopenharmony_ci $declaration =~ s/\}\s+;/};/g; 13128c2ecf20Sopenharmony_ci # Better handle inlined enums 13138c2ecf20Sopenharmony_ci do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/); 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci my @def_args = split /\n/, $declaration; 13168c2ecf20Sopenharmony_ci my $level = 1; 13178c2ecf20Sopenharmony_ci $declaration = ""; 13188c2ecf20Sopenharmony_ci foreach my $clause (@def_args) { 13198c2ecf20Sopenharmony_ci $clause =~ s/^\s+//; 13208c2ecf20Sopenharmony_ci $clause =~ s/\s+$//; 13218c2ecf20Sopenharmony_ci $clause =~ s/\s+/ /; 13228c2ecf20Sopenharmony_ci next if (!$clause); 13238c2ecf20Sopenharmony_ci $level-- if ($clause =~ m/(\})/ && $level > 1); 13248c2ecf20Sopenharmony_ci if (!($clause =~ m/^\s*#/)) { 13258c2ecf20Sopenharmony_ci $declaration .= "\t" x $level; 13268c2ecf20Sopenharmony_ci } 13278c2ecf20Sopenharmony_ci $declaration .= "\t" . $clause . "\n"; 13288c2ecf20Sopenharmony_ci $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/)); 13298c2ecf20Sopenharmony_ci } 13308c2ecf20Sopenharmony_ci output_declaration($declaration_name, 13318c2ecf20Sopenharmony_ci 'struct', 13328c2ecf20Sopenharmony_ci {'struct' => $declaration_name, 13338c2ecf20Sopenharmony_ci 'module' => $modulename, 13348c2ecf20Sopenharmony_ci 'definition' => $declaration, 13358c2ecf20Sopenharmony_ci 'parameterlist' => \@parameterlist, 13368c2ecf20Sopenharmony_ci 'parameterdescs' => \%parameterdescs, 13378c2ecf20Sopenharmony_ci 'parametertypes' => \%parametertypes, 13388c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 13398c2ecf20Sopenharmony_ci 'sections' => \%sections, 13408c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose, 13418c2ecf20Sopenharmony_ci 'type' => $decl_type 13428c2ecf20Sopenharmony_ci }); 13438c2ecf20Sopenharmony_ci } 13448c2ecf20Sopenharmony_ci else { 13458c2ecf20Sopenharmony_ci print STDERR "${file}:$.: error: Cannot parse struct or union!\n"; 13468c2ecf20Sopenharmony_ci ++$errors; 13478c2ecf20Sopenharmony_ci } 13488c2ecf20Sopenharmony_ci} 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_cisub show_warnings($$) { 13528c2ecf20Sopenharmony_ci my $functype = shift; 13538c2ecf20Sopenharmony_ci my $name = shift; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci return 0 if (defined($nosymbol_table{$name})); 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_ci return 1 if ($output_selection == OUTPUT_ALL); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci if ($output_selection == OUTPUT_EXPORTED) { 13608c2ecf20Sopenharmony_ci if (defined($function_table{$name})) { 13618c2ecf20Sopenharmony_ci return 1; 13628c2ecf20Sopenharmony_ci } else { 13638c2ecf20Sopenharmony_ci return 0; 13648c2ecf20Sopenharmony_ci } 13658c2ecf20Sopenharmony_ci } 13668c2ecf20Sopenharmony_ci if ($output_selection == OUTPUT_INTERNAL) { 13678c2ecf20Sopenharmony_ci if (!($functype eq "function" && defined($function_table{$name}))) { 13688c2ecf20Sopenharmony_ci return 1; 13698c2ecf20Sopenharmony_ci } else { 13708c2ecf20Sopenharmony_ci return 0; 13718c2ecf20Sopenharmony_ci } 13728c2ecf20Sopenharmony_ci } 13738c2ecf20Sopenharmony_ci if ($output_selection == OUTPUT_INCLUDE) { 13748c2ecf20Sopenharmony_ci if (defined($function_table{$name})) { 13758c2ecf20Sopenharmony_ci return 1; 13768c2ecf20Sopenharmony_ci } else { 13778c2ecf20Sopenharmony_ci return 0; 13788c2ecf20Sopenharmony_ci } 13798c2ecf20Sopenharmony_ci } 13808c2ecf20Sopenharmony_ci die("Please add the new output type at show_warnings()"); 13818c2ecf20Sopenharmony_ci} 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_cisub dump_enum($$) { 13848c2ecf20Sopenharmony_ci my $x = shift; 13858c2ecf20Sopenharmony_ci my $file = shift; 13868c2ecf20Sopenharmony_ci my $members; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci $x =~ s@/\*.*?\*/@@gos; # strip comments. 13908c2ecf20Sopenharmony_ci # strip #define macros inside enums 13918c2ecf20Sopenharmony_ci $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_ci if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) { 13948c2ecf20Sopenharmony_ci $declaration_name = $2; 13958c2ecf20Sopenharmony_ci $members = $1; 13968c2ecf20Sopenharmony_ci } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { 13978c2ecf20Sopenharmony_ci $declaration_name = $1; 13988c2ecf20Sopenharmony_ci $members = $2; 13998c2ecf20Sopenharmony_ci } 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci if ($members) { 14028c2ecf20Sopenharmony_ci my %_members; 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_ci $members =~ s/\s+$//; 14058c2ecf20Sopenharmony_ci 14068c2ecf20Sopenharmony_ci foreach my $arg (split ',', $members) { 14078c2ecf20Sopenharmony_ci $arg =~ s/^\s*(\w+).*/$1/; 14088c2ecf20Sopenharmony_ci push @parameterlist, $arg; 14098c2ecf20Sopenharmony_ci if (!$parameterdescs{$arg}) { 14108c2ecf20Sopenharmony_ci $parameterdescs{$arg} = $undescribed; 14118c2ecf20Sopenharmony_ci if (show_warnings("enum", $declaration_name)) { 14128c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; 14138c2ecf20Sopenharmony_ci } 14148c2ecf20Sopenharmony_ci } 14158c2ecf20Sopenharmony_ci $_members{$arg} = 1; 14168c2ecf20Sopenharmony_ci } 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ci while (my ($k, $v) = each %parameterdescs) { 14198c2ecf20Sopenharmony_ci if (!exists($_members{$k})) { 14208c2ecf20Sopenharmony_ci if (show_warnings("enum", $declaration_name)) { 14218c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; 14228c2ecf20Sopenharmony_ci } 14238c2ecf20Sopenharmony_ci } 14248c2ecf20Sopenharmony_ci } 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_ci output_declaration($declaration_name, 14278c2ecf20Sopenharmony_ci 'enum', 14288c2ecf20Sopenharmony_ci {'enum' => $declaration_name, 14298c2ecf20Sopenharmony_ci 'module' => $modulename, 14308c2ecf20Sopenharmony_ci 'parameterlist' => \@parameterlist, 14318c2ecf20Sopenharmony_ci 'parameterdescs' => \%parameterdescs, 14328c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 14338c2ecf20Sopenharmony_ci 'sections' => \%sections, 14348c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose 14358c2ecf20Sopenharmony_ci }); 14368c2ecf20Sopenharmony_ci } else { 14378c2ecf20Sopenharmony_ci print STDERR "${file}:$.: error: Cannot parse enum!\n"; 14388c2ecf20Sopenharmony_ci ++$errors; 14398c2ecf20Sopenharmony_ci } 14408c2ecf20Sopenharmony_ci} 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_cimy $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x; 14438c2ecf20Sopenharmony_cimy $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; 14448c2ecf20Sopenharmony_cimy $typedef_args = qr { \s*\((.*)\); }x; 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_cimy $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x; 14478c2ecf20Sopenharmony_cimy $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x; 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_cisub dump_typedef($$) { 14508c2ecf20Sopenharmony_ci my $x = shift; 14518c2ecf20Sopenharmony_ci my $file = shift; 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_ci $x =~ s@/\*.*?\*/@@gos; # strip comments. 14548c2ecf20Sopenharmony_ci 14558c2ecf20Sopenharmony_ci # Parse function typedef prototypes 14568c2ecf20Sopenharmony_ci if ($x =~ $typedef1 || $x =~ $typedef2) { 14578c2ecf20Sopenharmony_ci $return_type = $1; 14588c2ecf20Sopenharmony_ci $declaration_name = $2; 14598c2ecf20Sopenharmony_ci my $args = $3; 14608c2ecf20Sopenharmony_ci $return_type =~ s/^\s+//; 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci create_parameterlist($args, ',', $file, $declaration_name); 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_ci output_declaration($declaration_name, 14658c2ecf20Sopenharmony_ci 'function', 14668c2ecf20Sopenharmony_ci {'function' => $declaration_name, 14678c2ecf20Sopenharmony_ci 'typedef' => 1, 14688c2ecf20Sopenharmony_ci 'module' => $modulename, 14698c2ecf20Sopenharmony_ci 'functiontype' => $return_type, 14708c2ecf20Sopenharmony_ci 'parameterlist' => \@parameterlist, 14718c2ecf20Sopenharmony_ci 'parameterdescs' => \%parameterdescs, 14728c2ecf20Sopenharmony_ci 'parametertypes' => \%parametertypes, 14738c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 14748c2ecf20Sopenharmony_ci 'sections' => \%sections, 14758c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose 14768c2ecf20Sopenharmony_ci }); 14778c2ecf20Sopenharmony_ci return; 14788c2ecf20Sopenharmony_ci } 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { 14818c2ecf20Sopenharmony_ci $x =~ s/\(*.\)\s*;$/;/; 14828c2ecf20Sopenharmony_ci $x =~ s/\[*.\]\s*;$/;/; 14838c2ecf20Sopenharmony_ci } 14848c2ecf20Sopenharmony_ci 14858c2ecf20Sopenharmony_ci if ($x =~ /typedef.*\s+(\w+)\s*;/) { 14868c2ecf20Sopenharmony_ci $declaration_name = $1; 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci output_declaration($declaration_name, 14898c2ecf20Sopenharmony_ci 'typedef', 14908c2ecf20Sopenharmony_ci {'typedef' => $declaration_name, 14918c2ecf20Sopenharmony_ci 'module' => $modulename, 14928c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 14938c2ecf20Sopenharmony_ci 'sections' => \%sections, 14948c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose 14958c2ecf20Sopenharmony_ci }); 14968c2ecf20Sopenharmony_ci } 14978c2ecf20Sopenharmony_ci else { 14988c2ecf20Sopenharmony_ci print STDERR "${file}:$.: error: Cannot parse typedef!\n"; 14998c2ecf20Sopenharmony_ci ++$errors; 15008c2ecf20Sopenharmony_ci } 15018c2ecf20Sopenharmony_ci} 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_cisub save_struct_actual($) { 15048c2ecf20Sopenharmony_ci my $actual = shift; 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci # strip all spaces from the actual param so that it looks like one string item 15078c2ecf20Sopenharmony_ci $actual =~ s/\s*//g; 15088c2ecf20Sopenharmony_ci $struct_actual = $struct_actual . $actual . " "; 15098c2ecf20Sopenharmony_ci} 15108c2ecf20Sopenharmony_ci 15118c2ecf20Sopenharmony_cisub create_parameterlist($$$$) { 15128c2ecf20Sopenharmony_ci my $args = shift; 15138c2ecf20Sopenharmony_ci my $splitter = shift; 15148c2ecf20Sopenharmony_ci my $file = shift; 15158c2ecf20Sopenharmony_ci my $declaration_name = shift; 15168c2ecf20Sopenharmony_ci my $type; 15178c2ecf20Sopenharmony_ci my $param; 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci # temporarily replace commas inside function pointer definition 15208c2ecf20Sopenharmony_ci while ($args =~ /(\([^\),]+),/) { 15218c2ecf20Sopenharmony_ci $args =~ s/(\([^\),]+),/$1#/g; 15228c2ecf20Sopenharmony_ci } 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ci foreach my $arg (split($splitter, $args)) { 15258c2ecf20Sopenharmony_ci # strip comments 15268c2ecf20Sopenharmony_ci $arg =~ s/\/\*.*\*\///; 15278c2ecf20Sopenharmony_ci # strip leading/trailing spaces 15288c2ecf20Sopenharmony_ci $arg =~ s/^\s*//; 15298c2ecf20Sopenharmony_ci $arg =~ s/\s*$//; 15308c2ecf20Sopenharmony_ci $arg =~ s/\s+/ /; 15318c2ecf20Sopenharmony_ci 15328c2ecf20Sopenharmony_ci if ($arg =~ /^#/) { 15338c2ecf20Sopenharmony_ci # Treat preprocessor directive as a typeless variable just to fill 15348c2ecf20Sopenharmony_ci # corresponding data structures "correctly". Catch it later in 15358c2ecf20Sopenharmony_ci # output_* subs. 15368c2ecf20Sopenharmony_ci push_parameter($arg, "", "", $file); 15378c2ecf20Sopenharmony_ci } elsif ($arg =~ m/\(.+\)\s*\(/) { 15388c2ecf20Sopenharmony_ci # pointer-to-function 15398c2ecf20Sopenharmony_ci $arg =~ tr/#/,/; 15408c2ecf20Sopenharmony_ci $arg =~ m/[^\(]+\(\*?\s*([\w\.]*)\s*\)/; 15418c2ecf20Sopenharmony_ci $param = $1; 15428c2ecf20Sopenharmony_ci $type = $arg; 15438c2ecf20Sopenharmony_ci $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 15448c2ecf20Sopenharmony_ci save_struct_actual($param); 15458c2ecf20Sopenharmony_ci push_parameter($param, $type, $arg, $file, $declaration_name); 15468c2ecf20Sopenharmony_ci } elsif ($arg) { 15478c2ecf20Sopenharmony_ci $arg =~ s/\s*:\s*/:/g; 15488c2ecf20Sopenharmony_ci $arg =~ s/\s*\[/\[/g; 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_ci my @args = split('\s*,\s*', $arg); 15518c2ecf20Sopenharmony_ci if ($args[0] =~ m/\*/) { 15528c2ecf20Sopenharmony_ci $args[0] =~ s/(\*+)\s*/ $1/; 15538c2ecf20Sopenharmony_ci } 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci my @first_arg; 15568c2ecf20Sopenharmony_ci if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { 15578c2ecf20Sopenharmony_ci shift @args; 15588c2ecf20Sopenharmony_ci push(@first_arg, split('\s+', $1)); 15598c2ecf20Sopenharmony_ci push(@first_arg, $2); 15608c2ecf20Sopenharmony_ci } else { 15618c2ecf20Sopenharmony_ci @first_arg = split('\s+', shift @args); 15628c2ecf20Sopenharmony_ci } 15638c2ecf20Sopenharmony_ci 15648c2ecf20Sopenharmony_ci unshift(@args, pop @first_arg); 15658c2ecf20Sopenharmony_ci $type = join " ", @first_arg; 15668c2ecf20Sopenharmony_ci 15678c2ecf20Sopenharmony_ci foreach $param (@args) { 15688c2ecf20Sopenharmony_ci if ($param =~ m/^(\*+)\s*(.*)/) { 15698c2ecf20Sopenharmony_ci save_struct_actual($2); 15708c2ecf20Sopenharmony_ci 15718c2ecf20Sopenharmony_ci push_parameter($2, "$type $1", $arg, $file, $declaration_name); 15728c2ecf20Sopenharmony_ci } 15738c2ecf20Sopenharmony_ci elsif ($param =~ m/(.*?):(\d+)/) { 15748c2ecf20Sopenharmony_ci if ($type ne "") { # skip unnamed bit-fields 15758c2ecf20Sopenharmony_ci save_struct_actual($1); 15768c2ecf20Sopenharmony_ci push_parameter($1, "$type:$2", $arg, $file, $declaration_name) 15778c2ecf20Sopenharmony_ci } 15788c2ecf20Sopenharmony_ci } 15798c2ecf20Sopenharmony_ci else { 15808c2ecf20Sopenharmony_ci save_struct_actual($param); 15818c2ecf20Sopenharmony_ci push_parameter($param, $type, $arg, $file, $declaration_name); 15828c2ecf20Sopenharmony_ci } 15838c2ecf20Sopenharmony_ci } 15848c2ecf20Sopenharmony_ci } 15858c2ecf20Sopenharmony_ci } 15868c2ecf20Sopenharmony_ci} 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_cisub push_parameter($$$$$) { 15898c2ecf20Sopenharmony_ci my $param = shift; 15908c2ecf20Sopenharmony_ci my $type = shift; 15918c2ecf20Sopenharmony_ci my $org_arg = shift; 15928c2ecf20Sopenharmony_ci my $file = shift; 15938c2ecf20Sopenharmony_ci my $declaration_name = shift; 15948c2ecf20Sopenharmony_ci 15958c2ecf20Sopenharmony_ci if (($anon_struct_union == 1) && ($type eq "") && 15968c2ecf20Sopenharmony_ci ($param eq "}")) { 15978c2ecf20Sopenharmony_ci return; # ignore the ending }; from anon. struct/union 15988c2ecf20Sopenharmony_ci } 15998c2ecf20Sopenharmony_ci 16008c2ecf20Sopenharmony_ci $anon_struct_union = 0; 16018c2ecf20Sopenharmony_ci $param =~ s/[\[\)].*//; 16028c2ecf20Sopenharmony_ci 16038c2ecf20Sopenharmony_ci if ($type eq "" && $param =~ /\.\.\.$/) 16048c2ecf20Sopenharmony_ci { 16058c2ecf20Sopenharmony_ci if (!$param =~ /\w\.\.\.$/) { 16068c2ecf20Sopenharmony_ci # handles unnamed variable parameters 16078c2ecf20Sopenharmony_ci $param = "..."; 16088c2ecf20Sopenharmony_ci } 16098c2ecf20Sopenharmony_ci elsif ($param =~ /\w\.\.\.$/) { 16108c2ecf20Sopenharmony_ci # for named variable parameters of the form `x...`, remove the dots 16118c2ecf20Sopenharmony_ci $param =~ s/\.\.\.$//; 16128c2ecf20Sopenharmony_ci } 16138c2ecf20Sopenharmony_ci if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") { 16148c2ecf20Sopenharmony_ci $parameterdescs{$param} = "variable arguments"; 16158c2ecf20Sopenharmony_ci } 16168c2ecf20Sopenharmony_ci } 16178c2ecf20Sopenharmony_ci elsif ($type eq "" && ($param eq "" or $param eq "void")) 16188c2ecf20Sopenharmony_ci { 16198c2ecf20Sopenharmony_ci $param="void"; 16208c2ecf20Sopenharmony_ci $parameterdescs{void} = "no arguments"; 16218c2ecf20Sopenharmony_ci } 16228c2ecf20Sopenharmony_ci elsif ($type eq "" && ($param eq "struct" or $param eq "union")) 16238c2ecf20Sopenharmony_ci # handle unnamed (anonymous) union or struct: 16248c2ecf20Sopenharmony_ci { 16258c2ecf20Sopenharmony_ci $type = $param; 16268c2ecf20Sopenharmony_ci $param = "{unnamed_" . $param . "}"; 16278c2ecf20Sopenharmony_ci $parameterdescs{$param} = "anonymous\n"; 16288c2ecf20Sopenharmony_ci $anon_struct_union = 1; 16298c2ecf20Sopenharmony_ci } 16308c2ecf20Sopenharmony_ci 16318c2ecf20Sopenharmony_ci # warn if parameter has no description 16328c2ecf20Sopenharmony_ci # (but ignore ones starting with # as these are not parameters 16338c2ecf20Sopenharmony_ci # but inline preprocessor statements); 16348c2ecf20Sopenharmony_ci # Note: It will also ignore void params and unnamed structs/unions 16358c2ecf20Sopenharmony_ci if (!defined $parameterdescs{$param} && $param !~ /^#/) { 16368c2ecf20Sopenharmony_ci $parameterdescs{$param} = $undescribed; 16378c2ecf20Sopenharmony_ci 16388c2ecf20Sopenharmony_ci if (show_warnings($type, $declaration_name) && $param !~ /\./) { 16398c2ecf20Sopenharmony_ci print STDERR 16408c2ecf20Sopenharmony_ci "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; 16418c2ecf20Sopenharmony_ci ++$warnings; 16428c2ecf20Sopenharmony_ci } 16438c2ecf20Sopenharmony_ci } 16448c2ecf20Sopenharmony_ci 16458c2ecf20Sopenharmony_ci # strip spaces from $param so that it is one continuous string 16468c2ecf20Sopenharmony_ci # on @parameterlist; 16478c2ecf20Sopenharmony_ci # this fixes a problem where check_sections() cannot find 16488c2ecf20Sopenharmony_ci # a parameter like "addr[6 + 2]" because it actually appears 16498c2ecf20Sopenharmony_ci # as "addr[6", "+", "2]" on the parameter list; 16508c2ecf20Sopenharmony_ci # but it's better to maintain the param string unchanged for output, 16518c2ecf20Sopenharmony_ci # so just weaken the string compare in check_sections() to ignore 16528c2ecf20Sopenharmony_ci # "[blah" in a parameter string; 16538c2ecf20Sopenharmony_ci ###$param =~ s/\s*//g; 16548c2ecf20Sopenharmony_ci push @parameterlist, $param; 16558c2ecf20Sopenharmony_ci $org_arg =~ s/\s\s+/ /g; 16568c2ecf20Sopenharmony_ci $parametertypes{$param} = $org_arg; 16578c2ecf20Sopenharmony_ci} 16588c2ecf20Sopenharmony_ci 16598c2ecf20Sopenharmony_cisub check_sections($$$$$) { 16608c2ecf20Sopenharmony_ci my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; 16618c2ecf20Sopenharmony_ci my @sects = split ' ', $sectcheck; 16628c2ecf20Sopenharmony_ci my @prms = split ' ', $prmscheck; 16638c2ecf20Sopenharmony_ci my $err; 16648c2ecf20Sopenharmony_ci my ($px, $sx); 16658c2ecf20Sopenharmony_ci my $prm_clean; # strip trailing "[array size]" and/or beginning "*" 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci foreach $sx (0 .. $#sects) { 16688c2ecf20Sopenharmony_ci $err = 1; 16698c2ecf20Sopenharmony_ci foreach $px (0 .. $#prms) { 16708c2ecf20Sopenharmony_ci $prm_clean = $prms[$px]; 16718c2ecf20Sopenharmony_ci $prm_clean =~ s/\[.*\]//; 16728c2ecf20Sopenharmony_ci $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; 16738c2ecf20Sopenharmony_ci # ignore array size in a parameter string; 16748c2ecf20Sopenharmony_ci # however, the original param string may contain 16758c2ecf20Sopenharmony_ci # spaces, e.g.: addr[6 + 2] 16768c2ecf20Sopenharmony_ci # and this appears in @prms as "addr[6" since the 16778c2ecf20Sopenharmony_ci # parameter list is split at spaces; 16788c2ecf20Sopenharmony_ci # hence just ignore "[..." for the sections check; 16798c2ecf20Sopenharmony_ci $prm_clean =~ s/\[.*//; 16808c2ecf20Sopenharmony_ci 16818c2ecf20Sopenharmony_ci ##$prm_clean =~ s/^\**//; 16828c2ecf20Sopenharmony_ci if ($prm_clean eq $sects[$sx]) { 16838c2ecf20Sopenharmony_ci $err = 0; 16848c2ecf20Sopenharmony_ci last; 16858c2ecf20Sopenharmony_ci } 16868c2ecf20Sopenharmony_ci } 16878c2ecf20Sopenharmony_ci if ($err) { 16888c2ecf20Sopenharmony_ci if ($decl_type eq "function") { 16898c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: " . 16908c2ecf20Sopenharmony_ci "Excess function parameter " . 16918c2ecf20Sopenharmony_ci "'$sects[$sx]' " . 16928c2ecf20Sopenharmony_ci "description in '$decl_name'\n"; 16938c2ecf20Sopenharmony_ci ++$warnings; 16948c2ecf20Sopenharmony_ci } 16958c2ecf20Sopenharmony_ci } 16968c2ecf20Sopenharmony_ci } 16978c2ecf20Sopenharmony_ci} 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_ci## 17008c2ecf20Sopenharmony_ci# Checks the section describing the return value of a function. 17018c2ecf20Sopenharmony_cisub check_return_section { 17028c2ecf20Sopenharmony_ci my $file = shift; 17038c2ecf20Sopenharmony_ci my $declaration_name = shift; 17048c2ecf20Sopenharmony_ci my $return_type = shift; 17058c2ecf20Sopenharmony_ci 17068c2ecf20Sopenharmony_ci # Ignore an empty return type (It's a macro) 17078c2ecf20Sopenharmony_ci # Ignore functions with a "void" return type. (But don't ignore "void *") 17088c2ecf20Sopenharmony_ci if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) { 17098c2ecf20Sopenharmony_ci return; 17108c2ecf20Sopenharmony_ci } 17118c2ecf20Sopenharmony_ci 17128c2ecf20Sopenharmony_ci if (!defined($sections{$section_return}) || 17138c2ecf20Sopenharmony_ci $sections{$section_return} eq "") { 17148c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: " . 17158c2ecf20Sopenharmony_ci "No description found for return value of " . 17168c2ecf20Sopenharmony_ci "'$declaration_name'\n"; 17178c2ecf20Sopenharmony_ci ++$warnings; 17188c2ecf20Sopenharmony_ci } 17198c2ecf20Sopenharmony_ci} 17208c2ecf20Sopenharmony_ci 17218c2ecf20Sopenharmony_ci## 17228c2ecf20Sopenharmony_ci# takes a function prototype and the name of the current file being 17238c2ecf20Sopenharmony_ci# processed and spits out all the details stored in the global 17248c2ecf20Sopenharmony_ci# arrays/hashes. 17258c2ecf20Sopenharmony_cisub dump_function($$) { 17268c2ecf20Sopenharmony_ci my $prototype = shift; 17278c2ecf20Sopenharmony_ci my $file = shift; 17288c2ecf20Sopenharmony_ci my $noret = 0; 17298c2ecf20Sopenharmony_ci 17308c2ecf20Sopenharmony_ci print_lineno($new_start_line); 17318c2ecf20Sopenharmony_ci 17328c2ecf20Sopenharmony_ci $prototype =~ s/^static +//; 17338c2ecf20Sopenharmony_ci $prototype =~ s/^extern +//; 17348c2ecf20Sopenharmony_ci $prototype =~ s/^asmlinkage +//; 17358c2ecf20Sopenharmony_ci $prototype =~ s/^inline +//; 17368c2ecf20Sopenharmony_ci $prototype =~ s/^__inline__ +//; 17378c2ecf20Sopenharmony_ci $prototype =~ s/^__inline +//; 17388c2ecf20Sopenharmony_ci $prototype =~ s/^__always_inline +//; 17398c2ecf20Sopenharmony_ci $prototype =~ s/^noinline +//; 17408c2ecf20Sopenharmony_ci $prototype =~ s/__init +//; 17418c2ecf20Sopenharmony_ci $prototype =~ s/__init_or_module +//; 17428c2ecf20Sopenharmony_ci $prototype =~ s/__meminit +//; 17438c2ecf20Sopenharmony_ci $prototype =~ s/__must_check +//; 17448c2ecf20Sopenharmony_ci $prototype =~ s/__weak +//; 17458c2ecf20Sopenharmony_ci $prototype =~ s/__sched +//; 17468c2ecf20Sopenharmony_ci $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; 17478c2ecf20Sopenharmony_ci my $define = $prototype =~ s/^#\s*define\s+//; #ak added 17488c2ecf20Sopenharmony_ci $prototype =~ s/__attribute__\s*\(\( 17498c2ecf20Sopenharmony_ci (?: 17508c2ecf20Sopenharmony_ci [\w\s]++ # attribute name 17518c2ecf20Sopenharmony_ci (?:\([^)]*+\))? # attribute arguments 17528c2ecf20Sopenharmony_ci \s*+,? # optional comma at the end 17538c2ecf20Sopenharmony_ci )+ 17548c2ecf20Sopenharmony_ci \)\)\s+//x; 17558c2ecf20Sopenharmony_ci 17568c2ecf20Sopenharmony_ci # Yes, this truly is vile. We are looking for: 17578c2ecf20Sopenharmony_ci # 1. Return type (may be nothing if we're looking at a macro) 17588c2ecf20Sopenharmony_ci # 2. Function name 17598c2ecf20Sopenharmony_ci # 3. Function parameters. 17608c2ecf20Sopenharmony_ci # 17618c2ecf20Sopenharmony_ci # All the while we have to watch out for function pointer parameters 17628c2ecf20Sopenharmony_ci # (which IIRC is what the two sections are for), C types (these 17638c2ecf20Sopenharmony_ci # regexps don't even start to express all the possibilities), and 17648c2ecf20Sopenharmony_ci # so on. 17658c2ecf20Sopenharmony_ci # 17668c2ecf20Sopenharmony_ci # If you mess with these regexps, it's a good idea to check that 17678c2ecf20Sopenharmony_ci # the following functions' documentation still comes out right: 17688c2ecf20Sopenharmony_ci # - parport_register_device (function pointer parameters) 17698c2ecf20Sopenharmony_ci # - atomic_set (macro) 17708c2ecf20Sopenharmony_ci # - pci_match_device, __copy_to_user (long return type) 17718c2ecf20Sopenharmony_ci 17728c2ecf20Sopenharmony_ci if ($define && $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s+/) { 17738c2ecf20Sopenharmony_ci # This is an object-like macro, it has no return type and no parameter 17748c2ecf20Sopenharmony_ci # list. 17758c2ecf20Sopenharmony_ci # Function-like macros are not allowed to have spaces between 17768c2ecf20Sopenharmony_ci # declaration_name and opening parenthesis (notice the \s+). 17778c2ecf20Sopenharmony_ci $return_type = $1; 17788c2ecf20Sopenharmony_ci $declaration_name = $2; 17798c2ecf20Sopenharmony_ci $noret = 1; 17808c2ecf20Sopenharmony_ci } elsif ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17818c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17828c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17838c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17848c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17858c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17868c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 17878c2ecf20Sopenharmony_ci $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17888c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17898c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17908c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17918c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17928c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17938c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17948c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17958c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 17968c2ecf20Sopenharmony_ci $prototype =~ m/^(\w+\s+\w+\s*\*+\s*\w+\s*\*+\s*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { 17978c2ecf20Sopenharmony_ci $return_type = $1; 17988c2ecf20Sopenharmony_ci $declaration_name = $2; 17998c2ecf20Sopenharmony_ci my $args = $3; 18008c2ecf20Sopenharmony_ci 18018c2ecf20Sopenharmony_ci create_parameterlist($args, ',', $file, $declaration_name); 18028c2ecf20Sopenharmony_ci } else { 18038c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; 18048c2ecf20Sopenharmony_ci return; 18058c2ecf20Sopenharmony_ci } 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_ci my $prms = join " ", @parameterlist; 18088c2ecf20Sopenharmony_ci check_sections($file, $declaration_name, "function", $sectcheck, $prms); 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_ci # This check emits a lot of warnings at the moment, because many 18118c2ecf20Sopenharmony_ci # functions don't have a 'Return' doc section. So until the number 18128c2ecf20Sopenharmony_ci # of warnings goes sufficiently down, the check is only performed in 18138c2ecf20Sopenharmony_ci # verbose mode. 18148c2ecf20Sopenharmony_ci # TODO: always perform the check. 18158c2ecf20Sopenharmony_ci if ($verbose && !$noret) { 18168c2ecf20Sopenharmony_ci check_return_section($file, $declaration_name, $return_type); 18178c2ecf20Sopenharmony_ci } 18188c2ecf20Sopenharmony_ci 18198c2ecf20Sopenharmony_ci # The function parser can be called with a typedef parameter. 18208c2ecf20Sopenharmony_ci # Handle it. 18218c2ecf20Sopenharmony_ci if ($return_type =~ /typedef/) { 18228c2ecf20Sopenharmony_ci output_declaration($declaration_name, 18238c2ecf20Sopenharmony_ci 'function', 18248c2ecf20Sopenharmony_ci {'function' => $declaration_name, 18258c2ecf20Sopenharmony_ci 'typedef' => 1, 18268c2ecf20Sopenharmony_ci 'module' => $modulename, 18278c2ecf20Sopenharmony_ci 'functiontype' => $return_type, 18288c2ecf20Sopenharmony_ci 'parameterlist' => \@parameterlist, 18298c2ecf20Sopenharmony_ci 'parameterdescs' => \%parameterdescs, 18308c2ecf20Sopenharmony_ci 'parametertypes' => \%parametertypes, 18318c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 18328c2ecf20Sopenharmony_ci 'sections' => \%sections, 18338c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose 18348c2ecf20Sopenharmony_ci }); 18358c2ecf20Sopenharmony_ci } else { 18368c2ecf20Sopenharmony_ci output_declaration($declaration_name, 18378c2ecf20Sopenharmony_ci 'function', 18388c2ecf20Sopenharmony_ci {'function' => $declaration_name, 18398c2ecf20Sopenharmony_ci 'module' => $modulename, 18408c2ecf20Sopenharmony_ci 'functiontype' => $return_type, 18418c2ecf20Sopenharmony_ci 'parameterlist' => \@parameterlist, 18428c2ecf20Sopenharmony_ci 'parameterdescs' => \%parameterdescs, 18438c2ecf20Sopenharmony_ci 'parametertypes' => \%parametertypes, 18448c2ecf20Sopenharmony_ci 'sectionlist' => \@sectionlist, 18458c2ecf20Sopenharmony_ci 'sections' => \%sections, 18468c2ecf20Sopenharmony_ci 'purpose' => $declaration_purpose 18478c2ecf20Sopenharmony_ci }); 18488c2ecf20Sopenharmony_ci } 18498c2ecf20Sopenharmony_ci} 18508c2ecf20Sopenharmony_ci 18518c2ecf20Sopenharmony_cisub reset_state { 18528c2ecf20Sopenharmony_ci $function = ""; 18538c2ecf20Sopenharmony_ci %parameterdescs = (); 18548c2ecf20Sopenharmony_ci %parametertypes = (); 18558c2ecf20Sopenharmony_ci @parameterlist = (); 18568c2ecf20Sopenharmony_ci %sections = (); 18578c2ecf20Sopenharmony_ci @sectionlist = (); 18588c2ecf20Sopenharmony_ci $sectcheck = ""; 18598c2ecf20Sopenharmony_ci $struct_actual = ""; 18608c2ecf20Sopenharmony_ci $prototype = ""; 18618c2ecf20Sopenharmony_ci 18628c2ecf20Sopenharmony_ci $state = STATE_NORMAL; 18638c2ecf20Sopenharmony_ci $inline_doc_state = STATE_INLINE_NA; 18648c2ecf20Sopenharmony_ci} 18658c2ecf20Sopenharmony_ci 18668c2ecf20Sopenharmony_cisub tracepoint_munge($) { 18678c2ecf20Sopenharmony_ci my $file = shift; 18688c2ecf20Sopenharmony_ci my $tracepointname = 0; 18698c2ecf20Sopenharmony_ci my $tracepointargs = 0; 18708c2ecf20Sopenharmony_ci 18718c2ecf20Sopenharmony_ci if ($prototype =~ m/TRACE_EVENT\((.*?),/) { 18728c2ecf20Sopenharmony_ci $tracepointname = $1; 18738c2ecf20Sopenharmony_ci } 18748c2ecf20Sopenharmony_ci if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) { 18758c2ecf20Sopenharmony_ci $tracepointname = $1; 18768c2ecf20Sopenharmony_ci } 18778c2ecf20Sopenharmony_ci if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) { 18788c2ecf20Sopenharmony_ci $tracepointname = $2; 18798c2ecf20Sopenharmony_ci } 18808c2ecf20Sopenharmony_ci $tracepointname =~ s/^\s+//; #strip leading whitespace 18818c2ecf20Sopenharmony_ci if ($prototype =~ m/TP_PROTO\((.*?)\)/) { 18828c2ecf20Sopenharmony_ci $tracepointargs = $1; 18838c2ecf20Sopenharmony_ci } 18848c2ecf20Sopenharmony_ci if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 18858c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". 18868c2ecf20Sopenharmony_ci "$prototype\n"; 18878c2ecf20Sopenharmony_ci } else { 18888c2ecf20Sopenharmony_ci $prototype = "static inline void trace_$tracepointname($tracepointargs)"; 18898c2ecf20Sopenharmony_ci } 18908c2ecf20Sopenharmony_ci} 18918c2ecf20Sopenharmony_ci 18928c2ecf20Sopenharmony_cisub syscall_munge() { 18938c2ecf20Sopenharmony_ci my $void = 0; 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_ci $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's 18968c2ecf20Sopenharmony_ci## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { 18978c2ecf20Sopenharmony_ci if ($prototype =~ m/SYSCALL_DEFINE0/) { 18988c2ecf20Sopenharmony_ci $void = 1; 18998c2ecf20Sopenharmony_ci## $prototype = "long sys_$1(void)"; 19008c2ecf20Sopenharmony_ci } 19018c2ecf20Sopenharmony_ci 19028c2ecf20Sopenharmony_ci $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name 19038c2ecf20Sopenharmony_ci if ($prototype =~ m/long (sys_.*?),/) { 19048c2ecf20Sopenharmony_ci $prototype =~ s/,/\(/; 19058c2ecf20Sopenharmony_ci } elsif ($void) { 19068c2ecf20Sopenharmony_ci $prototype =~ s/\)/\(void\)/; 19078c2ecf20Sopenharmony_ci } 19088c2ecf20Sopenharmony_ci 19098c2ecf20Sopenharmony_ci # now delete all of the odd-number commas in $prototype 19108c2ecf20Sopenharmony_ci # so that arg types & arg names don't have a comma between them 19118c2ecf20Sopenharmony_ci my $count = 0; 19128c2ecf20Sopenharmony_ci my $len = length($prototype); 19138c2ecf20Sopenharmony_ci if ($void) { 19148c2ecf20Sopenharmony_ci $len = 0; # skip the for-loop 19158c2ecf20Sopenharmony_ci } 19168c2ecf20Sopenharmony_ci for (my $ix = 0; $ix < $len; $ix++) { 19178c2ecf20Sopenharmony_ci if (substr($prototype, $ix, 1) eq ',') { 19188c2ecf20Sopenharmony_ci $count++; 19198c2ecf20Sopenharmony_ci if ($count % 2 == 1) { 19208c2ecf20Sopenharmony_ci substr($prototype, $ix, 1) = ' '; 19218c2ecf20Sopenharmony_ci } 19228c2ecf20Sopenharmony_ci } 19238c2ecf20Sopenharmony_ci } 19248c2ecf20Sopenharmony_ci} 19258c2ecf20Sopenharmony_ci 19268c2ecf20Sopenharmony_cisub process_proto_function($$) { 19278c2ecf20Sopenharmony_ci my $x = shift; 19288c2ecf20Sopenharmony_ci my $file = shift; 19298c2ecf20Sopenharmony_ci 19308c2ecf20Sopenharmony_ci $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 19318c2ecf20Sopenharmony_ci 19328c2ecf20Sopenharmony_ci if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { 19338c2ecf20Sopenharmony_ci # do nothing 19348c2ecf20Sopenharmony_ci } 19358c2ecf20Sopenharmony_ci elsif ($x =~ /([^\{]*)/) { 19368c2ecf20Sopenharmony_ci $prototype .= $1; 19378c2ecf20Sopenharmony_ci } 19388c2ecf20Sopenharmony_ci 19398c2ecf20Sopenharmony_ci if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { 19408c2ecf20Sopenharmony_ci $prototype =~ s@/\*.*?\*/@@gos; # strip comments. 19418c2ecf20Sopenharmony_ci $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 19428c2ecf20Sopenharmony_ci $prototype =~ s@^\s+@@gos; # strip leading spaces 19438c2ecf20Sopenharmony_ci 19448c2ecf20Sopenharmony_ci # Handle prototypes for function pointers like: 19458c2ecf20Sopenharmony_ci # int (*pcs_config)(struct foo) 19468c2ecf20Sopenharmony_ci $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos; 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci if ($prototype =~ /SYSCALL_DEFINE/) { 19498c2ecf20Sopenharmony_ci syscall_munge(); 19508c2ecf20Sopenharmony_ci } 19518c2ecf20Sopenharmony_ci if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ || 19528c2ecf20Sopenharmony_ci $prototype =~ /DEFINE_SINGLE_EVENT/) 19538c2ecf20Sopenharmony_ci { 19548c2ecf20Sopenharmony_ci tracepoint_munge($file); 19558c2ecf20Sopenharmony_ci } 19568c2ecf20Sopenharmony_ci dump_function($prototype, $file); 19578c2ecf20Sopenharmony_ci reset_state(); 19588c2ecf20Sopenharmony_ci } 19598c2ecf20Sopenharmony_ci} 19608c2ecf20Sopenharmony_ci 19618c2ecf20Sopenharmony_cisub process_proto_type($$) { 19628c2ecf20Sopenharmony_ci my $x = shift; 19638c2ecf20Sopenharmony_ci my $file = shift; 19648c2ecf20Sopenharmony_ci 19658c2ecf20Sopenharmony_ci $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 19668c2ecf20Sopenharmony_ci $x =~ s@^\s+@@gos; # strip leading spaces 19678c2ecf20Sopenharmony_ci $x =~ s@\s+$@@gos; # strip trailing spaces 19688c2ecf20Sopenharmony_ci $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 19698c2ecf20Sopenharmony_ci 19708c2ecf20Sopenharmony_ci if ($x =~ /^#/) { 19718c2ecf20Sopenharmony_ci # To distinguish preprocessor directive from regular declaration later. 19728c2ecf20Sopenharmony_ci $x .= ";"; 19738c2ecf20Sopenharmony_ci } 19748c2ecf20Sopenharmony_ci 19758c2ecf20Sopenharmony_ci while (1) { 19768c2ecf20Sopenharmony_ci if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) { 19778c2ecf20Sopenharmony_ci if( length $prototype ) { 19788c2ecf20Sopenharmony_ci $prototype .= " " 19798c2ecf20Sopenharmony_ci } 19808c2ecf20Sopenharmony_ci $prototype .= $1 . $2; 19818c2ecf20Sopenharmony_ci ($2 eq '{') && $brcount++; 19828c2ecf20Sopenharmony_ci ($2 eq '}') && $brcount--; 19838c2ecf20Sopenharmony_ci if (($2 eq ';') && ($brcount == 0)) { 19848c2ecf20Sopenharmony_ci dump_declaration($prototype, $file); 19858c2ecf20Sopenharmony_ci reset_state(); 19868c2ecf20Sopenharmony_ci last; 19878c2ecf20Sopenharmony_ci } 19888c2ecf20Sopenharmony_ci $x = $3; 19898c2ecf20Sopenharmony_ci } else { 19908c2ecf20Sopenharmony_ci $prototype .= $x; 19918c2ecf20Sopenharmony_ci last; 19928c2ecf20Sopenharmony_ci } 19938c2ecf20Sopenharmony_ci } 19948c2ecf20Sopenharmony_ci} 19958c2ecf20Sopenharmony_ci 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_cisub map_filename($) { 19988c2ecf20Sopenharmony_ci my $file; 19998c2ecf20Sopenharmony_ci my ($orig_file) = @_; 20008c2ecf20Sopenharmony_ci 20018c2ecf20Sopenharmony_ci if (defined($ENV{'SRCTREE'})) { 20028c2ecf20Sopenharmony_ci $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; 20038c2ecf20Sopenharmony_ci } else { 20048c2ecf20Sopenharmony_ci $file = $orig_file; 20058c2ecf20Sopenharmony_ci } 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci if (defined($source_map{$file})) { 20088c2ecf20Sopenharmony_ci $file = $source_map{$file}; 20098c2ecf20Sopenharmony_ci } 20108c2ecf20Sopenharmony_ci 20118c2ecf20Sopenharmony_ci return $file; 20128c2ecf20Sopenharmony_ci} 20138c2ecf20Sopenharmony_ci 20148c2ecf20Sopenharmony_cisub process_export_file($) { 20158c2ecf20Sopenharmony_ci my ($orig_file) = @_; 20168c2ecf20Sopenharmony_ci my $file = map_filename($orig_file); 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci if (!open(IN,"<$file")) { 20198c2ecf20Sopenharmony_ci print STDERR "Error: Cannot open file $file\n"; 20208c2ecf20Sopenharmony_ci ++$errors; 20218c2ecf20Sopenharmony_ci return; 20228c2ecf20Sopenharmony_ci } 20238c2ecf20Sopenharmony_ci 20248c2ecf20Sopenharmony_ci while (<IN>) { 20258c2ecf20Sopenharmony_ci if (/$export_symbol/) { 20268c2ecf20Sopenharmony_ci next if (defined($nosymbol_table{$2})); 20278c2ecf20Sopenharmony_ci $function_table{$2} = 1; 20288c2ecf20Sopenharmony_ci } 20298c2ecf20Sopenharmony_ci } 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_ci close(IN); 20328c2ecf20Sopenharmony_ci} 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci# 20358c2ecf20Sopenharmony_ci# Parsers for the various processing states. 20368c2ecf20Sopenharmony_ci# 20378c2ecf20Sopenharmony_ci# STATE_NORMAL: looking for the /** to begin everything. 20388c2ecf20Sopenharmony_ci# 20398c2ecf20Sopenharmony_cisub process_normal() { 20408c2ecf20Sopenharmony_ci if (/$doc_start/o) { 20418c2ecf20Sopenharmony_ci $state = STATE_NAME; # next line is always the function name 20428c2ecf20Sopenharmony_ci $in_doc_sect = 0; 20438c2ecf20Sopenharmony_ci $declaration_start_line = $. + 1; 20448c2ecf20Sopenharmony_ci } 20458c2ecf20Sopenharmony_ci} 20468c2ecf20Sopenharmony_ci 20478c2ecf20Sopenharmony_ci# 20488c2ecf20Sopenharmony_ci# STATE_NAME: Looking for the "name - description" line 20498c2ecf20Sopenharmony_ci# 20508c2ecf20Sopenharmony_cisub process_name($$) { 20518c2ecf20Sopenharmony_ci my $file = shift; 20528c2ecf20Sopenharmony_ci my $identifier; 20538c2ecf20Sopenharmony_ci my $descr; 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_ci if (/$doc_block/o) { 20568c2ecf20Sopenharmony_ci $state = STATE_DOCBLOCK; 20578c2ecf20Sopenharmony_ci $contents = ""; 20588c2ecf20Sopenharmony_ci $new_start_line = $.; 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_ci if ( $1 eq "" ) { 20618c2ecf20Sopenharmony_ci $section = $section_intro; 20628c2ecf20Sopenharmony_ci } else { 20638c2ecf20Sopenharmony_ci $section = $1; 20648c2ecf20Sopenharmony_ci } 20658c2ecf20Sopenharmony_ci } 20668c2ecf20Sopenharmony_ci elsif (/$doc_decl/o) { 20678c2ecf20Sopenharmony_ci $identifier = $1; 20688c2ecf20Sopenharmony_ci if (/\s*([\w\s]+?)(\(\))?\s*-/) { 20698c2ecf20Sopenharmony_ci $identifier = $1; 20708c2ecf20Sopenharmony_ci } 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci $state = STATE_BODY; 20738c2ecf20Sopenharmony_ci # if there's no @param blocks need to set up default section 20748c2ecf20Sopenharmony_ci # here 20758c2ecf20Sopenharmony_ci $contents = ""; 20768c2ecf20Sopenharmony_ci $section = $section_default; 20778c2ecf20Sopenharmony_ci $new_start_line = $. + 1; 20788c2ecf20Sopenharmony_ci if (/-(.*)/) { 20798c2ecf20Sopenharmony_ci # strip leading/trailing/multiple spaces 20808c2ecf20Sopenharmony_ci $descr= $1; 20818c2ecf20Sopenharmony_ci $descr =~ s/^\s*//; 20828c2ecf20Sopenharmony_ci $descr =~ s/\s*$//; 20838c2ecf20Sopenharmony_ci $descr =~ s/\s+/ /g; 20848c2ecf20Sopenharmony_ci $declaration_purpose = $descr; 20858c2ecf20Sopenharmony_ci $state = STATE_BODY_MAYBE; 20868c2ecf20Sopenharmony_ci } else { 20878c2ecf20Sopenharmony_ci $declaration_purpose = ""; 20888c2ecf20Sopenharmony_ci } 20898c2ecf20Sopenharmony_ci 20908c2ecf20Sopenharmony_ci if (($declaration_purpose eq "") && $verbose) { 20918c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: missing initial short description on line:\n"; 20928c2ecf20Sopenharmony_ci print STDERR $_; 20938c2ecf20Sopenharmony_ci ++$warnings; 20948c2ecf20Sopenharmony_ci } 20958c2ecf20Sopenharmony_ci 20968c2ecf20Sopenharmony_ci if ($identifier =~ m/^struct\b/) { 20978c2ecf20Sopenharmony_ci $decl_type = 'struct'; 20988c2ecf20Sopenharmony_ci } elsif ($identifier =~ m/^union\b/) { 20998c2ecf20Sopenharmony_ci $decl_type = 'union'; 21008c2ecf20Sopenharmony_ci } elsif ($identifier =~ m/^enum\b/) { 21018c2ecf20Sopenharmony_ci $decl_type = 'enum'; 21028c2ecf20Sopenharmony_ci } elsif ($identifier =~ m/^typedef\b/) { 21038c2ecf20Sopenharmony_ci $decl_type = 'typedef'; 21048c2ecf20Sopenharmony_ci } else { 21058c2ecf20Sopenharmony_ci $decl_type = 'function'; 21068c2ecf20Sopenharmony_ci } 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_ci if ($verbose) { 21098c2ecf20Sopenharmony_ci print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; 21108c2ecf20Sopenharmony_ci } 21118c2ecf20Sopenharmony_ci } else { 21128c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", 21138c2ecf20Sopenharmony_ci " - I thought it was a doc line\n"; 21148c2ecf20Sopenharmony_ci ++$warnings; 21158c2ecf20Sopenharmony_ci $state = STATE_NORMAL; 21168c2ecf20Sopenharmony_ci } 21178c2ecf20Sopenharmony_ci} 21188c2ecf20Sopenharmony_ci 21198c2ecf20Sopenharmony_ci 21208c2ecf20Sopenharmony_ci# 21218c2ecf20Sopenharmony_ci# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. 21228c2ecf20Sopenharmony_ci# 21238c2ecf20Sopenharmony_cisub process_body($$) { 21248c2ecf20Sopenharmony_ci my $file = shift; 21258c2ecf20Sopenharmony_ci 21268c2ecf20Sopenharmony_ci # Until all named variable macro parameters are 21278c2ecf20Sopenharmony_ci # documented using the bare name (`x`) rather than with 21288c2ecf20Sopenharmony_ci # dots (`x...`), strip the dots: 21298c2ecf20Sopenharmony_ci if ($section =~ /\w\.\.\.$/) { 21308c2ecf20Sopenharmony_ci $section =~ s/\.\.\.$//; 21318c2ecf20Sopenharmony_ci 21328c2ecf20Sopenharmony_ci if ($verbose) { 21338c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n"; 21348c2ecf20Sopenharmony_ci ++$warnings; 21358c2ecf20Sopenharmony_ci } 21368c2ecf20Sopenharmony_ci } 21378c2ecf20Sopenharmony_ci 21388c2ecf20Sopenharmony_ci if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) { 21398c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 21408c2ecf20Sopenharmony_ci $section = $section_default; 21418c2ecf20Sopenharmony_ci $new_start_line = $.; 21428c2ecf20Sopenharmony_ci $contents = ""; 21438c2ecf20Sopenharmony_ci } 21448c2ecf20Sopenharmony_ci 21458c2ecf20Sopenharmony_ci if (/$doc_sect/i) { # case insensitive for supported section names 21468c2ecf20Sopenharmony_ci $newsection = $1; 21478c2ecf20Sopenharmony_ci $newcontents = $2; 21488c2ecf20Sopenharmony_ci 21498c2ecf20Sopenharmony_ci # map the supported section names to the canonical names 21508c2ecf20Sopenharmony_ci if ($newsection =~ m/^description$/i) { 21518c2ecf20Sopenharmony_ci $newsection = $section_default; 21528c2ecf20Sopenharmony_ci } elsif ($newsection =~ m/^context$/i) { 21538c2ecf20Sopenharmony_ci $newsection = $section_context; 21548c2ecf20Sopenharmony_ci } elsif ($newsection =~ m/^returns?$/i) { 21558c2ecf20Sopenharmony_ci $newsection = $section_return; 21568c2ecf20Sopenharmony_ci } elsif ($newsection =~ m/^\@return$/) { 21578c2ecf20Sopenharmony_ci # special: @return is a section, not a param description 21588c2ecf20Sopenharmony_ci $newsection = $section_return; 21598c2ecf20Sopenharmony_ci } 21608c2ecf20Sopenharmony_ci 21618c2ecf20Sopenharmony_ci if (($contents ne "") && ($contents ne "\n")) { 21628c2ecf20Sopenharmony_ci if (!$in_doc_sect && $verbose) { 21638c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: contents before sections\n"; 21648c2ecf20Sopenharmony_ci ++$warnings; 21658c2ecf20Sopenharmony_ci } 21668c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 21678c2ecf20Sopenharmony_ci $section = $section_default; 21688c2ecf20Sopenharmony_ci } 21698c2ecf20Sopenharmony_ci 21708c2ecf20Sopenharmony_ci $in_doc_sect = 1; 21718c2ecf20Sopenharmony_ci $state = STATE_BODY; 21728c2ecf20Sopenharmony_ci $contents = $newcontents; 21738c2ecf20Sopenharmony_ci $new_start_line = $.; 21748c2ecf20Sopenharmony_ci while (substr($contents, 0, 1) eq " ") { 21758c2ecf20Sopenharmony_ci $contents = substr($contents, 1); 21768c2ecf20Sopenharmony_ci } 21778c2ecf20Sopenharmony_ci if ($contents ne "") { 21788c2ecf20Sopenharmony_ci $contents .= "\n"; 21798c2ecf20Sopenharmony_ci } 21808c2ecf20Sopenharmony_ci $section = $newsection; 21818c2ecf20Sopenharmony_ci $leading_space = undef; 21828c2ecf20Sopenharmony_ci } elsif (/$doc_end/) { 21838c2ecf20Sopenharmony_ci if (($contents ne "") && ($contents ne "\n")) { 21848c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 21858c2ecf20Sopenharmony_ci $section = $section_default; 21868c2ecf20Sopenharmony_ci $contents = ""; 21878c2ecf20Sopenharmony_ci } 21888c2ecf20Sopenharmony_ci # look for doc_com + <text> + doc_end: 21898c2ecf20Sopenharmony_ci if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { 21908c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: suspicious ending line: $_"; 21918c2ecf20Sopenharmony_ci ++$warnings; 21928c2ecf20Sopenharmony_ci } 21938c2ecf20Sopenharmony_ci 21948c2ecf20Sopenharmony_ci $prototype = ""; 21958c2ecf20Sopenharmony_ci $state = STATE_PROTO; 21968c2ecf20Sopenharmony_ci $brcount = 0; 21978c2ecf20Sopenharmony_ci $new_start_line = $. + 1; 21988c2ecf20Sopenharmony_ci } elsif (/$doc_content/) { 21998c2ecf20Sopenharmony_ci if ($1 eq "") { 22008c2ecf20Sopenharmony_ci if ($section eq $section_context) { 22018c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 22028c2ecf20Sopenharmony_ci $section = $section_default; 22038c2ecf20Sopenharmony_ci $contents = ""; 22048c2ecf20Sopenharmony_ci $new_start_line = $.; 22058c2ecf20Sopenharmony_ci $state = STATE_BODY; 22068c2ecf20Sopenharmony_ci } else { 22078c2ecf20Sopenharmony_ci if ($section ne $section_default) { 22088c2ecf20Sopenharmony_ci $state = STATE_BODY_WITH_BLANK_LINE; 22098c2ecf20Sopenharmony_ci } else { 22108c2ecf20Sopenharmony_ci $state = STATE_BODY; 22118c2ecf20Sopenharmony_ci } 22128c2ecf20Sopenharmony_ci $contents .= "\n"; 22138c2ecf20Sopenharmony_ci } 22148c2ecf20Sopenharmony_ci } elsif ($state == STATE_BODY_MAYBE) { 22158c2ecf20Sopenharmony_ci # Continued declaration purpose 22168c2ecf20Sopenharmony_ci chomp($declaration_purpose); 22178c2ecf20Sopenharmony_ci $declaration_purpose .= " " . $1; 22188c2ecf20Sopenharmony_ci $declaration_purpose =~ s/\s+/ /g; 22198c2ecf20Sopenharmony_ci } else { 22208c2ecf20Sopenharmony_ci my $cont = $1; 22218c2ecf20Sopenharmony_ci if ($section =~ m/^@/ || $section eq $section_context) { 22228c2ecf20Sopenharmony_ci if (!defined $leading_space) { 22238c2ecf20Sopenharmony_ci if ($cont =~ m/^(\s+)/) { 22248c2ecf20Sopenharmony_ci $leading_space = $1; 22258c2ecf20Sopenharmony_ci } else { 22268c2ecf20Sopenharmony_ci $leading_space = ""; 22278c2ecf20Sopenharmony_ci } 22288c2ecf20Sopenharmony_ci } 22298c2ecf20Sopenharmony_ci $cont =~ s/^$leading_space//; 22308c2ecf20Sopenharmony_ci } 22318c2ecf20Sopenharmony_ci $contents .= $cont . "\n"; 22328c2ecf20Sopenharmony_ci } 22338c2ecf20Sopenharmony_ci } else { 22348c2ecf20Sopenharmony_ci # i dont know - bad line? ignore. 22358c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: bad line: $_"; 22368c2ecf20Sopenharmony_ci ++$warnings; 22378c2ecf20Sopenharmony_ci } 22388c2ecf20Sopenharmony_ci} 22398c2ecf20Sopenharmony_ci 22408c2ecf20Sopenharmony_ci 22418c2ecf20Sopenharmony_ci# 22428c2ecf20Sopenharmony_ci# STATE_PROTO: reading a function/whatever prototype. 22438c2ecf20Sopenharmony_ci# 22448c2ecf20Sopenharmony_cisub process_proto($$) { 22458c2ecf20Sopenharmony_ci my $file = shift; 22468c2ecf20Sopenharmony_ci 22478c2ecf20Sopenharmony_ci if (/$doc_inline_oneline/) { 22488c2ecf20Sopenharmony_ci $section = $1; 22498c2ecf20Sopenharmony_ci $contents = $2; 22508c2ecf20Sopenharmony_ci if ($contents ne "") { 22518c2ecf20Sopenharmony_ci $contents .= "\n"; 22528c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 22538c2ecf20Sopenharmony_ci $section = $section_default; 22548c2ecf20Sopenharmony_ci $contents = ""; 22558c2ecf20Sopenharmony_ci } 22568c2ecf20Sopenharmony_ci } elsif (/$doc_inline_start/) { 22578c2ecf20Sopenharmony_ci $state = STATE_INLINE; 22588c2ecf20Sopenharmony_ci $inline_doc_state = STATE_INLINE_NAME; 22598c2ecf20Sopenharmony_ci } elsif ($decl_type eq 'function') { 22608c2ecf20Sopenharmony_ci process_proto_function($_, $file); 22618c2ecf20Sopenharmony_ci } else { 22628c2ecf20Sopenharmony_ci process_proto_type($_, $file); 22638c2ecf20Sopenharmony_ci } 22648c2ecf20Sopenharmony_ci} 22658c2ecf20Sopenharmony_ci 22668c2ecf20Sopenharmony_ci# 22678c2ecf20Sopenharmony_ci# STATE_DOCBLOCK: within a DOC: block. 22688c2ecf20Sopenharmony_ci# 22698c2ecf20Sopenharmony_cisub process_docblock($$) { 22708c2ecf20Sopenharmony_ci my $file = shift; 22718c2ecf20Sopenharmony_ci 22728c2ecf20Sopenharmony_ci if (/$doc_end/) { 22738c2ecf20Sopenharmony_ci dump_doc_section($file, $section, $contents); 22748c2ecf20Sopenharmony_ci $section = $section_default; 22758c2ecf20Sopenharmony_ci $contents = ""; 22768c2ecf20Sopenharmony_ci $function = ""; 22778c2ecf20Sopenharmony_ci %parameterdescs = (); 22788c2ecf20Sopenharmony_ci %parametertypes = (); 22798c2ecf20Sopenharmony_ci @parameterlist = (); 22808c2ecf20Sopenharmony_ci %sections = (); 22818c2ecf20Sopenharmony_ci @sectionlist = (); 22828c2ecf20Sopenharmony_ci $prototype = ""; 22838c2ecf20Sopenharmony_ci $state = STATE_NORMAL; 22848c2ecf20Sopenharmony_ci } elsif (/$doc_content/) { 22858c2ecf20Sopenharmony_ci if ( $1 eq "" ) { 22868c2ecf20Sopenharmony_ci $contents .= $blankline; 22878c2ecf20Sopenharmony_ci } else { 22888c2ecf20Sopenharmony_ci $contents .= $1 . "\n"; 22898c2ecf20Sopenharmony_ci } 22908c2ecf20Sopenharmony_ci } 22918c2ecf20Sopenharmony_ci} 22928c2ecf20Sopenharmony_ci 22938c2ecf20Sopenharmony_ci# 22948c2ecf20Sopenharmony_ci# STATE_INLINE: docbook comments within a prototype. 22958c2ecf20Sopenharmony_ci# 22968c2ecf20Sopenharmony_cisub process_inline($$) { 22978c2ecf20Sopenharmony_ci my $file = shift; 22988c2ecf20Sopenharmony_ci 22998c2ecf20Sopenharmony_ci # First line (state 1) needs to be a @parameter 23008c2ecf20Sopenharmony_ci if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { 23018c2ecf20Sopenharmony_ci $section = $1; 23028c2ecf20Sopenharmony_ci $contents = $2; 23038c2ecf20Sopenharmony_ci $new_start_line = $.; 23048c2ecf20Sopenharmony_ci if ($contents ne "") { 23058c2ecf20Sopenharmony_ci while (substr($contents, 0, 1) eq " ") { 23068c2ecf20Sopenharmony_ci $contents = substr($contents, 1); 23078c2ecf20Sopenharmony_ci } 23088c2ecf20Sopenharmony_ci $contents .= "\n"; 23098c2ecf20Sopenharmony_ci } 23108c2ecf20Sopenharmony_ci $inline_doc_state = STATE_INLINE_TEXT; 23118c2ecf20Sopenharmony_ci # Documentation block end */ 23128c2ecf20Sopenharmony_ci } elsif (/$doc_inline_end/) { 23138c2ecf20Sopenharmony_ci if (($contents ne "") && ($contents ne "\n")) { 23148c2ecf20Sopenharmony_ci dump_section($file, $section, $contents); 23158c2ecf20Sopenharmony_ci $section = $section_default; 23168c2ecf20Sopenharmony_ci $contents = ""; 23178c2ecf20Sopenharmony_ci } 23188c2ecf20Sopenharmony_ci $state = STATE_PROTO; 23198c2ecf20Sopenharmony_ci $inline_doc_state = STATE_INLINE_NA; 23208c2ecf20Sopenharmony_ci # Regular text 23218c2ecf20Sopenharmony_ci } elsif (/$doc_content/) { 23228c2ecf20Sopenharmony_ci if ($inline_doc_state == STATE_INLINE_TEXT) { 23238c2ecf20Sopenharmony_ci $contents .= $1 . "\n"; 23248c2ecf20Sopenharmony_ci # nuke leading blank lines 23258c2ecf20Sopenharmony_ci if ($contents =~ /^\s*$/) { 23268c2ecf20Sopenharmony_ci $contents = ""; 23278c2ecf20Sopenharmony_ci } 23288c2ecf20Sopenharmony_ci } elsif ($inline_doc_state == STATE_INLINE_NAME) { 23298c2ecf20Sopenharmony_ci $inline_doc_state = STATE_INLINE_ERROR; 23308c2ecf20Sopenharmony_ci print STDERR "${file}:$.: warning: "; 23318c2ecf20Sopenharmony_ci print STDERR "Incorrect use of kernel-doc format: $_"; 23328c2ecf20Sopenharmony_ci ++$warnings; 23338c2ecf20Sopenharmony_ci } 23348c2ecf20Sopenharmony_ci } 23358c2ecf20Sopenharmony_ci} 23368c2ecf20Sopenharmony_ci 23378c2ecf20Sopenharmony_ci 23388c2ecf20Sopenharmony_cisub process_file($) { 23398c2ecf20Sopenharmony_ci my $file; 23408c2ecf20Sopenharmony_ci my $initial_section_counter = $section_counter; 23418c2ecf20Sopenharmony_ci my ($orig_file) = @_; 23428c2ecf20Sopenharmony_ci 23438c2ecf20Sopenharmony_ci $file = map_filename($orig_file); 23448c2ecf20Sopenharmony_ci 23458c2ecf20Sopenharmony_ci if (!open(IN_FILE,"<$file")) { 23468c2ecf20Sopenharmony_ci print STDERR "Error: Cannot open file $file\n"; 23478c2ecf20Sopenharmony_ci ++$errors; 23488c2ecf20Sopenharmony_ci return; 23498c2ecf20Sopenharmony_ci } 23508c2ecf20Sopenharmony_ci 23518c2ecf20Sopenharmony_ci $. = 1; 23528c2ecf20Sopenharmony_ci 23538c2ecf20Sopenharmony_ci $section_counter = 0; 23548c2ecf20Sopenharmony_ci while (<IN_FILE>) { 23558c2ecf20Sopenharmony_ci while (s/\\\s*$//) { 23568c2ecf20Sopenharmony_ci $_ .= <IN_FILE>; 23578c2ecf20Sopenharmony_ci } 23588c2ecf20Sopenharmony_ci # Replace tabs by spaces 23598c2ecf20Sopenharmony_ci while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; 23608c2ecf20Sopenharmony_ci # Hand this line to the appropriate state handler 23618c2ecf20Sopenharmony_ci if ($state == STATE_NORMAL) { 23628c2ecf20Sopenharmony_ci process_normal(); 23638c2ecf20Sopenharmony_ci } elsif ($state == STATE_NAME) { 23648c2ecf20Sopenharmony_ci process_name($file, $_); 23658c2ecf20Sopenharmony_ci } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE || 23668c2ecf20Sopenharmony_ci $state == STATE_BODY_WITH_BLANK_LINE) { 23678c2ecf20Sopenharmony_ci process_body($file, $_); 23688c2ecf20Sopenharmony_ci } elsif ($state == STATE_INLINE) { # scanning for inline parameters 23698c2ecf20Sopenharmony_ci process_inline($file, $_); 23708c2ecf20Sopenharmony_ci } elsif ($state == STATE_PROTO) { 23718c2ecf20Sopenharmony_ci process_proto($file, $_); 23728c2ecf20Sopenharmony_ci } elsif ($state == STATE_DOCBLOCK) { 23738c2ecf20Sopenharmony_ci process_docblock($file, $_); 23748c2ecf20Sopenharmony_ci } 23758c2ecf20Sopenharmony_ci } 23768c2ecf20Sopenharmony_ci 23778c2ecf20Sopenharmony_ci # Make sure we got something interesting. 23788c2ecf20Sopenharmony_ci if ($initial_section_counter == $section_counter && $ 23798c2ecf20Sopenharmony_ci output_mode ne "none") { 23808c2ecf20Sopenharmony_ci if ($output_selection == OUTPUT_INCLUDE) { 23818c2ecf20Sopenharmony_ci print STDERR "${file}:1: warning: '$_' not found\n" 23828c2ecf20Sopenharmony_ci for keys %function_table; 23838c2ecf20Sopenharmony_ci } 23848c2ecf20Sopenharmony_ci else { 23858c2ecf20Sopenharmony_ci print STDERR "${file}:1: warning: no structured comments found\n"; 23868c2ecf20Sopenharmony_ci } 23878c2ecf20Sopenharmony_ci } 23888c2ecf20Sopenharmony_ci close IN_FILE; 23898c2ecf20Sopenharmony_ci} 23908c2ecf20Sopenharmony_ci 23918c2ecf20Sopenharmony_ci 23928c2ecf20Sopenharmony_ciif ($output_mode eq "rst") { 23938c2ecf20Sopenharmony_ci get_sphinx_version() if (!$sphinx_major); 23948c2ecf20Sopenharmony_ci} 23958c2ecf20Sopenharmony_ci 23968c2ecf20Sopenharmony_ci$kernelversion = get_kernel_version(); 23978c2ecf20Sopenharmony_ci 23988c2ecf20Sopenharmony_ci# generate a sequence of code that will splice in highlighting information 23998c2ecf20Sopenharmony_ci# using the s// operator. 24008c2ecf20Sopenharmony_cifor (my $k = 0; $k < @highlights; $k++) { 24018c2ecf20Sopenharmony_ci my $pattern = $highlights[$k][0]; 24028c2ecf20Sopenharmony_ci my $result = $highlights[$k][1]; 24038c2ecf20Sopenharmony_ci# print STDERR "scanning pattern:$pattern, highlight:($result)\n"; 24048c2ecf20Sopenharmony_ci $dohighlight .= "\$contents =~ s:$pattern:$result:gs;\n"; 24058c2ecf20Sopenharmony_ci} 24068c2ecf20Sopenharmony_ci 24078c2ecf20Sopenharmony_ci# Read the file that maps relative names to absolute names for 24088c2ecf20Sopenharmony_ci# separate source and object directories and for shadow trees. 24098c2ecf20Sopenharmony_ciif (open(SOURCE_MAP, "<.tmp_filelist.txt")) { 24108c2ecf20Sopenharmony_ci my ($relname, $absname); 24118c2ecf20Sopenharmony_ci while(<SOURCE_MAP>) { 24128c2ecf20Sopenharmony_ci chop(); 24138c2ecf20Sopenharmony_ci ($relname, $absname) = (split())[0..1]; 24148c2ecf20Sopenharmony_ci $relname =~ s:^/+::; 24158c2ecf20Sopenharmony_ci $source_map{$relname} = $absname; 24168c2ecf20Sopenharmony_ci } 24178c2ecf20Sopenharmony_ci close(SOURCE_MAP); 24188c2ecf20Sopenharmony_ci} 24198c2ecf20Sopenharmony_ci 24208c2ecf20Sopenharmony_ciif ($output_selection == OUTPUT_EXPORTED || 24218c2ecf20Sopenharmony_ci $output_selection == OUTPUT_INTERNAL) { 24228c2ecf20Sopenharmony_ci 24238c2ecf20Sopenharmony_ci push(@export_file_list, @ARGV); 24248c2ecf20Sopenharmony_ci 24258c2ecf20Sopenharmony_ci foreach (@export_file_list) { 24268c2ecf20Sopenharmony_ci chomp; 24278c2ecf20Sopenharmony_ci process_export_file($_); 24288c2ecf20Sopenharmony_ci } 24298c2ecf20Sopenharmony_ci} 24308c2ecf20Sopenharmony_ci 24318c2ecf20Sopenharmony_ciforeach (@ARGV) { 24328c2ecf20Sopenharmony_ci chomp; 24338c2ecf20Sopenharmony_ci process_file($_); 24348c2ecf20Sopenharmony_ci} 24358c2ecf20Sopenharmony_ciif ($verbose && $errors) { 24368c2ecf20Sopenharmony_ci print STDERR "$errors errors\n"; 24378c2ecf20Sopenharmony_ci} 24388c2ecf20Sopenharmony_ciif ($verbose && $warnings) { 24398c2ecf20Sopenharmony_ci print STDERR "$warnings warnings\n"; 24408c2ecf20Sopenharmony_ci} 24418c2ecf20Sopenharmony_ci 24428c2ecf20Sopenharmony_ciif ($Werror && $warnings) { 24438c2ecf20Sopenharmony_ci print STDERR "$warnings warnings as Errors\n"; 24448c2ecf20Sopenharmony_ci exit($warnings); 24458c2ecf20Sopenharmony_ci} else { 24468c2ecf20Sopenharmony_ci exit($output_mode eq "none" ? 0 : $errors) 24478c2ecf20Sopenharmony_ci} 2448