1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 238476378SJonathan Corbet# SPDX-License-Identifier: GPL-2.0 31da177e4SLinus Torvalds 4cb77f0d6SKamil Rytarowskiuse warnings; 51da177e4SLinus Torvaldsuse strict; 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 81da177e4SLinus Torvalds## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 91da177e4SLinus Torvalds## Copyright (C) 2001 Simon Huggins ## 1070c95b00SRandy Dunlap## Copyright (C) 2005-2012 Randy Dunlap ## 111b40c194SDan Luedtke## Copyright (C) 2012 Dan Luedtke ## 121da177e4SLinus Torvalds## ## 131da177e4SLinus Torvalds## #define enhancements by Armin Kuster <akuster@mvista.com> ## 141da177e4SLinus Torvalds## Copyright (c) 2000 MontaVista Software, Inc. ## 151da177e4SLinus Torvalds## ## 161da177e4SLinus Torvalds## This software falls under the GNU General Public License. ## 171da177e4SLinus Torvalds## Please read the COPYING file for more information ## 181da177e4SLinus Torvalds 1943caf1a6STomasz Warniełłouse Pod::Usage qw/pod2usage/; 2043caf1a6STomasz Warniełło 21a5cdaea5STomasz Warniełło=head1 NAME 22a5cdaea5STomasz Warniełło 23a5cdaea5STomasz Warniełłokernel-doc - Print formatted kernel documentation to stdout 24a5cdaea5STomasz Warniełło 25a5cdaea5STomasz Warniełło=head1 SYNOPSIS 26a5cdaea5STomasz Warniełło 27a5cdaea5STomasz Warniełło kernel-doc [-h] [-v] [-Werror] 28a5cdaea5STomasz Warniełło [ -man | 29a5cdaea5STomasz Warniełło -rst [-sphinx-version VERSION] [-enable-lineno] | 30a5cdaea5STomasz Warniełło -none 31a5cdaea5STomasz Warniełło ] 32a5cdaea5STomasz Warniełło [ 33a5cdaea5STomasz Warniełło -export | 34a5cdaea5STomasz Warniełło -internal | 35a5cdaea5STomasz Warniełło [-function NAME] ... | 36a5cdaea5STomasz Warniełło [-nosymbol NAME] ... 37a5cdaea5STomasz Warniełło ] 38a5cdaea5STomasz Warniełło [-no-doc-sections] 39a5cdaea5STomasz Warniełło [-export-file FILE] ... 40a5cdaea5STomasz Warniełło FILE ... 41a5cdaea5STomasz Warniełło 42a5cdaea5STomasz WarniełłoRun `kernel-doc -h` for details. 43a5cdaea5STomasz Warniełło 44f1583922STomasz Warniełło=head1 DESCRIPTION 45f1583922STomasz Warniełło 46f1583922STomasz WarniełłoRead C language source or header FILEs, extract embedded documentation comments, 47f1583922STomasz Warniełłoand print formatted documentation to standard output. 48f1583922STomasz Warniełło 49f1583922STomasz WarniełłoThe documentation comments are identified by the "/**" opening comment mark. 50f1583922STomasz Warniełło 51f1583922STomasz WarniełłoSee Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. 52f1583922STomasz Warniełło 53a5cdaea5STomasz Warniełło=cut 54a5cdaea5STomasz Warniełło 552875f787STomasz Warniełło# more perldoc at the end of the file 562875f787STomasz Warniełło 571da177e4SLinus Torvalds# 18/01/2001 - Cleanups 581da177e4SLinus Torvalds# Functions prototyped as foo(void) same as foo() 591da177e4SLinus Torvalds# Stop eval'ing where we don't need to. 601da177e4SLinus Torvalds# -- huggie@earth.li 611da177e4SLinus Torvalds 621da177e4SLinus Torvalds# 27/06/2001 - Allowed whitespace after initial "/**" and 631da177e4SLinus Torvalds# allowed comments before function declarations. 641da177e4SLinus Torvalds# -- Christian Kreibich <ck@whoop.org> 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds# Still to do: 671da177e4SLinus Torvalds# - add perldoc documentation 681da177e4SLinus Torvalds# - Look more closely at some of the scarier bits :) 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds# 26/05/2001 - Support for separate source and object trees. 711da177e4SLinus Torvalds# Return error code. 721da177e4SLinus Torvalds# Keith Owens <kaos@ocs.com.au> 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds# 23/09/2001 - Added support for typedefs, structs, enums and unions 751da177e4SLinus Torvalds# Support for Context section; can be terminated using empty line 761da177e4SLinus Torvalds# Small fixes (like spaces vs. \s in regex) 771da177e4SLinus Torvalds# -- Tim Jansen <tim@tjansen.de> 781da177e4SLinus Torvalds 791b40c194SDan Luedtke# 25/07/2012 - Added support for HTML5 801b40c194SDan Luedtke# -- Dan Luedtke <mail@danrl.de> 811da177e4SLinus Torvalds 82fadc0b31SJani Nikulasub usage { 83fadc0b31SJani Nikula my $message = <<"EOF"; 84fadc0b31SJani NikulaUsage: $0 [OPTION ...] FILE ... 851da177e4SLinus Torvalds 86fadc0b31SJani NikulaOutput selection modifiers: 87fadc0b31SJani Nikula -no-doc-sections Do not output DOC: sections. 880b0f5f29SDaniel Vetter -enable-lineno Enable output of #define LINENO lines. Only works with 890b0f5f29SDaniel Vetter reStructuredText format. 9088c2b57dSJani Nikula -export-file FILE Specify an additional FILE in which to look for 9188c2b57dSJani Nikula EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with 9288c2b57dSJani Nikula -export or -internal. May be specified multiple times. 93fadc0b31SJani Nikula 94fadc0b31SJani NikulaOther parameters: 95fadc0b31SJani Nikula -v Verbose output, more warnings and other information. 96fadc0b31SJani Nikula -h Print this help. 972c12c810SPierre-Louis Bossart -Werror Treat warnings as errors. 98fadc0b31SJani Nikula 99fadc0b31SJani NikulaEOF 100fadc0b31SJani Nikula print $message; 101fadc0b31SJani Nikula exit 1; 102fadc0b31SJani Nikula} 1031da177e4SLinus Torvalds 1041da177e4SLinus Torvalds# 1051da177e4SLinus Torvalds# format of comments. 1061da177e4SLinus Torvalds# In the following table, (...)? signifies optional structure. 1071da177e4SLinus Torvalds# (...)* signifies 0 or more structure elements 1081da177e4SLinus Torvalds# /** 1091da177e4SLinus Torvalds# * function_name(:)? (- short description)? 1101da177e4SLinus Torvalds# (* @parameterx: (description of parameter x)?)* 1111da177e4SLinus Torvalds# (* a blank line)? 1121da177e4SLinus Torvalds# * (Description:)? (Description of function)? 1131da177e4SLinus Torvalds# * (section header: (section description)? )* 1141da177e4SLinus Torvalds# (*)?*/ 1151da177e4SLinus Torvalds# 1161da177e4SLinus Torvalds# So .. the trivial example would be: 1171da177e4SLinus Torvalds# 1181da177e4SLinus Torvalds# /** 1191da177e4SLinus Torvalds# * my_function 120b9d97328SRandy Dunlap# */ 1211da177e4SLinus Torvalds# 122891dcd2fSRandy Dunlap# If the Description: header tag is omitted, then there must be a blank line 1231da177e4SLinus Torvalds# after the last parameter specification. 1241da177e4SLinus Torvalds# e.g. 1251da177e4SLinus Torvalds# /** 1261da177e4SLinus Torvalds# * my_function - does my stuff 1271da177e4SLinus Torvalds# * @my_arg: its mine damnit 1281da177e4SLinus Torvalds# * 1291da177e4SLinus Torvalds# * Does my stuff explained. 1301da177e4SLinus Torvalds# */ 1311da177e4SLinus Torvalds# 1321da177e4SLinus Torvalds# or, could also use: 1331da177e4SLinus Torvalds# /** 1341da177e4SLinus Torvalds# * my_function - does my stuff 1351da177e4SLinus Torvalds# * @my_arg: its mine damnit 1361da177e4SLinus Torvalds# * Description: Does my stuff explained. 1371da177e4SLinus Torvalds# */ 1381da177e4SLinus Torvalds# etc. 1391da177e4SLinus Torvalds# 140b9d97328SRandy Dunlap# Besides functions you can also write documentation for structs, unions, 1411da177e4SLinus Torvalds# enums and typedefs. Instead of the function name you must write the name 1421da177e4SLinus Torvalds# of the declaration; the struct/union/enum/typedef must always precede 1431da177e4SLinus Torvalds# the name. Nesting of declarations is not supported. 1441da177e4SLinus Torvalds# Use the argument mechanism to document members or constants. 1451da177e4SLinus Torvalds# e.g. 1461da177e4SLinus Torvalds# /** 1471da177e4SLinus Torvalds# * struct my_struct - short description 1481da177e4SLinus Torvalds# * @a: first member 1491da177e4SLinus Torvalds# * @b: second member 1501da177e4SLinus Torvalds# * 1511da177e4SLinus Torvalds# * Longer description 1521da177e4SLinus Torvalds# */ 1531da177e4SLinus Torvalds# struct my_struct { 1541da177e4SLinus Torvalds# int a; 1551da177e4SLinus Torvalds# int b; 156aeec46b9SMartin Waitz# /* private: */ 157aeec46b9SMartin Waitz# int c; 1581da177e4SLinus Torvalds# }; 1591da177e4SLinus Torvalds# 1601da177e4SLinus Torvalds# All descriptions can be multiline, except the short function description. 1611da177e4SLinus Torvalds# 162a4c6ebedSDanilo Cesar Lemes de Paula# For really longs structs, you can also describe arguments inside the 163a4c6ebedSDanilo Cesar Lemes de Paula# body of the struct. 164a4c6ebedSDanilo Cesar Lemes de Paula# eg. 165a4c6ebedSDanilo Cesar Lemes de Paula# /** 166a4c6ebedSDanilo Cesar Lemes de Paula# * struct my_struct - short description 167a4c6ebedSDanilo Cesar Lemes de Paula# * @a: first member 168a4c6ebedSDanilo Cesar Lemes de Paula# * @b: second member 169a4c6ebedSDanilo Cesar Lemes de Paula# * 170a4c6ebedSDanilo Cesar Lemes de Paula# * Longer description 171a4c6ebedSDanilo Cesar Lemes de Paula# */ 172a4c6ebedSDanilo Cesar Lemes de Paula# struct my_struct { 173a4c6ebedSDanilo Cesar Lemes de Paula# int a; 174a4c6ebedSDanilo Cesar Lemes de Paula# int b; 175a4c6ebedSDanilo Cesar Lemes de Paula# /** 176a4c6ebedSDanilo Cesar Lemes de Paula# * @c: This is longer description of C 177a4c6ebedSDanilo Cesar Lemes de Paula# * 178a4c6ebedSDanilo Cesar Lemes de Paula# * You can use paragraphs to describe arguments 179a4c6ebedSDanilo Cesar Lemes de Paula# * using this method. 180a4c6ebedSDanilo Cesar Lemes de Paula# */ 181a4c6ebedSDanilo Cesar Lemes de Paula# int c; 182a4c6ebedSDanilo Cesar Lemes de Paula# }; 183a4c6ebedSDanilo Cesar Lemes de Paula# 184a4c6ebedSDanilo Cesar Lemes de Paula# This should be use only for struct/enum members. 185a4c6ebedSDanilo Cesar Lemes de Paula# 1861da177e4SLinus Torvalds# You can also add additional sections. When documenting kernel functions you 1871da177e4SLinus Torvalds# should document the "Context:" of the function, e.g. whether the functions 1881da177e4SLinus Torvalds# can be called form interrupts. Unlike other sections you can end it with an 1891da177e4SLinus Torvalds# empty line. 1904092bac7SYacine Belkadi# A non-void function should have a "Return:" section describing the return 1914092bac7SYacine Belkadi# value(s). 1921da177e4SLinus Torvalds# Example-sections should contain the string EXAMPLE so that they are marked 1931da177e4SLinus Torvalds# appropriately in DocBook. 1941da177e4SLinus Torvalds# 1951da177e4SLinus Torvalds# Example: 1961da177e4SLinus Torvalds# /** 1971da177e4SLinus Torvalds# * user_function - function that can only be called in user context 1981da177e4SLinus Torvalds# * @a: some argument 1991da177e4SLinus Torvalds# * Context: !in_interrupt() 2001da177e4SLinus Torvalds# * 2011da177e4SLinus Torvalds# * Some description 2021da177e4SLinus Torvalds# * Example: 2031da177e4SLinus Torvalds# * user_function(22); 2041da177e4SLinus Torvalds# */ 2051da177e4SLinus Torvalds# ... 2061da177e4SLinus Torvalds# 2071da177e4SLinus Torvalds# 2081da177e4SLinus Torvalds# All descriptive text is further processed, scanning for the following special 2091da177e4SLinus Torvalds# patterns, which are highlighted appropriately. 2101da177e4SLinus Torvalds# 2111da177e4SLinus Torvalds# 'funcname()' - function 2121da177e4SLinus Torvalds# '$ENVVAR' - environmental variable 2131da177e4SLinus Torvalds# '&struct_name' - name of a structure (up to two words including 'struct') 2145267dd35SPaolo Bonzini# '&struct_name.member' - name of a structure member 2151da177e4SLinus Torvalds# '@parameter' - name of a parameter 2161da177e4SLinus Torvalds# '%CONST' - name of a constant. 217b97f193aSMauro Carvalho Chehab# '``LITERAL``' - literal string without any spaces on it. 2181da177e4SLinus Torvalds 2198484baaaSRandy Dunlap## init lots of data 2208484baaaSRandy Dunlap 2211da177e4SLinus Torvaldsmy $errors = 0; 2221da177e4SLinus Torvaldsmy $warnings = 0; 2235f8c7c98SRandy Dunlapmy $anon_struct_union = 0; 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds# match expressions used to find embedded type information 226b97f193aSMauro Carvalho Chehabmy $type_constant = '\b``([^\`]+)``\b'; 227b97f193aSMauro Carvalho Chehabmy $type_constant2 = '\%([-_\w]+)'; 2281da177e4SLinus Torvaldsmy $type_func = '(\w+)\(\)'; 229bfd228c7SMike Rapoportmy $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; 230ee2aa759SMauro Carvalho Chehabmy $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; 2315219f18aSJonathan Corbetmy $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params 232346282dbSMauro Carvalho Chehabmy $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params 2331da177e4SLinus Torvaldsmy $type_env = '(\$\w+)'; 234df31175bSPaolo Bonzinimy $type_enum = '\&(enum\s*([_\w]+))'; 235df31175bSPaolo Bonzinimy $type_struct = '\&(struct\s*([_\w]+))'; 236df31175bSPaolo Bonzinimy $type_typedef = '\&(typedef\s*([_\w]+))'; 237df31175bSPaolo Bonzinimy $type_union = '\&(union\s*([_\w]+))'; 2385267dd35SPaolo Bonzinimy $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; 239df31175bSPaolo Bonzinimy $type_fallback = '\&([_\w]+)'; 240f3341dcfSJani Nikulamy $type_member_func = $type_member . '\(\)'; 2411da177e4SLinus Torvalds 2421da177e4SLinus Torvalds# Output conversion substitutions. 2431da177e4SLinus Torvalds# One for each output format 2441da177e4SLinus Torvalds 2451da177e4SLinus Torvalds# these are pretty rough 2464d732701SDanilo Cesar Lemes de Paulamy @highlights_man = ( 2474d732701SDanilo Cesar Lemes de Paula [$type_constant, "\$1"], 248b97f193aSMauro Carvalho Chehab [$type_constant2, "\$1"], 2494d732701SDanilo Cesar Lemes de Paula [$type_func, "\\\\fB\$1\\\\fP"], 250df31175bSPaolo Bonzini [$type_enum, "\\\\fI\$1\\\\fP"], 2514d732701SDanilo Cesar Lemes de Paula [$type_struct, "\\\\fI\$1\\\\fP"], 252df31175bSPaolo Bonzini [$type_typedef, "\\\\fI\$1\\\\fP"], 253df31175bSPaolo Bonzini [$type_union, "\\\\fI\$1\\\\fP"], 2545267dd35SPaolo Bonzini [$type_param, "\\\\fI\$1\\\\fP"], 255ee2aa759SMauro Carvalho Chehab [$type_param_ref, "\\\\fI\$1\$2\\\\fP"], 256df31175bSPaolo Bonzini [$type_member, "\\\\fI\$1\$2\$3\\\\fP"], 257df31175bSPaolo Bonzini [$type_fallback, "\\\\fI\$1\\\\fP"] 2584d732701SDanilo Cesar Lemes de Paula ); 2591da177e4SLinus Torvaldsmy $blankline_man = ""; 2601da177e4SLinus Torvalds 261c0d1b6eeSJonathan Corbet# rst-mode 262c0d1b6eeSJonathan Corbetmy @highlights_rst = ( 263c0d1b6eeSJonathan Corbet [$type_constant, "``\$1``"], 264b97f193aSMauro Carvalho Chehab [$type_constant2, "``\$1``"], 265f3341dcfSJani Nikula # Note: need to escape () to avoid func matching later 2665267dd35SPaolo Bonzini [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"], 2675267dd35SPaolo Bonzini [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"], 2685219f18aSJonathan Corbet [$type_fp_param, "**\$1\\\\(\\\\)**"], 269346282dbSMauro Carvalho Chehab [$type_fp_param2, "**\$1\\\\(\\\\)**"], 270344fdb28SJonathan Corbet [$type_func, "\$1()"], 271df31175bSPaolo Bonzini [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], 272df31175bSPaolo Bonzini [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"], 273df31175bSPaolo Bonzini [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"], 274df31175bSPaolo Bonzini [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"], 275a7291e7eSJani Nikula # in rst this can refer to any type 276df31175bSPaolo Bonzini [$type_fallback, "\\:c\\:type\\:`\$1`"], 277ee2aa759SMauro Carvalho Chehab [$type_param_ref, "**\$1\$2**"] 278c0d1b6eeSJonathan Corbet ); 279c0d1b6eeSJonathan Corbetmy $blankline_rst = "\n"; 280c0d1b6eeSJonathan Corbet 2811da177e4SLinus Torvalds# read arguments 2821da177e4SLinus Torvaldsif ($#ARGV == -1) { 28343caf1a6STomasz Warniełło pod2usage( 28443caf1a6STomasz Warniełło -message => "No arguments!\n", 28543caf1a6STomasz Warniełło -exitval => 1, 28643caf1a6STomasz Warniełło -verbose => 99, 28743caf1a6STomasz Warniełło -sections => 'SYNOPSIS', 28843caf1a6STomasz Warniełło -output => \*STDERR, 28943caf1a6STomasz Warniełło ); 2901da177e4SLinus Torvalds} 2911da177e4SLinus Torvalds 2928484baaaSRandy Dunlapmy $kernelversion; 29393351d41SMauro Carvalho Chehabmy ($sphinx_major, $sphinx_minor, $sphinx_patch); 294efa44475SMauro Carvalho Chehab 2958484baaaSRandy Dunlapmy $dohighlight = ""; 2968484baaaSRandy Dunlap 2971da177e4SLinus Torvaldsmy $verbose = 0; 2982c12c810SPierre-Louis Bossartmy $Werror = 0; 299bdfe2be3SMauro Carvalho Chehabmy $output_mode = "rst"; 300e314ba31SDaniel Santosmy $output_preformatted = 0; 3014b44595aSJohannes Bergmy $no_doc_sections = 0; 3020b0f5f29SDaniel Vettermy $enable_lineno = 0; 303bdfe2be3SMauro Carvalho Chehabmy @highlights = @highlights_rst; 304bdfe2be3SMauro Carvalho Chehabmy $blankline = $blankline_rst; 3051da177e4SLinus Torvaldsmy $modulename = "Kernel API"; 306b6c3f456SJani Nikula 307b6c3f456SJani Nikulause constant { 308b6c3f456SJani Nikula OUTPUT_ALL => 0, # output all symbols and doc sections 309b6c3f456SJani Nikula OUTPUT_INCLUDE => 1, # output only specified symbols 310eab795ddSMauro Carvalho Chehab OUTPUT_EXPORTED => 2, # output exported symbols 311eab795ddSMauro Carvalho Chehab OUTPUT_INTERNAL => 3, # output non-exported symbols 312b6c3f456SJani Nikula}; 313b6c3f456SJani Nikulamy $output_selection = OUTPUT_ALL; 314b0d60bfbSJonathan Corbetmy $show_not_found = 0; # No longer used 315b2c4105bSBen Hutchings 31688c2b57dSJani Nikulamy @export_file_list; 31788c2b57dSJani Nikula 318b2c4105bSBen Hutchingsmy @build_time; 319b2c4105bSBen Hutchingsif (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 320b2c4105bSBen Hutchings (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { 321b2c4105bSBen Hutchings @build_time = gmtime($seconds); 322b2c4105bSBen Hutchings} else { 323b2c4105bSBen Hutchings @build_time = localtime; 324b2c4105bSBen Hutchings} 325b2c4105bSBen Hutchings 3261da177e4SLinus Torvaldsmy $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 3271da177e4SLinus Torvalds 'July', 'August', 'September', 'October', 328b2c4105bSBen Hutchings 'November', 'December')[$build_time[4]] . 329b2c4105bSBen Hutchings " " . ($build_time[5]+1900); 3301da177e4SLinus Torvalds 3318484baaaSRandy Dunlap# Essentially these are globals. 332b9d97328SRandy Dunlap# They probably want to be tidied up, made more localised or something. 333b9d97328SRandy Dunlap# CAVEAT EMPTOR! Some of the others I localised may not want to be, which 3341da177e4SLinus Torvalds# could cause "use of undefined value" or other bugs. 3351da177e4SLinus Torvaldsmy ($function, %function_table, %parametertypes, $declaration_purpose); 336eab795ddSMauro Carvalho Chehabmy %nosymbol_table = (); 3370b0f5f29SDaniel Vettermy $declaration_start_line; 3381da177e4SLinus Torvaldsmy ($type, $declaration_name, $return_type); 3391c32fd0cSIlya Dryomovmy ($newsection, $newcontents, $prototype, $brcount, %source_map); 3401da177e4SLinus Torvalds 341bd0e88e5SRandy Dunlapif (defined($ENV{'KBUILD_VERBOSE'})) { 342bd0e88e5SRandy Dunlap $verbose = "$ENV{'KBUILD_VERBOSE'}"; 343bd0e88e5SRandy Dunlap} 344bd0e88e5SRandy Dunlap 3452c12c810SPierre-Louis Bossartif (defined($ENV{'KCFLAGS'})) { 3462c12c810SPierre-Louis Bossart my $kcflags = "$ENV{'KCFLAGS'}"; 3472c12c810SPierre-Louis Bossart 3482c12c810SPierre-Louis Bossart if ($kcflags =~ /Werror/) { 3492c12c810SPierre-Louis Bossart $Werror = 1; 3502c12c810SPierre-Louis Bossart } 3512c12c810SPierre-Louis Bossart} 3522c12c810SPierre-Louis Bossart 353bed4ed30SLaurent Pinchartif (defined($ENV{'KDOC_WERROR'})) { 354bed4ed30SLaurent Pinchart $Werror = "$ENV{'KDOC_WERROR'}"; 355bed4ed30SLaurent Pinchart} 356bed4ed30SLaurent Pinchart 3571da177e4SLinus Torvalds# Generated docbook code is inserted in a template at a point where 3581da177e4SLinus Torvalds# docbook v3.1 requires a non-zero sequence of RefEntry's; see: 35993431e06SAlexander A. Klimov# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html 3601da177e4SLinus Torvalds# We keep track of number of generated entries and generate a dummy 3611da177e4SLinus Torvalds# if needs be to ensure the expanded template can be postprocessed 3621da177e4SLinus Torvalds# into html. 3631da177e4SLinus Torvaldsmy $section_counter = 0; 3641da177e4SLinus Torvalds 3651da177e4SLinus Torvaldsmy $lineprefix=""; 3661da177e4SLinus Torvalds 36748af606aSJani Nikula# Parser states 36848af606aSJani Nikulause constant { 36948af606aSJani Nikula STATE_NORMAL => 0, # normal code 37048af606aSJani Nikula STATE_NAME => 1, # looking for function name 37117b78717SJonathan Corbet STATE_BODY_MAYBE => 2, # body - or maybe more description 37217b78717SJonathan Corbet STATE_BODY => 3, # the body of the comment 3730d55d48bSMauro Carvalho Chehab STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line 3740d55d48bSMauro Carvalho Chehab STATE_PROTO => 5, # scanning prototype 3750d55d48bSMauro Carvalho Chehab STATE_DOCBLOCK => 6, # documentation block 3760d55d48bSMauro Carvalho Chehab STATE_INLINE => 7, # gathering doc outside main block 37748af606aSJani Nikula}; 3781da177e4SLinus Torvaldsmy $state; 379850622dfSRandy Dunlapmy $in_doc_sect; 380d742f24dSJonathan Corbetmy $leading_space; 3811da177e4SLinus Torvalds 38248af606aSJani Nikula# Inline documentation state 38348af606aSJani Nikulause constant { 38448af606aSJani Nikula STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) 38548af606aSJani Nikula STATE_INLINE_NAME => 1, # looking for member name (@foo:) 38648af606aSJani Nikula STATE_INLINE_TEXT => 2, # looking for member documentation 38748af606aSJani Nikula STATE_INLINE_END => 3, # done 38848af606aSJani Nikula STATE_INLINE_ERROR => 4, # error - Comment without header was found. 38948af606aSJani Nikula # Spit a warning as it's not 390a4c6ebedSDanilo Cesar Lemes de Paula # proper kernel-doc and ignore the rest. 39148af606aSJani Nikula}; 39248af606aSJani Nikulamy $inline_doc_state; 393a4c6ebedSDanilo Cesar Lemes de Paula 3941da177e4SLinus Torvalds#declaration types: can be 3951da177e4SLinus Torvalds# 'function', 'struct', 'union', 'enum', 'typedef' 3961da177e4SLinus Torvaldsmy $decl_type; 3971da177e4SLinus Torvalds 39852042e2dSMauro Carvalho Chehab# Name of the kernel-doc identifier for non-DOC markups 39952042e2dSMauro Carvalho Chehabmy $identifier; 40052042e2dSMauro Carvalho Chehab 4011da177e4SLinus Torvaldsmy $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 4021da177e4SLinus Torvaldsmy $doc_end = '\*/'; 4031da177e4SLinus Torvaldsmy $doc_com = '\s*\*\s*'; 40412ae6779SDaniel Santosmy $doc_com_body = '\s*\* ?'; 4051da177e4SLinus Torvaldsmy $doc_decl = $doc_com . '(\w+)'; 406f624adefSJani Nikula# @params and a strictly limited set of supported section names 407212209cfSJonathan Corbet# Specifically: 408212209cfSJonathan Corbet# Match @word: 409212209cfSJonathan Corbet# @...: 410212209cfSJonathan Corbet# @{section-name}: 411212209cfSJonathan Corbet# while trying to not match literal block starts like "example::" 412212209cfSJonathan Corbet# 4138569de68SJonathan Corbetmy $doc_sect = $doc_com . 414212209cfSJonathan Corbet '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; 41512ae6779SDaniel Santosmy $doc_content = $doc_com_body . '(.*)'; 4161da177e4SLinus Torvaldsmy $doc_block = $doc_com . 'DOC:\s*(.*)?'; 41748af606aSJani Nikulamy $doc_inline_start = '^\s*/\*\*\s*$'; 418fe7bc493SMauro Carvalho Chehabmy $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; 41948af606aSJani Nikulamy $doc_inline_end = '^\s*\*/\s*$'; 4200c9aa209SJani Nikulamy $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; 42186ae2e38SJani Nikulamy $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 422e86bdb24SAditya Srivastavamy $function_pointer = qr{([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)}; 423e86bdb24SAditya Srivastavamy $attribute = qr{__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)}i; 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvaldsmy %parameterdescs; 4260b0f5f29SDaniel Vettermy %parameterdesc_start_lines; 4271da177e4SLinus Torvaldsmy @parameterlist; 4281da177e4SLinus Torvaldsmy %sections; 4291da177e4SLinus Torvaldsmy @sectionlist; 4300b0f5f29SDaniel Vettermy %section_start_lines; 431a1d94aa5SRandy Dunlapmy $sectcheck; 432a1d94aa5SRandy Dunlapmy $struct_actual; 4331da177e4SLinus Torvalds 4341da177e4SLinus Torvaldsmy $contents = ""; 4350b0f5f29SDaniel Vettermy $new_start_line = 0; 436f624adefSJani Nikula 437f624adefSJani Nikula# the canonical section names. see also $doc_sect above. 4381da177e4SLinus Torvaldsmy $section_default = "Description"; # default section 4391da177e4SLinus Torvaldsmy $section_intro = "Introduction"; 4401da177e4SLinus Torvaldsmy $section = $section_default; 4411da177e4SLinus Torvaldsmy $section_context = "Context"; 4424092bac7SYacine Belkadimy $section_return = "Return"; 4431da177e4SLinus Torvalds 4441da177e4SLinus Torvaldsmy $undescribed = "-- undescribed --"; 4451da177e4SLinus Torvalds 4461da177e4SLinus Torvaldsreset_state(); 4471da177e4SLinus Torvalds 448b031ac4eSMauro Carvalho Chehabwhile ($ARGV[0] =~ m/^--?(.*)/) { 449b031ac4eSMauro Carvalho Chehab my $cmd = $1; 450b031ac4eSMauro Carvalho Chehab shift @ARGV; 451b031ac4eSMauro Carvalho Chehab if ($cmd eq "man") { 4521da177e4SLinus Torvalds $output_mode = "man"; 4534d732701SDanilo Cesar Lemes de Paula @highlights = @highlights_man; 4541da177e4SLinus Torvalds $blankline = $blankline_man; 455b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "rst") { 456c0d1b6eeSJonathan Corbet $output_mode = "rst"; 457c0d1b6eeSJonathan Corbet @highlights = @highlights_rst; 458c0d1b6eeSJonathan Corbet $blankline = $blankline_rst; 459b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "none") { 4603a025e1dSMatthew Wilcox $output_mode = "none"; 461b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document 4621da177e4SLinus Torvalds $modulename = shift @ARGV; 463b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "function") { # to only output specific functions 464b6c3f456SJani Nikula $output_selection = OUTPUT_INCLUDE; 4651da177e4SLinus Torvalds $function = shift @ARGV; 4661da177e4SLinus Torvalds $function_table{$function} = 1; 467eab795ddSMauro Carvalho Chehab } elsif ($cmd eq "nosymbol") { # Exclude specific symbols 468eab795ddSMauro Carvalho Chehab my $symbol = shift @ARGV; 469eab795ddSMauro Carvalho Chehab $nosymbol_table{$symbol} = 1; 470b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "export") { # only exported symbols 471b6c3f456SJani Nikula $output_selection = OUTPUT_EXPORTED; 472da9726ecSJani Nikula %function_table = (); 473b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "internal") { # only non-exported symbols 474b6c3f456SJani Nikula $output_selection = OUTPUT_INTERNAL; 475da9726ecSJani Nikula %function_table = (); 476b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "export-file") { 47788c2b57dSJani Nikula my $file = shift @ARGV; 47888c2b57dSJani Nikula push(@export_file_list, $file); 479b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq "v") { 4801da177e4SLinus Torvalds $verbose = 1; 4812c12c810SPierre-Louis Bossart } elsif ($cmd eq "Werror") { 4822c12c810SPierre-Louis Bossart $Werror = 1; 483b031ac4eSMauro Carvalho Chehab } elsif (($cmd eq "h") || ($cmd eq "help")) { 4841da177e4SLinus Torvalds usage(); 485b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq 'no-doc-sections') { 4864b44595aSJohannes Berg $no_doc_sections = 1; 487b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq 'enable-lineno') { 4880b0f5f29SDaniel Vetter $enable_lineno = 1; 489b031ac4eSMauro Carvalho Chehab } elsif ($cmd eq 'show-not-found') { 490b0d60bfbSJonathan Corbet $show_not_found = 1; # A no-op but don't fail 49193351d41SMauro Carvalho Chehab } elsif ($cmd eq "sphinx-version") { 49293351d41SMauro Carvalho Chehab my $ver_string = shift @ARGV; 49393351d41SMauro Carvalho Chehab if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) { 49493351d41SMauro Carvalho Chehab $sphinx_major = $1; 49593351d41SMauro Carvalho Chehab if (defined($2)) { 49693351d41SMauro Carvalho Chehab $sphinx_minor = substr($2,1); 49793351d41SMauro Carvalho Chehab } else { 49893351d41SMauro Carvalho Chehab $sphinx_minor = 0; 49993351d41SMauro Carvalho Chehab } 50093351d41SMauro Carvalho Chehab if (defined($3)) { 50193351d41SMauro Carvalho Chehab $sphinx_patch = substr($3,1) 50293351d41SMauro Carvalho Chehab } else { 50393351d41SMauro Carvalho Chehab $sphinx_patch = 0; 50493351d41SMauro Carvalho Chehab } 50593351d41SMauro Carvalho Chehab } else { 50693351d41SMauro Carvalho Chehab die "Sphinx version should either major.minor or major.minor.patch format\n"; 50793351d41SMauro Carvalho Chehab } 508b031ac4eSMauro Carvalho Chehab } else { 509b031ac4eSMauro Carvalho Chehab # Unknown argument 51043caf1a6STomasz Warniełło pod2usage( 51143caf1a6STomasz Warniełło -message => "Argument unknown!\n", 51243caf1a6STomasz Warniełło -exitval => 1, 51343caf1a6STomasz Warniełło -verbose => 99, 51443caf1a6STomasz Warniełło -sections => 'SYNOPSIS', 51543caf1a6STomasz Warniełło -output => \*STDERR, 51643caf1a6STomasz Warniełło ); 5171da177e4SLinus Torvalds } 5181da177e4SLinus Torvalds} 5191da177e4SLinus Torvalds 5208484baaaSRandy Dunlap# continue execution near EOF; 5218484baaaSRandy Dunlap 522efa44475SMauro Carvalho Chehab# The C domain dialect changed on Sphinx 3. So, we need to check the 523efa44475SMauro Carvalho Chehab# version in order to produce the right tags. 524efa44475SMauro Carvalho Chehabsub findprog($) 525efa44475SMauro Carvalho Chehab{ 526efa44475SMauro Carvalho Chehab foreach(split(/:/, $ENV{PATH})) { 527efa44475SMauro Carvalho Chehab return "$_/$_[0]" if(-x "$_/$_[0]"); 528efa44475SMauro Carvalho Chehab } 529efa44475SMauro Carvalho Chehab} 530efa44475SMauro Carvalho Chehab 531efa44475SMauro Carvalho Chehabsub get_sphinx_version() 532efa44475SMauro Carvalho Chehab{ 533efa44475SMauro Carvalho Chehab my $ver; 534efa44475SMauro Carvalho Chehab 535efa44475SMauro Carvalho Chehab my $cmd = "sphinx-build"; 536efa44475SMauro Carvalho Chehab if (!findprog($cmd)) { 537efa44475SMauro Carvalho Chehab my $cmd = "sphinx-build3"; 53893351d41SMauro Carvalho Chehab if (!findprog($cmd)) { 53993351d41SMauro Carvalho Chehab $sphinx_major = 1; 54093351d41SMauro Carvalho Chehab $sphinx_minor = 2; 54193351d41SMauro Carvalho Chehab $sphinx_patch = 0; 54293351d41SMauro Carvalho Chehab printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n", 54393351d41SMauro Carvalho Chehab $sphinx_major, $sphinx_minor, $sphinx_patch; 54493351d41SMauro Carvalho Chehab return; 54593351d41SMauro Carvalho Chehab } 546efa44475SMauro Carvalho Chehab } 547efa44475SMauro Carvalho Chehab 548efa44475SMauro Carvalho Chehab open IN, "$cmd --version 2>&1 |"; 549efa44475SMauro Carvalho Chehab while (<IN>) { 550efa44475SMauro Carvalho Chehab if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) { 55193351d41SMauro Carvalho Chehab $sphinx_major = $1; 55293351d41SMauro Carvalho Chehab $sphinx_minor = $2; 55393351d41SMauro Carvalho Chehab $sphinx_patch = $3; 554efa44475SMauro Carvalho Chehab last; 555efa44475SMauro Carvalho Chehab } 556efa44475SMauro Carvalho Chehab # Sphinx 1.2.x uses a different format 557efa44475SMauro Carvalho Chehab if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) { 55893351d41SMauro Carvalho Chehab $sphinx_major = $1; 55993351d41SMauro Carvalho Chehab $sphinx_minor = $2; 56093351d41SMauro Carvalho Chehab $sphinx_patch = $3; 561efa44475SMauro Carvalho Chehab last; 562efa44475SMauro Carvalho Chehab } 563efa44475SMauro Carvalho Chehab } 564efa44475SMauro Carvalho Chehab close IN; 565efa44475SMauro Carvalho Chehab} 566efa44475SMauro Carvalho Chehab 56753f049faSBorislav Petkov# get kernel version from env 56853f049faSBorislav Petkovsub get_kernel_version() { 5691b9bc22dSJohannes Berg my $version = 'unknown kernel version'; 57053f049faSBorislav Petkov 57153f049faSBorislav Petkov if (defined($ENV{'KERNELVERSION'})) { 57253f049faSBorislav Petkov $version = $ENV{'KERNELVERSION'}; 57353f049faSBorislav Petkov } 57453f049faSBorislav Petkov return $version; 57553f049faSBorislav Petkov} 5761da177e4SLinus Torvalds 5770b0f5f29SDaniel Vetter# 5780b0f5f29SDaniel Vettersub print_lineno { 5790b0f5f29SDaniel Vetter my $lineno = shift; 5800b0f5f29SDaniel Vetter if ($enable_lineno && defined($lineno)) { 5810b0f5f29SDaniel Vetter print "#define LINENO " . $lineno . "\n"; 5820b0f5f29SDaniel Vetter } 5830b0f5f29SDaniel Vetter} 5841da177e4SLinus Torvalds## 5851da177e4SLinus Torvalds# dumps section contents to arrays/hashes intended for that purpose. 5861da177e4SLinus Torvalds# 5871da177e4SLinus Torvaldssub dump_section { 58894dc7ad5SRandy Dunlap my $file = shift; 5891da177e4SLinus Torvalds my $name = shift; 5901da177e4SLinus Torvalds my $contents = join "\n", @_; 5911da177e4SLinus Torvalds 59213901ef2SJani Nikula if ($name =~ m/$type_param/) { 5931da177e4SLinus Torvalds $name = $1; 5941da177e4SLinus Torvalds $parameterdescs{$name} = $contents; 595a1d94aa5SRandy Dunlap $sectcheck = $sectcheck . $name . " "; 5960b0f5f29SDaniel Vetter $parameterdesc_start_lines{$name} = $new_start_line; 5970b0f5f29SDaniel Vetter $new_start_line = 0; 598ced69090SRandy Dunlap } elsif ($name eq "@\.\.\.") { 599ced69090SRandy Dunlap $name = "..."; 600ced69090SRandy Dunlap $parameterdescs{$name} = $contents; 601a1d94aa5SRandy Dunlap $sectcheck = $sectcheck . $name . " "; 6020b0f5f29SDaniel Vetter $parameterdesc_start_lines{$name} = $new_start_line; 6030b0f5f29SDaniel Vetter $new_start_line = 0; 6041da177e4SLinus Torvalds } else { 60594dc7ad5SRandy Dunlap if (defined($sections{$name}) && ($sections{$name} ne "")) { 60695b6be9dSJani Nikula # Only warn on user specified duplicate section names. 60795b6be9dSJani Nikula if ($name ne $section_default) { 60832217761SJani Nikula print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; 60932217761SJani Nikula ++$warnings; 61095b6be9dSJani Nikula } 61132217761SJani Nikula $sections{$name} .= $contents; 61232217761SJani Nikula } else { 6131da177e4SLinus Torvalds $sections{$name} = $contents; 6141da177e4SLinus Torvalds push @sectionlist, $name; 6150b0f5f29SDaniel Vetter $section_start_lines{$name} = $new_start_line; 6160b0f5f29SDaniel Vetter $new_start_line = 0; 6171da177e4SLinus Torvalds } 6181da177e4SLinus Torvalds } 61932217761SJani Nikula} 6201da177e4SLinus Torvalds 6211da177e4SLinus Torvalds## 622b112e0f7SJohannes Berg# dump DOC: section after checking that it should go out 623b112e0f7SJohannes Berg# 624b112e0f7SJohannes Bergsub dump_doc_section { 62594dc7ad5SRandy Dunlap my $file = shift; 626b112e0f7SJohannes Berg my $name = shift; 627b112e0f7SJohannes Berg my $contents = join "\n", @_; 628b112e0f7SJohannes Berg 6294b44595aSJohannes Berg if ($no_doc_sections) { 6304b44595aSJohannes Berg return; 6314b44595aSJohannes Berg } 6324b44595aSJohannes Berg 633eab795ddSMauro Carvalho Chehab return if (defined($nosymbol_table{$name})); 634eab795ddSMauro Carvalho Chehab 635b6c3f456SJani Nikula if (($output_selection == OUTPUT_ALL) || 636eab795ddSMauro Carvalho Chehab (($output_selection == OUTPUT_INCLUDE) && 637eab795ddSMauro Carvalho Chehab defined($function_table{$name}))) 638b112e0f7SJohannes Berg { 63994dc7ad5SRandy Dunlap dump_section($file, $name, $contents); 640b112e0f7SJohannes Berg output_blockhead({'sectionlist' => \@sectionlist, 641b112e0f7SJohannes Berg 'sections' => \%sections, 642b112e0f7SJohannes Berg 'module' => $modulename, 643b6c3f456SJani Nikula 'content-only' => ($output_selection != OUTPUT_ALL), }); 644b112e0f7SJohannes Berg } 645b112e0f7SJohannes Berg} 646b112e0f7SJohannes Berg 647b112e0f7SJohannes Berg## 6481da177e4SLinus Torvalds# output function 6491da177e4SLinus Torvalds# 6501da177e4SLinus Torvalds# parameterdescs, a hash. 6511da177e4SLinus Torvalds# function => "function name" 6521da177e4SLinus Torvalds# parameterlist => @list of parameters 6531da177e4SLinus Torvalds# parameterdescs => %parameter descriptions 6541da177e4SLinus Torvalds# sectionlist => @list of sections 655a21217daSRandy Dunlap# sections => %section descriptions 6561da177e4SLinus Torvalds# 6571da177e4SLinus Torvalds 6581da177e4SLinus Torvaldssub output_highlight { 6591da177e4SLinus Torvalds my $contents = join "\n",@_; 6601da177e4SLinus Torvalds my $line; 6611da177e4SLinus Torvalds 6621da177e4SLinus Torvalds# DEBUG 6631da177e4SLinus Torvalds# if (!defined $contents) { 6641da177e4SLinus Torvalds# use Carp; 6651da177e4SLinus Torvalds# confess "output_highlight got called with no args?\n"; 6661da177e4SLinus Torvalds# } 6671da177e4SLinus Torvalds 6683eb014a1SRandy Dunlap# print STDERR "contents b4:$contents\n"; 6691da177e4SLinus Torvalds eval $dohighlight; 6701da177e4SLinus Torvalds die $@ if $@; 6713eb014a1SRandy Dunlap# print STDERR "contents af:$contents\n"; 6723eb014a1SRandy Dunlap 6731da177e4SLinus Torvalds foreach $line (split "\n", $contents) { 67412ae6779SDaniel Santos if (! $output_preformatted) { 67512ae6779SDaniel Santos $line =~ s/^\s*//; 67612ae6779SDaniel Santos } 6771da177e4SLinus Torvalds if ($line eq ""){ 678e314ba31SDaniel Santos if (! $output_preformatted) { 6790bba924cSJonathan Corbet print $lineprefix, $blankline; 680e314ba31SDaniel Santos } 6811da177e4SLinus Torvalds } else { 682cdccb316SRandy Dunlap if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { 683cdccb316SRandy Dunlap print "\\&$line"; 684cdccb316SRandy Dunlap } else { 6851da177e4SLinus Torvalds print $lineprefix, $line; 6861da177e4SLinus Torvalds } 687cdccb316SRandy Dunlap } 6881da177e4SLinus Torvalds print "\n"; 6891da177e4SLinus Torvalds } 6901da177e4SLinus Torvalds} 6911da177e4SLinus Torvalds 6921da177e4SLinus Torvalds## 6931da177e4SLinus Torvalds# output function in man 6941da177e4SLinus Torvaldssub output_function_man(%) { 6951da177e4SLinus Torvalds my %args = %{$_[0]}; 6961da177e4SLinus Torvalds my ($parameter, $section); 6971da177e4SLinus Torvalds my $count; 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n"; 7001da177e4SLinus Torvalds 7011da177e4SLinus Torvalds print ".SH NAME\n"; 7021da177e4SLinus Torvalds print $args{'function'} . " \\- " . $args{'purpose'} . "\n"; 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds print ".SH SYNOPSIS\n"; 705a21217daSRandy Dunlap if ($args{'functiontype'} ne "") { 7061da177e4SLinus Torvalds print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n"; 707a21217daSRandy Dunlap } else { 708a21217daSRandy Dunlap print ".B \"" . $args{'function'} . "\n"; 709a21217daSRandy Dunlap } 7101da177e4SLinus Torvalds $count = 0; 7111da177e4SLinus Torvalds my $parenth = "("; 7121da177e4SLinus Torvalds my $post = ","; 7131da177e4SLinus Torvalds foreach my $parameter (@{$args{'parameterlist'}}) { 7141da177e4SLinus Torvalds if ($count == $#{$args{'parameterlist'}}) { 7151da177e4SLinus Torvalds $post = ");"; 7161da177e4SLinus Torvalds } 7171da177e4SLinus Torvalds $type = $args{'parametertypes'}{$parameter}; 718e86bdb24SAditya Srivastava if ($type =~ m/$function_pointer/) { 7191da177e4SLinus Torvalds # pointer-to-function 720ed8348e2SMauro Carvalho Chehab print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n"; 7211da177e4SLinus Torvalds } else { 7221da177e4SLinus Torvalds $type =~ s/([^\*])$/$1 /; 723ed8348e2SMauro Carvalho Chehab print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n"; 7241da177e4SLinus Torvalds } 7251da177e4SLinus Torvalds $count++; 7261da177e4SLinus Torvalds $parenth = ""; 7271da177e4SLinus Torvalds } 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds print ".SH ARGUMENTS\n"; 7301da177e4SLinus Torvalds foreach $parameter (@{$args{'parameterlist'}}) { 7311da177e4SLinus Torvalds my $parameter_name = $parameter; 7321da177e4SLinus Torvalds $parameter_name =~ s/\[.*//; 7331da177e4SLinus Torvalds 7341da177e4SLinus Torvalds print ".IP \"" . $parameter . "\" 12\n"; 7351da177e4SLinus Torvalds output_highlight($args{'parameterdescs'}{$parameter_name}); 7361da177e4SLinus Torvalds } 7371da177e4SLinus Torvalds foreach $section (@{$args{'sectionlist'}}) { 7381da177e4SLinus Torvalds print ".SH \"", uc $section, "\"\n"; 7391da177e4SLinus Torvalds output_highlight($args{'sections'}{$section}); 7401da177e4SLinus Torvalds } 7411da177e4SLinus Torvalds} 7421da177e4SLinus Torvalds 7431da177e4SLinus Torvalds## 7441da177e4SLinus Torvalds# output enum in man 7451da177e4SLinus Torvaldssub output_enum_man(%) { 7461da177e4SLinus Torvalds my %args = %{$_[0]}; 7471da177e4SLinus Torvalds my ($parameter, $section); 7481da177e4SLinus Torvalds my $count; 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds print ".SH NAME\n"; 7531da177e4SLinus Torvalds print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n"; 7541da177e4SLinus Torvalds 7551da177e4SLinus Torvalds print ".SH SYNOPSIS\n"; 7561da177e4SLinus Torvalds print "enum " . $args{'enum'} . " {\n"; 7571da177e4SLinus Torvalds $count = 0; 7581da177e4SLinus Torvalds foreach my $parameter (@{$args{'parameterlist'}}) { 7591da177e4SLinus Torvalds print ".br\n.BI \" $parameter\"\n"; 7601da177e4SLinus Torvalds if ($count == $#{$args{'parameterlist'}}) { 7611da177e4SLinus Torvalds print "\n};\n"; 7621da177e4SLinus Torvalds last; 7631da177e4SLinus Torvalds } 7641da177e4SLinus Torvalds else { 7651da177e4SLinus Torvalds print ", \n.br\n"; 7661da177e4SLinus Torvalds } 7671da177e4SLinus Torvalds $count++; 7681da177e4SLinus Torvalds } 7691da177e4SLinus Torvalds 7701da177e4SLinus Torvalds print ".SH Constants\n"; 7711da177e4SLinus Torvalds foreach $parameter (@{$args{'parameterlist'}}) { 7721da177e4SLinus Torvalds my $parameter_name = $parameter; 7731da177e4SLinus Torvalds $parameter_name =~ s/\[.*//; 7741da177e4SLinus Torvalds 7751da177e4SLinus Torvalds print ".IP \"" . $parameter . "\" 12\n"; 7761da177e4SLinus Torvalds output_highlight($args{'parameterdescs'}{$parameter_name}); 7771da177e4SLinus Torvalds } 7781da177e4SLinus Torvalds foreach $section (@{$args{'sectionlist'}}) { 7791da177e4SLinus Torvalds print ".SH \"$section\"\n"; 7801da177e4SLinus Torvalds output_highlight($args{'sections'}{$section}); 7811da177e4SLinus Torvalds } 7821da177e4SLinus Torvalds} 7831da177e4SLinus Torvalds 7841da177e4SLinus Torvalds## 7851da177e4SLinus Torvalds# output struct in man 7861da177e4SLinus Torvaldssub output_struct_man(%) { 7871da177e4SLinus Torvalds my %args = %{$_[0]}; 7881da177e4SLinus Torvalds my ($parameter, $section); 7891da177e4SLinus Torvalds 7901da177e4SLinus Torvalds print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n"; 7911da177e4SLinus Torvalds 7921da177e4SLinus Torvalds print ".SH NAME\n"; 7931da177e4SLinus Torvalds print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; 7941da177e4SLinus Torvalds 7958ad72163SMauro Carvalho Chehab my $declaration = $args{'definition'}; 7968ad72163SMauro Carvalho Chehab $declaration =~ s/\t/ /g; 7978ad72163SMauro Carvalho Chehab $declaration =~ s/\n/"\n.br\n.BI \"/g; 7981da177e4SLinus Torvalds print ".SH SYNOPSIS\n"; 7991da177e4SLinus Torvalds print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; 8008ad72163SMauro Carvalho Chehab print ".BI \"$declaration\n};\n.br\n\n"; 8011da177e4SLinus Torvalds 802c51d3dacSRandy Dunlap print ".SH Members\n"; 8031da177e4SLinus Torvalds foreach $parameter (@{$args{'parameterlist'}}) { 8041da177e4SLinus Torvalds ($parameter =~ /^#/) && next; 8051da177e4SLinus Torvalds 8061da177e4SLinus Torvalds my $parameter_name = $parameter; 8071da177e4SLinus Torvalds $parameter_name =~ s/\[.*//; 8081da177e4SLinus Torvalds 8091da177e4SLinus Torvalds ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 8101da177e4SLinus Torvalds print ".IP \"" . $parameter . "\" 12\n"; 8111da177e4SLinus Torvalds output_highlight($args{'parameterdescs'}{$parameter_name}); 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds foreach $section (@{$args{'sectionlist'}}) { 8141da177e4SLinus Torvalds print ".SH \"$section\"\n"; 8151da177e4SLinus Torvalds output_highlight($args{'sections'}{$section}); 8161da177e4SLinus Torvalds } 8171da177e4SLinus Torvalds} 8181da177e4SLinus Torvalds 8191da177e4SLinus Torvalds## 8201da177e4SLinus Torvalds# output typedef in man 8211da177e4SLinus Torvaldssub output_typedef_man(%) { 8221da177e4SLinus Torvalds my %args = %{$_[0]}; 8231da177e4SLinus Torvalds my ($parameter, $section); 8241da177e4SLinus Torvalds 8251da177e4SLinus Torvalds print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; 8261da177e4SLinus Torvalds 8271da177e4SLinus Torvalds print ".SH NAME\n"; 8281da177e4SLinus Torvalds print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n"; 8291da177e4SLinus Torvalds 8301da177e4SLinus Torvalds foreach $section (@{$args{'sectionlist'}}) { 8311da177e4SLinus Torvalds print ".SH \"$section\"\n"; 8321da177e4SLinus Torvalds output_highlight($args{'sections'}{$section}); 8331da177e4SLinus Torvalds } 8341da177e4SLinus Torvalds} 8351da177e4SLinus Torvalds 836b112e0f7SJohannes Bergsub output_blockhead_man(%) { 8371da177e4SLinus Torvalds my %args = %{$_[0]}; 8381da177e4SLinus Torvalds my ($parameter, $section); 8391da177e4SLinus Torvalds my $count; 8401da177e4SLinus Torvalds 8411da177e4SLinus Torvalds print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; 8421da177e4SLinus Torvalds 8431da177e4SLinus Torvalds foreach $section (@{$args{'sectionlist'}}) { 8441da177e4SLinus Torvalds print ".SH \"$section\"\n"; 8451da177e4SLinus Torvalds output_highlight($args{'sections'}{$section}); 8461da177e4SLinus Torvalds } 8471da177e4SLinus Torvalds} 8481da177e4SLinus Torvalds 8491da177e4SLinus Torvalds## 850c0d1b6eeSJonathan Corbet# output in restructured text 851c0d1b6eeSJonathan Corbet# 852c0d1b6eeSJonathan Corbet 853c0d1b6eeSJonathan Corbet# 854c0d1b6eeSJonathan Corbet# This could use some work; it's used to output the DOC: sections, and 855c0d1b6eeSJonathan Corbet# starts by putting out the name of the doc section itself, but that tends 856c0d1b6eeSJonathan Corbet# to duplicate a header already in the template file. 857c0d1b6eeSJonathan Corbet# 858c0d1b6eeSJonathan Corbetsub output_blockhead_rst(%) { 859c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 860c0d1b6eeSJonathan Corbet my ($parameter, $section); 861c0d1b6eeSJonathan Corbet 862c0d1b6eeSJonathan Corbet foreach $section (@{$args{'sectionlist'}}) { 863eab795ddSMauro Carvalho Chehab next if (defined($nosymbol_table{$section})); 864eab795ddSMauro Carvalho Chehab 8659e72184bSJani Nikula if ($output_selection != OUTPUT_INCLUDE) { 86606a755d6SMichal Wajdeczko print ".. _$section:\n\n"; 867c0d1b6eeSJonathan Corbet print "**$section**\n\n"; 8689e72184bSJani Nikula } 8690b0f5f29SDaniel Vetter print_lineno($section_start_lines{$section}); 870c0d1b6eeSJonathan Corbet output_highlight_rst($args{'sections'}{$section}); 871c0d1b6eeSJonathan Corbet print "\n"; 872c0d1b6eeSJonathan Corbet } 873c0d1b6eeSJonathan Corbet} 874c0d1b6eeSJonathan Corbet 875af250290SJonathan Corbet# 876af250290SJonathan Corbet# Apply the RST highlights to a sub-block of text. 877af250290SJonathan Corbet# 878af250290SJonathan Corbetsub highlight_block($) { 879af250290SJonathan Corbet # The dohighlight kludge requires the text be called $contents 880af250290SJonathan Corbet my $contents = shift; 881c0d1b6eeSJonathan Corbet eval $dohighlight; 882c0d1b6eeSJonathan Corbet die $@ if $@; 883af250290SJonathan Corbet return $contents; 884af250290SJonathan Corbet} 885c0d1b6eeSJonathan Corbet 886af250290SJonathan Corbet# 887af250290SJonathan Corbet# Regexes used only here. 888af250290SJonathan Corbet# 889af250290SJonathan Corbetmy $sphinx_literal = '^[^.].*::$'; 890af250290SJonathan Corbetmy $sphinx_cblock = '^\.\.\ +code-block::'; 891af250290SJonathan Corbet 892af250290SJonathan Corbetsub output_highlight_rst { 893af250290SJonathan Corbet my $input = join "\n",@_; 894af250290SJonathan Corbet my $output = ""; 895af250290SJonathan Corbet my $line; 896af250290SJonathan Corbet my $in_literal = 0; 897af250290SJonathan Corbet my $litprefix; 898af250290SJonathan Corbet my $block = ""; 899af250290SJonathan Corbet 900af250290SJonathan Corbet foreach $line (split "\n",$input) { 901af250290SJonathan Corbet # 902af250290SJonathan Corbet # If we're in a literal block, see if we should drop out 903af250290SJonathan Corbet # of it. Otherwise pass the line straight through unmunged. 904af250290SJonathan Corbet # 905af250290SJonathan Corbet if ($in_literal) { 906af250290SJonathan Corbet if (! ($line =~ /^\s*$/)) { 907af250290SJonathan Corbet # 908af250290SJonathan Corbet # If this is the first non-blank line in a literal 909af250290SJonathan Corbet # block we need to figure out what the proper indent is. 910af250290SJonathan Corbet # 911af250290SJonathan Corbet if ($litprefix eq "") { 912af250290SJonathan Corbet $line =~ /^(\s*)/; 913af250290SJonathan Corbet $litprefix = '^' . $1; 914af250290SJonathan Corbet $output .= $line . "\n"; 915af250290SJonathan Corbet } elsif (! ($line =~ /$litprefix/)) { 916af250290SJonathan Corbet $in_literal = 0; 917af250290SJonathan Corbet } else { 918af250290SJonathan Corbet $output .= $line . "\n"; 919af250290SJonathan Corbet } 920af250290SJonathan Corbet } else { 921af250290SJonathan Corbet $output .= $line . "\n"; 922af250290SJonathan Corbet } 923af250290SJonathan Corbet } 924af250290SJonathan Corbet # 925af250290SJonathan Corbet # Not in a literal block (or just dropped out) 926af250290SJonathan Corbet # 927af250290SJonathan Corbet if (! $in_literal) { 928af250290SJonathan Corbet $block .= $line . "\n"; 929af250290SJonathan Corbet if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { 930af250290SJonathan Corbet $in_literal = 1; 931af250290SJonathan Corbet $litprefix = ""; 932af250290SJonathan Corbet $output .= highlight_block($block); 933af250290SJonathan Corbet $block = "" 934af250290SJonathan Corbet } 935af250290SJonathan Corbet } 936af250290SJonathan Corbet } 937af250290SJonathan Corbet 938af250290SJonathan Corbet if ($block) { 939af250290SJonathan Corbet $output .= highlight_block($block); 940af250290SJonathan Corbet } 941af250290SJonathan Corbet foreach $line (split "\n", $output) { 942830066a7SJani Nikula print $lineprefix . $line . "\n"; 943c0d1b6eeSJonathan Corbet } 944c0d1b6eeSJonathan Corbet} 945c0d1b6eeSJonathan Corbet 946c0d1b6eeSJonathan Corbetsub output_function_rst(%) { 947c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 948c0d1b6eeSJonathan Corbet my ($parameter, $section); 949c099ff69SJani Nikula my $oldprefix = $lineprefix; 95082801d06SMauro Carvalho Chehab my $start = ""; 9516e9e4158SMauro Carvalho Chehab my $is_macro = 0; 952c0d1b6eeSJonathan Corbet 953efa44475SMauro Carvalho Chehab if ($sphinx_major < 3) { 954e3ad05feSMauro Carvalho Chehab if ($args{'typedef'}) { 95582801d06SMauro Carvalho Chehab print ".. c:type:: ". $args{'function'} . "\n\n"; 95682801d06SMauro Carvalho Chehab print_lineno($declaration_start_line); 95782801d06SMauro Carvalho Chehab print " **Typedef**: "; 95882801d06SMauro Carvalho Chehab $lineprefix = ""; 95982801d06SMauro Carvalho Chehab output_highlight_rst($args{'purpose'}); 96082801d06SMauro Carvalho Chehab $start = "\n\n**Syntax**\n\n ``"; 9616e9e4158SMauro Carvalho Chehab $is_macro = 1; 962c0d1b6eeSJonathan Corbet } else { 96382801d06SMauro Carvalho Chehab print ".. c:function:: "; 96482801d06SMauro Carvalho Chehab } 965e3ad05feSMauro Carvalho Chehab } else { 9666e9e4158SMauro Carvalho Chehab if ($args{'typedef'} || $args{'functiontype'} eq "") { 9676e9e4158SMauro Carvalho Chehab $is_macro = 1; 968e3ad05feSMauro Carvalho Chehab print ".. c:macro:: ". $args{'function'} . "\n\n"; 9696e9e4158SMauro Carvalho Chehab } else { 9706e9e4158SMauro Carvalho Chehab print ".. c:function:: "; 9716e9e4158SMauro Carvalho Chehab } 972e3ad05feSMauro Carvalho Chehab 973e3ad05feSMauro Carvalho Chehab if ($args{'typedef'}) { 974e3ad05feSMauro Carvalho Chehab print_lineno($declaration_start_line); 975e3ad05feSMauro Carvalho Chehab print " **Typedef**: "; 976e3ad05feSMauro Carvalho Chehab $lineprefix = ""; 977e3ad05feSMauro Carvalho Chehab output_highlight_rst($args{'purpose'}); 978e3ad05feSMauro Carvalho Chehab $start = "\n\n**Syntax**\n\n ``"; 979e3ad05feSMauro Carvalho Chehab } else { 9806e9e4158SMauro Carvalho Chehab print "``" if ($is_macro); 981e3ad05feSMauro Carvalho Chehab } 982e3ad05feSMauro Carvalho Chehab } 98382801d06SMauro Carvalho Chehab if ($args{'functiontype'} ne "") { 98482801d06SMauro Carvalho Chehab $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; 98582801d06SMauro Carvalho Chehab } else { 98682801d06SMauro Carvalho Chehab $start .= $args{'function'} . " ("; 987c0d1b6eeSJonathan Corbet } 988c0d1b6eeSJonathan Corbet print $start; 989c0d1b6eeSJonathan Corbet 990c0d1b6eeSJonathan Corbet my $count = 0; 991c0d1b6eeSJonathan Corbet foreach my $parameter (@{$args{'parameterlist'}}) { 992c0d1b6eeSJonathan Corbet if ($count ne 0) { 993c0d1b6eeSJonathan Corbet print ", "; 994c0d1b6eeSJonathan Corbet } 995c0d1b6eeSJonathan Corbet $count++; 996c0d1b6eeSJonathan Corbet $type = $args{'parametertypes'}{$parameter}; 997a88b1672SMauro Carvalho Chehab 998e86bdb24SAditya Srivastava if ($type =~ m/$function_pointer/) { 999c0d1b6eeSJonathan Corbet # pointer-to-function 1000e8f4ba83SPeter Maydell print $1 . $parameter . ") (" . $2 . ")"; 1001c0d1b6eeSJonathan Corbet } else { 1002ed8348e2SMauro Carvalho Chehab print $type; 1003c0d1b6eeSJonathan Corbet } 1004c0d1b6eeSJonathan Corbet } 10056e9e4158SMauro Carvalho Chehab if ($is_macro) { 10066e9e4158SMauro Carvalho Chehab print ")``\n\n"; 100782801d06SMauro Carvalho Chehab } else { 1008c099ff69SJani Nikula print ")\n\n"; 1009e3ad05feSMauro Carvalho Chehab } 10106e9e4158SMauro Carvalho Chehab if (!$args{'typedef'}) { 10110b0f5f29SDaniel Vetter print_lineno($declaration_start_line); 1012c099ff69SJani Nikula $lineprefix = " "; 1013c099ff69SJani Nikula output_highlight_rst($args{'purpose'}); 1014c099ff69SJani Nikula print "\n"; 101582801d06SMauro Carvalho Chehab } 1016c0d1b6eeSJonathan Corbet 1017ecbcfba1SJani Nikula print "**Parameters**\n\n"; 1018c099ff69SJani Nikula $lineprefix = " "; 1019c0d1b6eeSJonathan Corbet foreach $parameter (@{$args{'parameterlist'}}) { 1020c0d1b6eeSJonathan Corbet my $parameter_name = $parameter; 1021ada5f446SGabriel Krisman Bertazi $parameter_name =~ s/\[.*//; 1022c0d1b6eeSJonathan Corbet $type = $args{'parametertypes'}{$parameter}; 1023c0d1b6eeSJonathan Corbet 1024c0d1b6eeSJonathan Corbet if ($type ne "") { 1025ed8348e2SMauro Carvalho Chehab print "``$type``\n"; 1026c0d1b6eeSJonathan Corbet } else { 1027c0d1b6eeSJonathan Corbet print "``$parameter``\n"; 1028c0d1b6eeSJonathan Corbet } 10290b0f5f29SDaniel Vetter 10300b0f5f29SDaniel Vetter print_lineno($parameterdesc_start_lines{$parameter_name}); 10310b0f5f29SDaniel Vetter 10325e64fa9cSJani Nikula if (defined($args{'parameterdescs'}{$parameter_name}) && 10335e64fa9cSJani Nikula $args{'parameterdescs'}{$parameter_name} ne $undescribed) { 1034c0d1b6eeSJonathan Corbet output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1035c0d1b6eeSJonathan Corbet } else { 1036d4b08e0cSJani Nikula print " *undescribed*\n"; 1037c0d1b6eeSJonathan Corbet } 1038c0d1b6eeSJonathan Corbet print "\n"; 1039c0d1b6eeSJonathan Corbet } 1040c099ff69SJani Nikula 1041c099ff69SJani Nikula $lineprefix = $oldprefix; 1042c0d1b6eeSJonathan Corbet output_section_rst(@_); 1043c0d1b6eeSJonathan Corbet} 1044c0d1b6eeSJonathan Corbet 1045c0d1b6eeSJonathan Corbetsub output_section_rst(%) { 1046c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 1047c0d1b6eeSJonathan Corbet my $section; 1048c0d1b6eeSJonathan Corbet my $oldprefix = $lineprefix; 1049c0d1b6eeSJonathan Corbet $lineprefix = ""; 1050c0d1b6eeSJonathan Corbet 1051c0d1b6eeSJonathan Corbet foreach $section (@{$args{'sectionlist'}}) { 1052ecbcfba1SJani Nikula print "**$section**\n\n"; 10530b0f5f29SDaniel Vetter print_lineno($section_start_lines{$section}); 1054c0d1b6eeSJonathan Corbet output_highlight_rst($args{'sections'}{$section}); 1055c0d1b6eeSJonathan Corbet print "\n"; 1056c0d1b6eeSJonathan Corbet } 1057c0d1b6eeSJonathan Corbet print "\n"; 1058c0d1b6eeSJonathan Corbet $lineprefix = $oldprefix; 1059c0d1b6eeSJonathan Corbet} 1060c0d1b6eeSJonathan Corbet 1061c0d1b6eeSJonathan Corbetsub output_enum_rst(%) { 1062c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 1063c0d1b6eeSJonathan Corbet my ($parameter); 1064c099ff69SJani Nikula my $oldprefix = $lineprefix; 1065c0d1b6eeSJonathan Corbet my $count; 106662850976SJani Nikula 1067efa44475SMauro Carvalho Chehab if ($sphinx_major < 3) { 1068efa44475SMauro Carvalho Chehab my $name = "enum " . $args{'enum'}; 106962850976SJani Nikula print "\n\n.. c:type:: " . $name . "\n\n"; 1070efa44475SMauro Carvalho Chehab } else { 1071efa44475SMauro Carvalho Chehab my $name = $args{'enum'}; 1072efa44475SMauro Carvalho Chehab print "\n\n.. c:enum:: " . $name . "\n\n"; 1073efa44475SMauro Carvalho Chehab } 10740b0f5f29SDaniel Vetter print_lineno($declaration_start_line); 1075c099ff69SJani Nikula $lineprefix = " "; 1076c099ff69SJani Nikula output_highlight_rst($args{'purpose'}); 1077c099ff69SJani Nikula print "\n"; 1078c0d1b6eeSJonathan Corbet 1079ecbcfba1SJani Nikula print "**Constants**\n\n"; 1080c0d1b6eeSJonathan Corbet $lineprefix = " "; 1081c0d1b6eeSJonathan Corbet foreach $parameter (@{$args{'parameterlist'}}) { 1082ecbcfba1SJani Nikula print "``$parameter``\n"; 1083c0d1b6eeSJonathan Corbet if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 1084c0d1b6eeSJonathan Corbet output_highlight_rst($args{'parameterdescs'}{$parameter}); 1085c0d1b6eeSJonathan Corbet } else { 1086d4b08e0cSJani Nikula print " *undescribed*\n"; 1087c0d1b6eeSJonathan Corbet } 1088c0d1b6eeSJonathan Corbet print "\n"; 1089c0d1b6eeSJonathan Corbet } 1090c099ff69SJani Nikula 1091c0d1b6eeSJonathan Corbet $lineprefix = $oldprefix; 1092c0d1b6eeSJonathan Corbet output_section_rst(@_); 1093c0d1b6eeSJonathan Corbet} 1094c0d1b6eeSJonathan Corbet 1095c0d1b6eeSJonathan Corbetsub output_typedef_rst(%) { 1096c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 1097c0d1b6eeSJonathan Corbet my ($parameter); 1098c099ff69SJani Nikula my $oldprefix = $lineprefix; 1099efa44475SMauro Carvalho Chehab my $name; 1100c0d1b6eeSJonathan Corbet 1101efa44475SMauro Carvalho Chehab if ($sphinx_major < 3) { 1102efa44475SMauro Carvalho Chehab $name = "typedef " . $args{'typedef'}; 1103efa44475SMauro Carvalho Chehab } else { 1104efa44475SMauro Carvalho Chehab $name = $args{'typedef'}; 1105efa44475SMauro Carvalho Chehab } 110662850976SJani Nikula print "\n\n.. c:type:: " . $name . "\n\n"; 11070b0f5f29SDaniel Vetter print_lineno($declaration_start_line); 1108c099ff69SJani Nikula $lineprefix = " "; 1109c099ff69SJani Nikula output_highlight_rst($args{'purpose'}); 1110c099ff69SJani Nikula print "\n"; 1111c0d1b6eeSJonathan Corbet 1112c099ff69SJani Nikula $lineprefix = $oldprefix; 1113c0d1b6eeSJonathan Corbet output_section_rst(@_); 1114c0d1b6eeSJonathan Corbet} 1115c0d1b6eeSJonathan Corbet 1116c0d1b6eeSJonathan Corbetsub output_struct_rst(%) { 1117c0d1b6eeSJonathan Corbet my %args = %{$_[0]}; 1118c0d1b6eeSJonathan Corbet my ($parameter); 1119c099ff69SJani Nikula my $oldprefix = $lineprefix; 1120c0d1b6eeSJonathan Corbet 1121efa44475SMauro Carvalho Chehab if ($sphinx_major < 3) { 1122efa44475SMauro Carvalho Chehab my $name = $args{'type'} . " " . $args{'struct'}; 112362850976SJani Nikula print "\n\n.. c:type:: " . $name . "\n\n"; 1124efa44475SMauro Carvalho Chehab } else { 1125efa44475SMauro Carvalho Chehab my $name = $args{'struct'}; 112672b97d0bSMauro Carvalho Chehab if ($args{'type'} eq 'union') { 112772b97d0bSMauro Carvalho Chehab print "\n\n.. c:union:: " . $name . "\n\n"; 112872b97d0bSMauro Carvalho Chehab } else { 1129efa44475SMauro Carvalho Chehab print "\n\n.. c:struct:: " . $name . "\n\n"; 1130efa44475SMauro Carvalho Chehab } 113172b97d0bSMauro Carvalho Chehab } 11320b0f5f29SDaniel Vetter print_lineno($declaration_start_line); 1133c099ff69SJani Nikula $lineprefix = " "; 1134c099ff69SJani Nikula output_highlight_rst($args{'purpose'}); 1135c099ff69SJani Nikula print "\n"; 1136c0d1b6eeSJonathan Corbet 1137ecbcfba1SJani Nikula print "**Definition**\n\n"; 1138c0d1b6eeSJonathan Corbet print "::\n\n"; 11398ad72163SMauro Carvalho Chehab my $declaration = $args{'definition'}; 11408ad72163SMauro Carvalho Chehab $declaration =~ s/\t/ /g; 11418ad72163SMauro Carvalho Chehab print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; 1142c0d1b6eeSJonathan Corbet 1143ecbcfba1SJani Nikula print "**Members**\n\n"; 1144c099ff69SJani Nikula $lineprefix = " "; 1145c0d1b6eeSJonathan Corbet foreach $parameter (@{$args{'parameterlist'}}) { 1146c0d1b6eeSJonathan Corbet ($parameter =~ /^#/) && next; 1147c0d1b6eeSJonathan Corbet 1148c0d1b6eeSJonathan Corbet my $parameter_name = $parameter; 1149c0d1b6eeSJonathan Corbet $parameter_name =~ s/\[.*//; 1150c0d1b6eeSJonathan Corbet 1151c0d1b6eeSJonathan Corbet ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 1152c0d1b6eeSJonathan Corbet $type = $args{'parametertypes'}{$parameter}; 11530b0f5f29SDaniel Vetter print_lineno($parameterdesc_start_lines{$parameter_name}); 11546d232c80SMauro Carvalho Chehab print "``" . $parameter . "``\n"; 1155c0d1b6eeSJonathan Corbet output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1156c0d1b6eeSJonathan Corbet print "\n"; 1157c0d1b6eeSJonathan Corbet } 1158c0d1b6eeSJonathan Corbet print "\n"; 1159c099ff69SJani Nikula 1160c099ff69SJani Nikula $lineprefix = $oldprefix; 1161c0d1b6eeSJonathan Corbet output_section_rst(@_); 1162c0d1b6eeSJonathan Corbet} 1163c0d1b6eeSJonathan Corbet 11643a025e1dSMatthew Wilcox## none mode output functions 11653a025e1dSMatthew Wilcox 11663a025e1dSMatthew Wilcoxsub output_function_none(%) { 11673a025e1dSMatthew Wilcox} 11683a025e1dSMatthew Wilcox 11693a025e1dSMatthew Wilcoxsub output_enum_none(%) { 11703a025e1dSMatthew Wilcox} 11713a025e1dSMatthew Wilcox 11723a025e1dSMatthew Wilcoxsub output_typedef_none(%) { 11733a025e1dSMatthew Wilcox} 11743a025e1dSMatthew Wilcox 11753a025e1dSMatthew Wilcoxsub output_struct_none(%) { 11763a025e1dSMatthew Wilcox} 11773a025e1dSMatthew Wilcox 11783a025e1dSMatthew Wilcoxsub output_blockhead_none(%) { 11793a025e1dSMatthew Wilcox} 11803a025e1dSMatthew Wilcox 11811da177e4SLinus Torvalds## 118227205744SRandy Dunlap# generic output function for all types (function, struct/union, typedef, enum); 118327205744SRandy Dunlap# calls the generated, variable output_ function name based on 118427205744SRandy Dunlap# functype and output_mode 11851da177e4SLinus Torvaldssub output_declaration { 11861da177e4SLinus Torvalds no strict 'refs'; 11871da177e4SLinus Torvalds my $name = shift; 11881da177e4SLinus Torvalds my $functype = shift; 11891da177e4SLinus Torvalds my $func = "output_${functype}_$output_mode"; 1190eab795ddSMauro Carvalho Chehab 1191eab795ddSMauro Carvalho Chehab return if (defined($nosymbol_table{$name})); 1192eab795ddSMauro Carvalho Chehab 1193b6c3f456SJani Nikula if (($output_selection == OUTPUT_ALL) || 1194b6c3f456SJani Nikula (($output_selection == OUTPUT_INCLUDE || 1195b6c3f456SJani Nikula $output_selection == OUTPUT_EXPORTED) && 119686ae2e38SJani Nikula defined($function_table{$name})) || 1197eab795ddSMauro Carvalho Chehab ($output_selection == OUTPUT_INTERNAL && 119886ae2e38SJani Nikula !($functype eq "function" && defined($function_table{$name})))) 11991da177e4SLinus Torvalds { 12001da177e4SLinus Torvalds &$func(@_); 12011da177e4SLinus Torvalds $section_counter++; 12021da177e4SLinus Torvalds } 12031da177e4SLinus Torvalds} 12041da177e4SLinus Torvalds 12051da177e4SLinus Torvalds## 120627205744SRandy Dunlap# generic output function - calls the right one based on current output mode. 1207b112e0f7SJohannes Bergsub output_blockhead { 12081da177e4SLinus Torvalds no strict 'refs'; 1209b112e0f7SJohannes Berg my $func = "output_blockhead_" . $output_mode; 12101da177e4SLinus Torvalds &$func(@_); 12111da177e4SLinus Torvalds $section_counter++; 12121da177e4SLinus Torvalds} 12131da177e4SLinus Torvalds 12141da177e4SLinus Torvalds## 12151da177e4SLinus Torvalds# takes a declaration (struct, union, enum, typedef) and 12161da177e4SLinus Torvalds# invokes the right handler. NOT called for functions. 12171da177e4SLinus Torvaldssub dump_declaration($$) { 12181da177e4SLinus Torvalds no strict 'refs'; 12191da177e4SLinus Torvalds my ($prototype, $file) = @_; 12201da177e4SLinus Torvalds my $func = "dump_" . $decl_type; 12211da177e4SLinus Torvalds &$func(@_); 12221da177e4SLinus Torvalds} 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvaldssub dump_union($$) { 12251da177e4SLinus Torvalds dump_struct(@_); 12261da177e4SLinus Torvalds} 12271da177e4SLinus Torvalds 12281da177e4SLinus Torvaldssub dump_struct($$) { 12291da177e4SLinus Torvalds my $x = shift; 12301da177e4SLinus Torvalds my $file = shift; 1231a746fe32SAditya Srivastava my $decl_type; 1232a746fe32SAditya Srivastava my $members; 1233a746fe32SAditya Srivastava my $type = qr{struct|union}; 1234a746fe32SAditya Srivastava # For capturing struct/union definition body, i.e. "{members*}qualifiers*" 1235e86bdb24SAditya Srivastava my $qualifiers = qr{$attribute|__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned}; 1236e86bdb24SAditya Srivastava my $definition_body = qr{\{(.*)\}\s*$qualifiers*}; 1237e86bdb24SAditya Srivastava my $struct_members = qr{($type)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;}; 12381da177e4SLinus Torvalds 1239a746fe32SAditya Srivastava if ($x =~ /($type)\s+(\w+)\s*$definition_body/) { 1240a746fe32SAditya Srivastava $decl_type = $1; 12411da177e4SLinus Torvalds $declaration_name = $2; 1242a746fe32SAditya Srivastava $members = $3; 1243a746fe32SAditya Srivastava } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) { 1244a746fe32SAditya Srivastava $decl_type = $1; 1245a746fe32SAditya Srivastava $declaration_name = $3; 1246a746fe32SAditya Srivastava $members = $2; 1247a746fe32SAditya Srivastava } 12481da177e4SLinus Torvalds 1249a746fe32SAditya Srivastava if ($members) { 125052042e2dSMauro Carvalho Chehab if ($identifier ne $declaration_name) { 125152042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; 125252042e2dSMauro Carvalho Chehab return; 125352042e2dSMauro Carvalho Chehab } 125452042e2dSMauro Carvalho Chehab 1255aeec46b9SMartin Waitz # ignore members marked private: 12560d8c39e6SMauro Carvalho Chehab $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; 12570d8c39e6SMauro Carvalho Chehab $members =~ s/\/\*\s*private:.*//gosi; 1258aeec46b9SMartin Waitz # strip comments: 1259aeec46b9SMartin Waitz $members =~ s/\/\*.*?\*\///gos; 1260ef5da59fSRandy Dunlap # strip attributes 1261e86bdb24SAditya Srivastava $members =~ s/\s*$attribute/ /gi; 12623d9bfb19SSakari Ailus $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos; 12633d9bfb19SSakari Ailus $members =~ s/\s*__packed\s*/ /gos; 1264f0074929SJonathan Corbet $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos; 1265f861537dSAndré Almeida $members =~ s/\s*____cacheline_aligned_in_smp/ /gos; 1266a070991fSJonathan Cameron $members =~ s/\s*____cacheline_aligned/ /gos; 126750d7bd38SKees Cook # unwrap struct_group(): 126850d7bd38SKees Cook # - first eat non-declaration parameters and rewrite for final match 126950d7bd38SKees Cook # - then remove macro, outer parens, and trailing semicolon 127050d7bd38SKees Cook $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos; 127150d7bd38SKees Cook $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos; 127250d7bd38SKees Cook $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos; 127350d7bd38SKees Cook $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos; 12743556108eSMauro Carvalho Chehab 1275e86bdb24SAditya Srivastava my $args = qr{([^,)]+)}; 1276b22b5a9eSConchúr Navid # replace DECLARE_BITMAP 12773556108eSMauro Carvalho Chehab $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos; 1278603bdf5dSRandy Dunlap $members =~ s/DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, PHY_INTERFACE_MODE_MAX)/gos; 1279e86bdb24SAditya Srivastava $members =~ s/DECLARE_BITMAP\s*\($args,\s*$args\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; 12801cb566baSJakub Kicinski # replace DECLARE_HASHTABLE 1281e86bdb24SAditya Srivastava $members =~ s/DECLARE_HASHTABLE\s*\($args,\s*$args\)/unsigned long $1\[1 << (($2) - 1)\]/gos; 128245005b27SMauro Carvalho Chehab # replace DECLARE_KFIFO 1283e86bdb24SAditya Srivastava $members =~ s/DECLARE_KFIFO\s*\($args,\s*$args,\s*$args\)/$2 \*$1/gos; 128445005b27SMauro Carvalho Chehab # replace DECLARE_KFIFO_PTR 1285e86bdb24SAditya Srivastava $members =~ s/DECLARE_KFIFO_PTR\s*\($args,\s*$args\)/$2 \*$1/gos; 12863080ea55SKees Cook # replace DECLARE_FLEX_ARRAY 12873080ea55SKees Cook $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos; 12888ad72163SMauro Carvalho Chehab my $declaration = $members; 12898ad72163SMauro Carvalho Chehab 12908ad72163SMauro Carvalho Chehab # Split nested struct/union elements as newer ones 1291e86bdb24SAditya Srivastava while ($members =~ m/$struct_members/) { 129284ce5b98SMauro Carvalho Chehab my $newmember; 129384ce5b98SMauro Carvalho Chehab my $maintype = $1; 129484ce5b98SMauro Carvalho Chehab my $ids = $4; 12958ad72163SMauro Carvalho Chehab my $content = $3; 129684ce5b98SMauro Carvalho Chehab foreach my $id(split /,/, $ids) { 129784ce5b98SMauro Carvalho Chehab $newmember .= "$maintype $id; "; 129884ce5b98SMauro Carvalho Chehab 12998ad72163SMauro Carvalho Chehab $id =~ s/[:\[].*//; 130084ce5b98SMauro Carvalho Chehab $id =~ s/^\s*\**(\S+)\s*/$1/; 13018ad72163SMauro Carvalho Chehab foreach my $arg (split /;/, $content) { 13028ad72163SMauro Carvalho Chehab next if ($arg =~ m/^\s*$/); 13037c0d7e87SMauro Carvalho Chehab if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { 13047c0d7e87SMauro Carvalho Chehab # pointer-to-function 13057c0d7e87SMauro Carvalho Chehab my $type = $1; 13067c0d7e87SMauro Carvalho Chehab my $name = $2; 13077c0d7e87SMauro Carvalho Chehab my $extra = $3; 13087c0d7e87SMauro Carvalho Chehab next if (!$name); 13097c0d7e87SMauro Carvalho Chehab if ($id =~ m/^\s*$/) { 13107c0d7e87SMauro Carvalho Chehab # anonymous struct/union 13117c0d7e87SMauro Carvalho Chehab $newmember .= "$type$name$extra; "; 13127c0d7e87SMauro Carvalho Chehab } else { 13137c0d7e87SMauro Carvalho Chehab $newmember .= "$type$id.$name$extra; "; 13147c0d7e87SMauro Carvalho Chehab } 13157c0d7e87SMauro Carvalho Chehab } else { 131684ce5b98SMauro Carvalho Chehab my $type; 131784ce5b98SMauro Carvalho Chehab my $names; 131884ce5b98SMauro Carvalho Chehab $arg =~ s/^\s+//; 131984ce5b98SMauro Carvalho Chehab $arg =~ s/\s+$//; 132084ce5b98SMauro Carvalho Chehab # Handle bitmaps 132184ce5b98SMauro Carvalho Chehab $arg =~ s/:\s*\d+\s*//g; 132284ce5b98SMauro Carvalho Chehab # Handle arrays 1323d404d579SMauro Carvalho Chehab $arg =~ s/\[.*\]//g; 132484ce5b98SMauro Carvalho Chehab # The type may have multiple words, 132584ce5b98SMauro Carvalho Chehab # and multiple IDs can be defined, like: 132684ce5b98SMauro Carvalho Chehab # const struct foo, *bar, foobar 132784ce5b98SMauro Carvalho Chehab # So, we remove spaces when parsing the 132884ce5b98SMauro Carvalho Chehab # names, in order to match just names 132984ce5b98SMauro Carvalho Chehab # and commas for the names 133084ce5b98SMauro Carvalho Chehab $arg =~ s/\s*,\s*/,/g; 133184ce5b98SMauro Carvalho Chehab if ($arg =~ m/(.*)\s+([\S+,]+)/) { 133284ce5b98SMauro Carvalho Chehab $type = $1; 133384ce5b98SMauro Carvalho Chehab $names = $2; 133484ce5b98SMauro Carvalho Chehab } else { 133584ce5b98SMauro Carvalho Chehab $newmember .= "$arg; "; 133684ce5b98SMauro Carvalho Chehab next; 133784ce5b98SMauro Carvalho Chehab } 133884ce5b98SMauro Carvalho Chehab foreach my $name (split /,/, $names) { 133984ce5b98SMauro Carvalho Chehab $name =~ s/^\s*\**(\S+)\s*/$1/; 13408ad72163SMauro Carvalho Chehab next if (($name =~ m/^\s*$/)); 13418ad72163SMauro Carvalho Chehab if ($id =~ m/^\s*$/) { 13428ad72163SMauro Carvalho Chehab # anonymous struct/union 13438ad72163SMauro Carvalho Chehab $newmember .= "$type $name; "; 13448ad72163SMauro Carvalho Chehab } else { 13458ad72163SMauro Carvalho Chehab $newmember .= "$type $id.$name; "; 13468ad72163SMauro Carvalho Chehab } 13478ad72163SMauro Carvalho Chehab } 13487c0d7e87SMauro Carvalho Chehab } 134984ce5b98SMauro Carvalho Chehab } 135084ce5b98SMauro Carvalho Chehab } 1351e86bdb24SAditya Srivastava $members =~ s/$struct_members/$newmember/; 135284ce5b98SMauro Carvalho Chehab } 13538ad72163SMauro Carvalho Chehab 13548ad72163SMauro Carvalho Chehab # Ignore other nested elements, like enums 1355673bb2dfSBen Hutchings $members =~ s/(\{[^\{\}]*\})//g; 13568ad72163SMauro Carvalho Chehab 1357151c468bSMauro Carvalho Chehab create_parameterlist($members, ';', $file, $declaration_name); 13581081de2dSMauro Carvalho Chehab check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); 13591da177e4SLinus Torvalds 13608ad72163SMauro Carvalho Chehab # Adjust declaration for better display 1361673bb2dfSBen Hutchings $declaration =~ s/([\{;])/$1\n/g; 1362673bb2dfSBen Hutchings $declaration =~ s/\}\s+;/};/g; 13638ad72163SMauro Carvalho Chehab # Better handle inlined enums 1364673bb2dfSBen Hutchings do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/); 13658ad72163SMauro Carvalho Chehab 13668ad72163SMauro Carvalho Chehab my @def_args = split /\n/, $declaration; 13678ad72163SMauro Carvalho Chehab my $level = 1; 13688ad72163SMauro Carvalho Chehab $declaration = ""; 13698ad72163SMauro Carvalho Chehab foreach my $clause (@def_args) { 13708ad72163SMauro Carvalho Chehab $clause =~ s/^\s+//; 13718ad72163SMauro Carvalho Chehab $clause =~ s/\s+$//; 13728ad72163SMauro Carvalho Chehab $clause =~ s/\s+/ /; 13738ad72163SMauro Carvalho Chehab next if (!$clause); 1374673bb2dfSBen Hutchings $level-- if ($clause =~ m/(\})/ && $level > 1); 13758ad72163SMauro Carvalho Chehab if (!($clause =~ m/^\s*#/)) { 13768ad72163SMauro Carvalho Chehab $declaration .= "\t" x $level; 13778ad72163SMauro Carvalho Chehab } 13788ad72163SMauro Carvalho Chehab $declaration .= "\t" . $clause . "\n"; 1379673bb2dfSBen Hutchings $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/)); 13808ad72163SMauro Carvalho Chehab } 13811da177e4SLinus Torvalds output_declaration($declaration_name, 13821da177e4SLinus Torvalds 'struct', 13831da177e4SLinus Torvalds {'struct' => $declaration_name, 13841da177e4SLinus Torvalds 'module' => $modulename, 13858ad72163SMauro Carvalho Chehab 'definition' => $declaration, 13861da177e4SLinus Torvalds 'parameterlist' => \@parameterlist, 13871da177e4SLinus Torvalds 'parameterdescs' => \%parameterdescs, 13881da177e4SLinus Torvalds 'parametertypes' => \%parametertypes, 13891da177e4SLinus Torvalds 'sectionlist' => \@sectionlist, 13901da177e4SLinus Torvalds 'sections' => \%sections, 13911da177e4SLinus Torvalds 'purpose' => $declaration_purpose, 13921da177e4SLinus Torvalds 'type' => $decl_type 13931da177e4SLinus Torvalds }); 13941da177e4SLinus Torvalds } 13951da177e4SLinus Torvalds else { 1396d40e1e65SBart Van Assche print STDERR "${file}:$.: error: Cannot parse struct or union!\n"; 13971da177e4SLinus Torvalds ++$errors; 13981da177e4SLinus Torvalds } 13991da177e4SLinus Torvalds} 14001da177e4SLinus Torvalds 140185afe608SMauro Carvalho Chehab 140285afe608SMauro Carvalho Chehabsub show_warnings($$) { 140385afe608SMauro Carvalho Chehab my $functype = shift; 140485afe608SMauro Carvalho Chehab my $name = shift; 140585afe608SMauro Carvalho Chehab 1406eab795ddSMauro Carvalho Chehab return 0 if (defined($nosymbol_table{$name})); 1407eab795ddSMauro Carvalho Chehab 140885afe608SMauro Carvalho Chehab return 1 if ($output_selection == OUTPUT_ALL); 140985afe608SMauro Carvalho Chehab 141085afe608SMauro Carvalho Chehab if ($output_selection == OUTPUT_EXPORTED) { 141185afe608SMauro Carvalho Chehab if (defined($function_table{$name})) { 141285afe608SMauro Carvalho Chehab return 1; 141385afe608SMauro Carvalho Chehab } else { 141485afe608SMauro Carvalho Chehab return 0; 141585afe608SMauro Carvalho Chehab } 141685afe608SMauro Carvalho Chehab } 141785afe608SMauro Carvalho Chehab if ($output_selection == OUTPUT_INTERNAL) { 141885afe608SMauro Carvalho Chehab if (!($functype eq "function" && defined($function_table{$name}))) { 141985afe608SMauro Carvalho Chehab return 1; 142085afe608SMauro Carvalho Chehab } else { 142185afe608SMauro Carvalho Chehab return 0; 142285afe608SMauro Carvalho Chehab } 142385afe608SMauro Carvalho Chehab } 142485afe608SMauro Carvalho Chehab if ($output_selection == OUTPUT_INCLUDE) { 142585afe608SMauro Carvalho Chehab if (defined($function_table{$name})) { 142685afe608SMauro Carvalho Chehab return 1; 142785afe608SMauro Carvalho Chehab } else { 142885afe608SMauro Carvalho Chehab return 0; 142985afe608SMauro Carvalho Chehab } 143085afe608SMauro Carvalho Chehab } 143185afe608SMauro Carvalho Chehab die("Please add the new output type at show_warnings()"); 143285afe608SMauro Carvalho Chehab} 143385afe608SMauro Carvalho Chehab 14341da177e4SLinus Torvaldssub dump_enum($$) { 14351da177e4SLinus Torvalds my $x = shift; 14361da177e4SLinus Torvalds my $file = shift; 1437d38c8cfbSMauro Carvalho Chehab my $members; 1438d38c8cfbSMauro Carvalho Chehab 14391da177e4SLinus Torvalds 1440aeec46b9SMartin Waitz $x =~ s@/\*.*?\*/@@gos; # strip comments. 14414468e21eSConchúr Navid # strip #define macros inside enums 14424468e21eSConchúr Navid $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; 1443b6d676dbSRandy Dunlap 1444d38c8cfbSMauro Carvalho Chehab if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) { 1445d38c8cfbSMauro Carvalho Chehab $declaration_name = $2; 1446d38c8cfbSMauro Carvalho Chehab $members = $1; 1447d38c8cfbSMauro Carvalho Chehab } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { 14481da177e4SLinus Torvalds $declaration_name = $1; 1449d38c8cfbSMauro Carvalho Chehab $members = $2; 1450d38c8cfbSMauro Carvalho Chehab } 1451d38c8cfbSMauro Carvalho Chehab 1452ae5b17e4SAndy Shevchenko if ($members) { 145352042e2dSMauro Carvalho Chehab if ($identifier ne $declaration_name) { 14540b54c2e3SMauro Carvalho Chehab if ($identifier eq "") { 14550b54c2e3SMauro Carvalho Chehab print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; 14560b54c2e3SMauro Carvalho Chehab } else { 145752042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; 14580b54c2e3SMauro Carvalho Chehab } 145952042e2dSMauro Carvalho Chehab return; 146052042e2dSMauro Carvalho Chehab } 14610b54c2e3SMauro Carvalho Chehab $declaration_name = "(anonymous)" if ($declaration_name eq ""); 146252042e2dSMauro Carvalho Chehab 14635cb5c31cSJohannes Berg my %_members; 14645cb5c31cSJohannes Berg 1465463a0fdcSMarkus Heiser $members =~ s/\s+$//; 14661da177e4SLinus Torvalds 14671da177e4SLinus Torvalds foreach my $arg (split ',', $members) { 14681da177e4SLinus Torvalds $arg =~ s/^\s*(\w+).*/$1/; 14691da177e4SLinus Torvalds push @parameterlist, $arg; 14701da177e4SLinus Torvalds if (!$parameterdescs{$arg}) { 14711da177e4SLinus Torvalds $parameterdescs{$arg} = $undescribed; 147285afe608SMauro Carvalho Chehab if (show_warnings("enum", $declaration_name)) { 14732defb272SMauro Carvalho Chehab print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; 14742defb272SMauro Carvalho Chehab } 14751da177e4SLinus Torvalds } 14765cb5c31cSJohannes Berg $_members{$arg} = 1; 14775cb5c31cSJohannes Berg } 14781da177e4SLinus Torvalds 14795cb5c31cSJohannes Berg while (my ($k, $v) = each %parameterdescs) { 14805cb5c31cSJohannes Berg if (!exists($_members{$k})) { 148185afe608SMauro Carvalho Chehab if (show_warnings("enum", $declaration_name)) { 14822defb272SMauro Carvalho Chehab print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; 14832defb272SMauro Carvalho Chehab } 14845cb5c31cSJohannes Berg } 14851da177e4SLinus Torvalds } 14861da177e4SLinus Torvalds 14871da177e4SLinus Torvalds output_declaration($declaration_name, 14881da177e4SLinus Torvalds 'enum', 14891da177e4SLinus Torvalds {'enum' => $declaration_name, 14901da177e4SLinus Torvalds 'module' => $modulename, 14911da177e4SLinus Torvalds 'parameterlist' => \@parameterlist, 14921da177e4SLinus Torvalds 'parameterdescs' => \%parameterdescs, 14931da177e4SLinus Torvalds 'sectionlist' => \@sectionlist, 14941da177e4SLinus Torvalds 'sections' => \%sections, 14951da177e4SLinus Torvalds 'purpose' => $declaration_purpose 14961da177e4SLinus Torvalds }); 1497d38c8cfbSMauro Carvalho Chehab } else { 1498d40e1e65SBart Van Assche print STDERR "${file}:$.: error: Cannot parse enum!\n"; 14991da177e4SLinus Torvalds ++$errors; 15001da177e4SLinus Torvalds } 15011da177e4SLinus Torvalds} 15021da177e4SLinus Torvalds 15037d2c6b1eSMauro Carvalho Chehabmy $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x; 15047efc6c42SMauro Carvalho Chehabmy $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; 15057efc6c42SMauro Carvalho Chehabmy $typedef_args = qr { \s*\((.*)\); }x; 15067efc6c42SMauro Carvalho Chehab 15077efc6c42SMauro Carvalho Chehabmy $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x; 15087efc6c42SMauro Carvalho Chehabmy $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x; 15097efc6c42SMauro Carvalho Chehab 15101da177e4SLinus Torvaldssub dump_typedef($$) { 15111da177e4SLinus Torvalds my $x = shift; 15121da177e4SLinus Torvalds my $file = shift; 15131da177e4SLinus Torvalds 1514aeec46b9SMartin Waitz $x =~ s@/\*.*?\*/@@gos; # strip comments. 151583766452SMauro Carvalho Chehab 15167efc6c42SMauro Carvalho Chehab # Parse function typedef prototypes 15177efc6c42SMauro Carvalho Chehab if ($x =~ $typedef1 || $x =~ $typedef2) { 151883766452SMauro Carvalho Chehab $return_type = $1; 151983766452SMauro Carvalho Chehab $declaration_name = $2; 152083766452SMauro Carvalho Chehab my $args = $3; 15216b80975cSMauro Carvalho Chehab $return_type =~ s/^\s+//; 152283766452SMauro Carvalho Chehab 152352042e2dSMauro Carvalho Chehab if ($identifier ne $declaration_name) { 152452042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; 152552042e2dSMauro Carvalho Chehab return; 152652042e2dSMauro Carvalho Chehab } 152752042e2dSMauro Carvalho Chehab 1528151c468bSMauro Carvalho Chehab create_parameterlist($args, ',', $file, $declaration_name); 152983766452SMauro Carvalho Chehab 153083766452SMauro Carvalho Chehab output_declaration($declaration_name, 153183766452SMauro Carvalho Chehab 'function', 153283766452SMauro Carvalho Chehab {'function' => $declaration_name, 153382801d06SMauro Carvalho Chehab 'typedef' => 1, 153483766452SMauro Carvalho Chehab 'module' => $modulename, 153583766452SMauro Carvalho Chehab 'functiontype' => $return_type, 153683766452SMauro Carvalho Chehab 'parameterlist' => \@parameterlist, 153783766452SMauro Carvalho Chehab 'parameterdescs' => \%parameterdescs, 153883766452SMauro Carvalho Chehab 'parametertypes' => \%parametertypes, 153983766452SMauro Carvalho Chehab 'sectionlist' => \@sectionlist, 154083766452SMauro Carvalho Chehab 'sections' => \%sections, 154183766452SMauro Carvalho Chehab 'purpose' => $declaration_purpose 154283766452SMauro Carvalho Chehab }); 154383766452SMauro Carvalho Chehab return; 154483766452SMauro Carvalho Chehab } 154583766452SMauro Carvalho Chehab 15461da177e4SLinus Torvalds while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { 15471da177e4SLinus Torvalds $x =~ s/\(*.\)\s*;$/;/; 15481da177e4SLinus Torvalds $x =~ s/\[*.\]\s*;$/;/; 15491da177e4SLinus Torvalds } 15501da177e4SLinus Torvalds 15511da177e4SLinus Torvalds if ($x =~ /typedef.*\s+(\w+)\s*;/) { 15521da177e4SLinus Torvalds $declaration_name = $1; 15531da177e4SLinus Torvalds 155452042e2dSMauro Carvalho Chehab if ($identifier ne $declaration_name) { 155552042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; 155652042e2dSMauro Carvalho Chehab return; 155752042e2dSMauro Carvalho Chehab } 155852042e2dSMauro Carvalho Chehab 15591da177e4SLinus Torvalds output_declaration($declaration_name, 15601da177e4SLinus Torvalds 'typedef', 15611da177e4SLinus Torvalds {'typedef' => $declaration_name, 15621da177e4SLinus Torvalds 'module' => $modulename, 15631da177e4SLinus Torvalds 'sectionlist' => \@sectionlist, 15641da177e4SLinus Torvalds 'sections' => \%sections, 15651da177e4SLinus Torvalds 'purpose' => $declaration_purpose 15661da177e4SLinus Torvalds }); 15671da177e4SLinus Torvalds } 15681da177e4SLinus Torvalds else { 1569d40e1e65SBart Van Assche print STDERR "${file}:$.: error: Cannot parse typedef!\n"; 15701da177e4SLinus Torvalds ++$errors; 15711da177e4SLinus Torvalds } 15721da177e4SLinus Torvalds} 15731da177e4SLinus Torvalds 1574a1d94aa5SRandy Dunlapsub save_struct_actual($) { 1575a1d94aa5SRandy Dunlap my $actual = shift; 1576a1d94aa5SRandy Dunlap 1577a1d94aa5SRandy Dunlap # strip all spaces from the actual param so that it looks like one string item 1578a1d94aa5SRandy Dunlap $actual =~ s/\s*//g; 1579a1d94aa5SRandy Dunlap $struct_actual = $struct_actual . $actual . " "; 1580a1d94aa5SRandy Dunlap} 1581a1d94aa5SRandy Dunlap 1582151c468bSMauro Carvalho Chehabsub create_parameterlist($$$$) { 15831da177e4SLinus Torvalds my $args = shift; 15841da177e4SLinus Torvalds my $splitter = shift; 15851da177e4SLinus Torvalds my $file = shift; 1586151c468bSMauro Carvalho Chehab my $declaration_name = shift; 15871da177e4SLinus Torvalds my $type; 15881da177e4SLinus Torvalds my $param; 15891da177e4SLinus Torvalds 1590a6d3fe77SMartin Waitz # temporarily replace commas inside function pointer definition 1591e86bdb24SAditya Srivastava my $arg_expr = qr{\([^\),]+}; 1592e86bdb24SAditya Srivastava while ($args =~ /$arg_expr,/) { 1593e86bdb24SAditya Srivastava $args =~ s/($arg_expr),/$1#/g; 15941da177e4SLinus Torvalds } 15951da177e4SLinus Torvalds 15961da177e4SLinus Torvalds foreach my $arg (split($splitter, $args)) { 15971da177e4SLinus Torvalds # strip comments 15981da177e4SLinus Torvalds $arg =~ s/\/\*.*\*\///; 15991da177e4SLinus Torvalds # strip leading/trailing spaces 16001da177e4SLinus Torvalds $arg =~ s/^\s*//; 16011da177e4SLinus Torvalds $arg =~ s/\s*$//; 16021da177e4SLinus Torvalds $arg =~ s/\s+/ /; 16031da177e4SLinus Torvalds 16041da177e4SLinus Torvalds if ($arg =~ /^#/) { 16051da177e4SLinus Torvalds # Treat preprocessor directive as a typeless variable just to fill 16061da177e4SLinus Torvalds # corresponding data structures "correctly". Catch it later in 16071da177e4SLinus Torvalds # output_* subs. 1608ed8348e2SMauro Carvalho Chehab push_parameter($arg, "", "", $file); 160900d62961SRichard Kennedy } elsif ($arg =~ m/\(.+\)\s*\(/) { 16101da177e4SLinus Torvalds # pointer-to-function 16111da177e4SLinus Torvalds $arg =~ tr/#/,/; 1612336ced2dSAditya Srivastava $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)/; 16131da177e4SLinus Torvalds $param = $1; 16141da177e4SLinus Torvalds $type = $arg; 161500d62961SRichard Kennedy $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 1616a1d94aa5SRandy Dunlap save_struct_actual($param); 1617ed8348e2SMauro Carvalho Chehab push_parameter($param, $type, $arg, $file, $declaration_name); 1618aeec46b9SMartin Waitz } elsif ($arg) { 16191da177e4SLinus Torvalds $arg =~ s/\s*:\s*/:/g; 16201da177e4SLinus Torvalds $arg =~ s/\s*\[/\[/g; 16211da177e4SLinus Torvalds 16221da177e4SLinus Torvalds my @args = split('\s*,\s*', $arg); 16231da177e4SLinus Torvalds if ($args[0] =~ m/\*/) { 16241da177e4SLinus Torvalds $args[0] =~ s/(\*+)\s*/ $1/; 16251da177e4SLinus Torvalds } 1626884f2810SBorislav Petkov 1627884f2810SBorislav Petkov my @first_arg; 1628884f2810SBorislav Petkov if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { 1629884f2810SBorislav Petkov shift @args; 1630884f2810SBorislav Petkov push(@first_arg, split('\s+', $1)); 1631884f2810SBorislav Petkov push(@first_arg, $2); 1632884f2810SBorislav Petkov } else { 1633884f2810SBorislav Petkov @first_arg = split('\s+', shift @args); 1634884f2810SBorislav Petkov } 1635884f2810SBorislav Petkov 16361da177e4SLinus Torvalds unshift(@args, pop @first_arg); 16371da177e4SLinus Torvalds $type = join " ", @first_arg; 16381da177e4SLinus Torvalds 16391da177e4SLinus Torvalds foreach $param (@args) { 16401da177e4SLinus Torvalds if ($param =~ m/^(\*+)\s*(.*)/) { 1641a1d94aa5SRandy Dunlap save_struct_actual($2); 1642ed8348e2SMauro Carvalho Chehab 1643ed8348e2SMauro Carvalho Chehab push_parameter($2, "$type $1", $arg, $file, $declaration_name); 16441da177e4SLinus Torvalds } 16451da177e4SLinus Torvalds elsif ($param =~ m/(.*?):(\d+)/) { 16467b97887eSRandy Dunlap if ($type ne "") { # skip unnamed bit-fields 1647a1d94aa5SRandy Dunlap save_struct_actual($1); 1648ed8348e2SMauro Carvalho Chehab push_parameter($1, "$type:$2", $arg, $file, $declaration_name) 16491da177e4SLinus Torvalds } 16507b97887eSRandy Dunlap } 16511da177e4SLinus Torvalds else { 1652a1d94aa5SRandy Dunlap save_struct_actual($param); 1653ed8348e2SMauro Carvalho Chehab push_parameter($param, $type, $arg, $file, $declaration_name); 16541da177e4SLinus Torvalds } 16551da177e4SLinus Torvalds } 16561da177e4SLinus Torvalds } 16571da177e4SLinus Torvalds } 16581da177e4SLinus Torvalds} 16591da177e4SLinus Torvalds 1660ed8348e2SMauro Carvalho Chehabsub push_parameter($$$$$) { 16611da177e4SLinus Torvalds my $param = shift; 16621da177e4SLinus Torvalds my $type = shift; 1663ed8348e2SMauro Carvalho Chehab my $org_arg = shift; 16641da177e4SLinus Torvalds my $file = shift; 1665151c468bSMauro Carvalho Chehab my $declaration_name = shift; 16661da177e4SLinus Torvalds 16675f8c7c98SRandy Dunlap if (($anon_struct_union == 1) && ($type eq "") && 16685f8c7c98SRandy Dunlap ($param eq "}")) { 16695f8c7c98SRandy Dunlap return; # ignore the ending }; from anon. struct/union 16705f8c7c98SRandy Dunlap } 16715f8c7c98SRandy Dunlap 16725f8c7c98SRandy Dunlap $anon_struct_union = 0; 1673f9b5c530SMauro Carvalho Chehab $param =~ s/[\[\)].*//; 16741da177e4SLinus Torvalds 1675a6d3fe77SMartin Waitz if ($type eq "" && $param =~ /\.\.\.$/) 16761da177e4SLinus Torvalds { 1677c950a173SSilvio Fricke if (!$param =~ /\w\.\.\.$/) { 1678c950a173SSilvio Fricke # handles unnamed variable parameters 1679ef00028bSJonathan Corbet $param = "..."; 1680c950a173SSilvio Fricke } 168143756e34SJonathan Neuschäfer elsif ($param =~ /\w\.\.\.$/) { 168243756e34SJonathan Neuschäfer # for named variable parameters of the form `x...`, remove the dots 168343756e34SJonathan Neuschäfer $param =~ s/\.\.\.$//; 168443756e34SJonathan Neuschäfer } 1685ced69090SRandy Dunlap if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") { 1686a6d3fe77SMartin Waitz $parameterdescs{$param} = "variable arguments"; 16871da177e4SLinus Torvalds } 1688ced69090SRandy Dunlap } 16891da177e4SLinus Torvalds elsif ($type eq "" && ($param eq "" or $param eq "void")) 16901da177e4SLinus Torvalds { 16911da177e4SLinus Torvalds $param="void"; 16921da177e4SLinus Torvalds $parameterdescs{void} = "no arguments"; 16931da177e4SLinus Torvalds } 1694134fe01bSRandy Dunlap elsif ($type eq "" && ($param eq "struct" or $param eq "union")) 1695134fe01bSRandy Dunlap # handle unnamed (anonymous) union or struct: 1696134fe01bSRandy Dunlap { 1697134fe01bSRandy Dunlap $type = $param; 1698134fe01bSRandy Dunlap $param = "{unnamed_" . $param . "}"; 1699134fe01bSRandy Dunlap $parameterdescs{$param} = "anonymous\n"; 17005f8c7c98SRandy Dunlap $anon_struct_union = 1; 1701134fe01bSRandy Dunlap } 1702134fe01bSRandy Dunlap 1703a6d3fe77SMartin Waitz # warn if parameter has no description 1704134fe01bSRandy Dunlap # (but ignore ones starting with # as these are not parameters 1705134fe01bSRandy Dunlap # but inline preprocessor statements); 1706151c468bSMauro Carvalho Chehab # Note: It will also ignore void params and unnamed structs/unions 1707f9b5c530SMauro Carvalho Chehab if (!defined $parameterdescs{$param} && $param !~ /^#/) { 1708f9b5c530SMauro Carvalho Chehab $parameterdescs{$param} = $undescribed; 17091da177e4SLinus Torvalds 1710be5cd20cSJonathan Corbet if (show_warnings($type, $declaration_name) && $param !~ /\./) { 1711151c468bSMauro Carvalho Chehab print STDERR 1712151c468bSMauro Carvalho Chehab "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; 17131da177e4SLinus Torvalds ++$warnings; 17141da177e4SLinus Torvalds } 17152defb272SMauro Carvalho Chehab } 17161da177e4SLinus Torvalds 171725985edcSLucas De Marchi # strip spaces from $param so that it is one continuous string 1718e34e7dbbSRandy Dunlap # on @parameterlist; 1719e34e7dbbSRandy Dunlap # this fixes a problem where check_sections() cannot find 1720e34e7dbbSRandy Dunlap # a parameter like "addr[6 + 2]" because it actually appears 1721e34e7dbbSRandy Dunlap # as "addr[6", "+", "2]" on the parameter list; 1722e34e7dbbSRandy Dunlap # but it's better to maintain the param string unchanged for output, 1723e34e7dbbSRandy Dunlap # so just weaken the string compare in check_sections() to ignore 1724e34e7dbbSRandy Dunlap # "[blah" in a parameter string; 1725e34e7dbbSRandy Dunlap ###$param =~ s/\s*//g; 17261da177e4SLinus Torvalds push @parameterlist, $param; 1727ed8348e2SMauro Carvalho Chehab $org_arg =~ s/\s\s+/ /g; 1728ed8348e2SMauro Carvalho Chehab $parametertypes{$param} = $org_arg; 17291da177e4SLinus Torvalds} 17301da177e4SLinus Torvalds 17311081de2dSMauro Carvalho Chehabsub check_sections($$$$$) { 17321081de2dSMauro Carvalho Chehab my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; 1733a1d94aa5SRandy Dunlap my @sects = split ' ', $sectcheck; 1734a1d94aa5SRandy Dunlap my @prms = split ' ', $prmscheck; 1735a1d94aa5SRandy Dunlap my $err; 1736a1d94aa5SRandy Dunlap my ($px, $sx); 1737a1d94aa5SRandy Dunlap my $prm_clean; # strip trailing "[array size]" and/or beginning "*" 1738a1d94aa5SRandy Dunlap 1739a1d94aa5SRandy Dunlap foreach $sx (0 .. $#sects) { 1740a1d94aa5SRandy Dunlap $err = 1; 1741a1d94aa5SRandy Dunlap foreach $px (0 .. $#prms) { 1742a1d94aa5SRandy Dunlap $prm_clean = $prms[$px]; 1743a1d94aa5SRandy Dunlap $prm_clean =~ s/\[.*\]//; 1744e86bdb24SAditya Srivastava $prm_clean =~ s/$attribute//i; 1745e34e7dbbSRandy Dunlap # ignore array size in a parameter string; 1746e34e7dbbSRandy Dunlap # however, the original param string may contain 1747e34e7dbbSRandy Dunlap # spaces, e.g.: addr[6 + 2] 1748e34e7dbbSRandy Dunlap # and this appears in @prms as "addr[6" since the 1749e34e7dbbSRandy Dunlap # parameter list is split at spaces; 1750e34e7dbbSRandy Dunlap # hence just ignore "[..." for the sections check; 1751e34e7dbbSRandy Dunlap $prm_clean =~ s/\[.*//; 1752e34e7dbbSRandy Dunlap 1753a1d94aa5SRandy Dunlap ##$prm_clean =~ s/^\**//; 1754a1d94aa5SRandy Dunlap if ($prm_clean eq $sects[$sx]) { 1755a1d94aa5SRandy Dunlap $err = 0; 1756a1d94aa5SRandy Dunlap last; 1757a1d94aa5SRandy Dunlap } 1758a1d94aa5SRandy Dunlap } 1759a1d94aa5SRandy Dunlap if ($err) { 1760a1d94aa5SRandy Dunlap if ($decl_type eq "function") { 1761d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: " . 1762a1d94aa5SRandy Dunlap "Excess function parameter " . 1763a1d94aa5SRandy Dunlap "'$sects[$sx]' " . 1764a1d94aa5SRandy Dunlap "description in '$decl_name'\n"; 1765a1d94aa5SRandy Dunlap ++$warnings; 1766a1d94aa5SRandy Dunlap } 1767a1d94aa5SRandy Dunlap } 1768a1d94aa5SRandy Dunlap } 1769a1d94aa5SRandy Dunlap} 1770a1d94aa5SRandy Dunlap 17711da177e4SLinus Torvalds## 17724092bac7SYacine Belkadi# Checks the section describing the return value of a function. 17734092bac7SYacine Belkadisub check_return_section { 17744092bac7SYacine Belkadi my $file = shift; 17754092bac7SYacine Belkadi my $declaration_name = shift; 17764092bac7SYacine Belkadi my $return_type = shift; 17774092bac7SYacine Belkadi 17784092bac7SYacine Belkadi # Ignore an empty return type (It's a macro) 17794092bac7SYacine Belkadi # Ignore functions with a "void" return type. (But don't ignore "void *") 17804092bac7SYacine Belkadi if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) { 17814092bac7SYacine Belkadi return; 17824092bac7SYacine Belkadi } 17834092bac7SYacine Belkadi 17844092bac7SYacine Belkadi if (!defined($sections{$section_return}) || 17854092bac7SYacine Belkadi $sections{$section_return} eq "") { 1786d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: " . 17874092bac7SYacine Belkadi "No description found for return value of " . 17884092bac7SYacine Belkadi "'$declaration_name'\n"; 17894092bac7SYacine Belkadi ++$warnings; 17904092bac7SYacine Belkadi } 17914092bac7SYacine Belkadi} 17924092bac7SYacine Belkadi 17934092bac7SYacine Belkadi## 17941da177e4SLinus Torvalds# takes a function prototype and the name of the current file being 17951da177e4SLinus Torvalds# processed and spits out all the details stored in the global 17961da177e4SLinus Torvalds# arrays/hashes. 17971da177e4SLinus Torvaldssub dump_function($$) { 17981da177e4SLinus Torvalds my $prototype = shift; 17991da177e4SLinus Torvalds my $file = shift; 1800cbb4d3e6SHoria Geanta my $noret = 0; 18011da177e4SLinus Torvalds 18025ef09c96SMauro Carvalho Chehab print_lineno($new_start_line); 18035eb6b4b3SMauro Carvalho Chehab 18041da177e4SLinus Torvalds $prototype =~ s/^static +//; 18051da177e4SLinus Torvalds $prototype =~ s/^extern +//; 18064dc3b16bSPavel Pisa $prototype =~ s/^asmlinkage +//; 18071da177e4SLinus Torvalds $prototype =~ s/^inline +//; 18081da177e4SLinus Torvalds $prototype =~ s/^__inline__ +//; 180932e79401SRandy Dunlap $prototype =~ s/^__inline +//; 181032e79401SRandy Dunlap $prototype =~ s/^__always_inline +//; 181132e79401SRandy Dunlap $prototype =~ s/^noinline +//; 181274fc5c65SRandy Dunlap $prototype =~ s/__init +//; 181320072205SRandy Dunlap $prototype =~ s/__init_or_module +//; 181480342d48SMatthew Wilcox $prototype =~ s/__deprecated +//; 1815084aa001SAditya Srivastava $prototype =~ s/__flatten +//; 1816270a0096SRandy Dunlap $prototype =~ s/__meminit +//; 181770c95b00SRandy Dunlap $prototype =~ s/__must_check +//; 18180df7c0e3SRandy Dunlap $prototype =~ s/__weak +//; 18190891f959SMatthew Wilcox $prototype =~ s/__sched +//; 182095e760cbSRandy Dunlap $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; 1821a40a8a11SKees Cook $prototype =~ s/__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//; 1822cbb4d3e6SHoria Geanta my $define = $prototype =~ s/^#\s*define\s+//; #ak added 1823084aa001SAditya Srivastava $prototype =~ s/__attribute_const__ +//; 1824b1aaa546SPaolo Bonzini $prototype =~ s/__attribute__\s*\(\( 1825b1aaa546SPaolo Bonzini (?: 1826b1aaa546SPaolo Bonzini [\w\s]++ # attribute name 1827b1aaa546SPaolo Bonzini (?:\([^)]*+\))? # attribute arguments 1828b1aaa546SPaolo Bonzini \s*+,? # optional comma at the end 1829b1aaa546SPaolo Bonzini )+ 1830b1aaa546SPaolo Bonzini \)\)\s+//x; 18311da177e4SLinus Torvalds 18321da177e4SLinus Torvalds # Yes, this truly is vile. We are looking for: 18331da177e4SLinus Torvalds # 1. Return type (may be nothing if we're looking at a macro) 18341da177e4SLinus Torvalds # 2. Function name 18351da177e4SLinus Torvalds # 3. Function parameters. 18361da177e4SLinus Torvalds # 18371da177e4SLinus Torvalds # All the while we have to watch out for function pointer parameters 18381da177e4SLinus Torvalds # (which IIRC is what the two sections are for), C types (these 18391da177e4SLinus Torvalds # regexps don't even start to express all the possibilities), and 18401da177e4SLinus Torvalds # so on. 18411da177e4SLinus Torvalds # 18421da177e4SLinus Torvalds # If you mess with these regexps, it's a good idea to check that 18431da177e4SLinus Torvalds # the following functions' documentation still comes out right: 18441da177e4SLinus Torvalds # - parport_register_device (function pointer parameters) 18451da177e4SLinus Torvalds # - atomic_set (macro) 18469598f91fSMartin Waitz # - pci_match_device, __copy_to_user (long return type) 1847e86bdb24SAditya Srivastava my $name = qr{[a-zA-Z0-9_~:]+}; 1848e86bdb24SAditya Srivastava my $prototype_end1 = qr{[^\(]*}; 1849e86bdb24SAditya Srivastava my $prototype_end2 = qr{[^\{]*}; 1850e86bdb24SAditya Srivastava my $prototype_end = qr{\(($prototype_end1|$prototype_end2)\)}; 1851e86bdb24SAditya Srivastava my $type1 = qr{[\w\s]+}; 1852e86bdb24SAditya Srivastava my $type2 = qr{$type1\*+}; 18531da177e4SLinus Torvalds 1854e86bdb24SAditya Srivastava if ($define && $prototype =~ m/^()($name)\s+/) { 1855cbb4d3e6SHoria Geanta # This is an object-like macro, it has no return type and no parameter 1856cbb4d3e6SHoria Geanta # list. 1857cbb4d3e6SHoria Geanta # Function-like macros are not allowed to have spaces between 1858cbb4d3e6SHoria Geanta # declaration_name and opening parenthesis (notice the \s+). 1859cbb4d3e6SHoria Geanta $return_type = $1; 1860cbb4d3e6SHoria Geanta $declaration_name = $2; 1861cbb4d3e6SHoria Geanta $noret = 1; 1862e86bdb24SAditya Srivastava } elsif ($prototype =~ m/^()($name)\s*$prototype_end/ || 1863e86bdb24SAditya Srivastava $prototype =~ m/^($type1)\s+($name)\s*$prototype_end/ || 1864e86bdb24SAditya Srivastava $prototype =~ m/^($type2+)\s*($name)\s*$prototype_end/) { 18651da177e4SLinus Torvalds $return_type = $1; 18661da177e4SLinus Torvalds $declaration_name = $2; 18671da177e4SLinus Torvalds my $args = $3; 18681da177e4SLinus Torvalds 1869151c468bSMauro Carvalho Chehab create_parameterlist($args, ',', $file, $declaration_name); 18701da177e4SLinus Torvalds } else { 1871d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; 18721da177e4SLinus Torvalds return; 18731da177e4SLinus Torvalds } 18741da177e4SLinus Torvalds 187552042e2dSMauro Carvalho Chehab if ($identifier ne $declaration_name) { 187652042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n"; 187752042e2dSMauro Carvalho Chehab return; 187852042e2dSMauro Carvalho Chehab } 187952042e2dSMauro Carvalho Chehab 1880a1d94aa5SRandy Dunlap my $prms = join " ", @parameterlist; 18811081de2dSMauro Carvalho Chehab check_sections($file, $declaration_name, "function", $sectcheck, $prms); 1882a1d94aa5SRandy Dunlap 18834092bac7SYacine Belkadi # This check emits a lot of warnings at the moment, because many 18844092bac7SYacine Belkadi # functions don't have a 'Return' doc section. So until the number 18854092bac7SYacine Belkadi # of warnings goes sufficiently down, the check is only performed in 18864092bac7SYacine Belkadi # verbose mode. 18874092bac7SYacine Belkadi # TODO: always perform the check. 1888cbb4d3e6SHoria Geanta if ($verbose && !$noret) { 18894092bac7SYacine Belkadi check_return_section($file, $declaration_name, $return_type); 18904092bac7SYacine Belkadi } 18914092bac7SYacine Belkadi 189247bcacfdSMauro Carvalho Chehab # The function parser can be called with a typedef parameter. 189347bcacfdSMauro Carvalho Chehab # Handle it. 189447bcacfdSMauro Carvalho Chehab if ($return_type =~ /typedef/) { 189547bcacfdSMauro Carvalho Chehab output_declaration($declaration_name, 189647bcacfdSMauro Carvalho Chehab 'function', 189747bcacfdSMauro Carvalho Chehab {'function' => $declaration_name, 189847bcacfdSMauro Carvalho Chehab 'typedef' => 1, 189947bcacfdSMauro Carvalho Chehab 'module' => $modulename, 190047bcacfdSMauro Carvalho Chehab 'functiontype' => $return_type, 190147bcacfdSMauro Carvalho Chehab 'parameterlist' => \@parameterlist, 190247bcacfdSMauro Carvalho Chehab 'parameterdescs' => \%parameterdescs, 190347bcacfdSMauro Carvalho Chehab 'parametertypes' => \%parametertypes, 190447bcacfdSMauro Carvalho Chehab 'sectionlist' => \@sectionlist, 190547bcacfdSMauro Carvalho Chehab 'sections' => \%sections, 190647bcacfdSMauro Carvalho Chehab 'purpose' => $declaration_purpose 190747bcacfdSMauro Carvalho Chehab }); 190847bcacfdSMauro Carvalho Chehab } else { 19091da177e4SLinus Torvalds output_declaration($declaration_name, 19101da177e4SLinus Torvalds 'function', 19111da177e4SLinus Torvalds {'function' => $declaration_name, 19121da177e4SLinus Torvalds 'module' => $modulename, 19131da177e4SLinus Torvalds 'functiontype' => $return_type, 19141da177e4SLinus Torvalds 'parameterlist' => \@parameterlist, 19151da177e4SLinus Torvalds 'parameterdescs' => \%parameterdescs, 19161da177e4SLinus Torvalds 'parametertypes' => \%parametertypes, 19171da177e4SLinus Torvalds 'sectionlist' => \@sectionlist, 19181da177e4SLinus Torvalds 'sections' => \%sections, 19191da177e4SLinus Torvalds 'purpose' => $declaration_purpose 19201da177e4SLinus Torvalds }); 19211da177e4SLinus Torvalds } 192247bcacfdSMauro Carvalho Chehab} 19231da177e4SLinus Torvalds 19241da177e4SLinus Torvaldssub reset_state { 19251da177e4SLinus Torvalds $function = ""; 19261da177e4SLinus Torvalds %parameterdescs = (); 19271da177e4SLinus Torvalds %parametertypes = (); 19281da177e4SLinus Torvalds @parameterlist = (); 19291da177e4SLinus Torvalds %sections = (); 19301da177e4SLinus Torvalds @sectionlist = (); 1931a1d94aa5SRandy Dunlap $sectcheck = ""; 1932a1d94aa5SRandy Dunlap $struct_actual = ""; 19331da177e4SLinus Torvalds $prototype = ""; 19341da177e4SLinus Torvalds 193548af606aSJani Nikula $state = STATE_NORMAL; 193648af606aSJani Nikula $inline_doc_state = STATE_INLINE_NA; 19371da177e4SLinus Torvalds} 19381da177e4SLinus Torvalds 193956afb0f8SJason Baronsub tracepoint_munge($) { 194056afb0f8SJason Baron my $file = shift; 194156afb0f8SJason Baron my $tracepointname = 0; 194256afb0f8SJason Baron my $tracepointargs = 0; 194356afb0f8SJason Baron 194456afb0f8SJason Baron if ($prototype =~ m/TRACE_EVENT\((.*?),/) { 194556afb0f8SJason Baron $tracepointname = $1; 194656afb0f8SJason Baron } 19473a9089fdSJason Baron if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) { 19483a9089fdSJason Baron $tracepointname = $1; 19493a9089fdSJason Baron } 19503a9089fdSJason Baron if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) { 19513a9089fdSJason Baron $tracepointname = $2; 19523a9089fdSJason Baron } 19533a9089fdSJason Baron $tracepointname =~ s/^\s+//; #strip leading whitespace 195456afb0f8SJason Baron if ($prototype =~ m/TP_PROTO\((.*?)\)/) { 195556afb0f8SJason Baron $tracepointargs = $1; 195656afb0f8SJason Baron } 195756afb0f8SJason Baron if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 1958d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". 195956afb0f8SJason Baron "$prototype\n"; 196056afb0f8SJason Baron } else { 196156afb0f8SJason Baron $prototype = "static inline void trace_$tracepointname($tracepointargs)"; 196252042e2dSMauro Carvalho Chehab $identifier = "trace_$identifier"; 196356afb0f8SJason Baron } 196456afb0f8SJason Baron} 196556afb0f8SJason Baron 1966b4870bc5SRandy Dunlapsub syscall_munge() { 1967b4870bc5SRandy Dunlap my $void = 0; 1968b4870bc5SRandy Dunlap 19697c9aa015SMauro Carvalho Chehab $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's 1970b4870bc5SRandy Dunlap## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { 1971b4870bc5SRandy Dunlap if ($prototype =~ m/SYSCALL_DEFINE0/) { 1972b4870bc5SRandy Dunlap $void = 1; 1973b4870bc5SRandy Dunlap## $prototype = "long sys_$1(void)"; 1974b4870bc5SRandy Dunlap } 1975b4870bc5SRandy Dunlap 1976b4870bc5SRandy Dunlap $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name 1977b4870bc5SRandy Dunlap if ($prototype =~ m/long (sys_.*?),/) { 1978b4870bc5SRandy Dunlap $prototype =~ s/,/\(/; 1979b4870bc5SRandy Dunlap } elsif ($void) { 1980b4870bc5SRandy Dunlap $prototype =~ s/\)/\(void\)/; 1981b4870bc5SRandy Dunlap } 1982b4870bc5SRandy Dunlap 1983b4870bc5SRandy Dunlap # now delete all of the odd-number commas in $prototype 1984b4870bc5SRandy Dunlap # so that arg types & arg names don't have a comma between them 1985b4870bc5SRandy Dunlap my $count = 0; 1986b4870bc5SRandy Dunlap my $len = length($prototype); 1987b4870bc5SRandy Dunlap if ($void) { 1988b4870bc5SRandy Dunlap $len = 0; # skip the for-loop 1989b4870bc5SRandy Dunlap } 1990b4870bc5SRandy Dunlap for (my $ix = 0; $ix < $len; $ix++) { 1991b4870bc5SRandy Dunlap if (substr($prototype, $ix, 1) eq ',') { 1992b4870bc5SRandy Dunlap $count++; 1993b4870bc5SRandy Dunlap if ($count % 2 == 1) { 1994b4870bc5SRandy Dunlap substr($prototype, $ix, 1) = ' '; 1995b4870bc5SRandy Dunlap } 1996b4870bc5SRandy Dunlap } 1997b4870bc5SRandy Dunlap } 1998b4870bc5SRandy Dunlap} 1999b4870bc5SRandy Dunlap 2000b7afa92bSDaniel Vettersub process_proto_function($$) { 20011da177e4SLinus Torvalds my $x = shift; 20021da177e4SLinus Torvalds my $file = shift; 20031da177e4SLinus Torvalds 200451f5a0c8SRandy Dunlap $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 200551f5a0c8SRandy Dunlap 2006890c78c2SRandy Dunlap if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { 20071da177e4SLinus Torvalds # do nothing 20081da177e4SLinus Torvalds } 20091da177e4SLinus Torvalds elsif ($x =~ /([^\{]*)/) { 20101da177e4SLinus Torvalds $prototype .= $1; 20111da177e4SLinus Torvalds } 2012b4870bc5SRandy Dunlap 2013890c78c2SRandy Dunlap if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { 20141da177e4SLinus Torvalds $prototype =~ s@/\*.*?\*/@@gos; # strip comments. 20151da177e4SLinus Torvalds $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 20161da177e4SLinus Torvalds $prototype =~ s@^\s+@@gos; # strip leading spaces 20177ae281b0SMauro Carvalho Chehab 20187ae281b0SMauro Carvalho Chehab # Handle prototypes for function pointers like: 20197ae281b0SMauro Carvalho Chehab # int (*pcs_config)(struct foo) 20207ae281b0SMauro Carvalho Chehab $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos; 20217ae281b0SMauro Carvalho Chehab 2022b4870bc5SRandy Dunlap if ($prototype =~ /SYSCALL_DEFINE/) { 2023b4870bc5SRandy Dunlap syscall_munge(); 2024b4870bc5SRandy Dunlap } 20253a9089fdSJason Baron if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ || 20263a9089fdSJason Baron $prototype =~ /DEFINE_SINGLE_EVENT/) 20273a9089fdSJason Baron { 202856afb0f8SJason Baron tracepoint_munge($file); 202956afb0f8SJason Baron } 20301da177e4SLinus Torvalds dump_function($prototype, $file); 20311da177e4SLinus Torvalds reset_state(); 20321da177e4SLinus Torvalds } 20331da177e4SLinus Torvalds} 20341da177e4SLinus Torvalds 2035b7afa92bSDaniel Vettersub process_proto_type($$) { 20361da177e4SLinus Torvalds my $x = shift; 20371da177e4SLinus Torvalds my $file = shift; 20381da177e4SLinus Torvalds 20391da177e4SLinus Torvalds $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 20401da177e4SLinus Torvalds $x =~ s@^\s+@@gos; # strip leading spaces 20411da177e4SLinus Torvalds $x =~ s@\s+$@@gos; # strip trailing spaces 204251f5a0c8SRandy Dunlap $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 204351f5a0c8SRandy Dunlap 20441da177e4SLinus Torvalds if ($x =~ /^#/) { 20451da177e4SLinus Torvalds # To distinguish preprocessor directive from regular declaration later. 20461da177e4SLinus Torvalds $x .= ";"; 20471da177e4SLinus Torvalds } 20481da177e4SLinus Torvalds 20491da177e4SLinus Torvalds while (1) { 2050673bb2dfSBen Hutchings if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) { 2051463a0fdcSMarkus Heiser if( length $prototype ) { 2052463a0fdcSMarkus Heiser $prototype .= " " 2053463a0fdcSMarkus Heiser } 20541da177e4SLinus Torvalds $prototype .= $1 . $2; 20551da177e4SLinus Torvalds ($2 eq '{') && $brcount++; 20561da177e4SLinus Torvalds ($2 eq '}') && $brcount--; 20571da177e4SLinus Torvalds if (($2 eq ';') && ($brcount == 0)) { 20581da177e4SLinus Torvalds dump_declaration($prototype, $file); 20591da177e4SLinus Torvalds reset_state(); 20601da177e4SLinus Torvalds last; 20611da177e4SLinus Torvalds } 20621da177e4SLinus Torvalds $x = $3; 20631da177e4SLinus Torvalds } else { 20641da177e4SLinus Torvalds $prototype .= $x; 20651da177e4SLinus Torvalds last; 20661da177e4SLinus Torvalds } 20671da177e4SLinus Torvalds } 20681da177e4SLinus Torvalds} 20691da177e4SLinus Torvalds 20706b5b55f6SRandy Dunlap 20711ad560e4SJani Nikulasub map_filename($) { 20721ad560e4SJani Nikula my $file; 20731ad560e4SJani Nikula my ($orig_file) = @_; 20741ad560e4SJani Nikula 20751ad560e4SJani Nikula if (defined($ENV{'SRCTREE'})) { 20761ad560e4SJani Nikula $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; 20771ad560e4SJani Nikula } else { 20781ad560e4SJani Nikula $file = $orig_file; 20791ad560e4SJani Nikula } 20801ad560e4SJani Nikula 20811ad560e4SJani Nikula if (defined($source_map{$file})) { 20821ad560e4SJani Nikula $file = $source_map{$file}; 20831ad560e4SJani Nikula } 20841ad560e4SJani Nikula 20851ad560e4SJani Nikula return $file; 20861ad560e4SJani Nikula} 20871ad560e4SJani Nikula 208888c2b57dSJani Nikulasub process_export_file($) { 208988c2b57dSJani Nikula my ($orig_file) = @_; 209088c2b57dSJani Nikula my $file = map_filename($orig_file); 209188c2b57dSJani Nikula 209288c2b57dSJani Nikula if (!open(IN,"<$file")) { 209388c2b57dSJani Nikula print STDERR "Error: Cannot open file $file\n"; 209488c2b57dSJani Nikula ++$errors; 209588c2b57dSJani Nikula return; 209688c2b57dSJani Nikula } 209788c2b57dSJani Nikula 209888c2b57dSJani Nikula while (<IN>) { 209988c2b57dSJani Nikula if (/$export_symbol/) { 2100eab795ddSMauro Carvalho Chehab next if (defined($nosymbol_table{$2})); 210188c2b57dSJani Nikula $function_table{$2} = 1; 210288c2b57dSJani Nikula } 210388c2b57dSJani Nikula } 210488c2b57dSJani Nikula 210588c2b57dSJani Nikula close(IN); 210688c2b57dSJani Nikula} 210788c2b57dSJani Nikula 210807048d13SJonathan Corbet# 210907048d13SJonathan Corbet# Parsers for the various processing states. 211007048d13SJonathan Corbet# 211107048d13SJonathan Corbet# STATE_NORMAL: looking for the /** to begin everything. 211207048d13SJonathan Corbet# 211307048d13SJonathan Corbetsub process_normal() { 21141da177e4SLinus Torvalds if (/$doc_start/o) { 211548af606aSJani Nikula $state = STATE_NAME; # next line is always the function name 2116850622dfSRandy Dunlap $in_doc_sect = 0; 21170b0f5f29SDaniel Vetter $declaration_start_line = $. + 1; 21181da177e4SLinus Torvalds } 211907048d13SJonathan Corbet} 212007048d13SJonathan Corbet 21213cac2bc4SJonathan Corbet# 21223cac2bc4SJonathan Corbet# STATE_NAME: Looking for the "name - description" line 21233cac2bc4SJonathan Corbet# 21243cac2bc4SJonathan Corbetsub process_name($$) { 21253cac2bc4SJonathan Corbet my $file = shift; 21261da177e4SLinus Torvalds my $descr; 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds if (/$doc_block/o) { 212948af606aSJani Nikula $state = STATE_DOCBLOCK; 21301da177e4SLinus Torvalds $contents = ""; 21315ef09c96SMauro Carvalho Chehab $new_start_line = $.; 21320b0f5f29SDaniel Vetter 21331da177e4SLinus Torvalds if ( $1 eq "" ) { 21341da177e4SLinus Torvalds $section = $section_intro; 21351da177e4SLinus Torvalds } else { 21361da177e4SLinus Torvalds $section = $1; 21371da177e4SLinus Torvalds } 213852042e2dSMauro Carvalho Chehab } elsif (/$doc_decl/o) { 21391da177e4SLinus Torvalds $identifier = $1; 21403e58e839SAditya Srivastava my $is_kernel_comment = 0; 2141e86bdb24SAditya Srivastava my $decl_start = qr{$doc_com}; 2142f9bbc12cSAditya Srivastava # test for pointer declaration type, foo * bar() - desc 2143f9bbc12cSAditya Srivastava my $fn_type = qr{\w+\s*\*\s*}; 2144f9bbc12cSAditya Srivastava my $parenthesis = qr{\(\w*\)}; 2145f9bbc12cSAditya Srivastava my $decl_end = qr{[-:].*}; 2146e86bdb24SAditya Srivastava if (/^$decl_start([\w\s]+?)$parenthesis?\s*$decl_end?$/) { 21471da177e4SLinus Torvalds $identifier = $1; 21481da177e4SLinus Torvalds } 214952042e2dSMauro Carvalho Chehab if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { 215052042e2dSMauro Carvalho Chehab $decl_type = $1; 215152042e2dSMauro Carvalho Chehab $identifier = $2; 21523e58e839SAditya Srivastava $is_kernel_comment = 1; 215352042e2dSMauro Carvalho Chehab } 2154f9bbc12cSAditya Srivastava # Look for foo() or static void foo() - description; or misspelt 2155f9bbc12cSAditya Srivastava # identifier 2156e86bdb24SAditya Srivastava elsif (/^$decl_start$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ || 2157e86bdb24SAditya Srivastava /^$decl_start$fn_type?(\w+.*)$parenthesis?\s*$decl_end$/) { 2158f9bbc12cSAditya Srivastava $identifier = $1; 2159f9bbc12cSAditya Srivastava $decl_type = 'function'; 2160f9bbc12cSAditya Srivastava $identifier =~ s/^define\s+//; 2161f9bbc12cSAditya Srivastava $is_kernel_comment = 1; 2162f9bbc12cSAditya Srivastava } 216352042e2dSMauro Carvalho Chehab $identifier =~ s/\s+$//; 21641da177e4SLinus Torvalds 216517b78717SJonathan Corbet $state = STATE_BODY; 21660b0f5f29SDaniel Vetter # if there's no @param blocks need to set up default section 21670b0f5f29SDaniel Vetter # here 21682f4ad40aSJani Nikula $contents = ""; 21692f4ad40aSJani Nikula $section = $section_default; 21700b0f5f29SDaniel Vetter $new_start_line = $. + 1; 217152042e2dSMauro Carvalho Chehab if (/[-:](.*)/) { 217251f5a0c8SRandy Dunlap # strip leading/trailing/multiple spaces 2173a21217daSRandy Dunlap $descr= $1; 2174a21217daSRandy Dunlap $descr =~ s/^\s*//; 2175a21217daSRandy Dunlap $descr =~ s/\s*$//; 217612ae6779SDaniel Santos $descr =~ s/\s+/ /g; 21770bba924cSJonathan Corbet $declaration_purpose = $descr; 217817b78717SJonathan Corbet $state = STATE_BODY_MAYBE; 21791da177e4SLinus Torvalds } else { 21801da177e4SLinus Torvalds $declaration_purpose = ""; 21811da177e4SLinus Torvalds } 218277cc23b8SRandy Dunlap 21833e58e839SAditya Srivastava if (!$is_kernel_comment) { 21843e58e839SAditya Srivastava print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n"; 21853e58e839SAditya Srivastava print STDERR $_; 21863e58e839SAditya Srivastava ++$warnings; 21873e58e839SAditya Srivastava $state = STATE_NORMAL; 21883e58e839SAditya Srivastava } 21893e58e839SAditya Srivastava 219077cc23b8SRandy Dunlap if (($declaration_purpose eq "") && $verbose) { 2191d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: missing initial short description on line:\n"; 219277cc23b8SRandy Dunlap print STDERR $_; 219377cc23b8SRandy Dunlap ++$warnings; 219477cc23b8SRandy Dunlap } 219577cc23b8SRandy Dunlap 21960b54c2e3SMauro Carvalho Chehab if ($identifier eq "" && $decl_type ne "enum") { 219752042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; 219852042e2dSMauro Carvalho Chehab print STDERR $_; 219952042e2dSMauro Carvalho Chehab ++$warnings; 220052042e2dSMauro Carvalho Chehab $state = STATE_NORMAL; 22011da177e4SLinus Torvalds } 22021da177e4SLinus Torvalds 22031da177e4SLinus Torvalds if ($verbose) { 220452042e2dSMauro Carvalho Chehab print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n"; 22051da177e4SLinus Torvalds } 22061da177e4SLinus Torvalds } else { 2207d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", 22081da177e4SLinus Torvalds " - I thought it was a doc line\n"; 22091da177e4SLinus Torvalds ++$warnings; 221048af606aSJani Nikula $state = STATE_NORMAL; 22111da177e4SLinus Torvalds } 22123cac2bc4SJonathan Corbet} 22133cac2bc4SJonathan Corbet 22143cac2bc4SJonathan Corbet 2215d742f24dSJonathan Corbet# 2216d742f24dSJonathan Corbet# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. 2217d742f24dSJonathan Corbet# 2218d742f24dSJonathan Corbetsub process_body($$) { 2219d742f24dSJonathan Corbet my $file = shift; 22203cac2bc4SJonathan Corbet 222143756e34SJonathan Neuschäfer # Until all named variable macro parameters are 222243756e34SJonathan Neuschäfer # documented using the bare name (`x`) rather than with 222343756e34SJonathan Neuschäfer # dots (`x...`), strip the dots: 222443756e34SJonathan Neuschäfer if ($section =~ /\w\.\.\.$/) { 222543756e34SJonathan Neuschäfer $section =~ s/\.\.\.$//; 222643756e34SJonathan Neuschäfer 222743756e34SJonathan Neuschäfer if ($verbose) { 222843756e34SJonathan Neuschäfer print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n"; 222943756e34SJonathan Neuschäfer ++$warnings; 223043756e34SJonathan Neuschäfer } 223143756e34SJonathan Neuschäfer } 223243756e34SJonathan Neuschäfer 22330d55d48bSMauro Carvalho Chehab if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) { 22340d55d48bSMauro Carvalho Chehab dump_section($file, $section, $contents); 22350d55d48bSMauro Carvalho Chehab $section = $section_default; 22365ef09c96SMauro Carvalho Chehab $new_start_line = $.; 22370d55d48bSMauro Carvalho Chehab $contents = ""; 22380d55d48bSMauro Carvalho Chehab } 22390d55d48bSMauro Carvalho Chehab 2240f624adefSJani Nikula if (/$doc_sect/i) { # case insensitive for supported section names 22411da177e4SLinus Torvalds $newsection = $1; 22421da177e4SLinus Torvalds $newcontents = $2; 22431da177e4SLinus Torvalds 2244f624adefSJani Nikula # map the supported section names to the canonical names 2245f624adefSJani Nikula if ($newsection =~ m/^description$/i) { 2246f624adefSJani Nikula $newsection = $section_default; 2247f624adefSJani Nikula } elsif ($newsection =~ m/^context$/i) { 2248f624adefSJani Nikula $newsection = $section_context; 2249f624adefSJani Nikula } elsif ($newsection =~ m/^returns?$/i) { 2250f624adefSJani Nikula $newsection = $section_return; 2251f624adefSJani Nikula } elsif ($newsection =~ m/^\@return$/) { 2252f624adefSJani Nikula # special: @return is a section, not a param description 2253f624adefSJani Nikula $newsection = $section_return; 2254f624adefSJani Nikula } 2255f624adefSJani Nikula 2256792aa2f2SRandy Dunlap if (($contents ne "") && ($contents ne "\n")) { 2257850622dfSRandy Dunlap if (!$in_doc_sect && $verbose) { 2258d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: contents before sections\n"; 2259850622dfSRandy Dunlap ++$warnings; 2260850622dfSRandy Dunlap } 22610bba924cSJonathan Corbet dump_section($file, $section, $contents); 22621da177e4SLinus Torvalds $section = $section_default; 22631da177e4SLinus Torvalds } 22641da177e4SLinus Torvalds 2265850622dfSRandy Dunlap $in_doc_sect = 1; 226617b78717SJonathan Corbet $state = STATE_BODY; 22671da177e4SLinus Torvalds $contents = $newcontents; 22680b0f5f29SDaniel Vetter $new_start_line = $.; 22697c9aa015SMauro Carvalho Chehab while (substr($contents, 0, 1) eq " ") { 227005189497SRandy Dunlap $contents = substr($contents, 1); 227105189497SRandy Dunlap } 22720a726301SJani Nikula if ($contents ne "") { 22731da177e4SLinus Torvalds $contents .= "\n"; 22741da177e4SLinus Torvalds } 22751da177e4SLinus Torvalds $section = $newsection; 2276b7886de4SJani Nikula $leading_space = undef; 22771da177e4SLinus Torvalds } elsif (/$doc_end/) { 22784c98ecafSRandy Dunlap if (($contents ne "") && ($contents ne "\n")) { 22790bba924cSJonathan Corbet dump_section($file, $section, $contents); 22801da177e4SLinus Torvalds $section = $section_default; 22811da177e4SLinus Torvalds $contents = ""; 22821da177e4SLinus Torvalds } 228346b958ebSRandy Dunlap # look for doc_com + <text> + doc_end: 228446b958ebSRandy Dunlap if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { 2285d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: suspicious ending line: $_"; 228646b958ebSRandy Dunlap ++$warnings; 228746b958ebSRandy Dunlap } 22881da177e4SLinus Torvalds 22891da177e4SLinus Torvalds $prototype = ""; 229048af606aSJani Nikula $state = STATE_PROTO; 22911da177e4SLinus Torvalds $brcount = 0; 22925ef09c96SMauro Carvalho Chehab $new_start_line = $. + 1; 22931da177e4SLinus Torvalds } elsif (/$doc_content/) { 22946423133bSJohannes Weiner if ($1 eq "") { 22950d55d48bSMauro Carvalho Chehab if ($section eq $section_context) { 22960bba924cSJonathan Corbet dump_section($file, $section, $contents); 22971da177e4SLinus Torvalds $section = $section_default; 22981da177e4SLinus Torvalds $contents = ""; 22990b0f5f29SDaniel Vetter $new_start_line = $.; 23000d55d48bSMauro Carvalho Chehab $state = STATE_BODY; 23011da177e4SLinus Torvalds } else { 23020d55d48bSMauro Carvalho Chehab if ($section ne $section_default) { 23030d55d48bSMauro Carvalho Chehab $state = STATE_BODY_WITH_BLANK_LINE; 23040d55d48bSMauro Carvalho Chehab } else { 23050d55d48bSMauro Carvalho Chehab $state = STATE_BODY; 23060d55d48bSMauro Carvalho Chehab } 23076423133bSJohannes Weiner $contents .= "\n"; 23086423133bSJohannes Weiner } 230917b78717SJonathan Corbet } elsif ($state == STATE_BODY_MAYBE) { 23106423133bSJohannes Weiner # Continued declaration purpose 23116423133bSJohannes Weiner chomp($declaration_purpose); 23120bba924cSJonathan Corbet $declaration_purpose .= " " . $1; 231312ae6779SDaniel Santos $declaration_purpose =~ s/\s+/ /g; 23146423133bSJohannes Weiner } else { 2315b7886de4SJani Nikula my $cont = $1; 2316b7886de4SJani Nikula if ($section =~ m/^@/ || $section eq $section_context) { 2317b7886de4SJani Nikula if (!defined $leading_space) { 2318b7886de4SJani Nikula if ($cont =~ m/^(\s+)/) { 2319b7886de4SJani Nikula $leading_space = $1; 2320b7886de4SJani Nikula } else { 2321b7886de4SJani Nikula $leading_space = ""; 2322b7886de4SJani Nikula } 2323b7886de4SJani Nikula } 2324b7886de4SJani Nikula $cont =~ s/^$leading_space//; 2325b7886de4SJani Nikula } 2326b7886de4SJani Nikula $contents .= $cont . "\n"; 23271da177e4SLinus Torvalds } 23281da177e4SLinus Torvalds } else { 23291da177e4SLinus Torvalds # i dont know - bad line? ignore. 2330d40e1e65SBart Van Assche print STDERR "${file}:$.: warning: bad line: $_"; 23311da177e4SLinus Torvalds ++$warnings; 23321da177e4SLinus Torvalds } 2333d742f24dSJonathan Corbet} 2334d742f24dSJonathan Corbet 2335d742f24dSJonathan Corbet 2336cc794812SJonathan Corbet# 2337cc794812SJonathan Corbet# STATE_PROTO: reading a function/whatever prototype. 2338cc794812SJonathan Corbet# 2339cc794812SJonathan Corbetsub process_proto($$) { 2340cc794812SJonathan Corbet my $file = shift; 2341cc794812SJonathan Corbet 2342cc794812SJonathan Corbet if (/$doc_inline_oneline/) { 2343cc794812SJonathan Corbet $section = $1; 2344cc794812SJonathan Corbet $contents = $2; 2345cc794812SJonathan Corbet if ($contents ne "") { 2346cc794812SJonathan Corbet $contents .= "\n"; 2347cc794812SJonathan Corbet dump_section($file, $section, $contents); 2348cc794812SJonathan Corbet $section = $section_default; 2349cc794812SJonathan Corbet $contents = ""; 2350cc794812SJonathan Corbet } 2351cc794812SJonathan Corbet } elsif (/$doc_inline_start/) { 2352cc794812SJonathan Corbet $state = STATE_INLINE; 2353cc794812SJonathan Corbet $inline_doc_state = STATE_INLINE_NAME; 2354cc794812SJonathan Corbet } elsif ($decl_type eq 'function') { 2355cc794812SJonathan Corbet process_proto_function($_, $file); 2356cc794812SJonathan Corbet } else { 2357cc794812SJonathan Corbet process_proto_type($_, $file); 2358cc794812SJonathan Corbet } 2359cc794812SJonathan Corbet} 2360cc794812SJonathan Corbet 2361c17add56SJonathan Corbet# 2362c17add56SJonathan Corbet# STATE_DOCBLOCK: within a DOC: block. 2363c17add56SJonathan Corbet# 2364c17add56SJonathan Corbetsub process_docblock($$) { 2365c17add56SJonathan Corbet my $file = shift; 2366cc794812SJonathan Corbet 2367c17add56SJonathan Corbet if (/$doc_end/) { 2368c17add56SJonathan Corbet dump_doc_section($file, $section, $contents); 2369c17add56SJonathan Corbet $section = $section_default; 2370c17add56SJonathan Corbet $contents = ""; 2371c17add56SJonathan Corbet $function = ""; 2372c17add56SJonathan Corbet %parameterdescs = (); 2373c17add56SJonathan Corbet %parametertypes = (); 2374c17add56SJonathan Corbet @parameterlist = (); 2375c17add56SJonathan Corbet %sections = (); 2376c17add56SJonathan Corbet @sectionlist = (); 2377c17add56SJonathan Corbet $prototype = ""; 2378c17add56SJonathan Corbet $state = STATE_NORMAL; 2379c17add56SJonathan Corbet } elsif (/$doc_content/) { 2380c17add56SJonathan Corbet if ( $1 eq "" ) { 2381c17add56SJonathan Corbet $contents .= $blankline; 2382c17add56SJonathan Corbet } else { 2383c17add56SJonathan Corbet $contents .= $1 . "\n"; 2384c17add56SJonathan Corbet } 2385c17add56SJonathan Corbet } 2386d742f24dSJonathan Corbet} 2387d742f24dSJonathan Corbet 2388c17add56SJonathan Corbet# 2389c17add56SJonathan Corbet# STATE_INLINE: docbook comments within a prototype. 2390c17add56SJonathan Corbet# 2391c17add56SJonathan Corbetsub process_inline($$) { 2392c17add56SJonathan Corbet my $file = shift; 2393d742f24dSJonathan Corbet 2394a4c6ebedSDanilo Cesar Lemes de Paula # First line (state 1) needs to be a @parameter 239548af606aSJani Nikula if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { 2396a4c6ebedSDanilo Cesar Lemes de Paula $section = $1; 2397a4c6ebedSDanilo Cesar Lemes de Paula $contents = $2; 23980b0f5f29SDaniel Vetter $new_start_line = $.; 2399a4c6ebedSDanilo Cesar Lemes de Paula if ($contents ne "") { 24007c9aa015SMauro Carvalho Chehab while (substr($contents, 0, 1) eq " ") { 2401a4c6ebedSDanilo Cesar Lemes de Paula $contents = substr($contents, 1); 2402a4c6ebedSDanilo Cesar Lemes de Paula } 2403a4c6ebedSDanilo Cesar Lemes de Paula $contents .= "\n"; 2404a4c6ebedSDanilo Cesar Lemes de Paula } 240548af606aSJani Nikula $inline_doc_state = STATE_INLINE_TEXT; 2406a4c6ebedSDanilo Cesar Lemes de Paula # Documentation block end */ 240748af606aSJani Nikula } elsif (/$doc_inline_end/) { 2408a4c6ebedSDanilo Cesar Lemes de Paula if (($contents ne "") && ($contents ne "\n")) { 24090bba924cSJonathan Corbet dump_section($file, $section, $contents); 2410a4c6ebedSDanilo Cesar Lemes de Paula $section = $section_default; 2411a4c6ebedSDanilo Cesar Lemes de Paula $contents = ""; 2412a4c6ebedSDanilo Cesar Lemes de Paula } 241348af606aSJani Nikula $state = STATE_PROTO; 241448af606aSJani Nikula $inline_doc_state = STATE_INLINE_NA; 2415a4c6ebedSDanilo Cesar Lemes de Paula # Regular text 2416a4c6ebedSDanilo Cesar Lemes de Paula } elsif (/$doc_content/) { 241748af606aSJani Nikula if ($inline_doc_state == STATE_INLINE_TEXT) { 2418a4c6ebedSDanilo Cesar Lemes de Paula $contents .= $1 . "\n"; 24196450c895SJani Nikula # nuke leading blank lines 24206450c895SJani Nikula if ($contents =~ /^\s*$/) { 24216450c895SJani Nikula $contents = ""; 24226450c895SJani Nikula } 242348af606aSJani Nikula } elsif ($inline_doc_state == STATE_INLINE_NAME) { 242448af606aSJani Nikula $inline_doc_state = STATE_INLINE_ERROR; 2425e7ca311eSDaniel Vetter print STDERR "${file}:$.: warning: "; 2426a4c6ebedSDanilo Cesar Lemes de Paula print STDERR "Incorrect use of kernel-doc format: $_"; 2427a4c6ebedSDanilo Cesar Lemes de Paula ++$warnings; 2428a4c6ebedSDanilo Cesar Lemes de Paula } 2429a4c6ebedSDanilo Cesar Lemes de Paula } 24300c9aa209SJani Nikula} 2431c17add56SJonathan Corbet 2432c17add56SJonathan Corbet 2433c17add56SJonathan Corbetsub process_file($) { 2434c17add56SJonathan Corbet my $file; 2435c17add56SJonathan Corbet my $initial_section_counter = $section_counter; 2436c17add56SJonathan Corbet my ($orig_file) = @_; 2437c17add56SJonathan Corbet 2438c17add56SJonathan Corbet $file = map_filename($orig_file); 2439c17add56SJonathan Corbet 2440dbe8ba00SMauro Carvalho Chehab if (!open(IN_FILE,"<$file")) { 2441c17add56SJonathan Corbet print STDERR "Error: Cannot open file $file\n"; 2442c17add56SJonathan Corbet ++$errors; 2443c17add56SJonathan Corbet return; 24441da177e4SLinus Torvalds } 2445c17add56SJonathan Corbet 2446c17add56SJonathan Corbet $. = 1; 2447c17add56SJonathan Corbet 2448c17add56SJonathan Corbet $section_counter = 0; 2449dbe8ba00SMauro Carvalho Chehab while (<IN_FILE>) { 2450c17add56SJonathan Corbet while (s/\\\s*$//) { 2451dbe8ba00SMauro Carvalho Chehab $_ .= <IN_FILE>; 2452c17add56SJonathan Corbet } 2453c17add56SJonathan Corbet # Replace tabs by spaces 2454c17add56SJonathan Corbet while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; 2455c17add56SJonathan Corbet # Hand this line to the appropriate state handler 2456c17add56SJonathan Corbet if ($state == STATE_NORMAL) { 2457c17add56SJonathan Corbet process_normal(); 2458c17add56SJonathan Corbet } elsif ($state == STATE_NAME) { 2459c17add56SJonathan Corbet process_name($file, $_); 24600d55d48bSMauro Carvalho Chehab } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE || 24610d55d48bSMauro Carvalho Chehab $state == STATE_BODY_WITH_BLANK_LINE) { 2462c17add56SJonathan Corbet process_body($file, $_); 2463c17add56SJonathan Corbet } elsif ($state == STATE_INLINE) { # scanning for inline parameters 2464c17add56SJonathan Corbet process_inline($file, $_); 2465cc794812SJonathan Corbet } elsif ($state == STATE_PROTO) { 2466cc794812SJonathan Corbet process_proto($file, $_); 246748af606aSJani Nikula } elsif ($state == STATE_DOCBLOCK) { 2468c17add56SJonathan Corbet process_docblock($file, $_); 24691da177e4SLinus Torvalds } 24701da177e4SLinus Torvalds } 2471c17add56SJonathan Corbet 2472c17add56SJonathan Corbet # Make sure we got something interesting. 2473b0d60bfbSJonathan Corbet if ($initial_section_counter == $section_counter && $ 2474b0d60bfbSJonathan Corbet output_mode ne "none") { 2475b0d60bfbSJonathan Corbet if ($output_selection == OUTPUT_INCLUDE) { 2476b0d60bfbSJonathan Corbet print STDERR "${file}:1: warning: '$_' not found\n" 2477b0d60bfbSJonathan Corbet for keys %function_table; 24783a025e1dSMatthew Wilcox } 2479b0d60bfbSJonathan Corbet else { 2480b0d60bfbSJonathan Corbet print STDERR "${file}:1: warning: no structured comments found\n"; 2481e946c43aSJohannes Berg } 24821da177e4SLinus Torvalds } 2483dbe8ba00SMauro Carvalho Chehab close IN_FILE; 24841da177e4SLinus Torvalds} 24858484baaaSRandy Dunlap 24868484baaaSRandy Dunlap 248793351d41SMauro Carvalho Chehabif ($output_mode eq "rst") { 248893351d41SMauro Carvalho Chehab get_sphinx_version() if (!$sphinx_major); 248993351d41SMauro Carvalho Chehab} 249093351d41SMauro Carvalho Chehab 24918484baaaSRandy Dunlap$kernelversion = get_kernel_version(); 24928484baaaSRandy Dunlap 24938484baaaSRandy Dunlap# generate a sequence of code that will splice in highlighting information 24948484baaaSRandy Dunlap# using the s// operator. 24951ef06233SMauro Carvalho Chehabfor (my $k = 0; $k < @highlights; $k++) { 24964d732701SDanilo Cesar Lemes de Paula my $pattern = $highlights[$k][0]; 24974d732701SDanilo Cesar Lemes de Paula my $result = $highlights[$k][1]; 24984d732701SDanilo Cesar Lemes de Paula# print STDERR "scanning pattern:$pattern, highlight:($result)\n"; 24994d732701SDanilo Cesar Lemes de Paula $dohighlight .= "\$contents =~ s:$pattern:$result:gs;\n"; 25008484baaaSRandy Dunlap} 25018484baaaSRandy Dunlap 25028484baaaSRandy Dunlap# Read the file that maps relative names to absolute names for 25038484baaaSRandy Dunlap# separate source and object directories and for shadow trees. 25048484baaaSRandy Dunlapif (open(SOURCE_MAP, "<.tmp_filelist.txt")) { 25058484baaaSRandy Dunlap my ($relname, $absname); 25068484baaaSRandy Dunlap while(<SOURCE_MAP>) { 25078484baaaSRandy Dunlap chop(); 25088484baaaSRandy Dunlap ($relname, $absname) = (split())[0..1]; 25098484baaaSRandy Dunlap $relname =~ s:^/+::; 25108484baaaSRandy Dunlap $source_map{$relname} = $absname; 25118484baaaSRandy Dunlap } 25128484baaaSRandy Dunlap close(SOURCE_MAP); 25138484baaaSRandy Dunlap} 25148484baaaSRandy Dunlap 251588c2b57dSJani Nikulaif ($output_selection == OUTPUT_EXPORTED || 251688c2b57dSJani Nikula $output_selection == OUTPUT_INTERNAL) { 2517c9b2cfb3SJani Nikula 2518c9b2cfb3SJani Nikula push(@export_file_list, @ARGV); 2519c9b2cfb3SJani Nikula 252088c2b57dSJani Nikula foreach (@export_file_list) { 252188c2b57dSJani Nikula chomp; 252288c2b57dSJani Nikula process_export_file($_); 252388c2b57dSJani Nikula } 252488c2b57dSJani Nikula} 252588c2b57dSJani Nikula 25268484baaaSRandy Dunlapforeach (@ARGV) { 25278484baaaSRandy Dunlap chomp; 25288484baaaSRandy Dunlap process_file($_); 25298484baaaSRandy Dunlap} 25308484baaaSRandy Dunlapif ($verbose && $errors) { 25318484baaaSRandy Dunlap print STDERR "$errors errors\n"; 25328484baaaSRandy Dunlap} 25338484baaaSRandy Dunlapif ($verbose && $warnings) { 25348484baaaSRandy Dunlap print STDERR "$warnings warnings\n"; 25358484baaaSRandy Dunlap} 25368484baaaSRandy Dunlap 25372c12c810SPierre-Louis Bossartif ($Werror && $warnings) { 25382c12c810SPierre-Louis Bossart print STDERR "$warnings warnings as Errors\n"; 25392c12c810SPierre-Louis Bossart exit($warnings); 25402c12c810SPierre-Louis Bossart} else { 25412c12c810SPierre-Louis Bossart exit($output_mode eq "none" ? 0 : $errors) 25422c12c810SPierre-Louis Bossart} 25432875f787STomasz Warniełło 25442875f787STomasz Warniełło__END__ 25452875f787STomasz Warniełło 25462875f787STomasz Warniełło=head1 OPTIONS 25472875f787STomasz Warniełło 25482875f787STomasz Warniełło=head2 Output format selection (mutually exclusive): 25492875f787STomasz Warniełło 25502875f787STomasz Warniełło=over 8 25512875f787STomasz Warniełło 25522875f787STomasz Warniełło=item -man 25532875f787STomasz Warniełło 25542875f787STomasz WarniełłoOutput troff manual page format. 25552875f787STomasz Warniełło 25562875f787STomasz Warniełło=item -rst 25572875f787STomasz Warniełło 25582875f787STomasz WarniełłoOutput reStructuredText format. This is the default. 25592875f787STomasz Warniełło 25602875f787STomasz Warniełło=item -none 25612875f787STomasz Warniełło 25622875f787STomasz WarniełłoDo not output documentation, only warnings. 25632875f787STomasz Warniełło 25642875f787STomasz Warniełło=back 25652875f787STomasz Warniełło 2566dd803b04STomasz Warniełło=head2 Output format modifiers 2567dd803b04STomasz Warniełło 2568dd803b04STomasz Warniełło=head3 reStructuredText only 2569dd803b04STomasz Warniełło 2570dd803b04STomasz Warniełło=over 8 2571dd803b04STomasz Warniełło 2572dd803b04STomasz Warniełło=item -sphinx-version VERSION 2573dd803b04STomasz Warniełło 2574dd803b04STomasz WarniełłoUse the ReST C domain dialect compatible with a specific Sphinx Version. 2575dd803b04STomasz Warniełło 2576dd803b04STomasz WarniełłoIf not specified, kernel-doc will auto-detect using the sphinx-build version 2577dd803b04STomasz Warniełłofound on PATH. 2578dd803b04STomasz Warniełło 2579dd803b04STomasz Warniełło=back 2580dd803b04STomasz Warniełło 2581*9c77f108STomasz Warniełło=head2 Output selection (mutually exclusive): 2582*9c77f108STomasz Warniełło 2583*9c77f108STomasz Warniełło=over 8 2584*9c77f108STomasz Warniełło 2585*9c77f108STomasz Warniełło=item -export 2586*9c77f108STomasz Warniełło 2587*9c77f108STomasz WarniełłoOnly output documentation for the symbols that have been exported using 2588*9c77f108STomasz WarniełłoEXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() in any input FILE or -export-file FILE. 2589*9c77f108STomasz Warniełło 2590*9c77f108STomasz Warniełło=item -internal 2591*9c77f108STomasz Warniełło 2592*9c77f108STomasz WarniełłoOnly output documentation for the symbols that have NOT been exported using 2593*9c77f108STomasz WarniełłoEXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() in any input FILE or -export-file FILE. 2594*9c77f108STomasz Warniełło 2595*9c77f108STomasz Warniełło=item -function NAME 2596*9c77f108STomasz Warniełło 2597*9c77f108STomasz WarniełłoOnly output documentation for the given function or DOC: section title. 2598*9c77f108STomasz WarniełłoAll other functions and DOC: sections are ignored. 2599*9c77f108STomasz Warniełło 2600*9c77f108STomasz WarniełłoMay be specified multiple times. 2601*9c77f108STomasz Warniełło 2602*9c77f108STomasz Warniełło=item -nosymbol NAME 2603*9c77f108STomasz Warniełło 2604*9c77f108STomasz WarniełłoExclude the specified symbol from the output documentation. 2605*9c77f108STomasz Warniełło 2606*9c77f108STomasz WarniełłoMay be specified multiple times. 2607*9c77f108STomasz Warniełło 2608*9c77f108STomasz Warniełło=back 2609*9c77f108STomasz Warniełło 26102875f787STomasz Warniełło=cut 2611