1*78a88f79SMario Six#!/usr/bin/env perl 2*78a88f79SMario Six# SPDX-License-Identifier: GPL-2.0 38fac9c7bSMasahiro Yamada 4*78a88f79SMario Sixuse warnings; 58fac9c7bSMasahiro Yamadause strict; 68fac9c7bSMasahiro Yamada 78fac9c7bSMasahiro Yamada## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 88fac9c7bSMasahiro Yamada## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 98fac9c7bSMasahiro Yamada## Copyright (C) 2001 Simon Huggins ## 108fac9c7bSMasahiro Yamada## Copyright (C) 2005-2012 Randy Dunlap ## 118fac9c7bSMasahiro Yamada## Copyright (C) 2012 Dan Luedtke ## 128fac9c7bSMasahiro Yamada## ## 138fac9c7bSMasahiro Yamada## #define enhancements by Armin Kuster <akuster@mvista.com> ## 148fac9c7bSMasahiro Yamada## Copyright (c) 2000 MontaVista Software, Inc. ## 158fac9c7bSMasahiro Yamada## ## 168fac9c7bSMasahiro Yamada## This software falls under the GNU General Public License. ## 178fac9c7bSMasahiro Yamada## Please read the COPYING file for more information ## 188fac9c7bSMasahiro Yamada 198fac9c7bSMasahiro Yamada# 18/01/2001 - Cleanups 208fac9c7bSMasahiro Yamada# Functions prototyped as foo(void) same as foo() 218fac9c7bSMasahiro Yamada# Stop eval'ing where we don't need to. 228fac9c7bSMasahiro Yamada# -- huggie@earth.li 238fac9c7bSMasahiro Yamada 248fac9c7bSMasahiro Yamada# 27/06/2001 - Allowed whitespace after initial "/**" and 258fac9c7bSMasahiro Yamada# allowed comments before function declarations. 268fac9c7bSMasahiro Yamada# -- Christian Kreibich <ck@whoop.org> 278fac9c7bSMasahiro Yamada 288fac9c7bSMasahiro Yamada# Still to do: 298fac9c7bSMasahiro Yamada# - add perldoc documentation 308fac9c7bSMasahiro Yamada# - Look more closely at some of the scarier bits :) 318fac9c7bSMasahiro Yamada 328fac9c7bSMasahiro Yamada# 26/05/2001 - Support for separate source and object trees. 338fac9c7bSMasahiro Yamada# Return error code. 348fac9c7bSMasahiro Yamada# Keith Owens <kaos@ocs.com.au> 358fac9c7bSMasahiro Yamada 368fac9c7bSMasahiro Yamada# 23/09/2001 - Added support for typedefs, structs, enums and unions 378fac9c7bSMasahiro Yamada# Support for Context section; can be terminated using empty line 388fac9c7bSMasahiro Yamada# Small fixes (like spaces vs. \s in regex) 398fac9c7bSMasahiro Yamada# -- Tim Jansen <tim@tjansen.de> 408fac9c7bSMasahiro Yamada 418fac9c7bSMasahiro Yamada# 25/07/2012 - Added support for HTML5 428fac9c7bSMasahiro Yamada# -- Dan Luedtke <mail@danrl.de> 438fac9c7bSMasahiro Yamada 44*78a88f79SMario Sixsub usage { 45*78a88f79SMario Six my $message = <<"EOF"; 46*78a88f79SMario SixUsage: $0 [OPTION ...] FILE ... 478fac9c7bSMasahiro Yamada 48*78a88f79SMario SixRead C language source or header FILEs, extract embedded documentation comments, 49*78a88f79SMario Sixand print formatted documentation to standard output. 508fac9c7bSMasahiro Yamada 51*78a88f79SMario SixThe documentation comments are identified by "/**" opening comment mark. See 52*78a88f79SMario SixDocumentation/doc-guide/kernel-doc.rst for the documentation comment syntax. 53*78a88f79SMario Six 54*78a88f79SMario SixOutput format selection (mutually exclusive): 55*78a88f79SMario Six -man Output troff manual page format. This is the default. 56*78a88f79SMario Six -rst Output reStructuredText format. 57*78a88f79SMario Six -none Do not output documentation, only warnings. 58*78a88f79SMario Six 59*78a88f79SMario SixOutput selection (mutually exclusive): 60*78a88f79SMario Six -export Only output documentation for symbols that have been 61*78a88f79SMario Six exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 62*78a88f79SMario Six in any input FILE or -export-file FILE. 63*78a88f79SMario Six -internal Only output documentation for symbols that have NOT been 64*78a88f79SMario Six exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() 65*78a88f79SMario Six in any input FILE or -export-file FILE. 66*78a88f79SMario Six -function NAME Only output documentation for the given function(s) 67*78a88f79SMario Six or DOC: section title(s). All other functions and DOC: 68*78a88f79SMario Six sections are ignored. May be specified multiple times. 69*78a88f79SMario Six -nofunction NAME Do NOT output documentation for the given function(s); 70*78a88f79SMario Six only output documentation for the other functions and 71*78a88f79SMario Six DOC: sections. May be specified multiple times. 72*78a88f79SMario Six 73*78a88f79SMario SixOutput selection modifiers: 74*78a88f79SMario Six -no-doc-sections Do not output DOC: sections. 75*78a88f79SMario Six -enable-lineno Enable output of #define LINENO lines. Only works with 76*78a88f79SMario Six reStructuredText format. 77*78a88f79SMario Six -export-file FILE Specify an additional FILE in which to look for 78*78a88f79SMario Six EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with 79*78a88f79SMario Six -export or -internal. May be specified multiple times. 80*78a88f79SMario Six 81*78a88f79SMario SixOther parameters: 82*78a88f79SMario Six -v Verbose output, more warnings and other information. 83*78a88f79SMario Six -h Print this help. 84*78a88f79SMario Six 85*78a88f79SMario SixEOF 86*78a88f79SMario Six print $message; 87*78a88f79SMario Six exit 1; 88*78a88f79SMario Six} 898fac9c7bSMasahiro Yamada 908fac9c7bSMasahiro Yamada# 918fac9c7bSMasahiro Yamada# format of comments. 928fac9c7bSMasahiro Yamada# In the following table, (...)? signifies optional structure. 938fac9c7bSMasahiro Yamada# (...)* signifies 0 or more structure elements 948fac9c7bSMasahiro Yamada# /** 958fac9c7bSMasahiro Yamada# * function_name(:)? (- short description)? 968fac9c7bSMasahiro Yamada# (* @parameterx: (description of parameter x)?)* 978fac9c7bSMasahiro Yamada# (* a blank line)? 988fac9c7bSMasahiro Yamada# * (Description:)? (Description of function)? 998fac9c7bSMasahiro Yamada# * (section header: (section description)? )* 1008fac9c7bSMasahiro Yamada# (*)?*/ 1018fac9c7bSMasahiro Yamada# 1028fac9c7bSMasahiro Yamada# So .. the trivial example would be: 1038fac9c7bSMasahiro Yamada# 1048fac9c7bSMasahiro Yamada# /** 1058fac9c7bSMasahiro Yamada# * my_function 1068fac9c7bSMasahiro Yamada# */ 1078fac9c7bSMasahiro Yamada# 1088fac9c7bSMasahiro Yamada# If the Description: header tag is omitted, then there must be a blank line 1098fac9c7bSMasahiro Yamada# after the last parameter specification. 1108fac9c7bSMasahiro Yamada# e.g. 1118fac9c7bSMasahiro Yamada# /** 1128fac9c7bSMasahiro Yamada# * my_function - does my stuff 1138fac9c7bSMasahiro Yamada# * @my_arg: its mine damnit 1148fac9c7bSMasahiro Yamada# * 1158fac9c7bSMasahiro Yamada# * Does my stuff explained. 1168fac9c7bSMasahiro Yamada# */ 1178fac9c7bSMasahiro Yamada# 1188fac9c7bSMasahiro Yamada# or, could also use: 1198fac9c7bSMasahiro Yamada# /** 1208fac9c7bSMasahiro Yamada# * my_function - does my stuff 1218fac9c7bSMasahiro Yamada# * @my_arg: its mine damnit 1228fac9c7bSMasahiro Yamada# * Description: Does my stuff explained. 1238fac9c7bSMasahiro Yamada# */ 1248fac9c7bSMasahiro Yamada# etc. 1258fac9c7bSMasahiro Yamada# 1268fac9c7bSMasahiro Yamada# Besides functions you can also write documentation for structs, unions, 1278fac9c7bSMasahiro Yamada# enums and typedefs. Instead of the function name you must write the name 1288fac9c7bSMasahiro Yamada# of the declaration; the struct/union/enum/typedef must always precede 1298fac9c7bSMasahiro Yamada# the name. Nesting of declarations is not supported. 1308fac9c7bSMasahiro Yamada# Use the argument mechanism to document members or constants. 1318fac9c7bSMasahiro Yamada# e.g. 1328fac9c7bSMasahiro Yamada# /** 1338fac9c7bSMasahiro Yamada# * struct my_struct - short description 1348fac9c7bSMasahiro Yamada# * @a: first member 1358fac9c7bSMasahiro Yamada# * @b: second member 1368fac9c7bSMasahiro Yamada# * 1378fac9c7bSMasahiro Yamada# * Longer description 1388fac9c7bSMasahiro Yamada# */ 1398fac9c7bSMasahiro Yamada# struct my_struct { 1408fac9c7bSMasahiro Yamada# int a; 1418fac9c7bSMasahiro Yamada# int b; 1428fac9c7bSMasahiro Yamada# /* private: */ 1438fac9c7bSMasahiro Yamada# int c; 1448fac9c7bSMasahiro Yamada# }; 1458fac9c7bSMasahiro Yamada# 1468fac9c7bSMasahiro Yamada# All descriptions can be multiline, except the short function description. 1478fac9c7bSMasahiro Yamada# 148*78a88f79SMario Six# For really longs structs, you can also describe arguments inside the 149*78a88f79SMario Six# body of the struct. 150*78a88f79SMario Six# eg. 151*78a88f79SMario Six# /** 152*78a88f79SMario Six# * struct my_struct - short description 153*78a88f79SMario Six# * @a: first member 154*78a88f79SMario Six# * @b: second member 155*78a88f79SMario Six# * 156*78a88f79SMario Six# * Longer description 157*78a88f79SMario Six# */ 158*78a88f79SMario Six# struct my_struct { 159*78a88f79SMario Six# int a; 160*78a88f79SMario Six# int b; 161*78a88f79SMario Six# /** 162*78a88f79SMario Six# * @c: This is longer description of C 163*78a88f79SMario Six# * 164*78a88f79SMario Six# * You can use paragraphs to describe arguments 165*78a88f79SMario Six# * using this method. 166*78a88f79SMario Six# */ 167*78a88f79SMario Six# int c; 168*78a88f79SMario Six# }; 169*78a88f79SMario Six# 170*78a88f79SMario Six# This should be use only for struct/enum members. 171*78a88f79SMario Six# 1728fac9c7bSMasahiro Yamada# You can also add additional sections. When documenting kernel functions you 1738fac9c7bSMasahiro Yamada# should document the "Context:" of the function, e.g. whether the functions 1748fac9c7bSMasahiro Yamada# can be called form interrupts. Unlike other sections you can end it with an 1758fac9c7bSMasahiro Yamada# empty line. 176ced03298SMasahiro Yamada# A non-void function should have a "Return:" section describing the return 177ced03298SMasahiro Yamada# value(s). 1788fac9c7bSMasahiro Yamada# Example-sections should contain the string EXAMPLE so that they are marked 1798fac9c7bSMasahiro Yamada# appropriately in DocBook. 1808fac9c7bSMasahiro Yamada# 1818fac9c7bSMasahiro Yamada# Example: 1828fac9c7bSMasahiro Yamada# /** 1838fac9c7bSMasahiro Yamada# * user_function - function that can only be called in user context 1848fac9c7bSMasahiro Yamada# * @a: some argument 1858fac9c7bSMasahiro Yamada# * Context: !in_interrupt() 1868fac9c7bSMasahiro Yamada# * 1878fac9c7bSMasahiro Yamada# * Some description 1888fac9c7bSMasahiro Yamada# * Example: 1898fac9c7bSMasahiro Yamada# * user_function(22); 1908fac9c7bSMasahiro Yamada# */ 1918fac9c7bSMasahiro Yamada# ... 1928fac9c7bSMasahiro Yamada# 1938fac9c7bSMasahiro Yamada# 1948fac9c7bSMasahiro Yamada# All descriptive text is further processed, scanning for the following special 1958fac9c7bSMasahiro Yamada# patterns, which are highlighted appropriately. 1968fac9c7bSMasahiro Yamada# 1978fac9c7bSMasahiro Yamada# 'funcname()' - function 1988fac9c7bSMasahiro Yamada# '$ENVVAR' - environmental variable 1998fac9c7bSMasahiro Yamada# '&struct_name' - name of a structure (up to two words including 'struct') 200*78a88f79SMario Six# '&struct_name.member' - name of a structure member 2018fac9c7bSMasahiro Yamada# '@parameter' - name of a parameter 2028fac9c7bSMasahiro Yamada# '%CONST' - name of a constant. 203*78a88f79SMario Six# '``LITERAL``' - literal string without any spaces on it. 2048fac9c7bSMasahiro Yamada 2058fac9c7bSMasahiro Yamada## init lots of data 2068fac9c7bSMasahiro Yamada 2078fac9c7bSMasahiro Yamadamy $errors = 0; 2088fac9c7bSMasahiro Yamadamy $warnings = 0; 2098fac9c7bSMasahiro Yamadamy $anon_struct_union = 0; 2108fac9c7bSMasahiro Yamada 2118fac9c7bSMasahiro Yamada# match expressions used to find embedded type information 212*78a88f79SMario Sixmy $type_constant = '\b``([^\`]+)``\b'; 213*78a88f79SMario Sixmy $type_constant2 = '\%([-_\w]+)'; 2148fac9c7bSMasahiro Yamadamy $type_func = '(\w+)\(\)'; 215*78a88f79SMario Sixmy $type_param = '\@(\w*(\.\w+)*(\.\.\.)?)'; 216*78a88f79SMario Sixmy $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params 2178fac9c7bSMasahiro Yamadamy $type_env = '(\$\w+)'; 218*78a88f79SMario Sixmy $type_enum = '\&(enum\s*([_\w]+))'; 219*78a88f79SMario Sixmy $type_struct = '\&(struct\s*([_\w]+))'; 220*78a88f79SMario Sixmy $type_typedef = '\&(typedef\s*([_\w]+))'; 221*78a88f79SMario Sixmy $type_union = '\&(union\s*([_\w]+))'; 222*78a88f79SMario Sixmy $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; 223*78a88f79SMario Sixmy $type_fallback = '\&([_\w]+)'; 224*78a88f79SMario Sixmy $type_member_func = $type_member . '\(\)'; 2258fac9c7bSMasahiro Yamada 2268fac9c7bSMasahiro Yamada# Output conversion substitutions. 2278fac9c7bSMasahiro Yamada# One for each output format 2288fac9c7bSMasahiro Yamada 2298fac9c7bSMasahiro Yamada# these are pretty rough 230*78a88f79SMario Sixmy @highlights_man = ( 231*78a88f79SMario Six [$type_constant, "\$1"], 232*78a88f79SMario Six [$type_constant2, "\$1"], 233*78a88f79SMario Six [$type_func, "\\\\fB\$1\\\\fP"], 234*78a88f79SMario Six [$type_enum, "\\\\fI\$1\\\\fP"], 235*78a88f79SMario Six [$type_struct, "\\\\fI\$1\\\\fP"], 236*78a88f79SMario Six [$type_typedef, "\\\\fI\$1\\\\fP"], 237*78a88f79SMario Six [$type_union, "\\\\fI\$1\\\\fP"], 238*78a88f79SMario Six [$type_param, "\\\\fI\$1\\\\fP"], 239*78a88f79SMario Six [$type_member, "\\\\fI\$1\$2\$3\\\\fP"], 240*78a88f79SMario Six [$type_fallback, "\\\\fI\$1\\\\fP"] 241*78a88f79SMario Six ); 2428fac9c7bSMasahiro Yamadamy $blankline_man = ""; 2438fac9c7bSMasahiro Yamada 244*78a88f79SMario Six# rst-mode 245*78a88f79SMario Sixmy @highlights_rst = ( 246*78a88f79SMario Six [$type_constant, "``\$1``"], 247*78a88f79SMario Six [$type_constant2, "``\$1``"], 248*78a88f79SMario Six # Note: need to escape () to avoid func matching later 249*78a88f79SMario Six [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"], 250*78a88f79SMario Six [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"], 251*78a88f79SMario Six [$type_fp_param, "**\$1\\\\(\\\\)**"], 252*78a88f79SMario Six [$type_func, "\\:c\\:func\\:`\$1()`"], 253*78a88f79SMario Six [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], 254*78a88f79SMario Six [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"], 255*78a88f79SMario Six [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"], 256*78a88f79SMario Six [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"], 257*78a88f79SMario Six # in rst this can refer to any type 258*78a88f79SMario Six [$type_fallback, "\\:c\\:type\\:`\$1`"], 259*78a88f79SMario Six [$type_param, "**\$1**"] 260*78a88f79SMario Six ); 261*78a88f79SMario Sixmy $blankline_rst = "\n"; 2628fac9c7bSMasahiro Yamada 2638fac9c7bSMasahiro Yamada# read arguments 2648fac9c7bSMasahiro Yamadaif ($#ARGV == -1) { 2658fac9c7bSMasahiro Yamada usage(); 2668fac9c7bSMasahiro Yamada} 2678fac9c7bSMasahiro Yamada 2688fac9c7bSMasahiro Yamadamy $kernelversion; 2698fac9c7bSMasahiro Yamadamy $dohighlight = ""; 2708fac9c7bSMasahiro Yamada 2718fac9c7bSMasahiro Yamadamy $verbose = 0; 272*78a88f79SMario Sixmy $output_mode = "rst"; 273ced03298SMasahiro Yamadamy $output_preformatted = 0; 2748fac9c7bSMasahiro Yamadamy $no_doc_sections = 0; 275*78a88f79SMario Sixmy $enable_lineno = 0; 276*78a88f79SMario Sixmy @highlights = @highlights_rst; 277*78a88f79SMario Sixmy $blankline = $blankline_rst; 278*78a88f79SMario Sixmy $modulename = "Kernel API"; 279*78a88f79SMario Six 280*78a88f79SMario Sixuse constant { 281*78a88f79SMario Six OUTPUT_ALL => 0, # output all symbols and doc sections 282*78a88f79SMario Six OUTPUT_INCLUDE => 1, # output only specified symbols 283*78a88f79SMario Six OUTPUT_EXCLUDE => 2, # output everything except specified symbols 284*78a88f79SMario Six OUTPUT_EXPORTED => 3, # output exported symbols 285*78a88f79SMario Six OUTPUT_INTERNAL => 4, # output non-exported symbols 286*78a88f79SMario Six}; 287*78a88f79SMario Sixmy $output_selection = OUTPUT_ALL; 288*78a88f79SMario Sixmy $show_not_found = 0; 289*78a88f79SMario Six 290*78a88f79SMario Sixmy @export_file_list; 291*78a88f79SMario Six 292*78a88f79SMario Sixmy @build_time; 293*78a88f79SMario Sixif (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 294*78a88f79SMario Six (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { 295*78a88f79SMario Six @build_time = gmtime($seconds); 296*78a88f79SMario Six} else { 297*78a88f79SMario Six @build_time = localtime; 298*78a88f79SMario Six} 299*78a88f79SMario Six 3008fac9c7bSMasahiro Yamadamy $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 3018fac9c7bSMasahiro Yamada 'July', 'August', 'September', 'October', 302*78a88f79SMario Six 'November', 'December')[$build_time[4]] . 303*78a88f79SMario Six " " . ($build_time[5]+1900); 3048fac9c7bSMasahiro Yamada 3058fac9c7bSMasahiro Yamada# Essentially these are globals. 3068fac9c7bSMasahiro Yamada# They probably want to be tidied up, made more localised or something. 3078fac9c7bSMasahiro Yamada# CAVEAT EMPTOR! Some of the others I localised may not want to be, which 3088fac9c7bSMasahiro Yamada# could cause "use of undefined value" or other bugs. 3098fac9c7bSMasahiro Yamadamy ($function, %function_table, %parametertypes, $declaration_purpose); 310*78a88f79SMario Sixmy $declaration_start_line; 3118fac9c7bSMasahiro Yamadamy ($type, $declaration_name, $return_type); 3128fac9c7bSMasahiro Yamadamy ($newsection, $newcontents, $prototype, $brcount, %source_map); 3138fac9c7bSMasahiro Yamada 3148fac9c7bSMasahiro Yamadaif (defined($ENV{'KBUILD_VERBOSE'})) { 3158fac9c7bSMasahiro Yamada $verbose = "$ENV{'KBUILD_VERBOSE'}"; 3168fac9c7bSMasahiro Yamada} 3178fac9c7bSMasahiro Yamada 3188fac9c7bSMasahiro Yamada# Generated docbook code is inserted in a template at a point where 3198fac9c7bSMasahiro Yamada# docbook v3.1 requires a non-zero sequence of RefEntry's; see: 3208fac9c7bSMasahiro Yamada# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html 3218fac9c7bSMasahiro Yamada# We keep track of number of generated entries and generate a dummy 3228fac9c7bSMasahiro Yamada# if needs be to ensure the expanded template can be postprocessed 3238fac9c7bSMasahiro Yamada# into html. 3248fac9c7bSMasahiro Yamadamy $section_counter = 0; 3258fac9c7bSMasahiro Yamada 3268fac9c7bSMasahiro Yamadamy $lineprefix=""; 3278fac9c7bSMasahiro Yamada 328*78a88f79SMario Six# Parser states 329*78a88f79SMario Sixuse constant { 330*78a88f79SMario Six STATE_NORMAL => 0, # normal code 331*78a88f79SMario Six STATE_NAME => 1, # looking for function name 332*78a88f79SMario Six STATE_BODY_MAYBE => 2, # body - or maybe more description 333*78a88f79SMario Six STATE_BODY => 3, # the body of the comment 334*78a88f79SMario Six STATE_PROTO => 4, # scanning prototype 335*78a88f79SMario Six STATE_DOCBLOCK => 5, # documentation block 336*78a88f79SMario Six STATE_INLINE => 6, # gathering documentation outside main block 337*78a88f79SMario Six}; 3388fac9c7bSMasahiro Yamadamy $state; 3398fac9c7bSMasahiro Yamadamy $in_doc_sect; 340*78a88f79SMario Sixmy $leading_space; 341*78a88f79SMario Six 342*78a88f79SMario Six# Inline documentation state 343*78a88f79SMario Sixuse constant { 344*78a88f79SMario Six STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) 345*78a88f79SMario Six STATE_INLINE_NAME => 1, # looking for member name (@foo:) 346*78a88f79SMario Six STATE_INLINE_TEXT => 2, # looking for member documentation 347*78a88f79SMario Six STATE_INLINE_END => 3, # done 348*78a88f79SMario Six STATE_INLINE_ERROR => 4, # error - Comment without header was found. 349*78a88f79SMario Six # Spit a warning as it's not 350*78a88f79SMario Six # proper kernel-doc and ignore the rest. 351*78a88f79SMario Six}; 352*78a88f79SMario Sixmy $inline_doc_state; 3538fac9c7bSMasahiro Yamada 3548fac9c7bSMasahiro Yamada#declaration types: can be 3558fac9c7bSMasahiro Yamada# 'function', 'struct', 'union', 'enum', 'typedef' 3568fac9c7bSMasahiro Yamadamy $decl_type; 3578fac9c7bSMasahiro Yamada 3588fac9c7bSMasahiro Yamadamy $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 3598fac9c7bSMasahiro Yamadamy $doc_end = '\*/'; 3608fac9c7bSMasahiro Yamadamy $doc_com = '\s*\*\s*'; 361ced03298SMasahiro Yamadamy $doc_com_body = '\s*\* ?'; 3628fac9c7bSMasahiro Yamadamy $doc_decl = $doc_com . '(\w+)'; 363*78a88f79SMario Six# @params and a strictly limited set of supported section names 364*78a88f79SMario Sixmy $doc_sect = $doc_com . 365*78a88f79SMario Six '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)'; 366ced03298SMasahiro Yamadamy $doc_content = $doc_com_body . '(.*)'; 3678fac9c7bSMasahiro Yamadamy $doc_block = $doc_com . 'DOC:\s*(.*)?'; 368*78a88f79SMario Sixmy $doc_inline_start = '^\s*/\*\*\s*$'; 369*78a88f79SMario Sixmy $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; 370*78a88f79SMario Sixmy $doc_inline_end = '^\s*\*/\s*$'; 371*78a88f79SMario Sixmy $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; 372*78a88f79SMario Sixmy $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 3738fac9c7bSMasahiro Yamada 3748fac9c7bSMasahiro Yamadamy %parameterdescs; 375*78a88f79SMario Sixmy %parameterdesc_start_lines; 3768fac9c7bSMasahiro Yamadamy @parameterlist; 3778fac9c7bSMasahiro Yamadamy %sections; 3788fac9c7bSMasahiro Yamadamy @sectionlist; 379*78a88f79SMario Sixmy %section_start_lines; 3808fac9c7bSMasahiro Yamadamy $sectcheck; 3818fac9c7bSMasahiro Yamadamy $struct_actual; 3828fac9c7bSMasahiro Yamada 3838fac9c7bSMasahiro Yamadamy $contents = ""; 384*78a88f79SMario Sixmy $new_start_line = 0; 385*78a88f79SMario Six 386*78a88f79SMario Six# the canonical section names. see also $doc_sect above. 3878fac9c7bSMasahiro Yamadamy $section_default = "Description"; # default section 3888fac9c7bSMasahiro Yamadamy $section_intro = "Introduction"; 3898fac9c7bSMasahiro Yamadamy $section = $section_default; 3908fac9c7bSMasahiro Yamadamy $section_context = "Context"; 391ced03298SMasahiro Yamadamy $section_return = "Return"; 3928fac9c7bSMasahiro Yamada 3938fac9c7bSMasahiro Yamadamy $undescribed = "-- undescribed --"; 3948fac9c7bSMasahiro Yamada 3958fac9c7bSMasahiro Yamadareset_state(); 3968fac9c7bSMasahiro Yamada 397*78a88f79SMario Sixwhile ($ARGV[0] =~ m/^--?(.*)/) { 398*78a88f79SMario Six my $cmd = $1; 399*78a88f79SMario Six shift @ARGV; 400*78a88f79SMario Six if ($cmd eq "man") { 4018fac9c7bSMasahiro Yamada $output_mode = "man"; 402*78a88f79SMario Six @highlights = @highlights_man; 4038fac9c7bSMasahiro Yamada $blankline = $blankline_man; 404*78a88f79SMario Six } elsif ($cmd eq "rst") { 405*78a88f79SMario Six $output_mode = "rst"; 406*78a88f79SMario Six @highlights = @highlights_rst; 407*78a88f79SMario Six $blankline = $blankline_rst; 408*78a88f79SMario Six } elsif ($cmd eq "none") { 409*78a88f79SMario Six $output_mode = "none"; 410*78a88f79SMario Six } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document 4118fac9c7bSMasahiro Yamada $modulename = shift @ARGV; 412*78a88f79SMario Six } elsif ($cmd eq "function") { # to only output specific functions 413*78a88f79SMario Six $output_selection = OUTPUT_INCLUDE; 4148fac9c7bSMasahiro Yamada $function = shift @ARGV; 4158fac9c7bSMasahiro Yamada $function_table{$function} = 1; 416*78a88f79SMario Six } elsif ($cmd eq "nofunction") { # output all except specific functions 417*78a88f79SMario Six $output_selection = OUTPUT_EXCLUDE; 4188fac9c7bSMasahiro Yamada $function = shift @ARGV; 4198fac9c7bSMasahiro Yamada $function_table{$function} = 1; 420*78a88f79SMario Six } elsif ($cmd eq "export") { # only exported symbols 421*78a88f79SMario Six $output_selection = OUTPUT_EXPORTED; 422*78a88f79SMario Six %function_table = (); 423*78a88f79SMario Six } elsif ($cmd eq "internal") { # only non-exported symbols 424*78a88f79SMario Six $output_selection = OUTPUT_INTERNAL; 425*78a88f79SMario Six %function_table = (); 426*78a88f79SMario Six } elsif ($cmd eq "export-file") { 427*78a88f79SMario Six my $file = shift @ARGV; 428*78a88f79SMario Six push(@export_file_list, $file); 429*78a88f79SMario Six } elsif ($cmd eq "v") { 4308fac9c7bSMasahiro Yamada $verbose = 1; 431*78a88f79SMario Six } elsif (($cmd eq "h") || ($cmd eq "help")) { 4328fac9c7bSMasahiro Yamada usage(); 433*78a88f79SMario Six } elsif ($cmd eq 'no-doc-sections') { 4348fac9c7bSMasahiro Yamada $no_doc_sections = 1; 435*78a88f79SMario Six } elsif ($cmd eq 'enable-lineno') { 436*78a88f79SMario Six $enable_lineno = 1; 437*78a88f79SMario Six } elsif ($cmd eq 'show-not-found') { 438ced03298SMasahiro Yamada $show_not_found = 1; 439*78a88f79SMario Six } else { 440*78a88f79SMario Six # Unknown argument 441*78a88f79SMario Six usage(); 4428fac9c7bSMasahiro Yamada } 4438fac9c7bSMasahiro Yamada} 4448fac9c7bSMasahiro Yamada 4458fac9c7bSMasahiro Yamada# continue execution near EOF; 4468fac9c7bSMasahiro Yamada 4478fac9c7bSMasahiro Yamada# get kernel version from env 4488fac9c7bSMasahiro Yamadasub get_kernel_version() { 4498fac9c7bSMasahiro Yamada my $version = 'unknown kernel version'; 4508fac9c7bSMasahiro Yamada 451*78a88f79SMario Six if (defined($ENV{'KERNELVERSION'})) { 452*78a88f79SMario Six $version = $ENV{'KERNELVERSION'}; 4538fac9c7bSMasahiro Yamada } 4548fac9c7bSMasahiro Yamada return $version; 4558fac9c7bSMasahiro Yamada} 4568fac9c7bSMasahiro Yamada 457*78a88f79SMario Six# 458*78a88f79SMario Sixsub print_lineno { 459*78a88f79SMario Six my $lineno = shift; 460*78a88f79SMario Six if ($enable_lineno && defined($lineno)) { 461*78a88f79SMario Six print "#define LINENO " . $lineno . "\n"; 462*78a88f79SMario Six } 463*78a88f79SMario Six} 4648fac9c7bSMasahiro Yamada## 4658fac9c7bSMasahiro Yamada# dumps section contents to arrays/hashes intended for that purpose. 4668fac9c7bSMasahiro Yamada# 4678fac9c7bSMasahiro Yamadasub dump_section { 4688fac9c7bSMasahiro Yamada my $file = shift; 4698fac9c7bSMasahiro Yamada my $name = shift; 4708fac9c7bSMasahiro Yamada my $contents = join "\n", @_; 4718fac9c7bSMasahiro Yamada 472*78a88f79SMario Six if ($name =~ m/$type_param/) { 4738fac9c7bSMasahiro Yamada $name = $1; 4748fac9c7bSMasahiro Yamada $parameterdescs{$name} = $contents; 4758fac9c7bSMasahiro Yamada $sectcheck = $sectcheck . $name . " "; 476*78a88f79SMario Six $parameterdesc_start_lines{$name} = $new_start_line; 477*78a88f79SMario Six $new_start_line = 0; 4788fac9c7bSMasahiro Yamada } elsif ($name eq "@\.\.\.") { 4798fac9c7bSMasahiro Yamada $name = "..."; 4808fac9c7bSMasahiro Yamada $parameterdescs{$name} = $contents; 4818fac9c7bSMasahiro Yamada $sectcheck = $sectcheck . $name . " "; 482*78a88f79SMario Six $parameterdesc_start_lines{$name} = $new_start_line; 483*78a88f79SMario Six $new_start_line = 0; 4848fac9c7bSMasahiro Yamada } else { 4858fac9c7bSMasahiro Yamada if (defined($sections{$name}) && ($sections{$name} ne "")) { 486*78a88f79SMario Six # Only warn on user specified duplicate section names. 487*78a88f79SMario Six if ($name ne $section_default) { 488*78a88f79SMario Six print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; 489*78a88f79SMario Six ++$warnings; 4908fac9c7bSMasahiro Yamada } 491*78a88f79SMario Six $sections{$name} .= $contents; 492*78a88f79SMario Six } else { 4938fac9c7bSMasahiro Yamada $sections{$name} = $contents; 4948fac9c7bSMasahiro Yamada push @sectionlist, $name; 495*78a88f79SMario Six $section_start_lines{$name} = $new_start_line; 496*78a88f79SMario Six $new_start_line = 0; 497*78a88f79SMario Six } 4988fac9c7bSMasahiro Yamada } 4998fac9c7bSMasahiro Yamada} 5008fac9c7bSMasahiro Yamada 5018fac9c7bSMasahiro Yamada## 5028fac9c7bSMasahiro Yamada# dump DOC: section after checking that it should go out 5038fac9c7bSMasahiro Yamada# 5048fac9c7bSMasahiro Yamadasub dump_doc_section { 5058fac9c7bSMasahiro Yamada my $file = shift; 5068fac9c7bSMasahiro Yamada my $name = shift; 5078fac9c7bSMasahiro Yamada my $contents = join "\n", @_; 5088fac9c7bSMasahiro Yamada 5098fac9c7bSMasahiro Yamada if ($no_doc_sections) { 5108fac9c7bSMasahiro Yamada return; 5118fac9c7bSMasahiro Yamada } 5128fac9c7bSMasahiro Yamada 513*78a88f79SMario Six if (($output_selection == OUTPUT_ALL) || 514*78a88f79SMario Six ($output_selection == OUTPUT_INCLUDE && 515*78a88f79SMario Six defined($function_table{$name})) || 516*78a88f79SMario Six ($output_selection == OUTPUT_EXCLUDE && 517*78a88f79SMario Six !defined($function_table{$name}))) 5188fac9c7bSMasahiro Yamada { 5198fac9c7bSMasahiro Yamada dump_section($file, $name, $contents); 5208fac9c7bSMasahiro Yamada output_blockhead({'sectionlist' => \@sectionlist, 5218fac9c7bSMasahiro Yamada 'sections' => \%sections, 5228fac9c7bSMasahiro Yamada 'module' => $modulename, 523*78a88f79SMario Six 'content-only' => ($output_selection != OUTPUT_ALL), }); 5248fac9c7bSMasahiro Yamada } 5258fac9c7bSMasahiro Yamada} 5268fac9c7bSMasahiro Yamada 5278fac9c7bSMasahiro Yamada## 5288fac9c7bSMasahiro Yamada# output function 5298fac9c7bSMasahiro Yamada# 5308fac9c7bSMasahiro Yamada# parameterdescs, a hash. 5318fac9c7bSMasahiro Yamada# function => "function name" 5328fac9c7bSMasahiro Yamada# parameterlist => @list of parameters 5338fac9c7bSMasahiro Yamada# parameterdescs => %parameter descriptions 5348fac9c7bSMasahiro Yamada# sectionlist => @list of sections 5358fac9c7bSMasahiro Yamada# sections => %section descriptions 5368fac9c7bSMasahiro Yamada# 5378fac9c7bSMasahiro Yamada 5388fac9c7bSMasahiro Yamadasub output_highlight { 5398fac9c7bSMasahiro Yamada my $contents = join "\n",@_; 5408fac9c7bSMasahiro Yamada my $line; 5418fac9c7bSMasahiro Yamada 5428fac9c7bSMasahiro Yamada# DEBUG 5438fac9c7bSMasahiro Yamada# if (!defined $contents) { 5448fac9c7bSMasahiro Yamada# use Carp; 5458fac9c7bSMasahiro Yamada# confess "output_highlight got called with no args?\n"; 5468fac9c7bSMasahiro Yamada# } 5478fac9c7bSMasahiro Yamada 5488fac9c7bSMasahiro Yamada# print STDERR "contents b4:$contents\n"; 5498fac9c7bSMasahiro Yamada eval $dohighlight; 5508fac9c7bSMasahiro Yamada die $@ if $@; 5518fac9c7bSMasahiro Yamada# print STDERR "contents af:$contents\n"; 5528fac9c7bSMasahiro Yamada 5538fac9c7bSMasahiro Yamada foreach $line (split "\n", $contents) { 554ced03298SMasahiro Yamada if (! $output_preformatted) { 555ced03298SMasahiro Yamada $line =~ s/^\s*//; 556ced03298SMasahiro Yamada } 5578fac9c7bSMasahiro Yamada if ($line eq ""){ 558ced03298SMasahiro Yamada if (! $output_preformatted) { 559*78a88f79SMario Six print $lineprefix, $blankline; 560ced03298SMasahiro Yamada } 5618fac9c7bSMasahiro Yamada } else { 5628fac9c7bSMasahiro Yamada if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { 5638fac9c7bSMasahiro Yamada print "\\&$line"; 5648fac9c7bSMasahiro Yamada } else { 5658fac9c7bSMasahiro Yamada print $lineprefix, $line; 5668fac9c7bSMasahiro Yamada } 5678fac9c7bSMasahiro Yamada } 5688fac9c7bSMasahiro Yamada print "\n"; 5698fac9c7bSMasahiro Yamada } 5708fac9c7bSMasahiro Yamada} 5718fac9c7bSMasahiro Yamada 5728fac9c7bSMasahiro Yamada## 5738fac9c7bSMasahiro Yamada# output function in man 5748fac9c7bSMasahiro Yamadasub output_function_man(%) { 5758fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 5768fac9c7bSMasahiro Yamada my ($parameter, $section); 5778fac9c7bSMasahiro Yamada my $count; 5788fac9c7bSMasahiro Yamada 579*78a88f79SMario Six print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n"; 5808fac9c7bSMasahiro Yamada 5818fac9c7bSMasahiro Yamada print ".SH NAME\n"; 5828fac9c7bSMasahiro Yamada print $args{'function'} . " \\- " . $args{'purpose'} . "\n"; 5838fac9c7bSMasahiro Yamada 5848fac9c7bSMasahiro Yamada print ".SH SYNOPSIS\n"; 5858fac9c7bSMasahiro Yamada if ($args{'functiontype'} ne "") { 5868fac9c7bSMasahiro Yamada print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n"; 5878fac9c7bSMasahiro Yamada } else { 5888fac9c7bSMasahiro Yamada print ".B \"" . $args{'function'} . "\n"; 5898fac9c7bSMasahiro Yamada } 5908fac9c7bSMasahiro Yamada $count = 0; 5918fac9c7bSMasahiro Yamada my $parenth = "("; 5928fac9c7bSMasahiro Yamada my $post = ","; 5938fac9c7bSMasahiro Yamada foreach my $parameter (@{$args{'parameterlist'}}) { 5948fac9c7bSMasahiro Yamada if ($count == $#{$args{'parameterlist'}}) { 5958fac9c7bSMasahiro Yamada $post = ");"; 5968fac9c7bSMasahiro Yamada } 5978fac9c7bSMasahiro Yamada $type = $args{'parametertypes'}{$parameter}; 5988fac9c7bSMasahiro Yamada if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 5998fac9c7bSMasahiro Yamada # pointer-to-function 6008fac9c7bSMasahiro Yamada print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n"; 6018fac9c7bSMasahiro Yamada } else { 6028fac9c7bSMasahiro Yamada $type =~ s/([^\*])$/$1 /; 6038fac9c7bSMasahiro Yamada print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n"; 6048fac9c7bSMasahiro Yamada } 6058fac9c7bSMasahiro Yamada $count++; 6068fac9c7bSMasahiro Yamada $parenth = ""; 6078fac9c7bSMasahiro Yamada } 6088fac9c7bSMasahiro Yamada 6098fac9c7bSMasahiro Yamada print ".SH ARGUMENTS\n"; 6108fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 6118fac9c7bSMasahiro Yamada my $parameter_name = $parameter; 6128fac9c7bSMasahiro Yamada $parameter_name =~ s/\[.*//; 6138fac9c7bSMasahiro Yamada 6148fac9c7bSMasahiro Yamada print ".IP \"" . $parameter . "\" 12\n"; 6158fac9c7bSMasahiro Yamada output_highlight($args{'parameterdescs'}{$parameter_name}); 6168fac9c7bSMasahiro Yamada } 6178fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 6188fac9c7bSMasahiro Yamada print ".SH \"", uc $section, "\"\n"; 6198fac9c7bSMasahiro Yamada output_highlight($args{'sections'}{$section}); 6208fac9c7bSMasahiro Yamada } 6218fac9c7bSMasahiro Yamada} 6228fac9c7bSMasahiro Yamada 6238fac9c7bSMasahiro Yamada## 6248fac9c7bSMasahiro Yamada# output enum in man 6258fac9c7bSMasahiro Yamadasub output_enum_man(%) { 6268fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 6278fac9c7bSMasahiro Yamada my ($parameter, $section); 6288fac9c7bSMasahiro Yamada my $count; 6298fac9c7bSMasahiro Yamada 630*78a88f79SMario Six print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; 6318fac9c7bSMasahiro Yamada 6328fac9c7bSMasahiro Yamada print ".SH NAME\n"; 6338fac9c7bSMasahiro Yamada print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n"; 6348fac9c7bSMasahiro Yamada 6358fac9c7bSMasahiro Yamada print ".SH SYNOPSIS\n"; 6368fac9c7bSMasahiro Yamada print "enum " . $args{'enum'} . " {\n"; 6378fac9c7bSMasahiro Yamada $count = 0; 6388fac9c7bSMasahiro Yamada foreach my $parameter (@{$args{'parameterlist'}}) { 6398fac9c7bSMasahiro Yamada print ".br\n.BI \" $parameter\"\n"; 6408fac9c7bSMasahiro Yamada if ($count == $#{$args{'parameterlist'}}) { 6418fac9c7bSMasahiro Yamada print "\n};\n"; 6428fac9c7bSMasahiro Yamada last; 6438fac9c7bSMasahiro Yamada } 6448fac9c7bSMasahiro Yamada else { 6458fac9c7bSMasahiro Yamada print ", \n.br\n"; 6468fac9c7bSMasahiro Yamada } 6478fac9c7bSMasahiro Yamada $count++; 6488fac9c7bSMasahiro Yamada } 6498fac9c7bSMasahiro Yamada 6508fac9c7bSMasahiro Yamada print ".SH Constants\n"; 6518fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 6528fac9c7bSMasahiro Yamada my $parameter_name = $parameter; 6538fac9c7bSMasahiro Yamada $parameter_name =~ s/\[.*//; 6548fac9c7bSMasahiro Yamada 6558fac9c7bSMasahiro Yamada print ".IP \"" . $parameter . "\" 12\n"; 6568fac9c7bSMasahiro Yamada output_highlight($args{'parameterdescs'}{$parameter_name}); 6578fac9c7bSMasahiro Yamada } 6588fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 6598fac9c7bSMasahiro Yamada print ".SH \"$section\"\n"; 6608fac9c7bSMasahiro Yamada output_highlight($args{'sections'}{$section}); 6618fac9c7bSMasahiro Yamada } 6628fac9c7bSMasahiro Yamada} 6638fac9c7bSMasahiro Yamada 6648fac9c7bSMasahiro Yamada## 6658fac9c7bSMasahiro Yamada# output struct in man 6668fac9c7bSMasahiro Yamadasub output_struct_man(%) { 6678fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 6688fac9c7bSMasahiro Yamada my ($parameter, $section); 6698fac9c7bSMasahiro Yamada 670*78a88f79SMario Six print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n"; 6718fac9c7bSMasahiro Yamada 6728fac9c7bSMasahiro Yamada print ".SH NAME\n"; 6738fac9c7bSMasahiro Yamada print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; 6748fac9c7bSMasahiro Yamada 675*78a88f79SMario Six my $declaration = $args{'definition'}; 676*78a88f79SMario Six $declaration =~ s/\t/ /g; 677*78a88f79SMario Six $declaration =~ s/\n/"\n.br\n.BI \"/g; 6788fac9c7bSMasahiro Yamada print ".SH SYNOPSIS\n"; 6798fac9c7bSMasahiro Yamada print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; 680*78a88f79SMario Six print ".BI \"$declaration\n};\n.br\n\n"; 6818fac9c7bSMasahiro Yamada 6828fac9c7bSMasahiro Yamada print ".SH Members\n"; 6838fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 6848fac9c7bSMasahiro Yamada ($parameter =~ /^#/) && next; 6858fac9c7bSMasahiro Yamada 6868fac9c7bSMasahiro Yamada my $parameter_name = $parameter; 6878fac9c7bSMasahiro Yamada $parameter_name =~ s/\[.*//; 6888fac9c7bSMasahiro Yamada 6898fac9c7bSMasahiro Yamada ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 6908fac9c7bSMasahiro Yamada print ".IP \"" . $parameter . "\" 12\n"; 6918fac9c7bSMasahiro Yamada output_highlight($args{'parameterdescs'}{$parameter_name}); 6928fac9c7bSMasahiro Yamada } 6938fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 6948fac9c7bSMasahiro Yamada print ".SH \"$section\"\n"; 6958fac9c7bSMasahiro Yamada output_highlight($args{'sections'}{$section}); 6968fac9c7bSMasahiro Yamada } 6978fac9c7bSMasahiro Yamada} 6988fac9c7bSMasahiro Yamada 6998fac9c7bSMasahiro Yamada## 7008fac9c7bSMasahiro Yamada# output typedef in man 7018fac9c7bSMasahiro Yamadasub output_typedef_man(%) { 7028fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 7038fac9c7bSMasahiro Yamada my ($parameter, $section); 7048fac9c7bSMasahiro Yamada 705*78a88f79SMario Six print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; 7068fac9c7bSMasahiro Yamada 7078fac9c7bSMasahiro Yamada print ".SH NAME\n"; 7088fac9c7bSMasahiro Yamada print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n"; 7098fac9c7bSMasahiro Yamada 7108fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 7118fac9c7bSMasahiro Yamada print ".SH \"$section\"\n"; 7128fac9c7bSMasahiro Yamada output_highlight($args{'sections'}{$section}); 7138fac9c7bSMasahiro Yamada } 7148fac9c7bSMasahiro Yamada} 7158fac9c7bSMasahiro Yamada 7168fac9c7bSMasahiro Yamadasub output_blockhead_man(%) { 7178fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 7188fac9c7bSMasahiro Yamada my ($parameter, $section); 7198fac9c7bSMasahiro Yamada my $count; 7208fac9c7bSMasahiro Yamada 721*78a88f79SMario Six print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; 7228fac9c7bSMasahiro Yamada 7238fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 7248fac9c7bSMasahiro Yamada print ".SH \"$section\"\n"; 7258fac9c7bSMasahiro Yamada output_highlight($args{'sections'}{$section}); 7268fac9c7bSMasahiro Yamada } 7278fac9c7bSMasahiro Yamada} 7288fac9c7bSMasahiro Yamada 7298fac9c7bSMasahiro Yamada## 730*78a88f79SMario Six# output in restructured text 731*78a88f79SMario Six# 732*78a88f79SMario Six 733*78a88f79SMario Six# 734*78a88f79SMario Six# This could use some work; it's used to output the DOC: sections, and 735*78a88f79SMario Six# starts by putting out the name of the doc section itself, but that tends 736*78a88f79SMario Six# to duplicate a header already in the template file. 737*78a88f79SMario Six# 738*78a88f79SMario Sixsub output_blockhead_rst(%) { 7398fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 7408fac9c7bSMasahiro Yamada my ($parameter, $section); 7418fac9c7bSMasahiro Yamada 742*78a88f79SMario Six foreach $section (@{$args{'sectionlist'}}) { 743*78a88f79SMario Six if ($output_selection != OUTPUT_INCLUDE) { 744*78a88f79SMario Six print "**$section**\n\n"; 745*78a88f79SMario Six } 746*78a88f79SMario Six print_lineno($section_start_lines{$section}); 747*78a88f79SMario Six output_highlight_rst($args{'sections'}{$section}); 748*78a88f79SMario Six print "\n"; 749*78a88f79SMario Six } 750*78a88f79SMario Six} 7518fac9c7bSMasahiro Yamada 752*78a88f79SMario Six# 753*78a88f79SMario Six# Apply the RST highlights to a sub-block of text. 754*78a88f79SMario Six# 755*78a88f79SMario Sixsub highlight_block($) { 756*78a88f79SMario Six # The dohighlight kludge requires the text be called $contents 757*78a88f79SMario Six my $contents = shift; 758*78a88f79SMario Six eval $dohighlight; 759*78a88f79SMario Six die $@ if $@; 760*78a88f79SMario Six return $contents; 761*78a88f79SMario Six} 762*78a88f79SMario Six 763*78a88f79SMario Six# 764*78a88f79SMario Six# Regexes used only here. 765*78a88f79SMario Six# 766*78a88f79SMario Sixmy $sphinx_literal = '^[^.].*::$'; 767*78a88f79SMario Sixmy $sphinx_cblock = '^\.\.\ +code-block::'; 768*78a88f79SMario Six 769*78a88f79SMario Sixsub output_highlight_rst { 770*78a88f79SMario Six my $input = join "\n",@_; 771*78a88f79SMario Six my $output = ""; 772*78a88f79SMario Six my $line; 773*78a88f79SMario Six my $in_literal = 0; 774*78a88f79SMario Six my $litprefix; 775*78a88f79SMario Six my $block = ""; 776*78a88f79SMario Six 777*78a88f79SMario Six foreach $line (split "\n",$input) { 778*78a88f79SMario Six # 779*78a88f79SMario Six # If we're in a literal block, see if we should drop out 780*78a88f79SMario Six # of it. Otherwise pass the line straight through unmunged. 781*78a88f79SMario Six # 782*78a88f79SMario Six if ($in_literal) { 783*78a88f79SMario Six if (! ($line =~ /^\s*$/)) { 784*78a88f79SMario Six # 785*78a88f79SMario Six # If this is the first non-blank line in a literal 786*78a88f79SMario Six # block we need to figure out what the proper indent is. 787*78a88f79SMario Six # 788*78a88f79SMario Six if ($litprefix eq "") { 789*78a88f79SMario Six $line =~ /^(\s*)/; 790*78a88f79SMario Six $litprefix = '^' . $1; 791*78a88f79SMario Six $output .= $line . "\n"; 792*78a88f79SMario Six } elsif (! ($line =~ /$litprefix/)) { 793*78a88f79SMario Six $in_literal = 0; 7948fac9c7bSMasahiro Yamada } else { 795*78a88f79SMario Six $output .= $line . "\n"; 796*78a88f79SMario Six } 797*78a88f79SMario Six } else { 798*78a88f79SMario Six $output .= $line . "\n"; 799*78a88f79SMario Six } 800*78a88f79SMario Six } 801*78a88f79SMario Six # 802*78a88f79SMario Six # Not in a literal block (or just dropped out) 803*78a88f79SMario Six # 804*78a88f79SMario Six if (! $in_literal) { 805*78a88f79SMario Six $block .= $line . "\n"; 806*78a88f79SMario Six if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { 807*78a88f79SMario Six $in_literal = 1; 808*78a88f79SMario Six $litprefix = ""; 809*78a88f79SMario Six $output .= highlight_block($block); 810*78a88f79SMario Six $block = "" 811*78a88f79SMario Six } 812*78a88f79SMario Six } 813*78a88f79SMario Six } 814*78a88f79SMario Six 815*78a88f79SMario Six if ($block) { 816*78a88f79SMario Six $output .= highlight_block($block); 817*78a88f79SMario Six } 818*78a88f79SMario Six foreach $line (split "\n", $output) { 819*78a88f79SMario Six print $lineprefix . $line . "\n"; 820*78a88f79SMario Six } 821*78a88f79SMario Six} 822*78a88f79SMario Six 823*78a88f79SMario Sixsub output_function_rst(%) { 824*78a88f79SMario Six my %args = %{$_[0]}; 825*78a88f79SMario Six my ($parameter, $section); 826*78a88f79SMario Six my $oldprefix = $lineprefix; 827*78a88f79SMario Six my $start = ""; 828*78a88f79SMario Six 829*78a88f79SMario Six if ($args{'typedef'}) { 830*78a88f79SMario Six print ".. c:type:: ". $args{'function'} . "\n\n"; 831*78a88f79SMario Six print_lineno($declaration_start_line); 832*78a88f79SMario Six print " **Typedef**: "; 833*78a88f79SMario Six $lineprefix = ""; 834*78a88f79SMario Six output_highlight_rst($args{'purpose'}); 835*78a88f79SMario Six $start = "\n\n**Syntax**\n\n ``"; 836*78a88f79SMario Six } else { 837*78a88f79SMario Six print ".. c:function:: "; 838*78a88f79SMario Six } 839*78a88f79SMario Six if ($args{'functiontype'} ne "") { 840*78a88f79SMario Six $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; 841*78a88f79SMario Six } else { 842*78a88f79SMario Six $start .= $args{'function'} . " ("; 8438fac9c7bSMasahiro Yamada } 8448fac9c7bSMasahiro Yamada print $start; 8458fac9c7bSMasahiro Yamada 8468fac9c7bSMasahiro Yamada my $count = 0; 8478fac9c7bSMasahiro Yamada foreach my $parameter (@{$args{'parameterlist'}}) { 848*78a88f79SMario Six if ($count ne 0) { 849*78a88f79SMario Six print ", "; 850*78a88f79SMario Six } 851*78a88f79SMario Six $count++; 8528fac9c7bSMasahiro Yamada $type = $args{'parametertypes'}{$parameter}; 853*78a88f79SMario Six 8548fac9c7bSMasahiro Yamada if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 8558fac9c7bSMasahiro Yamada # pointer-to-function 8568fac9c7bSMasahiro Yamada print $1 . $parameter . ") (" . $2; 8578fac9c7bSMasahiro Yamada } else { 8588fac9c7bSMasahiro Yamada print $type . " " . $parameter; 8598fac9c7bSMasahiro Yamada } 8608fac9c7bSMasahiro Yamada } 861*78a88f79SMario Six if ($args{'typedef'}) { 862*78a88f79SMario Six print ");``\n\n"; 863*78a88f79SMario Six } else { 864*78a88f79SMario Six print ")\n\n"; 865*78a88f79SMario Six print_lineno($declaration_start_line); 866*78a88f79SMario Six $lineprefix = " "; 867*78a88f79SMario Six output_highlight_rst($args{'purpose'}); 868*78a88f79SMario Six print "\n"; 8698fac9c7bSMasahiro Yamada } 8708fac9c7bSMasahiro Yamada 871*78a88f79SMario Six print "**Parameters**\n\n"; 872*78a88f79SMario Six $lineprefix = " "; 8738fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 8748fac9c7bSMasahiro Yamada my $parameter_name = $parameter; 8758fac9c7bSMasahiro Yamada $parameter_name =~ s/\[.*//; 876*78a88f79SMario Six $type = $args{'parametertypes'}{$parameter}; 8778fac9c7bSMasahiro Yamada 878*78a88f79SMario Six if ($type ne "") { 879*78a88f79SMario Six print "``$type $parameter``\n"; 880*78a88f79SMario Six } else { 881*78a88f79SMario Six print "``$parameter``\n"; 8828fac9c7bSMasahiro Yamada } 8838fac9c7bSMasahiro Yamada 884*78a88f79SMario Six print_lineno($parameterdesc_start_lines{$parameter_name}); 885*78a88f79SMario Six 886*78a88f79SMario Six if (defined($args{'parameterdescs'}{$parameter_name}) && 887*78a88f79SMario Six $args{'parameterdescs'}{$parameter_name} ne $undescribed) { 888*78a88f79SMario Six output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 889*78a88f79SMario Six } else { 890*78a88f79SMario Six print " *undescribed*\n"; 891*78a88f79SMario Six } 892*78a88f79SMario Six print "\n"; 893*78a88f79SMario Six } 894*78a88f79SMario Six 895*78a88f79SMario Six $lineprefix = $oldprefix; 896*78a88f79SMario Six output_section_rst(@_); 897*78a88f79SMario Six} 898*78a88f79SMario Six 899*78a88f79SMario Sixsub output_section_rst(%) { 9008fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 9018fac9c7bSMasahiro Yamada my $section; 902*78a88f79SMario Six my $oldprefix = $lineprefix; 903*78a88f79SMario Six $lineprefix = ""; 9048fac9c7bSMasahiro Yamada 9058fac9c7bSMasahiro Yamada foreach $section (@{$args{'sectionlist'}}) { 906*78a88f79SMario Six print "**$section**\n\n"; 907*78a88f79SMario Six print_lineno($section_start_lines{$section}); 908*78a88f79SMario Six output_highlight_rst($args{'sections'}{$section}); 909*78a88f79SMario Six print "\n"; 9108fac9c7bSMasahiro Yamada } 911*78a88f79SMario Six print "\n"; 912*78a88f79SMario Six $lineprefix = $oldprefix; 9138fac9c7bSMasahiro Yamada} 9148fac9c7bSMasahiro Yamada 915*78a88f79SMario Sixsub output_enum_rst(%) { 9168fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 9178fac9c7bSMasahiro Yamada my ($parameter); 918*78a88f79SMario Six my $oldprefix = $lineprefix; 9198fac9c7bSMasahiro Yamada my $count; 920*78a88f79SMario Six my $name = "enum " . $args{'enum'}; 9218fac9c7bSMasahiro Yamada 922*78a88f79SMario Six print "\n\n.. c:type:: " . $name . "\n\n"; 923*78a88f79SMario Six print_lineno($declaration_start_line); 924*78a88f79SMario Six $lineprefix = " "; 925*78a88f79SMario Six output_highlight_rst($args{'purpose'}); 926*78a88f79SMario Six print "\n"; 927*78a88f79SMario Six 928*78a88f79SMario Six print "**Constants**\n\n"; 929*78a88f79SMario Six $lineprefix = " "; 9308fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 931*78a88f79SMario Six print "``$parameter``\n"; 932*78a88f79SMario Six if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 933*78a88f79SMario Six output_highlight_rst($args{'parameterdescs'}{$parameter}); 934*78a88f79SMario Six } else { 935*78a88f79SMario Six print " *undescribed*\n"; 9368fac9c7bSMasahiro Yamada } 9378fac9c7bSMasahiro Yamada print "\n"; 9388fac9c7bSMasahiro Yamada } 9398fac9c7bSMasahiro Yamada 940*78a88f79SMario Six $lineprefix = $oldprefix; 941*78a88f79SMario Six output_section_rst(@_); 9428fac9c7bSMasahiro Yamada} 9438fac9c7bSMasahiro Yamada 944*78a88f79SMario Sixsub output_typedef_rst(%) { 9458fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 9468fac9c7bSMasahiro Yamada my ($parameter); 947*78a88f79SMario Six my $oldprefix = $lineprefix; 948*78a88f79SMario Six my $name = "typedef " . $args{'typedef'}; 9498fac9c7bSMasahiro Yamada 950*78a88f79SMario Six print "\n\n.. c:type:: " . $name . "\n\n"; 951*78a88f79SMario Six print_lineno($declaration_start_line); 952*78a88f79SMario Six $lineprefix = " "; 953*78a88f79SMario Six output_highlight_rst($args{'purpose'}); 954*78a88f79SMario Six print "\n"; 955*78a88f79SMario Six 956*78a88f79SMario Six $lineprefix = $oldprefix; 957*78a88f79SMario Six output_section_rst(@_); 9588fac9c7bSMasahiro Yamada} 9598fac9c7bSMasahiro Yamada 960*78a88f79SMario Sixsub output_struct_rst(%) { 9618fac9c7bSMasahiro Yamada my %args = %{$_[0]}; 9628fac9c7bSMasahiro Yamada my ($parameter); 963*78a88f79SMario Six my $oldprefix = $lineprefix; 964*78a88f79SMario Six my $name = $args{'type'} . " " . $args{'struct'}; 9658fac9c7bSMasahiro Yamada 966*78a88f79SMario Six print "\n\n.. c:type:: " . $name . "\n\n"; 967*78a88f79SMario Six print_lineno($declaration_start_line); 968*78a88f79SMario Six $lineprefix = " "; 969*78a88f79SMario Six output_highlight_rst($args{'purpose'}); 970*78a88f79SMario Six print "\n"; 9718fac9c7bSMasahiro Yamada 972*78a88f79SMario Six print "**Definition**\n\n"; 973*78a88f79SMario Six print "::\n\n"; 974*78a88f79SMario Six my $declaration = $args{'definition'}; 975*78a88f79SMario Six $declaration =~ s/\t/ /g; 976*78a88f79SMario Six print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; 9778fac9c7bSMasahiro Yamada 978*78a88f79SMario Six print "**Members**\n\n"; 979*78a88f79SMario Six $lineprefix = " "; 9808fac9c7bSMasahiro Yamada foreach $parameter (@{$args{'parameterlist'}}) { 9818fac9c7bSMasahiro Yamada ($parameter =~ /^#/) && next; 9828fac9c7bSMasahiro Yamada 9838fac9c7bSMasahiro Yamada my $parameter_name = $parameter; 9848fac9c7bSMasahiro Yamada $parameter_name =~ s/\[.*//; 9858fac9c7bSMasahiro Yamada 9868fac9c7bSMasahiro Yamada ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 987*78a88f79SMario Six $type = $args{'parametertypes'}{$parameter}; 988*78a88f79SMario Six print_lineno($parameterdesc_start_lines{$parameter_name}); 989*78a88f79SMario Six print "``" . $parameter . "``\n"; 990*78a88f79SMario Six output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 991*78a88f79SMario Six print "\n"; 9928fac9c7bSMasahiro Yamada } 9938fac9c7bSMasahiro Yamada print "\n"; 994*78a88f79SMario Six 995*78a88f79SMario Six $lineprefix = $oldprefix; 996*78a88f79SMario Six output_section_rst(@_); 9978fac9c7bSMasahiro Yamada} 9988fac9c7bSMasahiro Yamada 999*78a88f79SMario Six## none mode output functions 10008fac9c7bSMasahiro Yamada 1001*78a88f79SMario Sixsub output_function_none(%) { 10028fac9c7bSMasahiro Yamada} 10038fac9c7bSMasahiro Yamada 1004*78a88f79SMario Sixsub output_enum_none(%) { 10058fac9c7bSMasahiro Yamada} 10068fac9c7bSMasahiro Yamada 1007*78a88f79SMario Sixsub output_typedef_none(%) { 10088fac9c7bSMasahiro Yamada} 10098fac9c7bSMasahiro Yamada 1010*78a88f79SMario Sixsub output_struct_none(%) { 10118fac9c7bSMasahiro Yamada} 10128fac9c7bSMasahiro Yamada 1013*78a88f79SMario Sixsub output_blockhead_none(%) { 10148fac9c7bSMasahiro Yamada} 10158fac9c7bSMasahiro Yamada 10168fac9c7bSMasahiro Yamada## 10178fac9c7bSMasahiro Yamada# generic output function for all types (function, struct/union, typedef, enum); 10188fac9c7bSMasahiro Yamada# calls the generated, variable output_ function name based on 10198fac9c7bSMasahiro Yamada# functype and output_mode 10208fac9c7bSMasahiro Yamadasub output_declaration { 10218fac9c7bSMasahiro Yamada no strict 'refs'; 10228fac9c7bSMasahiro Yamada my $name = shift; 10238fac9c7bSMasahiro Yamada my $functype = shift; 10248fac9c7bSMasahiro Yamada my $func = "output_${functype}_$output_mode"; 1025*78a88f79SMario Six if (($output_selection == OUTPUT_ALL) || 1026*78a88f79SMario Six (($output_selection == OUTPUT_INCLUDE || 1027*78a88f79SMario Six $output_selection == OUTPUT_EXPORTED) && 1028*78a88f79SMario Six defined($function_table{$name})) || 1029*78a88f79SMario Six (($output_selection == OUTPUT_EXCLUDE || 1030*78a88f79SMario Six $output_selection == OUTPUT_INTERNAL) && 1031*78a88f79SMario Six !($functype eq "function" && defined($function_table{$name})))) 10328fac9c7bSMasahiro Yamada { 10338fac9c7bSMasahiro Yamada &$func(@_); 10348fac9c7bSMasahiro Yamada $section_counter++; 10358fac9c7bSMasahiro Yamada } 10368fac9c7bSMasahiro Yamada} 10378fac9c7bSMasahiro Yamada 10388fac9c7bSMasahiro Yamada## 10398fac9c7bSMasahiro Yamada# generic output function - calls the right one based on current output mode. 10408fac9c7bSMasahiro Yamadasub output_blockhead { 10418fac9c7bSMasahiro Yamada no strict 'refs'; 10428fac9c7bSMasahiro Yamada my $func = "output_blockhead_" . $output_mode; 10438fac9c7bSMasahiro Yamada &$func(@_); 10448fac9c7bSMasahiro Yamada $section_counter++; 10458fac9c7bSMasahiro Yamada} 10468fac9c7bSMasahiro Yamada 10478fac9c7bSMasahiro Yamada## 10488fac9c7bSMasahiro Yamada# takes a declaration (struct, union, enum, typedef) and 10498fac9c7bSMasahiro Yamada# invokes the right handler. NOT called for functions. 10508fac9c7bSMasahiro Yamadasub dump_declaration($$) { 10518fac9c7bSMasahiro Yamada no strict 'refs'; 10528fac9c7bSMasahiro Yamada my ($prototype, $file) = @_; 10538fac9c7bSMasahiro Yamada my $func = "dump_" . $decl_type; 10548fac9c7bSMasahiro Yamada &$func(@_); 10558fac9c7bSMasahiro Yamada} 10568fac9c7bSMasahiro Yamada 10578fac9c7bSMasahiro Yamadasub dump_union($$) { 10588fac9c7bSMasahiro Yamada dump_struct(@_); 10598fac9c7bSMasahiro Yamada} 10608fac9c7bSMasahiro Yamada 10618fac9c7bSMasahiro Yamadasub dump_struct($$) { 10628fac9c7bSMasahiro Yamada my $x = shift; 10638fac9c7bSMasahiro Yamada my $file = shift; 10648fac9c7bSMasahiro Yamada 10658fac9c7bSMasahiro Yamada if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { 1066*78a88f79SMario Six my $decl_type = $1; 10678fac9c7bSMasahiro Yamada $declaration_name = $2; 10688fac9c7bSMasahiro Yamada my $members = $3; 10698fac9c7bSMasahiro Yamada 10708fac9c7bSMasahiro Yamada # ignore members marked private: 1071*78a88f79SMario Six $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; 1072*78a88f79SMario Six $members =~ s/\/\*\s*private:.*//gosi; 10738fac9c7bSMasahiro Yamada # strip comments: 10748fac9c7bSMasahiro Yamada $members =~ s/\/\*.*?\*\///gos; 10758fac9c7bSMasahiro Yamada # strip attributes 1076*78a88f79SMario Six $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; 1077*78a88f79SMario Six $members =~ s/__aligned\s*\([^;]*\)//gos; 1078*78a88f79SMario Six $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; 1079*78a88f79SMario Six # replace DECLARE_BITMAP 1080*78a88f79SMario Six $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; 1081*78a88f79SMario Six # replace DECLARE_HASHTABLE 1082*78a88f79SMario Six $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; 1083*78a88f79SMario Six # replace DECLARE_KFIFO 1084*78a88f79SMario Six $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; 1085*78a88f79SMario Six # replace DECLARE_KFIFO_PTR 1086*78a88f79SMario Six $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; 10878fac9c7bSMasahiro Yamada 1088*78a88f79SMario Six my $declaration = $members; 10898fac9c7bSMasahiro Yamada 1090*78a88f79SMario Six # Split nested struct/union elements as newer ones 1091*78a88f79SMario Six while ($members =~ m/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/) { 1092*78a88f79SMario Six my $newmember; 1093*78a88f79SMario Six my $maintype = $1; 1094*78a88f79SMario Six my $ids = $4; 1095*78a88f79SMario Six my $content = $3; 1096*78a88f79SMario Six foreach my $id(split /,/, $ids) { 1097*78a88f79SMario Six $newmember .= "$maintype $id; "; 1098*78a88f79SMario Six 1099*78a88f79SMario Six $id =~ s/[:\[].*//; 1100*78a88f79SMario Six $id =~ s/^\s*\**(\S+)\s*/$1/; 1101*78a88f79SMario Six foreach my $arg (split /;/, $content) { 1102*78a88f79SMario Six next if ($arg =~ m/^\s*$/); 1103*78a88f79SMario Six if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { 1104*78a88f79SMario Six # pointer-to-function 1105*78a88f79SMario Six my $type = $1; 1106*78a88f79SMario Six my $name = $2; 1107*78a88f79SMario Six my $extra = $3; 1108*78a88f79SMario Six next if (!$name); 1109*78a88f79SMario Six if ($id =~ m/^\s*$/) { 1110*78a88f79SMario Six # anonymous struct/union 1111*78a88f79SMario Six $newmember .= "$type$name$extra; "; 1112*78a88f79SMario Six } else { 1113*78a88f79SMario Six $newmember .= "$type$id.$name$extra; "; 1114*78a88f79SMario Six } 1115*78a88f79SMario Six } else { 1116*78a88f79SMario Six my $type; 1117*78a88f79SMario Six my $names; 1118*78a88f79SMario Six $arg =~ s/^\s+//; 1119*78a88f79SMario Six $arg =~ s/\s+$//; 1120*78a88f79SMario Six # Handle bitmaps 1121*78a88f79SMario Six $arg =~ s/:\s*\d+\s*//g; 1122*78a88f79SMario Six # Handle arrays 1123*78a88f79SMario Six $arg =~ s/\[.*\]//g; 1124*78a88f79SMario Six # The type may have multiple words, 1125*78a88f79SMario Six # and multiple IDs can be defined, like: 1126*78a88f79SMario Six # const struct foo, *bar, foobar 1127*78a88f79SMario Six # So, we remove spaces when parsing the 1128*78a88f79SMario Six # names, in order to match just names 1129*78a88f79SMario Six # and commas for the names 1130*78a88f79SMario Six $arg =~ s/\s*,\s*/,/g; 1131*78a88f79SMario Six if ($arg =~ m/(.*)\s+([\S+,]+)/) { 1132*78a88f79SMario Six $type = $1; 1133*78a88f79SMario Six $names = $2; 1134*78a88f79SMario Six } else { 1135*78a88f79SMario Six $newmember .= "$arg; "; 1136*78a88f79SMario Six next; 1137*78a88f79SMario Six } 1138*78a88f79SMario Six foreach my $name (split /,/, $names) { 1139*78a88f79SMario Six $name =~ s/^\s*\**(\S+)\s*/$1/; 1140*78a88f79SMario Six next if (($name =~ m/^\s*$/)); 1141*78a88f79SMario Six if ($id =~ m/^\s*$/) { 1142*78a88f79SMario Six # anonymous struct/union 1143*78a88f79SMario Six $newmember .= "$type $name; "; 1144*78a88f79SMario Six } else { 1145*78a88f79SMario Six $newmember .= "$type $id.$name; "; 1146*78a88f79SMario Six } 1147*78a88f79SMario Six } 1148*78a88f79SMario Six } 1149*78a88f79SMario Six } 1150*78a88f79SMario Six } 1151*78a88f79SMario Six $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)}([^\{\}\;]*)\;/$newmember/; 1152*78a88f79SMario Six } 1153*78a88f79SMario Six 1154*78a88f79SMario Six # Ignore other nested elements, like enums 1155*78a88f79SMario Six $members =~ s/({[^\{\}]*})//g; 1156*78a88f79SMario Six 1157*78a88f79SMario Six create_parameterlist($members, ';', $file, $declaration_name); 1158*78a88f79SMario Six check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); 1159*78a88f79SMario Six 1160*78a88f79SMario Six # Adjust declaration for better display 1161*78a88f79SMario Six $declaration =~ s/([{;])/$1\n/g; 1162*78a88f79SMario Six $declaration =~ s/}\s+;/};/g; 1163*78a88f79SMario Six # Better handle inlined enums 1164*78a88f79SMario Six do {} while ($declaration =~ s/(enum\s+{[^}]+),([^\n])/$1,\n$2/); 1165*78a88f79SMario Six 1166*78a88f79SMario Six my @def_args = split /\n/, $declaration; 1167*78a88f79SMario Six my $level = 1; 1168*78a88f79SMario Six $declaration = ""; 1169*78a88f79SMario Six foreach my $clause (@def_args) { 1170*78a88f79SMario Six $clause =~ s/^\s+//; 1171*78a88f79SMario Six $clause =~ s/\s+$//; 1172*78a88f79SMario Six $clause =~ s/\s+/ /; 1173*78a88f79SMario Six next if (!$clause); 1174*78a88f79SMario Six $level-- if ($clause =~ m/(})/ && $level > 1); 1175*78a88f79SMario Six if (!($clause =~ m/^\s*#/)) { 1176*78a88f79SMario Six $declaration .= "\t" x $level; 1177*78a88f79SMario Six } 1178*78a88f79SMario Six $declaration .= "\t" . $clause . "\n"; 1179*78a88f79SMario Six $level++ if ($clause =~ m/({)/ && !($clause =~m/}/)); 1180*78a88f79SMario Six } 11818fac9c7bSMasahiro Yamada output_declaration($declaration_name, 11828fac9c7bSMasahiro Yamada 'struct', 11838fac9c7bSMasahiro Yamada {'struct' => $declaration_name, 11848fac9c7bSMasahiro Yamada 'module' => $modulename, 1185*78a88f79SMario Six 'definition' => $declaration, 11868fac9c7bSMasahiro Yamada 'parameterlist' => \@parameterlist, 11878fac9c7bSMasahiro Yamada 'parameterdescs' => \%parameterdescs, 11888fac9c7bSMasahiro Yamada 'parametertypes' => \%parametertypes, 11898fac9c7bSMasahiro Yamada 'sectionlist' => \@sectionlist, 11908fac9c7bSMasahiro Yamada 'sections' => \%sections, 11918fac9c7bSMasahiro Yamada 'purpose' => $declaration_purpose, 11928fac9c7bSMasahiro Yamada 'type' => $decl_type 11938fac9c7bSMasahiro Yamada }); 11948fac9c7bSMasahiro Yamada } 11958fac9c7bSMasahiro Yamada else { 1196*78a88f79SMario Six print STDERR "${file}:$.: error: Cannot parse struct or union!\n"; 11978fac9c7bSMasahiro Yamada ++$errors; 11988fac9c7bSMasahiro Yamada } 11998fac9c7bSMasahiro Yamada} 12008fac9c7bSMasahiro Yamada 1201*78a88f79SMario Six 1202*78a88f79SMario Sixsub show_warnings($$) { 1203*78a88f79SMario Six my $functype = shift; 1204*78a88f79SMario Six my $name = shift; 1205*78a88f79SMario Six 1206*78a88f79SMario Six return 1 if ($output_selection == OUTPUT_ALL); 1207*78a88f79SMario Six 1208*78a88f79SMario Six if ($output_selection == OUTPUT_EXPORTED) { 1209*78a88f79SMario Six if (defined($function_table{$name})) { 1210*78a88f79SMario Six return 1; 1211*78a88f79SMario Six } else { 1212*78a88f79SMario Six return 0; 1213*78a88f79SMario Six } 1214*78a88f79SMario Six } 1215*78a88f79SMario Six if ($output_selection == OUTPUT_INTERNAL) { 1216*78a88f79SMario Six if (!($functype eq "function" && defined($function_table{$name}))) { 1217*78a88f79SMario Six return 1; 1218*78a88f79SMario Six } else { 1219*78a88f79SMario Six return 0; 1220*78a88f79SMario Six } 1221*78a88f79SMario Six } 1222*78a88f79SMario Six if ($output_selection == OUTPUT_INCLUDE) { 1223*78a88f79SMario Six if (defined($function_table{$name})) { 1224*78a88f79SMario Six return 1; 1225*78a88f79SMario Six } else { 1226*78a88f79SMario Six return 0; 1227*78a88f79SMario Six } 1228*78a88f79SMario Six } 1229*78a88f79SMario Six if ($output_selection == OUTPUT_EXCLUDE) { 1230*78a88f79SMario Six if (!defined($function_table{$name})) { 1231*78a88f79SMario Six return 1; 1232*78a88f79SMario Six } else { 1233*78a88f79SMario Six return 0; 1234*78a88f79SMario Six } 1235*78a88f79SMario Six } 1236*78a88f79SMario Six die("Please add the new output type at show_warnings()"); 1237*78a88f79SMario Six} 1238*78a88f79SMario Six 12398fac9c7bSMasahiro Yamadasub dump_enum($$) { 12408fac9c7bSMasahiro Yamada my $x = shift; 12418fac9c7bSMasahiro Yamada my $file = shift; 12428fac9c7bSMasahiro Yamada 12438fac9c7bSMasahiro Yamada $x =~ s@/\*.*?\*/@@gos; # strip comments. 1244*78a88f79SMario Six # strip #define macros inside enums 1245*78a88f79SMario Six $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; 12468fac9c7bSMasahiro Yamada 12478fac9c7bSMasahiro Yamada if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 12488fac9c7bSMasahiro Yamada $declaration_name = $1; 12498fac9c7bSMasahiro Yamada my $members = $2; 1250*78a88f79SMario Six my %_members; 1251*78a88f79SMario Six 1252*78a88f79SMario Six $members =~ s/\s+$//; 12538fac9c7bSMasahiro Yamada 12548fac9c7bSMasahiro Yamada foreach my $arg (split ',', $members) { 12558fac9c7bSMasahiro Yamada $arg =~ s/^\s*(\w+).*/$1/; 12568fac9c7bSMasahiro Yamada push @parameterlist, $arg; 12578fac9c7bSMasahiro Yamada if (!$parameterdescs{$arg}) { 12588fac9c7bSMasahiro Yamada $parameterdescs{$arg} = $undescribed; 1259*78a88f79SMario Six if (show_warnings("enum", $declaration_name)) { 1260*78a88f79SMario Six print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; 1261*78a88f79SMario Six } 1262*78a88f79SMario Six } 1263*78a88f79SMario Six $_members{$arg} = 1; 12648fac9c7bSMasahiro Yamada } 12658fac9c7bSMasahiro Yamada 1266*78a88f79SMario Six while (my ($k, $v) = each %parameterdescs) { 1267*78a88f79SMario Six if (!exists($_members{$k})) { 1268*78a88f79SMario Six if (show_warnings("enum", $declaration_name)) { 1269*78a88f79SMario Six print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; 1270*78a88f79SMario Six } 1271*78a88f79SMario Six } 12728fac9c7bSMasahiro Yamada } 12738fac9c7bSMasahiro Yamada 12748fac9c7bSMasahiro Yamada output_declaration($declaration_name, 12758fac9c7bSMasahiro Yamada 'enum', 12768fac9c7bSMasahiro Yamada {'enum' => $declaration_name, 12778fac9c7bSMasahiro Yamada 'module' => $modulename, 12788fac9c7bSMasahiro Yamada 'parameterlist' => \@parameterlist, 12798fac9c7bSMasahiro Yamada 'parameterdescs' => \%parameterdescs, 12808fac9c7bSMasahiro Yamada 'sectionlist' => \@sectionlist, 12818fac9c7bSMasahiro Yamada 'sections' => \%sections, 12828fac9c7bSMasahiro Yamada 'purpose' => $declaration_purpose 12838fac9c7bSMasahiro Yamada }); 12848fac9c7bSMasahiro Yamada } 12858fac9c7bSMasahiro Yamada else { 1286*78a88f79SMario Six print STDERR "${file}:$.: error: Cannot parse enum!\n"; 12878fac9c7bSMasahiro Yamada ++$errors; 12888fac9c7bSMasahiro Yamada } 12898fac9c7bSMasahiro Yamada} 12908fac9c7bSMasahiro Yamada 12918fac9c7bSMasahiro Yamadasub dump_typedef($$) { 12928fac9c7bSMasahiro Yamada my $x = shift; 12938fac9c7bSMasahiro Yamada my $file = shift; 12948fac9c7bSMasahiro Yamada 12958fac9c7bSMasahiro Yamada $x =~ s@/\*.*?\*/@@gos; # strip comments. 1296*78a88f79SMario Six 1297*78a88f79SMario Six # Parse function prototypes 1298*78a88f79SMario Six if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ || 1299*78a88f79SMario Six $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) { 1300*78a88f79SMario Six 1301*78a88f79SMario Six # Function typedefs 1302*78a88f79SMario Six $return_type = $1; 1303*78a88f79SMario Six $declaration_name = $2; 1304*78a88f79SMario Six my $args = $3; 1305*78a88f79SMario Six 1306*78a88f79SMario Six create_parameterlist($args, ',', $file, $declaration_name); 1307*78a88f79SMario Six 1308*78a88f79SMario Six output_declaration($declaration_name, 1309*78a88f79SMario Six 'function', 1310*78a88f79SMario Six {'function' => $declaration_name, 1311*78a88f79SMario Six 'typedef' => 1, 1312*78a88f79SMario Six 'module' => $modulename, 1313*78a88f79SMario Six 'functiontype' => $return_type, 1314*78a88f79SMario Six 'parameterlist' => \@parameterlist, 1315*78a88f79SMario Six 'parameterdescs' => \%parameterdescs, 1316*78a88f79SMario Six 'parametertypes' => \%parametertypes, 1317*78a88f79SMario Six 'sectionlist' => \@sectionlist, 1318*78a88f79SMario Six 'sections' => \%sections, 1319*78a88f79SMario Six 'purpose' => $declaration_purpose 1320*78a88f79SMario Six }); 1321*78a88f79SMario Six return; 1322*78a88f79SMario Six } 1323*78a88f79SMario Six 13248fac9c7bSMasahiro Yamada while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { 13258fac9c7bSMasahiro Yamada $x =~ s/\(*.\)\s*;$/;/; 13268fac9c7bSMasahiro Yamada $x =~ s/\[*.\]\s*;$/;/; 13278fac9c7bSMasahiro Yamada } 13288fac9c7bSMasahiro Yamada 13298fac9c7bSMasahiro Yamada if ($x =~ /typedef.*\s+(\w+)\s*;/) { 13308fac9c7bSMasahiro Yamada $declaration_name = $1; 13318fac9c7bSMasahiro Yamada 13328fac9c7bSMasahiro Yamada output_declaration($declaration_name, 13338fac9c7bSMasahiro Yamada 'typedef', 13348fac9c7bSMasahiro Yamada {'typedef' => $declaration_name, 13358fac9c7bSMasahiro Yamada 'module' => $modulename, 13368fac9c7bSMasahiro Yamada 'sectionlist' => \@sectionlist, 13378fac9c7bSMasahiro Yamada 'sections' => \%sections, 13388fac9c7bSMasahiro Yamada 'purpose' => $declaration_purpose 13398fac9c7bSMasahiro Yamada }); 13408fac9c7bSMasahiro Yamada } 13418fac9c7bSMasahiro Yamada else { 1342*78a88f79SMario Six print STDERR "${file}:$.: error: Cannot parse typedef!\n"; 13438fac9c7bSMasahiro Yamada ++$errors; 13448fac9c7bSMasahiro Yamada } 13458fac9c7bSMasahiro Yamada} 13468fac9c7bSMasahiro Yamada 13478fac9c7bSMasahiro Yamadasub save_struct_actual($) { 13488fac9c7bSMasahiro Yamada my $actual = shift; 13498fac9c7bSMasahiro Yamada 13508fac9c7bSMasahiro Yamada # strip all spaces from the actual param so that it looks like one string item 13518fac9c7bSMasahiro Yamada $actual =~ s/\s*//g; 13528fac9c7bSMasahiro Yamada $struct_actual = $struct_actual . $actual . " "; 13538fac9c7bSMasahiro Yamada} 13548fac9c7bSMasahiro Yamada 1355*78a88f79SMario Sixsub create_parameterlist($$$$) { 13568fac9c7bSMasahiro Yamada my $args = shift; 13578fac9c7bSMasahiro Yamada my $splitter = shift; 13588fac9c7bSMasahiro Yamada my $file = shift; 1359*78a88f79SMario Six my $declaration_name = shift; 13608fac9c7bSMasahiro Yamada my $type; 13618fac9c7bSMasahiro Yamada my $param; 13628fac9c7bSMasahiro Yamada 13638fac9c7bSMasahiro Yamada # temporarily replace commas inside function pointer definition 13648fac9c7bSMasahiro Yamada while ($args =~ /(\([^\),]+),/) { 13658fac9c7bSMasahiro Yamada $args =~ s/(\([^\),]+),/$1#/g; 13668fac9c7bSMasahiro Yamada } 13678fac9c7bSMasahiro Yamada 13688fac9c7bSMasahiro Yamada foreach my $arg (split($splitter, $args)) { 13698fac9c7bSMasahiro Yamada # strip comments 13708fac9c7bSMasahiro Yamada $arg =~ s/\/\*.*\*\///; 13718fac9c7bSMasahiro Yamada # strip leading/trailing spaces 13728fac9c7bSMasahiro Yamada $arg =~ s/^\s*//; 13738fac9c7bSMasahiro Yamada $arg =~ s/\s*$//; 13748fac9c7bSMasahiro Yamada $arg =~ s/\s+/ /; 13758fac9c7bSMasahiro Yamada 13768fac9c7bSMasahiro Yamada if ($arg =~ /^#/) { 13778fac9c7bSMasahiro Yamada # Treat preprocessor directive as a typeless variable just to fill 13788fac9c7bSMasahiro Yamada # corresponding data structures "correctly". Catch it later in 13798fac9c7bSMasahiro Yamada # output_* subs. 13808fac9c7bSMasahiro Yamada push_parameter($arg, "", $file); 13818fac9c7bSMasahiro Yamada } elsif ($arg =~ m/\(.+\)\s*\(/) { 13828fac9c7bSMasahiro Yamada # pointer-to-function 13838fac9c7bSMasahiro Yamada $arg =~ tr/#/,/; 1384*78a88f79SMario Six $arg =~ m/[^\(]+\(\*?\s*([\w\.]*)\s*\)/; 13858fac9c7bSMasahiro Yamada $param = $1; 13868fac9c7bSMasahiro Yamada $type = $arg; 13878fac9c7bSMasahiro Yamada $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 13888fac9c7bSMasahiro Yamada save_struct_actual($param); 1389*78a88f79SMario Six push_parameter($param, $type, $file, $declaration_name); 13908fac9c7bSMasahiro Yamada } elsif ($arg) { 13918fac9c7bSMasahiro Yamada $arg =~ s/\s*:\s*/:/g; 13928fac9c7bSMasahiro Yamada $arg =~ s/\s*\[/\[/g; 13938fac9c7bSMasahiro Yamada 13948fac9c7bSMasahiro Yamada my @args = split('\s*,\s*', $arg); 13958fac9c7bSMasahiro Yamada if ($args[0] =~ m/\*/) { 13968fac9c7bSMasahiro Yamada $args[0] =~ s/(\*+)\s*/ $1/; 13978fac9c7bSMasahiro Yamada } 13988fac9c7bSMasahiro Yamada 13998fac9c7bSMasahiro Yamada my @first_arg; 14008fac9c7bSMasahiro Yamada if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { 14018fac9c7bSMasahiro Yamada shift @args; 14028fac9c7bSMasahiro Yamada push(@first_arg, split('\s+', $1)); 14038fac9c7bSMasahiro Yamada push(@first_arg, $2); 14048fac9c7bSMasahiro Yamada } else { 14058fac9c7bSMasahiro Yamada @first_arg = split('\s+', shift @args); 14068fac9c7bSMasahiro Yamada } 14078fac9c7bSMasahiro Yamada 14088fac9c7bSMasahiro Yamada unshift(@args, pop @first_arg); 14098fac9c7bSMasahiro Yamada $type = join " ", @first_arg; 14108fac9c7bSMasahiro Yamada 14118fac9c7bSMasahiro Yamada foreach $param (@args) { 14128fac9c7bSMasahiro Yamada if ($param =~ m/^(\*+)\s*(.*)/) { 14138fac9c7bSMasahiro Yamada save_struct_actual($2); 1414*78a88f79SMario Six push_parameter($2, "$type $1", $file, $declaration_name); 14158fac9c7bSMasahiro Yamada } 14168fac9c7bSMasahiro Yamada elsif ($param =~ m/(.*?):(\d+)/) { 14178fac9c7bSMasahiro Yamada if ($type ne "") { # skip unnamed bit-fields 14188fac9c7bSMasahiro Yamada save_struct_actual($1); 1419*78a88f79SMario Six push_parameter($1, "$type:$2", $file, $declaration_name) 14208fac9c7bSMasahiro Yamada } 14218fac9c7bSMasahiro Yamada } 14228fac9c7bSMasahiro Yamada else { 14238fac9c7bSMasahiro Yamada save_struct_actual($param); 1424*78a88f79SMario Six push_parameter($param, $type, $file, $declaration_name); 14258fac9c7bSMasahiro Yamada } 14268fac9c7bSMasahiro Yamada } 14278fac9c7bSMasahiro Yamada } 14288fac9c7bSMasahiro Yamada } 14298fac9c7bSMasahiro Yamada} 14308fac9c7bSMasahiro Yamada 1431*78a88f79SMario Sixsub push_parameter($$$$) { 14328fac9c7bSMasahiro Yamada my $param = shift; 14338fac9c7bSMasahiro Yamada my $type = shift; 14348fac9c7bSMasahiro Yamada my $file = shift; 1435*78a88f79SMario Six my $declaration_name = shift; 14368fac9c7bSMasahiro Yamada 14378fac9c7bSMasahiro Yamada if (($anon_struct_union == 1) && ($type eq "") && 14388fac9c7bSMasahiro Yamada ($param eq "}")) { 14398fac9c7bSMasahiro Yamada return; # ignore the ending }; from anon. struct/union 14408fac9c7bSMasahiro Yamada } 14418fac9c7bSMasahiro Yamada 14428fac9c7bSMasahiro Yamada $anon_struct_union = 0; 1443*78a88f79SMario Six $param =~ s/[\[\)].*//; 14448fac9c7bSMasahiro Yamada 14458fac9c7bSMasahiro Yamada if ($type eq "" && $param =~ /\.\.\.$/) 14468fac9c7bSMasahiro Yamada { 1447*78a88f79SMario Six if (!$param =~ /\w\.\.\.$/) { 1448*78a88f79SMario Six # handles unnamed variable parameters 1449*78a88f79SMario Six $param = "..."; 1450*78a88f79SMario Six } 14518fac9c7bSMasahiro Yamada if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") { 14528fac9c7bSMasahiro Yamada $parameterdescs{$param} = "variable arguments"; 14538fac9c7bSMasahiro Yamada } 14548fac9c7bSMasahiro Yamada } 14558fac9c7bSMasahiro Yamada elsif ($type eq "" && ($param eq "" or $param eq "void")) 14568fac9c7bSMasahiro Yamada { 14578fac9c7bSMasahiro Yamada $param="void"; 14588fac9c7bSMasahiro Yamada $parameterdescs{void} = "no arguments"; 14598fac9c7bSMasahiro Yamada } 14608fac9c7bSMasahiro Yamada elsif ($type eq "" && ($param eq "struct" or $param eq "union")) 14618fac9c7bSMasahiro Yamada # handle unnamed (anonymous) union or struct: 14628fac9c7bSMasahiro Yamada { 14638fac9c7bSMasahiro Yamada $type = $param; 14648fac9c7bSMasahiro Yamada $param = "{unnamed_" . $param . "}"; 14658fac9c7bSMasahiro Yamada $parameterdescs{$param} = "anonymous\n"; 14668fac9c7bSMasahiro Yamada $anon_struct_union = 1; 14678fac9c7bSMasahiro Yamada } 14688fac9c7bSMasahiro Yamada 14698fac9c7bSMasahiro Yamada # warn if parameter has no description 14708fac9c7bSMasahiro Yamada # (but ignore ones starting with # as these are not parameters 14718fac9c7bSMasahiro Yamada # but inline preprocessor statements); 1472*78a88f79SMario Six # Note: It will also ignore void params and unnamed structs/unions 1473*78a88f79SMario Six if (!defined $parameterdescs{$param} && $param !~ /^#/) { 1474*78a88f79SMario Six $parameterdescs{$param} = $undescribed; 14758fac9c7bSMasahiro Yamada 1476*78a88f79SMario Six if (show_warnings($type, $declaration_name)) { 1477*78a88f79SMario Six print STDERR 1478*78a88f79SMario Six "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; 14798fac9c7bSMasahiro Yamada ++$warnings; 14808fac9c7bSMasahiro Yamada } 14818fac9c7bSMasahiro Yamada } 14828fac9c7bSMasahiro Yamada 14838fac9c7bSMasahiro Yamada # strip spaces from $param so that it is one continuous string 14848fac9c7bSMasahiro Yamada # on @parameterlist; 14858fac9c7bSMasahiro Yamada # this fixes a problem where check_sections() cannot find 14868fac9c7bSMasahiro Yamada # a parameter like "addr[6 + 2]" because it actually appears 14878fac9c7bSMasahiro Yamada # as "addr[6", "+", "2]" on the parameter list; 14888fac9c7bSMasahiro Yamada # but it's better to maintain the param string unchanged for output, 14898fac9c7bSMasahiro Yamada # so just weaken the string compare in check_sections() to ignore 14908fac9c7bSMasahiro Yamada # "[blah" in a parameter string; 14918fac9c7bSMasahiro Yamada ###$param =~ s/\s*//g; 14928fac9c7bSMasahiro Yamada push @parameterlist, $param; 1493*78a88f79SMario Six $type =~ s/\s\s+/ /g; 14948fac9c7bSMasahiro Yamada $parametertypes{$param} = $type; 14958fac9c7bSMasahiro Yamada} 14968fac9c7bSMasahiro Yamada 1497*78a88f79SMario Sixsub check_sections($$$$$) { 1498*78a88f79SMario Six my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; 14998fac9c7bSMasahiro Yamada my @sects = split ' ', $sectcheck; 15008fac9c7bSMasahiro Yamada my @prms = split ' ', $prmscheck; 15018fac9c7bSMasahiro Yamada my $err; 15028fac9c7bSMasahiro Yamada my ($px, $sx); 15038fac9c7bSMasahiro Yamada my $prm_clean; # strip trailing "[array size]" and/or beginning "*" 15048fac9c7bSMasahiro Yamada 15058fac9c7bSMasahiro Yamada foreach $sx (0 .. $#sects) { 15068fac9c7bSMasahiro Yamada $err = 1; 15078fac9c7bSMasahiro Yamada foreach $px (0 .. $#prms) { 15088fac9c7bSMasahiro Yamada $prm_clean = $prms[$px]; 15098fac9c7bSMasahiro Yamada $prm_clean =~ s/\[.*\]//; 15108fac9c7bSMasahiro Yamada $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; 15118fac9c7bSMasahiro Yamada # ignore array size in a parameter string; 15128fac9c7bSMasahiro Yamada # however, the original param string may contain 15138fac9c7bSMasahiro Yamada # spaces, e.g.: addr[6 + 2] 15148fac9c7bSMasahiro Yamada # and this appears in @prms as "addr[6" since the 15158fac9c7bSMasahiro Yamada # parameter list is split at spaces; 15168fac9c7bSMasahiro Yamada # hence just ignore "[..." for the sections check; 15178fac9c7bSMasahiro Yamada $prm_clean =~ s/\[.*//; 15188fac9c7bSMasahiro Yamada 15198fac9c7bSMasahiro Yamada ##$prm_clean =~ s/^\**//; 15208fac9c7bSMasahiro Yamada if ($prm_clean eq $sects[$sx]) { 15218fac9c7bSMasahiro Yamada $err = 0; 15228fac9c7bSMasahiro Yamada last; 15238fac9c7bSMasahiro Yamada } 15248fac9c7bSMasahiro Yamada } 15258fac9c7bSMasahiro Yamada if ($err) { 15268fac9c7bSMasahiro Yamada if ($decl_type eq "function") { 1527*78a88f79SMario Six print STDERR "${file}:$.: warning: " . 15288fac9c7bSMasahiro Yamada "Excess function parameter " . 15298fac9c7bSMasahiro Yamada "'$sects[$sx]' " . 15308fac9c7bSMasahiro Yamada "description in '$decl_name'\n"; 15318fac9c7bSMasahiro Yamada ++$warnings; 15328fac9c7bSMasahiro Yamada } 15338fac9c7bSMasahiro Yamada } 15348fac9c7bSMasahiro Yamada } 15358fac9c7bSMasahiro Yamada} 15368fac9c7bSMasahiro Yamada 15378fac9c7bSMasahiro Yamada## 1538ced03298SMasahiro Yamada# Checks the section describing the return value of a function. 1539ced03298SMasahiro Yamadasub check_return_section { 1540ced03298SMasahiro Yamada my $file = shift; 1541ced03298SMasahiro Yamada my $declaration_name = shift; 1542ced03298SMasahiro Yamada my $return_type = shift; 1543ced03298SMasahiro Yamada 1544ced03298SMasahiro Yamada # Ignore an empty return type (It's a macro) 1545ced03298SMasahiro Yamada # Ignore functions with a "void" return type. (But don't ignore "void *") 1546ced03298SMasahiro Yamada if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) { 1547ced03298SMasahiro Yamada return; 1548ced03298SMasahiro Yamada } 1549ced03298SMasahiro Yamada 1550ced03298SMasahiro Yamada if (!defined($sections{$section_return}) || 1551ced03298SMasahiro Yamada $sections{$section_return} eq "") { 1552*78a88f79SMario Six print STDERR "${file}:$.: warning: " . 1553ced03298SMasahiro Yamada "No description found for return value of " . 1554ced03298SMasahiro Yamada "'$declaration_name'\n"; 1555ced03298SMasahiro Yamada ++$warnings; 1556ced03298SMasahiro Yamada } 1557ced03298SMasahiro Yamada} 1558ced03298SMasahiro Yamada 1559ced03298SMasahiro Yamada## 15608fac9c7bSMasahiro Yamada# takes a function prototype and the name of the current file being 15618fac9c7bSMasahiro Yamada# processed and spits out all the details stored in the global 15628fac9c7bSMasahiro Yamada# arrays/hashes. 15638fac9c7bSMasahiro Yamadasub dump_function($$) { 15648fac9c7bSMasahiro Yamada my $prototype = shift; 15658fac9c7bSMasahiro Yamada my $file = shift; 1566176d0982SMasahiro Yamada my $noret = 0; 15678fac9c7bSMasahiro Yamada 15688fac9c7bSMasahiro Yamada $prototype =~ s/^static +//; 15698fac9c7bSMasahiro Yamada $prototype =~ s/^extern +//; 15708fac9c7bSMasahiro Yamada $prototype =~ s/^asmlinkage +//; 15718fac9c7bSMasahiro Yamada $prototype =~ s/^inline +//; 15728fac9c7bSMasahiro Yamada $prototype =~ s/^__inline__ +//; 15738fac9c7bSMasahiro Yamada $prototype =~ s/^__inline +//; 15748fac9c7bSMasahiro Yamada $prototype =~ s/^__always_inline +//; 15758fac9c7bSMasahiro Yamada $prototype =~ s/^noinline +//; 15768fac9c7bSMasahiro Yamada $prototype =~ s/__init +//; 15778fac9c7bSMasahiro Yamada $prototype =~ s/__init_or_module +//; 1578176d0982SMasahiro Yamada $prototype =~ s/__meminit +//; 15798fac9c7bSMasahiro Yamada $prototype =~ s/__must_check +//; 15808fac9c7bSMasahiro Yamada $prototype =~ s/__weak +//; 1581*78a88f79SMario Six $prototype =~ s/__sched +//; 1582176d0982SMasahiro Yamada my $define = $prototype =~ s/^#\s*define\s+//; #ak added 1583*78a88f79SMario Six $prototype =~ s/__attribute__\s*\(\( 1584*78a88f79SMario Six (?: 1585*78a88f79SMario Six [\w\s]++ # attribute name 1586*78a88f79SMario Six (?:\([^)]*+\))? # attribute arguments 1587*78a88f79SMario Six \s*+,? # optional comma at the end 1588*78a88f79SMario Six )+ 1589*78a88f79SMario Six \)\)\s+//x; 15908fac9c7bSMasahiro Yamada 15918fac9c7bSMasahiro Yamada # Yes, this truly is vile. We are looking for: 15928fac9c7bSMasahiro Yamada # 1. Return type (may be nothing if we're looking at a macro) 15938fac9c7bSMasahiro Yamada # 2. Function name 15948fac9c7bSMasahiro Yamada # 3. Function parameters. 15958fac9c7bSMasahiro Yamada # 15968fac9c7bSMasahiro Yamada # All the while we have to watch out for function pointer parameters 15978fac9c7bSMasahiro Yamada # (which IIRC is what the two sections are for), C types (these 15988fac9c7bSMasahiro Yamada # regexps don't even start to express all the possibilities), and 15998fac9c7bSMasahiro Yamada # so on. 16008fac9c7bSMasahiro Yamada # 16018fac9c7bSMasahiro Yamada # If you mess with these regexps, it's a good idea to check that 16028fac9c7bSMasahiro Yamada # the following functions' documentation still comes out right: 16038fac9c7bSMasahiro Yamada # - parport_register_device (function pointer parameters) 16048fac9c7bSMasahiro Yamada # - atomic_set (macro) 16058fac9c7bSMasahiro Yamada # - pci_match_device, __copy_to_user (long return type) 16068fac9c7bSMasahiro Yamada 1607176d0982SMasahiro Yamada if ($define && $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s+/) { 1608176d0982SMasahiro Yamada # This is an object-like macro, it has no return type and no parameter 1609176d0982SMasahiro Yamada # list. 1610176d0982SMasahiro Yamada # Function-like macros are not allowed to have spaces between 1611176d0982SMasahiro Yamada # declaration_name and opening parenthesis (notice the \s+). 1612176d0982SMasahiro Yamada $return_type = $1; 1613176d0982SMasahiro Yamada $declaration_name = $2; 1614176d0982SMasahiro Yamada $noret = 1; 1615176d0982SMasahiro Yamada } elsif ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 16168fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1617*78a88f79SMario Six $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 16188fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 16198fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 16208fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1621*78a88f79SMario Six $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 16228fac9c7bSMasahiro Yamada $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 16238fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 1624*78a88f79SMario Six $prototype =~ m/^(\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 16258fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 1626*78a88f79SMario Six $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 16278fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 1628*78a88f79SMario Six $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 16298fac9c7bSMasahiro Yamada $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 1630*78a88f79SMario Six $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || 1631*78a88f79SMario Six $prototype =~ m/^(\w+\s+\w+\s*\*+\s*\w+\s*\*+\s*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { 16328fac9c7bSMasahiro Yamada $return_type = $1; 16338fac9c7bSMasahiro Yamada $declaration_name = $2; 16348fac9c7bSMasahiro Yamada my $args = $3; 16358fac9c7bSMasahiro Yamada 1636*78a88f79SMario Six create_parameterlist($args, ',', $file, $declaration_name); 16378fac9c7bSMasahiro Yamada } else { 1638*78a88f79SMario Six print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; 16398fac9c7bSMasahiro Yamada return; 16408fac9c7bSMasahiro Yamada } 16418fac9c7bSMasahiro Yamada 16428fac9c7bSMasahiro Yamada my $prms = join " ", @parameterlist; 1643*78a88f79SMario Six check_sections($file, $declaration_name, "function", $sectcheck, $prms); 16448fac9c7bSMasahiro Yamada 1645ced03298SMasahiro Yamada # This check emits a lot of warnings at the moment, because many 1646ced03298SMasahiro Yamada # functions don't have a 'Return' doc section. So until the number 1647ced03298SMasahiro Yamada # of warnings goes sufficiently down, the check is only performed in 1648ced03298SMasahiro Yamada # verbose mode. 1649ced03298SMasahiro Yamada # TODO: always perform the check. 1650176d0982SMasahiro Yamada if ($verbose && !$noret) { 1651ced03298SMasahiro Yamada check_return_section($file, $declaration_name, $return_type); 1652ced03298SMasahiro Yamada } 1653ced03298SMasahiro Yamada 16548fac9c7bSMasahiro Yamada output_declaration($declaration_name, 16558fac9c7bSMasahiro Yamada 'function', 16568fac9c7bSMasahiro Yamada {'function' => $declaration_name, 16578fac9c7bSMasahiro Yamada 'module' => $modulename, 16588fac9c7bSMasahiro Yamada 'functiontype' => $return_type, 16598fac9c7bSMasahiro Yamada 'parameterlist' => \@parameterlist, 16608fac9c7bSMasahiro Yamada 'parameterdescs' => \%parameterdescs, 16618fac9c7bSMasahiro Yamada 'parametertypes' => \%parametertypes, 16628fac9c7bSMasahiro Yamada 'sectionlist' => \@sectionlist, 16638fac9c7bSMasahiro Yamada 'sections' => \%sections, 16648fac9c7bSMasahiro Yamada 'purpose' => $declaration_purpose 16658fac9c7bSMasahiro Yamada }); 16668fac9c7bSMasahiro Yamada} 16678fac9c7bSMasahiro Yamada 16688fac9c7bSMasahiro Yamadasub reset_state { 16698fac9c7bSMasahiro Yamada $function = ""; 16708fac9c7bSMasahiro Yamada %parameterdescs = (); 16718fac9c7bSMasahiro Yamada %parametertypes = (); 16728fac9c7bSMasahiro Yamada @parameterlist = (); 16738fac9c7bSMasahiro Yamada %sections = (); 16748fac9c7bSMasahiro Yamada @sectionlist = (); 16758fac9c7bSMasahiro Yamada $sectcheck = ""; 16768fac9c7bSMasahiro Yamada $struct_actual = ""; 16778fac9c7bSMasahiro Yamada $prototype = ""; 16788fac9c7bSMasahiro Yamada 1679*78a88f79SMario Six $state = STATE_NORMAL; 1680*78a88f79SMario Six $inline_doc_state = STATE_INLINE_NA; 16818fac9c7bSMasahiro Yamada} 16828fac9c7bSMasahiro Yamada 16838fac9c7bSMasahiro Yamadasub tracepoint_munge($) { 16848fac9c7bSMasahiro Yamada my $file = shift; 16858fac9c7bSMasahiro Yamada my $tracepointname = 0; 16868fac9c7bSMasahiro Yamada my $tracepointargs = 0; 16878fac9c7bSMasahiro Yamada 16888fac9c7bSMasahiro Yamada if ($prototype =~ m/TRACE_EVENT\((.*?),/) { 16898fac9c7bSMasahiro Yamada $tracepointname = $1; 16908fac9c7bSMasahiro Yamada } 16918fac9c7bSMasahiro Yamada if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) { 16928fac9c7bSMasahiro Yamada $tracepointname = $1; 16938fac9c7bSMasahiro Yamada } 16948fac9c7bSMasahiro Yamada if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) { 16958fac9c7bSMasahiro Yamada $tracepointname = $2; 16968fac9c7bSMasahiro Yamada } 16978fac9c7bSMasahiro Yamada $tracepointname =~ s/^\s+//; #strip leading whitespace 16988fac9c7bSMasahiro Yamada if ($prototype =~ m/TP_PROTO\((.*?)\)/) { 16998fac9c7bSMasahiro Yamada $tracepointargs = $1; 17008fac9c7bSMasahiro Yamada } 17018fac9c7bSMasahiro Yamada if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 1702*78a88f79SMario Six print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". 17038fac9c7bSMasahiro Yamada "$prototype\n"; 17048fac9c7bSMasahiro Yamada } else { 17058fac9c7bSMasahiro Yamada $prototype = "static inline void trace_$tracepointname($tracepointargs)"; 17068fac9c7bSMasahiro Yamada } 17078fac9c7bSMasahiro Yamada} 17088fac9c7bSMasahiro Yamada 17098fac9c7bSMasahiro Yamadasub syscall_munge() { 17108fac9c7bSMasahiro Yamada my $void = 0; 17118fac9c7bSMasahiro Yamada 1712*78a88f79SMario Six $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's 17138fac9c7bSMasahiro Yamada## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { 17148fac9c7bSMasahiro Yamada if ($prototype =~ m/SYSCALL_DEFINE0/) { 17158fac9c7bSMasahiro Yamada $void = 1; 17168fac9c7bSMasahiro Yamada## $prototype = "long sys_$1(void)"; 17178fac9c7bSMasahiro Yamada } 17188fac9c7bSMasahiro Yamada 17198fac9c7bSMasahiro Yamada $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name 17208fac9c7bSMasahiro Yamada if ($prototype =~ m/long (sys_.*?),/) { 17218fac9c7bSMasahiro Yamada $prototype =~ s/,/\(/; 17228fac9c7bSMasahiro Yamada } elsif ($void) { 17238fac9c7bSMasahiro Yamada $prototype =~ s/\)/\(void\)/; 17248fac9c7bSMasahiro Yamada } 17258fac9c7bSMasahiro Yamada 17268fac9c7bSMasahiro Yamada # now delete all of the odd-number commas in $prototype 17278fac9c7bSMasahiro Yamada # so that arg types & arg names don't have a comma between them 17288fac9c7bSMasahiro Yamada my $count = 0; 17298fac9c7bSMasahiro Yamada my $len = length($prototype); 17308fac9c7bSMasahiro Yamada if ($void) { 17318fac9c7bSMasahiro Yamada $len = 0; # skip the for-loop 17328fac9c7bSMasahiro Yamada } 17338fac9c7bSMasahiro Yamada for (my $ix = 0; $ix < $len; $ix++) { 17348fac9c7bSMasahiro Yamada if (substr($prototype, $ix, 1) eq ',') { 17358fac9c7bSMasahiro Yamada $count++; 17368fac9c7bSMasahiro Yamada if ($count % 2 == 1) { 17378fac9c7bSMasahiro Yamada substr($prototype, $ix, 1) = ' '; 17388fac9c7bSMasahiro Yamada } 17398fac9c7bSMasahiro Yamada } 17408fac9c7bSMasahiro Yamada } 17418fac9c7bSMasahiro Yamada} 17428fac9c7bSMasahiro Yamada 1743*78a88f79SMario Sixsub process_proto_function($$) { 17448fac9c7bSMasahiro Yamada my $x = shift; 17458fac9c7bSMasahiro Yamada my $file = shift; 17468fac9c7bSMasahiro Yamada 17478fac9c7bSMasahiro Yamada $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 17488fac9c7bSMasahiro Yamada 17498fac9c7bSMasahiro Yamada if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { 17508fac9c7bSMasahiro Yamada # do nothing 17518fac9c7bSMasahiro Yamada } 17528fac9c7bSMasahiro Yamada elsif ($x =~ /([^\{]*)/) { 17538fac9c7bSMasahiro Yamada $prototype .= $1; 17548fac9c7bSMasahiro Yamada } 17558fac9c7bSMasahiro Yamada 17568fac9c7bSMasahiro Yamada if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { 17578fac9c7bSMasahiro Yamada $prototype =~ s@/\*.*?\*/@@gos; # strip comments. 17588fac9c7bSMasahiro Yamada $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 17598fac9c7bSMasahiro Yamada $prototype =~ s@^\s+@@gos; # strip leading spaces 17608fac9c7bSMasahiro Yamada if ($prototype =~ /SYSCALL_DEFINE/) { 17618fac9c7bSMasahiro Yamada syscall_munge(); 17628fac9c7bSMasahiro Yamada } 17638fac9c7bSMasahiro Yamada if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ || 17648fac9c7bSMasahiro Yamada $prototype =~ /DEFINE_SINGLE_EVENT/) 17658fac9c7bSMasahiro Yamada { 17668fac9c7bSMasahiro Yamada tracepoint_munge($file); 17678fac9c7bSMasahiro Yamada } 17688fac9c7bSMasahiro Yamada dump_function($prototype, $file); 17698fac9c7bSMasahiro Yamada reset_state(); 17708fac9c7bSMasahiro Yamada } 17718fac9c7bSMasahiro Yamada} 17728fac9c7bSMasahiro Yamada 1773*78a88f79SMario Sixsub process_proto_type($$) { 17748fac9c7bSMasahiro Yamada my $x = shift; 17758fac9c7bSMasahiro Yamada my $file = shift; 17768fac9c7bSMasahiro Yamada 17778fac9c7bSMasahiro Yamada $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 17788fac9c7bSMasahiro Yamada $x =~ s@^\s+@@gos; # strip leading spaces 17798fac9c7bSMasahiro Yamada $x =~ s@\s+$@@gos; # strip trailing spaces 17808fac9c7bSMasahiro Yamada $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 17818fac9c7bSMasahiro Yamada 17828fac9c7bSMasahiro Yamada if ($x =~ /^#/) { 17838fac9c7bSMasahiro Yamada # To distinguish preprocessor directive from regular declaration later. 17848fac9c7bSMasahiro Yamada $x .= ";"; 17858fac9c7bSMasahiro Yamada } 17868fac9c7bSMasahiro Yamada 17878fac9c7bSMasahiro Yamada while (1) { 17888fac9c7bSMasahiro Yamada if ( $x =~ /([^{};]*)([{};])(.*)/ ) { 1789*78a88f79SMario Six if( length $prototype ) { 1790*78a88f79SMario Six $prototype .= " " 1791*78a88f79SMario Six } 17928fac9c7bSMasahiro Yamada $prototype .= $1 . $2; 17938fac9c7bSMasahiro Yamada ($2 eq '{') && $brcount++; 17948fac9c7bSMasahiro Yamada ($2 eq '}') && $brcount--; 17958fac9c7bSMasahiro Yamada if (($2 eq ';') && ($brcount == 0)) { 17968fac9c7bSMasahiro Yamada dump_declaration($prototype, $file); 17978fac9c7bSMasahiro Yamada reset_state(); 17988fac9c7bSMasahiro Yamada last; 17998fac9c7bSMasahiro Yamada } 18008fac9c7bSMasahiro Yamada $x = $3; 18018fac9c7bSMasahiro Yamada } else { 18028fac9c7bSMasahiro Yamada $prototype .= $x; 18038fac9c7bSMasahiro Yamada last; 18048fac9c7bSMasahiro Yamada } 18058fac9c7bSMasahiro Yamada } 18068fac9c7bSMasahiro Yamada} 18078fac9c7bSMasahiro Yamada 18088fac9c7bSMasahiro Yamada 1809*78a88f79SMario Sixsub map_filename($) { 18108fac9c7bSMasahiro Yamada my $file; 1811*78a88f79SMario Six my ($orig_file) = @_; 18128fac9c7bSMasahiro Yamada 18138fac9c7bSMasahiro Yamada if (defined($ENV{'SRCTREE'})) { 1814*78a88f79SMario Six $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; 1815*78a88f79SMario Six } else { 1816*78a88f79SMario Six $file = $orig_file; 18178fac9c7bSMasahiro Yamada } 1818*78a88f79SMario Six 18198fac9c7bSMasahiro Yamada if (defined($source_map{$file})) { 18208fac9c7bSMasahiro Yamada $file = $source_map{$file}; 18218fac9c7bSMasahiro Yamada } 18228fac9c7bSMasahiro Yamada 1823*78a88f79SMario Six return $file; 1824*78a88f79SMario Six} 1825*78a88f79SMario Six 1826*78a88f79SMario Sixsub process_export_file($) { 1827*78a88f79SMario Six my ($orig_file) = @_; 1828*78a88f79SMario Six my $file = map_filename($orig_file); 1829*78a88f79SMario Six 18308fac9c7bSMasahiro Yamada if (!open(IN,"<$file")) { 18318fac9c7bSMasahiro Yamada print STDERR "Error: Cannot open file $file\n"; 18328fac9c7bSMasahiro Yamada ++$errors; 18338fac9c7bSMasahiro Yamada return; 18348fac9c7bSMasahiro Yamada } 18358fac9c7bSMasahiro Yamada 18368fac9c7bSMasahiro Yamada while (<IN>) { 1837*78a88f79SMario Six if (/$export_symbol/) { 1838*78a88f79SMario Six $function_table{$2} = 1; 1839ced03298SMasahiro Yamada } 1840*78a88f79SMario Six } 1841*78a88f79SMario Six 1842*78a88f79SMario Six close(IN); 1843*78a88f79SMario Six} 1844*78a88f79SMario Six 1845*78a88f79SMario Six# 1846*78a88f79SMario Six# Parsers for the various processing states. 1847*78a88f79SMario Six# 1848*78a88f79SMario Six# STATE_NORMAL: looking for the /** to begin everything. 1849*78a88f79SMario Six# 1850*78a88f79SMario Sixsub process_normal() { 18518fac9c7bSMasahiro Yamada if (/$doc_start/o) { 1852*78a88f79SMario Six $state = STATE_NAME; # next line is always the function name 18538fac9c7bSMasahiro Yamada $in_doc_sect = 0; 1854*78a88f79SMario Six $declaration_start_line = $. + 1; 18558fac9c7bSMasahiro Yamada } 1856*78a88f79SMario Six} 1857*78a88f79SMario Six 1858*78a88f79SMario Six# 1859*78a88f79SMario Six# STATE_NAME: Looking for the "name - description" line 1860*78a88f79SMario Six# 1861*78a88f79SMario Sixsub process_name($$) { 1862*78a88f79SMario Six my $file = shift; 1863*78a88f79SMario Six my $identifier; 1864*78a88f79SMario Six my $descr; 1865*78a88f79SMario Six 18668fac9c7bSMasahiro Yamada if (/$doc_block/o) { 1867*78a88f79SMario Six $state = STATE_DOCBLOCK; 18688fac9c7bSMasahiro Yamada $contents = ""; 1869*78a88f79SMario Six $new_start_line = $. + 1; 1870*78a88f79SMario Six 18718fac9c7bSMasahiro Yamada if ( $1 eq "" ) { 18728fac9c7bSMasahiro Yamada $section = $section_intro; 18738fac9c7bSMasahiro Yamada } else { 18748fac9c7bSMasahiro Yamada $section = $1; 18758fac9c7bSMasahiro Yamada } 18768fac9c7bSMasahiro Yamada } 18778fac9c7bSMasahiro Yamada elsif (/$doc_decl/o) { 18788fac9c7bSMasahiro Yamada $identifier = $1; 1879*78a88f79SMario Six if (/\s*([\w\s]+?)(\(\))?\s*-/) { 18808fac9c7bSMasahiro Yamada $identifier = $1; 18818fac9c7bSMasahiro Yamada } 18828fac9c7bSMasahiro Yamada 1883*78a88f79SMario Six $state = STATE_BODY; 1884*78a88f79SMario Six # if there's no @param blocks need to set up default section 1885*78a88f79SMario Six # here 1886*78a88f79SMario Six $contents = ""; 1887*78a88f79SMario Six $section = $section_default; 1888*78a88f79SMario Six $new_start_line = $. + 1; 18898fac9c7bSMasahiro Yamada if (/-(.*)/) { 18908fac9c7bSMasahiro Yamada # strip leading/trailing/multiple spaces 18918fac9c7bSMasahiro Yamada $descr= $1; 18928fac9c7bSMasahiro Yamada $descr =~ s/^\s*//; 18938fac9c7bSMasahiro Yamada $descr =~ s/\s*$//; 1894ced03298SMasahiro Yamada $descr =~ s/\s+/ /g; 1895*78a88f79SMario Six $declaration_purpose = $descr; 1896*78a88f79SMario Six $state = STATE_BODY_MAYBE; 18978fac9c7bSMasahiro Yamada } else { 18988fac9c7bSMasahiro Yamada $declaration_purpose = ""; 18998fac9c7bSMasahiro Yamada } 19008fac9c7bSMasahiro Yamada 19018fac9c7bSMasahiro Yamada if (($declaration_purpose eq "") && $verbose) { 1902*78a88f79SMario Six print STDERR "${file}:$.: warning: missing initial short description on line:\n"; 19038fac9c7bSMasahiro Yamada print STDERR $_; 19048fac9c7bSMasahiro Yamada ++$warnings; 19058fac9c7bSMasahiro Yamada } 19068fac9c7bSMasahiro Yamada 19078fac9c7bSMasahiro Yamada if ($identifier =~ m/^struct/) { 19088fac9c7bSMasahiro Yamada $decl_type = 'struct'; 19098fac9c7bSMasahiro Yamada } elsif ($identifier =~ m/^union/) { 19108fac9c7bSMasahiro Yamada $decl_type = 'union'; 19118fac9c7bSMasahiro Yamada } elsif ($identifier =~ m/^enum/) { 19128fac9c7bSMasahiro Yamada $decl_type = 'enum'; 19138fac9c7bSMasahiro Yamada } elsif ($identifier =~ m/^typedef/) { 19148fac9c7bSMasahiro Yamada $decl_type = 'typedef'; 19158fac9c7bSMasahiro Yamada } else { 19168fac9c7bSMasahiro Yamada $decl_type = 'function'; 19178fac9c7bSMasahiro Yamada } 19188fac9c7bSMasahiro Yamada 19198fac9c7bSMasahiro Yamada if ($verbose) { 1920*78a88f79SMario Six print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; 19218fac9c7bSMasahiro Yamada } 19228fac9c7bSMasahiro Yamada } else { 1923*78a88f79SMario Six print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", 19248fac9c7bSMasahiro Yamada " - I thought it was a doc line\n"; 19258fac9c7bSMasahiro Yamada ++$warnings; 1926*78a88f79SMario Six $state = STATE_NORMAL; 19278fac9c7bSMasahiro Yamada } 1928*78a88f79SMario Six} 1929*78a88f79SMario Six 1930*78a88f79SMario Six 1931*78a88f79SMario Six# 1932*78a88f79SMario Six# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. 1933*78a88f79SMario Six# 1934*78a88f79SMario Sixsub process_body($$) { 1935*78a88f79SMario Six my $file = shift; 1936*78a88f79SMario Six 1937*78a88f79SMario Six if (/$doc_sect/i) { # case insensitive for supported section names 19388fac9c7bSMasahiro Yamada $newsection = $1; 19398fac9c7bSMasahiro Yamada $newcontents = $2; 19408fac9c7bSMasahiro Yamada 1941*78a88f79SMario Six # map the supported section names to the canonical names 1942*78a88f79SMario Six if ($newsection =~ m/^description$/i) { 1943*78a88f79SMario Six $newsection = $section_default; 1944*78a88f79SMario Six } elsif ($newsection =~ m/^context$/i) { 1945*78a88f79SMario Six $newsection = $section_context; 1946*78a88f79SMario Six } elsif ($newsection =~ m/^returns?$/i) { 1947*78a88f79SMario Six $newsection = $section_return; 1948*78a88f79SMario Six } elsif ($newsection =~ m/^\@return$/) { 1949*78a88f79SMario Six # special: @return is a section, not a param description 1950*78a88f79SMario Six $newsection = $section_return; 1951*78a88f79SMario Six } 1952*78a88f79SMario Six 19538fac9c7bSMasahiro Yamada if (($contents ne "") && ($contents ne "\n")) { 19548fac9c7bSMasahiro Yamada if (!$in_doc_sect && $verbose) { 1955*78a88f79SMario Six print STDERR "${file}:$.: warning: contents before sections\n"; 19568fac9c7bSMasahiro Yamada ++$warnings; 19578fac9c7bSMasahiro Yamada } 1958*78a88f79SMario Six dump_section($file, $section, $contents); 19598fac9c7bSMasahiro Yamada $section = $section_default; 19608fac9c7bSMasahiro Yamada } 19618fac9c7bSMasahiro Yamada 19628fac9c7bSMasahiro Yamada $in_doc_sect = 1; 1963*78a88f79SMario Six $state = STATE_BODY; 19648fac9c7bSMasahiro Yamada $contents = $newcontents; 1965*78a88f79SMario Six $new_start_line = $.; 1966*78a88f79SMario Six while (substr($contents, 0, 1) eq " ") { 19678fac9c7bSMasahiro Yamada $contents = substr($contents, 1); 19688fac9c7bSMasahiro Yamada } 1969*78a88f79SMario Six if ($contents ne "") { 19708fac9c7bSMasahiro Yamada $contents .= "\n"; 19718fac9c7bSMasahiro Yamada } 19728fac9c7bSMasahiro Yamada $section = $newsection; 1973*78a88f79SMario Six $leading_space = undef; 19748fac9c7bSMasahiro Yamada } elsif (/$doc_end/) { 19758fac9c7bSMasahiro Yamada if (($contents ne "") && ($contents ne "\n")) { 1976*78a88f79SMario Six dump_section($file, $section, $contents); 19778fac9c7bSMasahiro Yamada $section = $section_default; 19788fac9c7bSMasahiro Yamada $contents = ""; 19798fac9c7bSMasahiro Yamada } 19808fac9c7bSMasahiro Yamada # look for doc_com + <text> + doc_end: 19818fac9c7bSMasahiro Yamada if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { 1982*78a88f79SMario Six print STDERR "${file}:$.: warning: suspicious ending line: $_"; 19838fac9c7bSMasahiro Yamada ++$warnings; 19848fac9c7bSMasahiro Yamada } 19858fac9c7bSMasahiro Yamada 19868fac9c7bSMasahiro Yamada $prototype = ""; 1987*78a88f79SMario Six $state = STATE_PROTO; 19888fac9c7bSMasahiro Yamada $brcount = 0; 19898fac9c7bSMasahiro Yamada } elsif (/$doc_content/) { 19908fac9c7bSMasahiro Yamada # miguel-style comment kludge, look for blank lines after 19918fac9c7bSMasahiro Yamada # @parameter line to signify start of description 19928fac9c7bSMasahiro Yamada if ($1 eq "") { 19938fac9c7bSMasahiro Yamada if ($section =~ m/^@/ || $section eq $section_context) { 1994*78a88f79SMario Six dump_section($file, $section, $contents); 19958fac9c7bSMasahiro Yamada $section = $section_default; 19968fac9c7bSMasahiro Yamada $contents = ""; 1997*78a88f79SMario Six $new_start_line = $.; 19988fac9c7bSMasahiro Yamada } else { 19998fac9c7bSMasahiro Yamada $contents .= "\n"; 20008fac9c7bSMasahiro Yamada } 2001*78a88f79SMario Six $state = STATE_BODY; 2002*78a88f79SMario Six } elsif ($state == STATE_BODY_MAYBE) { 20038fac9c7bSMasahiro Yamada # Continued declaration purpose 20048fac9c7bSMasahiro Yamada chomp($declaration_purpose); 2005*78a88f79SMario Six $declaration_purpose .= " " . $1; 2006ced03298SMasahiro Yamada $declaration_purpose =~ s/\s+/ /g; 20078fac9c7bSMasahiro Yamada } else { 2008*78a88f79SMario Six my $cont = $1; 2009*78a88f79SMario Six if ($section =~ m/^@/ || $section eq $section_context) { 2010*78a88f79SMario Six if (!defined $leading_space) { 2011*78a88f79SMario Six if ($cont =~ m/^(\s+)/) { 2012*78a88f79SMario Six $leading_space = $1; 2013*78a88f79SMario Six } else { 2014*78a88f79SMario Six $leading_space = ""; 2015*78a88f79SMario Six } 2016*78a88f79SMario Six } 2017*78a88f79SMario Six $cont =~ s/^$leading_space//; 2018*78a88f79SMario Six } 2019*78a88f79SMario Six $contents .= $cont . "\n"; 20208fac9c7bSMasahiro Yamada } 20218fac9c7bSMasahiro Yamada } else { 20228fac9c7bSMasahiro Yamada # i dont know - bad line? ignore. 2023*78a88f79SMario Six print STDERR "${file}:$.: warning: bad line: $_"; 20248fac9c7bSMasahiro Yamada ++$warnings; 20258fac9c7bSMasahiro Yamada } 20268fac9c7bSMasahiro Yamada} 2027*78a88f79SMario Six 2028*78a88f79SMario Six 2029*78a88f79SMario Six# 2030*78a88f79SMario Six# STATE_PROTO: reading a function/whatever prototype. 2031*78a88f79SMario Six# 2032*78a88f79SMario Sixsub process_proto($$) { 2033*78a88f79SMario Six my $file = shift; 2034*78a88f79SMario Six 2035*78a88f79SMario Six if (/$doc_inline_oneline/) { 20368fac9c7bSMasahiro Yamada $section = $1; 2037*78a88f79SMario Six $contents = $2; 2038*78a88f79SMario Six if ($contents ne "") { 2039*78a88f79SMario Six $contents .= "\n"; 2040*78a88f79SMario Six dump_section($file, $section, $contents); 2041*78a88f79SMario Six $section = $section_default; 2042*78a88f79SMario Six $contents = ""; 2043*78a88f79SMario Six } 2044*78a88f79SMario Six } elsif (/$doc_inline_start/) { 2045*78a88f79SMario Six $state = STATE_INLINE; 2046*78a88f79SMario Six $inline_doc_state = STATE_INLINE_NAME; 2047*78a88f79SMario Six } elsif ($decl_type eq 'function') { 2048*78a88f79SMario Six process_proto_function($_, $file); 2049*78a88f79SMario Six } else { 2050*78a88f79SMario Six process_proto_type($_, $file); 20518fac9c7bSMasahiro Yamada } 20528fac9c7bSMasahiro Yamada} 2053*78a88f79SMario Six 2054*78a88f79SMario Six# 2055*78a88f79SMario Six# STATE_DOCBLOCK: within a DOC: block. 2056*78a88f79SMario Six# 2057*78a88f79SMario Sixsub process_docblock($$) { 2058*78a88f79SMario Six my $file = shift; 2059*78a88f79SMario Six 2060*78a88f79SMario Six if (/$doc_end/) { 2061*78a88f79SMario Six dump_doc_section($file, $section, $contents); 2062*78a88f79SMario Six $section = $section_default; 20638fac9c7bSMasahiro Yamada $contents = ""; 20648fac9c7bSMasahiro Yamada $function = ""; 20658fac9c7bSMasahiro Yamada %parameterdescs = (); 20668fac9c7bSMasahiro Yamada %parametertypes = (); 20678fac9c7bSMasahiro Yamada @parameterlist = (); 20688fac9c7bSMasahiro Yamada %sections = (); 20698fac9c7bSMasahiro Yamada @sectionlist = (); 20708fac9c7bSMasahiro Yamada $prototype = ""; 2071*78a88f79SMario Six $state = STATE_NORMAL; 2072*78a88f79SMario Six } elsif (/$doc_content/) { 2073*78a88f79SMario Six if ( $1 eq "" ) { 20748fac9c7bSMasahiro Yamada $contents .= $blankline; 2075*78a88f79SMario Six } else { 20768fac9c7bSMasahiro Yamada $contents .= $1 . "\n"; 20778fac9c7bSMasahiro Yamada } 20788fac9c7bSMasahiro Yamada } 20798fac9c7bSMasahiro Yamada} 2080*78a88f79SMario Six 2081*78a88f79SMario Six# 2082*78a88f79SMario Six# STATE_INLINE: docbook comments within a prototype. 2083*78a88f79SMario Six# 2084*78a88f79SMario Sixsub process_inline($$) { 2085*78a88f79SMario Six my $file = shift; 2086*78a88f79SMario Six 2087*78a88f79SMario Six # First line (state 1) needs to be a @parameter 2088*78a88f79SMario Six if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { 2089*78a88f79SMario Six $section = $1; 2090*78a88f79SMario Six $contents = $2; 2091*78a88f79SMario Six $new_start_line = $.; 2092*78a88f79SMario Six if ($contents ne "") { 2093*78a88f79SMario Six while (substr($contents, 0, 1) eq " ") { 2094*78a88f79SMario Six $contents = substr($contents, 1); 20958fac9c7bSMasahiro Yamada } 2096*78a88f79SMario Six $contents .= "\n"; 2097*78a88f79SMario Six } 2098*78a88f79SMario Six $inline_doc_state = STATE_INLINE_TEXT; 2099*78a88f79SMario Six # Documentation block end */ 2100*78a88f79SMario Six } elsif (/$doc_inline_end/) { 2101*78a88f79SMario Six if (($contents ne "") && ($contents ne "\n")) { 2102*78a88f79SMario Six dump_section($file, $section, $contents); 2103*78a88f79SMario Six $section = $section_default; 2104*78a88f79SMario Six $contents = ""; 2105*78a88f79SMario Six } 2106*78a88f79SMario Six $state = STATE_PROTO; 2107*78a88f79SMario Six $inline_doc_state = STATE_INLINE_NA; 2108*78a88f79SMario Six # Regular text 2109*78a88f79SMario Six } elsif (/$doc_content/) { 2110*78a88f79SMario Six if ($inline_doc_state == STATE_INLINE_TEXT) { 2111*78a88f79SMario Six $contents .= $1 . "\n"; 2112*78a88f79SMario Six # nuke leading blank lines 2113*78a88f79SMario Six if ($contents =~ /^\s*$/) { 2114*78a88f79SMario Six $contents = ""; 2115*78a88f79SMario Six } 2116*78a88f79SMario Six } elsif ($inline_doc_state == STATE_INLINE_NAME) { 2117*78a88f79SMario Six $inline_doc_state = STATE_INLINE_ERROR; 2118*78a88f79SMario Six print STDERR "${file}:$.: warning: "; 2119*78a88f79SMario Six print STDERR "Incorrect use of kernel-doc format: $_"; 2120*78a88f79SMario Six ++$warnings; 2121*78a88f79SMario Six } 2122*78a88f79SMario Six } 2123*78a88f79SMario Six} 2124*78a88f79SMario Six 2125*78a88f79SMario Six 2126*78a88f79SMario Sixsub process_file($) { 2127*78a88f79SMario Six my $file; 2128*78a88f79SMario Six my $initial_section_counter = $section_counter; 2129*78a88f79SMario Six my ($orig_file) = @_; 2130*78a88f79SMario Six 2131*78a88f79SMario Six $file = map_filename($orig_file); 2132*78a88f79SMario Six 2133*78a88f79SMario Six if (!open(IN,"<$file")) { 2134*78a88f79SMario Six print STDERR "Error: Cannot open file $file\n"; 2135*78a88f79SMario Six ++$errors; 2136*78a88f79SMario Six return; 2137*78a88f79SMario Six } 2138*78a88f79SMario Six 2139*78a88f79SMario Six $. = 1; 2140*78a88f79SMario Six 2141*78a88f79SMario Six $section_counter = 0; 2142*78a88f79SMario Six while (<IN>) { 2143*78a88f79SMario Six while (s/\\\s*$//) { 2144*78a88f79SMario Six $_ .= <IN>; 2145*78a88f79SMario Six } 2146*78a88f79SMario Six # Replace tabs by spaces 2147*78a88f79SMario Six while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; 2148*78a88f79SMario Six # Hand this line to the appropriate state handler 2149*78a88f79SMario Six if ($state == STATE_NORMAL) { 2150*78a88f79SMario Six process_normal(); 2151*78a88f79SMario Six } elsif ($state == STATE_NAME) { 2152*78a88f79SMario Six process_name($file, $_); 2153*78a88f79SMario Six } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { 2154*78a88f79SMario Six process_body($file, $_); 2155*78a88f79SMario Six } elsif ($state == STATE_INLINE) { # scanning for inline parameters 2156*78a88f79SMario Six process_inline($file, $_); 2157*78a88f79SMario Six } elsif ($state == STATE_PROTO) { 2158*78a88f79SMario Six process_proto($file, $_); 2159*78a88f79SMario Six } elsif ($state == STATE_DOCBLOCK) { 2160*78a88f79SMario Six process_docblock($file, $_); 2161*78a88f79SMario Six } 2162*78a88f79SMario Six } 2163*78a88f79SMario Six 2164*78a88f79SMario Six # Make sure we got something interesting. 21658fac9c7bSMasahiro Yamada if ($initial_section_counter == $section_counter) { 2166*78a88f79SMario Six if ($output_mode ne "none") { 2167*78a88f79SMario Six print STDERR "${file}:1: warning: no structured comments found\n"; 2168ced03298SMasahiro Yamada } 2169*78a88f79SMario Six if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { 2170*78a88f79SMario Six print STDERR " Was looking for '$_'.\n" for keys %function_table; 21718fac9c7bSMasahiro Yamada } 21728fac9c7bSMasahiro Yamada } 21738fac9c7bSMasahiro Yamada} 21748fac9c7bSMasahiro Yamada 21758fac9c7bSMasahiro Yamada 21768fac9c7bSMasahiro Yamada$kernelversion = get_kernel_version(); 21778fac9c7bSMasahiro Yamada 21788fac9c7bSMasahiro Yamada# generate a sequence of code that will splice in highlighting information 21798fac9c7bSMasahiro Yamada# using the s// operator. 2180*78a88f79SMario Sixfor (my $k = 0; $k < @highlights; $k++) { 2181*78a88f79SMario Six my $pattern = $highlights[$k][0]; 2182*78a88f79SMario Six my $result = $highlights[$k][1]; 2183*78a88f79SMario Six# print STDERR "scanning pattern:$pattern, highlight:($result)\n"; 2184*78a88f79SMario Six $dohighlight .= "\$contents =~ s:$pattern:$result:gs;\n"; 21858fac9c7bSMasahiro Yamada} 21868fac9c7bSMasahiro Yamada 21878fac9c7bSMasahiro Yamada# Read the file that maps relative names to absolute names for 21888fac9c7bSMasahiro Yamada# separate source and object directories and for shadow trees. 21898fac9c7bSMasahiro Yamadaif (open(SOURCE_MAP, "<.tmp_filelist.txt")) { 21908fac9c7bSMasahiro Yamada my ($relname, $absname); 21918fac9c7bSMasahiro Yamada while(<SOURCE_MAP>) { 21928fac9c7bSMasahiro Yamada chop(); 21938fac9c7bSMasahiro Yamada ($relname, $absname) = (split())[0..1]; 21948fac9c7bSMasahiro Yamada $relname =~ s:^/+::; 21958fac9c7bSMasahiro Yamada $source_map{$relname} = $absname; 21968fac9c7bSMasahiro Yamada } 21978fac9c7bSMasahiro Yamada close(SOURCE_MAP); 21988fac9c7bSMasahiro Yamada} 21998fac9c7bSMasahiro Yamada 2200*78a88f79SMario Sixif ($output_selection == OUTPUT_EXPORTED || 2201*78a88f79SMario Six $output_selection == OUTPUT_INTERNAL) { 2202*78a88f79SMario Six 2203*78a88f79SMario Six push(@export_file_list, @ARGV); 2204*78a88f79SMario Six 2205*78a88f79SMario Six foreach (@export_file_list) { 2206*78a88f79SMario Six chomp; 2207*78a88f79SMario Six process_export_file($_); 2208*78a88f79SMario Six } 2209*78a88f79SMario Six} 2210*78a88f79SMario Six 22118fac9c7bSMasahiro Yamadaforeach (@ARGV) { 22128fac9c7bSMasahiro Yamada chomp; 22138fac9c7bSMasahiro Yamada process_file($_); 22148fac9c7bSMasahiro Yamada} 22158fac9c7bSMasahiro Yamadaif ($verbose && $errors) { 22168fac9c7bSMasahiro Yamada print STDERR "$errors errors\n"; 22178fac9c7bSMasahiro Yamada} 22188fac9c7bSMasahiro Yamadaif ($verbose && $warnings) { 22198fac9c7bSMasahiro Yamada print STDERR "$warnings warnings\n"; 22208fac9c7bSMasahiro Yamada} 22218fac9c7bSMasahiro Yamada 2222*78a88f79SMario Sixexit($output_mode eq "none" ? 0 : $errors); 2223