kernel-doc 66 KB

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