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