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