11d6fea64SMauro Carvalho Chehab#!/usr/bin/env python3 21d6fea64SMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0 31d6fea64SMauro Carvalho Chehab# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>. 41d6fea64SMauro Carvalho Chehab# 5485f6f79SMauro Carvalho Chehab# pylint: disable=C0301,R0902,R0911,R0912,R0913,R0914,R0915,R0917 61d6fea64SMauro Carvalho Chehab 71d6fea64SMauro Carvalho Chehab""" 81d6fea64SMauro Carvalho ChehabImplement output filters to print kernel-doc documentation. 91d6fea64SMauro Carvalho Chehab 101d6fea64SMauro Carvalho ChehabThe implementation uses a virtual base class (OutputFormat) which 111d6fea64SMauro Carvalho Chehabcontains a dispatches to virtual methods, and some code to filter 121d6fea64SMauro Carvalho Chehabout output messages. 131d6fea64SMauro Carvalho Chehab 141d6fea64SMauro Carvalho ChehabThe actual implementation is done on one separate class per each type 151d6fea64SMauro Carvalho Chehabof output. Currently, there are output classes for ReST and man/troff. 161d6fea64SMauro Carvalho Chehab""" 171d6fea64SMauro Carvalho Chehab 181d6fea64SMauro Carvalho Chehabimport os 191d6fea64SMauro Carvalho Chehabimport re 201d6fea64SMauro Carvalho Chehabfrom datetime import datetime 211d6fea64SMauro Carvalho Chehab 221d6fea64SMauro Carvalho Chehabfrom kdoc_parser import KernelDoc, type_param 23*04a383ceSMauro Carvalho Chehabfrom kdoc_re import KernRe 241d6fea64SMauro Carvalho Chehab 251d6fea64SMauro Carvalho Chehab 26*04a383ceSMauro Carvalho Chehabfunction_pointer = KernRe(r"([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)", cache=False) 271d6fea64SMauro Carvalho Chehab 281d6fea64SMauro Carvalho Chehab# match expressions used to find embedded type information 29*04a383ceSMauro Carvalho Chehabtype_constant = KernRe(r"\b``([^\`]+)``\b", cache=False) 30*04a383ceSMauro Carvalho Chehabtype_constant2 = KernRe(r"\%([-_*\w]+)", cache=False) 31*04a383ceSMauro Carvalho Chehabtype_func = KernRe(r"(\w+)\(\)", cache=False) 32*04a383ceSMauro Carvalho Chehabtype_param_ref = KernRe(r"([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False) 331d6fea64SMauro Carvalho Chehab 341d6fea64SMauro Carvalho Chehab# Special RST handling for func ptr params 35*04a383ceSMauro Carvalho Chehabtype_fp_param = KernRe(r"\@(\w+)\(\)", cache=False) 361d6fea64SMauro Carvalho Chehab 371d6fea64SMauro Carvalho Chehab# Special RST handling for structs with func ptr params 38*04a383ceSMauro Carvalho Chehabtype_fp_param2 = KernRe(r"\@(\w+->\S+)\(\)", cache=False) 391d6fea64SMauro Carvalho Chehab 40*04a383ceSMauro Carvalho Chehabtype_env = KernRe(r"(\$\w+)", cache=False) 41*04a383ceSMauro Carvalho Chehabtype_enum = KernRe(r"\&(enum\s*([_\w]+))", cache=False) 42*04a383ceSMauro Carvalho Chehabtype_struct = KernRe(r"\&(struct\s*([_\w]+))", cache=False) 43*04a383ceSMauro Carvalho Chehabtype_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False) 44*04a383ceSMauro Carvalho Chehabtype_union = KernRe(r"\&(union\s*([_\w]+))", cache=False) 45*04a383ceSMauro Carvalho Chehabtype_member = KernRe(r"\&([_\w]+)(\.|->)([_\w]+)", cache=False) 46*04a383ceSMauro Carvalho Chehabtype_fallback = KernRe(r"\&([_\w]+)", cache=False) 47*04a383ceSMauro Carvalho Chehabtype_member_func = type_member + KernRe(r"\(\)", cache=False) 481d6fea64SMauro Carvalho Chehab 491d6fea64SMauro Carvalho Chehab 501d6fea64SMauro Carvalho Chehabclass OutputFormat: 51485f6f79SMauro Carvalho Chehab """ 52485f6f79SMauro Carvalho Chehab Base class for OutputFormat. If used as-is, it means that only 53485f6f79SMauro Carvalho Chehab warnings will be displayed. 54485f6f79SMauro Carvalho Chehab """ 55485f6f79SMauro Carvalho Chehab 561d6fea64SMauro Carvalho Chehab # output mode. 571d6fea64SMauro Carvalho Chehab OUTPUT_ALL = 0 # output all symbols and doc sections 581d6fea64SMauro Carvalho Chehab OUTPUT_INCLUDE = 1 # output only specified symbols 591d6fea64SMauro Carvalho Chehab OUTPUT_EXPORTED = 2 # output exported symbols 601d6fea64SMauro Carvalho Chehab OUTPUT_INTERNAL = 3 # output non-exported symbols 611d6fea64SMauro Carvalho Chehab 621d6fea64SMauro Carvalho Chehab # Virtual member to be overriden at the inherited classes 631d6fea64SMauro Carvalho Chehab highlights = [] 641d6fea64SMauro Carvalho Chehab 651d6fea64SMauro Carvalho Chehab def __init__(self): 661d6fea64SMauro Carvalho Chehab """Declare internal vars and set mode to OUTPUT_ALL""" 671d6fea64SMauro Carvalho Chehab 681d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_ALL 691d6fea64SMauro Carvalho Chehab self.enable_lineno = None 701d6fea64SMauro Carvalho Chehab self.nosymbol = {} 711d6fea64SMauro Carvalho Chehab self.symbol = None 7216740c29SMauro Carvalho Chehab self.function_table = None 731d6fea64SMauro Carvalho Chehab self.config = None 740873e554SMauro Carvalho Chehab self.no_doc_sections = False 751d6fea64SMauro Carvalho Chehab 764fa5e411SMauro Carvalho Chehab self.data = "" 774fa5e411SMauro Carvalho Chehab 781d6fea64SMauro Carvalho Chehab def set_config(self, config): 79485f6f79SMauro Carvalho Chehab """ 80485f6f79SMauro Carvalho Chehab Setup global config variables used by both parser and output. 81485f6f79SMauro Carvalho Chehab """ 82485f6f79SMauro Carvalho Chehab 831d6fea64SMauro Carvalho Chehab self.config = config 841d6fea64SMauro Carvalho Chehab 851d6fea64SMauro Carvalho Chehab def set_filter(self, export, internal, symbol, nosymbol, function_table, 860873e554SMauro Carvalho Chehab enable_lineno, no_doc_sections): 871d6fea64SMauro Carvalho Chehab """ 881d6fea64SMauro Carvalho Chehab Initialize filter variables according with the requested mode. 891d6fea64SMauro Carvalho Chehab 901d6fea64SMauro Carvalho Chehab Only one choice is valid between export, internal and symbol. 911d6fea64SMauro Carvalho Chehab 921d6fea64SMauro Carvalho Chehab The nosymbol filter can be used on all modes. 931d6fea64SMauro Carvalho Chehab """ 941d6fea64SMauro Carvalho Chehab 951d6fea64SMauro Carvalho Chehab self.enable_lineno = enable_lineno 960873e554SMauro Carvalho Chehab self.no_doc_sections = no_doc_sections 9716740c29SMauro Carvalho Chehab self.function_table = function_table 981d6fea64SMauro Carvalho Chehab 991d6fea64SMauro Carvalho Chehab if symbol: 1001d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_INCLUDE 1011d6fea64SMauro Carvalho Chehab elif export: 1021d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_EXPORTED 1031d6fea64SMauro Carvalho Chehab elif internal: 1041d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_INTERNAL 1051d6fea64SMauro Carvalho Chehab else: 1061d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_ALL 1071d6fea64SMauro Carvalho Chehab 1081d6fea64SMauro Carvalho Chehab if nosymbol: 1091d6fea64SMauro Carvalho Chehab self.nosymbol = set(nosymbol) 1101d6fea64SMauro Carvalho Chehab 1111d6fea64SMauro Carvalho Chehab 1121d6fea64SMauro Carvalho Chehab def highlight_block(self, block): 1131d6fea64SMauro Carvalho Chehab """ 1141d6fea64SMauro Carvalho Chehab Apply the RST highlights to a sub-block of text. 1151d6fea64SMauro Carvalho Chehab """ 1161d6fea64SMauro Carvalho Chehab 1171d6fea64SMauro Carvalho Chehab for r, sub in self.highlights: 1181d6fea64SMauro Carvalho Chehab block = r.sub(sub, block) 1191d6fea64SMauro Carvalho Chehab 1201d6fea64SMauro Carvalho Chehab return block 1211d6fea64SMauro Carvalho Chehab 1229cbc2d3bSMauro Carvalho Chehab def out_warnings(self, args): 123485f6f79SMauro Carvalho Chehab """ 124485f6f79SMauro Carvalho Chehab Output warnings for identifiers that will be displayed. 125485f6f79SMauro Carvalho Chehab """ 126485f6f79SMauro Carvalho Chehab 1279cbc2d3bSMauro Carvalho Chehab warnings = args.get('warnings', []) 1289cbc2d3bSMauro Carvalho Chehab 12911afeab6SMauro Carvalho Chehab for log_msg in warnings: 13016740c29SMauro Carvalho Chehab self.config.warning(log_msg) 1319cbc2d3bSMauro Carvalho Chehab 1329cbc2d3bSMauro Carvalho Chehab def check_doc(self, name, args): 1331d6fea64SMauro Carvalho Chehab """Check if DOC should be output""" 1341d6fea64SMauro Carvalho Chehab 1350873e554SMauro Carvalho Chehab if self.no_doc_sections: 1360873e554SMauro Carvalho Chehab return False 1370873e554SMauro Carvalho Chehab 138408269aeSMauro Carvalho Chehab if name in self.nosymbol: 139408269aeSMauro Carvalho Chehab return False 140408269aeSMauro Carvalho Chehab 1411d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_ALL: 1429cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1431d6fea64SMauro Carvalho Chehab return True 1441d6fea64SMauro Carvalho Chehab 1451d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_INCLUDE: 1461d6fea64SMauro Carvalho Chehab if name in self.function_table: 1479cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1481d6fea64SMauro Carvalho Chehab return True 1491d6fea64SMauro Carvalho Chehab 1501d6fea64SMauro Carvalho Chehab return False 1511d6fea64SMauro Carvalho Chehab 1529cbc2d3bSMauro Carvalho Chehab def check_declaration(self, dtype, name, args): 153485f6f79SMauro Carvalho Chehab """ 154485f6f79SMauro Carvalho Chehab Checks if a declaration should be output or not based on the 155485f6f79SMauro Carvalho Chehab filtering criteria. 156485f6f79SMauro Carvalho Chehab """ 157485f6f79SMauro Carvalho Chehab 1581d6fea64SMauro Carvalho Chehab if name in self.nosymbol: 1591d6fea64SMauro Carvalho Chehab return False 1601d6fea64SMauro Carvalho Chehab 1611d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_ALL: 1629cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1631d6fea64SMauro Carvalho Chehab return True 1641d6fea64SMauro Carvalho Chehab 1651d6fea64SMauro Carvalho Chehab if self.out_mode in [self.OUTPUT_INCLUDE, self.OUTPUT_EXPORTED]: 1661d6fea64SMauro Carvalho Chehab if name in self.function_table: 1671d6fea64SMauro Carvalho Chehab return True 1681d6fea64SMauro Carvalho Chehab 1691d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_INTERNAL: 1701d6fea64SMauro Carvalho Chehab if dtype != "function": 1719cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1721d6fea64SMauro Carvalho Chehab return True 1731d6fea64SMauro Carvalho Chehab 1741d6fea64SMauro Carvalho Chehab if name not in self.function_table: 1759cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1761d6fea64SMauro Carvalho Chehab return True 1771d6fea64SMauro Carvalho Chehab 1781d6fea64SMauro Carvalho Chehab return False 1791d6fea64SMauro Carvalho Chehab 1801d6fea64SMauro Carvalho Chehab def msg(self, fname, name, args): 181485f6f79SMauro Carvalho Chehab """ 182485f6f79SMauro Carvalho Chehab Handles a single entry from kernel-doc parser 183485f6f79SMauro Carvalho Chehab """ 184485f6f79SMauro Carvalho Chehab 1854fa5e411SMauro Carvalho Chehab self.data = "" 1861d6fea64SMauro Carvalho Chehab 1871d6fea64SMauro Carvalho Chehab dtype = args.get('type', "") 1881d6fea64SMauro Carvalho Chehab 1891d6fea64SMauro Carvalho Chehab if dtype == "doc": 1901d6fea64SMauro Carvalho Chehab self.out_doc(fname, name, args) 1914fa5e411SMauro Carvalho Chehab return self.data 1921d6fea64SMauro Carvalho Chehab 1939cbc2d3bSMauro Carvalho Chehab if not self.check_declaration(dtype, name, args): 1944fa5e411SMauro Carvalho Chehab return self.data 1951d6fea64SMauro Carvalho Chehab 1961d6fea64SMauro Carvalho Chehab if dtype == "function": 1971d6fea64SMauro Carvalho Chehab self.out_function(fname, name, args) 1984fa5e411SMauro Carvalho Chehab return self.data 1991d6fea64SMauro Carvalho Chehab 2001d6fea64SMauro Carvalho Chehab if dtype == "enum": 2011d6fea64SMauro Carvalho Chehab self.out_enum(fname, name, args) 2024fa5e411SMauro Carvalho Chehab return self.data 2031d6fea64SMauro Carvalho Chehab 2041d6fea64SMauro Carvalho Chehab if dtype == "typedef": 2051d6fea64SMauro Carvalho Chehab self.out_typedef(fname, name, args) 2064fa5e411SMauro Carvalho Chehab return self.data 2071d6fea64SMauro Carvalho Chehab 2081d6fea64SMauro Carvalho Chehab if dtype in ["struct", "union"]: 2091d6fea64SMauro Carvalho Chehab self.out_struct(fname, name, args) 2104fa5e411SMauro Carvalho Chehab return self.data 2111d6fea64SMauro Carvalho Chehab 2121d6fea64SMauro Carvalho Chehab # Warn if some type requires an output logic 2131d6fea64SMauro Carvalho Chehab self.config.log.warning("doesn't now how to output '%s' block", 2141d6fea64SMauro Carvalho Chehab dtype) 2151d6fea64SMauro Carvalho Chehab 2164fa5e411SMauro Carvalho Chehab return None 2171d6fea64SMauro Carvalho Chehab 2181d6fea64SMauro Carvalho Chehab # Virtual methods to be overridden by inherited classes 219485f6f79SMauro Carvalho Chehab # At the base class, those do nothing. 2201d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 221485f6f79SMauro Carvalho Chehab """Outputs a DOC block""" 2221d6fea64SMauro Carvalho Chehab 2231d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 224485f6f79SMauro Carvalho Chehab """Outputs a function""" 2251d6fea64SMauro Carvalho Chehab 2261d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 227485f6f79SMauro Carvalho Chehab """Outputs an enum""" 2281d6fea64SMauro Carvalho Chehab 2291d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 230485f6f79SMauro Carvalho Chehab """Outputs a typedef""" 2311d6fea64SMauro Carvalho Chehab 2321d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 233485f6f79SMauro Carvalho Chehab """Outputs a struct""" 2341d6fea64SMauro Carvalho Chehab 2351d6fea64SMauro Carvalho Chehab 2361d6fea64SMauro Carvalho Chehabclass RestFormat(OutputFormat): 237485f6f79SMauro Carvalho Chehab """Consts and functions used by ReST output""" 2381d6fea64SMauro Carvalho Chehab 2391d6fea64SMauro Carvalho Chehab highlights = [ 2401d6fea64SMauro Carvalho Chehab (type_constant, r"``\1``"), 2411d6fea64SMauro Carvalho Chehab (type_constant2, r"``\1``"), 2421d6fea64SMauro Carvalho Chehab 2431d6fea64SMauro Carvalho Chehab # Note: need to escape () to avoid func matching later 2441d6fea64SMauro Carvalho Chehab (type_member_func, r":c:type:`\1\2\3\\(\\) <\1>`"), 2451d6fea64SMauro Carvalho Chehab (type_member, r":c:type:`\1\2\3 <\1>`"), 2461d6fea64SMauro Carvalho Chehab (type_fp_param, r"**\1\\(\\)**"), 2471d6fea64SMauro Carvalho Chehab (type_fp_param2, r"**\1\\(\\)**"), 2481d6fea64SMauro Carvalho Chehab (type_func, r"\1()"), 2491d6fea64SMauro Carvalho Chehab (type_enum, r":c:type:`\1 <\2>`"), 2501d6fea64SMauro Carvalho Chehab (type_struct, r":c:type:`\1 <\2>`"), 2511d6fea64SMauro Carvalho Chehab (type_typedef, r":c:type:`\1 <\2>`"), 2521d6fea64SMauro Carvalho Chehab (type_union, r":c:type:`\1 <\2>`"), 2531d6fea64SMauro Carvalho Chehab 2541d6fea64SMauro Carvalho Chehab # in rst this can refer to any type 2551d6fea64SMauro Carvalho Chehab (type_fallback, r":c:type:`\1`"), 2561d6fea64SMauro Carvalho Chehab (type_param_ref, r"**\1\2**") 2571d6fea64SMauro Carvalho Chehab ] 2581d6fea64SMauro Carvalho Chehab blankline = "\n" 2591d6fea64SMauro Carvalho Chehab 260*04a383ceSMauro Carvalho Chehab sphinx_literal = KernRe(r'^[^.].*::$', cache=False) 261*04a383ceSMauro Carvalho Chehab sphinx_cblock = KernRe(r'^\.\.\ +code-block::', cache=False) 2621d6fea64SMauro Carvalho Chehab 2631d6fea64SMauro Carvalho Chehab def __init__(self): 2641d6fea64SMauro Carvalho Chehab """ 2651d6fea64SMauro Carvalho Chehab Creates class variables. 2661d6fea64SMauro Carvalho Chehab 2671d6fea64SMauro Carvalho Chehab Not really mandatory, but it is a good coding style and makes 2681d6fea64SMauro Carvalho Chehab pylint happy. 2691d6fea64SMauro Carvalho Chehab """ 2701d6fea64SMauro Carvalho Chehab 2711d6fea64SMauro Carvalho Chehab super().__init__() 2721d6fea64SMauro Carvalho Chehab self.lineprefix = "" 2731d6fea64SMauro Carvalho Chehab 2741d6fea64SMauro Carvalho Chehab def print_lineno(self, ln): 2751d6fea64SMauro Carvalho Chehab """Outputs a line number""" 2761d6fea64SMauro Carvalho Chehab 277c3597ab2SMauro Carvalho Chehab if self.enable_lineno and ln is not None: 278c3597ab2SMauro Carvalho Chehab ln += 1 2794fa5e411SMauro Carvalho Chehab self.data += f".. LINENO {ln}\n" 2801d6fea64SMauro Carvalho Chehab 2811d6fea64SMauro Carvalho Chehab def output_highlight(self, args): 282485f6f79SMauro Carvalho Chehab """ 283485f6f79SMauro Carvalho Chehab Outputs a C symbol that may require being converted to ReST using 284485f6f79SMauro Carvalho Chehab the self.highlights variable 285485f6f79SMauro Carvalho Chehab """ 286485f6f79SMauro Carvalho Chehab 2871d6fea64SMauro Carvalho Chehab input_text = args 2881d6fea64SMauro Carvalho Chehab output = "" 2891d6fea64SMauro Carvalho Chehab in_literal = False 2901d6fea64SMauro Carvalho Chehab litprefix = "" 2911d6fea64SMauro Carvalho Chehab block = "" 2921d6fea64SMauro Carvalho Chehab 2931d6fea64SMauro Carvalho Chehab for line in input_text.strip("\n").split("\n"): 2941d6fea64SMauro Carvalho Chehab 2951d6fea64SMauro Carvalho Chehab # If we're in a literal block, see if we should drop out of it. 2961d6fea64SMauro Carvalho Chehab # Otherwise, pass the line straight through unmunged. 2971d6fea64SMauro Carvalho Chehab if in_literal: 2981d6fea64SMauro Carvalho Chehab if line.strip(): # If the line is not blank 2991d6fea64SMauro Carvalho Chehab # If this is the first non-blank line in a literal block, 3001d6fea64SMauro Carvalho Chehab # figure out the proper indent. 3011d6fea64SMauro Carvalho Chehab if not litprefix: 302*04a383ceSMauro Carvalho Chehab r = KernRe(r'^(\s*)') 3031d6fea64SMauro Carvalho Chehab if r.match(line): 3041d6fea64SMauro Carvalho Chehab litprefix = '^' + r.group(1) 3051d6fea64SMauro Carvalho Chehab else: 3061d6fea64SMauro Carvalho Chehab litprefix = "" 3071d6fea64SMauro Carvalho Chehab 3081d6fea64SMauro Carvalho Chehab output += line + "\n" 309*04a383ceSMauro Carvalho Chehab elif not KernRe(litprefix).match(line): 3101d6fea64SMauro Carvalho Chehab in_literal = False 3111d6fea64SMauro Carvalho Chehab else: 3121d6fea64SMauro Carvalho Chehab output += line + "\n" 3131d6fea64SMauro Carvalho Chehab else: 3141d6fea64SMauro Carvalho Chehab output += line + "\n" 3151d6fea64SMauro Carvalho Chehab 3161d6fea64SMauro Carvalho Chehab # Not in a literal block (or just dropped out) 3171d6fea64SMauro Carvalho Chehab if not in_literal: 3181d6fea64SMauro Carvalho Chehab block += line + "\n" 3191d6fea64SMauro Carvalho Chehab if self.sphinx_literal.match(line) or self.sphinx_cblock.match(line): 3201d6fea64SMauro Carvalho Chehab in_literal = True 3211d6fea64SMauro Carvalho Chehab litprefix = "" 3221d6fea64SMauro Carvalho Chehab output += self.highlight_block(block) 3231d6fea64SMauro Carvalho Chehab block = "" 3241d6fea64SMauro Carvalho Chehab 3251d6fea64SMauro Carvalho Chehab # Handle any remaining block 3261d6fea64SMauro Carvalho Chehab if block: 3271d6fea64SMauro Carvalho Chehab output += self.highlight_block(block) 3281d6fea64SMauro Carvalho Chehab 3291d6fea64SMauro Carvalho Chehab # Print the output with the line prefix 3301d6fea64SMauro Carvalho Chehab for line in output.strip("\n").split("\n"): 3314fa5e411SMauro Carvalho Chehab self.data += self.lineprefix + line + "\n" 3321d6fea64SMauro Carvalho Chehab 333408269aeSMauro Carvalho Chehab def out_section(self, args, out_docblock=False): 3341d6fea64SMauro Carvalho Chehab """ 3351d6fea64SMauro Carvalho Chehab Outputs a block section. 3361d6fea64SMauro Carvalho Chehab 3371d6fea64SMauro Carvalho Chehab This could use some work; it's used to output the DOC: sections, and 3381d6fea64SMauro Carvalho Chehab starts by putting out the name of the doc section itself, but that 3391d6fea64SMauro Carvalho Chehab tends to duplicate a header already in the template file. 3401d6fea64SMauro Carvalho Chehab """ 3411d6fea64SMauro Carvalho Chehab 3421d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 3431d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 3441d6fea64SMauro Carvalho Chehab section_start_lines = args.get('section_start_lines', {}) 3451d6fea64SMauro Carvalho Chehab 3461d6fea64SMauro Carvalho Chehab for section in sectionlist: 3471d6fea64SMauro Carvalho Chehab # Skip sections that are in the nosymbol_table 3481d6fea64SMauro Carvalho Chehab if section in self.nosymbol: 3491d6fea64SMauro Carvalho Chehab continue 3501d6fea64SMauro Carvalho Chehab 351408269aeSMauro Carvalho Chehab if out_docblock: 3529235ec5eSMauro Carvalho Chehab if not self.out_mode == self.OUTPUT_INCLUDE: 3534fa5e411SMauro Carvalho Chehab self.data += f".. _{section}:\n\n" 3549235ec5eSMauro Carvalho Chehab self.data += f'{self.lineprefix}**{section}**\n\n' 3559235ec5eSMauro Carvalho Chehab else: 3564fa5e411SMauro Carvalho Chehab self.data += f'{self.lineprefix}**{section}**\n\n' 3571d6fea64SMauro Carvalho Chehab 3581d6fea64SMauro Carvalho Chehab self.print_lineno(section_start_lines.get(section, 0)) 3591d6fea64SMauro Carvalho Chehab self.output_highlight(sections[section]) 3604fa5e411SMauro Carvalho Chehab self.data += "\n" 3614fa5e411SMauro Carvalho Chehab self.data += "\n" 3621d6fea64SMauro Carvalho Chehab 3631d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 3649cbc2d3bSMauro Carvalho Chehab if not self.check_doc(name, args): 3651d6fea64SMauro Carvalho Chehab return 366408269aeSMauro Carvalho Chehab self.out_section(args, out_docblock=True) 3671d6fea64SMauro Carvalho Chehab 3681d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 3691d6fea64SMauro Carvalho Chehab 3701d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 3711d6fea64SMauro Carvalho Chehab signature = "" 3721d6fea64SMauro Carvalho Chehab 3731d6fea64SMauro Carvalho Chehab func_macro = args.get('func_macro', False) 3741d6fea64SMauro Carvalho Chehab if func_macro: 3751d6fea64SMauro Carvalho Chehab signature = args['function'] 3761d6fea64SMauro Carvalho Chehab else: 3771d6fea64SMauro Carvalho Chehab if args.get('functiontype'): 3781d6fea64SMauro Carvalho Chehab signature = args['functiontype'] + " " 3791d6fea64SMauro Carvalho Chehab signature += args['function'] + " (" 3801d6fea64SMauro Carvalho Chehab 3811d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 3821d6fea64SMauro Carvalho Chehab parameterdescs = args.get('parameterdescs', {}) 3831d6fea64SMauro Carvalho Chehab parameterdesc_start_lines = args.get('parameterdesc_start_lines', {}) 3841d6fea64SMauro Carvalho Chehab 385c3597ab2SMauro Carvalho Chehab ln = args.get('declaration_start_line', 0) 3861d6fea64SMauro Carvalho Chehab 3871d6fea64SMauro Carvalho Chehab count = 0 3881d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 3891d6fea64SMauro Carvalho Chehab if count != 0: 3901d6fea64SMauro Carvalho Chehab signature += ", " 3911d6fea64SMauro Carvalho Chehab count += 1 3921d6fea64SMauro Carvalho Chehab dtype = args['parametertypes'].get(parameter, "") 3931d6fea64SMauro Carvalho Chehab 3941d6fea64SMauro Carvalho Chehab if function_pointer.search(dtype): 3951d6fea64SMauro Carvalho Chehab signature += function_pointer.group(1) + parameter + function_pointer.group(3) 3961d6fea64SMauro Carvalho Chehab else: 3971d6fea64SMauro Carvalho Chehab signature += dtype 3981d6fea64SMauro Carvalho Chehab 3991d6fea64SMauro Carvalho Chehab if not func_macro: 4001d6fea64SMauro Carvalho Chehab signature += ")" 4011d6fea64SMauro Carvalho Chehab 402c3597ab2SMauro Carvalho Chehab self.print_lineno(ln) 4031d6fea64SMauro Carvalho Chehab if args.get('typedef') or not args.get('functiontype'): 4044fa5e411SMauro Carvalho Chehab self.data += f".. c:macro:: {args['function']}\n\n" 4051d6fea64SMauro Carvalho Chehab 4061d6fea64SMauro Carvalho Chehab if args.get('typedef'): 4074fa5e411SMauro Carvalho Chehab self.data += " **Typedef**: " 4081d6fea64SMauro Carvalho Chehab self.lineprefix = "" 4091d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', "")) 4104fa5e411SMauro Carvalho Chehab self.data += "\n\n**Syntax**\n\n" 4114fa5e411SMauro Carvalho Chehab self.data += f" ``{signature}``\n\n" 4121d6fea64SMauro Carvalho Chehab else: 4134fa5e411SMauro Carvalho Chehab self.data += f"``{signature}``\n\n" 4141d6fea64SMauro Carvalho Chehab else: 4154fa5e411SMauro Carvalho Chehab self.data += f".. c:function:: {signature}\n\n" 4161d6fea64SMauro Carvalho Chehab 4171d6fea64SMauro Carvalho Chehab if not args.get('typedef'): 4181d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 4191d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4201d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', "")) 4214fa5e411SMauro Carvalho Chehab self.data += "\n" 4221d6fea64SMauro Carvalho Chehab 4231d6fea64SMauro Carvalho Chehab # Put descriptive text into a container (HTML <div>) to help set 4241d6fea64SMauro Carvalho Chehab # function prototypes apart 4251d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4261d6fea64SMauro Carvalho Chehab 4271d6fea64SMauro Carvalho Chehab if parameterlist: 4284fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 4294fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Parameters**\n\n" 4301d6fea64SMauro Carvalho Chehab 4311d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 432*04a383ceSMauro Carvalho Chehab parameter_name = KernRe(r'\[.*').sub('', parameter) 4331d6fea64SMauro Carvalho Chehab dtype = args['parametertypes'].get(parameter, "") 4341d6fea64SMauro Carvalho Chehab 4351d6fea64SMauro Carvalho Chehab if dtype: 4364fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{dtype}``\n" 4371d6fea64SMauro Carvalho Chehab else: 4384fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{parameter}``\n" 4391d6fea64SMauro Carvalho Chehab 4401d6fea64SMauro Carvalho Chehab self.print_lineno(parameterdesc_start_lines.get(parameter_name, 0)) 4411d6fea64SMauro Carvalho Chehab 4421d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4431d6fea64SMauro Carvalho Chehab if parameter_name in parameterdescs and \ 4441d6fea64SMauro Carvalho Chehab parameterdescs[parameter_name] != KernelDoc.undescribed: 4451d6fea64SMauro Carvalho Chehab 4461d6fea64SMauro Carvalho Chehab self.output_highlight(parameterdescs[parameter_name]) 4474fa5e411SMauro Carvalho Chehab self.data += "\n" 4481d6fea64SMauro Carvalho Chehab else: 4494fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}*undescribed*\n\n" 4501d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4511d6fea64SMauro Carvalho Chehab 4521d6fea64SMauro Carvalho Chehab self.out_section(args) 4531d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 4541d6fea64SMauro Carvalho Chehab 4551d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 4561d6fea64SMauro Carvalho Chehab 4571d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 4581d6fea64SMauro Carvalho Chehab name = args.get('enum', '') 4591d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 4601d6fea64SMauro Carvalho Chehab parameterdescs = args.get('parameterdescs', {}) 461c3597ab2SMauro Carvalho Chehab ln = args.get('declaration_start_line', 0) 4621d6fea64SMauro Carvalho Chehab 4634fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:enum:: {name}\n\n" 4641d6fea64SMauro Carvalho Chehab 4651d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 4661d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4671d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', '')) 4684fa5e411SMauro Carvalho Chehab self.data += "\n" 4691d6fea64SMauro Carvalho Chehab 4704fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 4711d6fea64SMauro Carvalho Chehab outer = self.lineprefix + " " 4721d6fea64SMauro Carvalho Chehab self.lineprefix = outer + " " 4734fa5e411SMauro Carvalho Chehab self.data += f"{outer}**Constants**\n\n" 4741d6fea64SMauro Carvalho Chehab 4751d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 4764fa5e411SMauro Carvalho Chehab self.data += f"{outer}``{parameter}``\n" 4771d6fea64SMauro Carvalho Chehab 4781d6fea64SMauro Carvalho Chehab if parameterdescs.get(parameter, '') != KernelDoc.undescribed: 4791d6fea64SMauro Carvalho Chehab self.output_highlight(parameterdescs[parameter]) 4801d6fea64SMauro Carvalho Chehab else: 4814fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}*undescribed*\n\n" 4824fa5e411SMauro Carvalho Chehab self.data += "\n" 4831d6fea64SMauro Carvalho Chehab 4841d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 4851d6fea64SMauro Carvalho Chehab self.out_section(args) 4861d6fea64SMauro Carvalho Chehab 4871d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 4881d6fea64SMauro Carvalho Chehab 4891d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 4901d6fea64SMauro Carvalho Chehab name = args.get('typedef', '') 491c3597ab2SMauro Carvalho Chehab ln = args.get('declaration_start_line', 0) 4921d6fea64SMauro Carvalho Chehab 4934fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:type:: {name}\n\n" 4941d6fea64SMauro Carvalho Chehab 4951d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 4961d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4971d6fea64SMauro Carvalho Chehab 4981d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', '')) 4991d6fea64SMauro Carvalho Chehab 5004fa5e411SMauro Carvalho Chehab self.data += "\n" 5011d6fea64SMauro Carvalho Chehab 5021d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 5031d6fea64SMauro Carvalho Chehab self.out_section(args) 5041d6fea64SMauro Carvalho Chehab 5051d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 5061d6fea64SMauro Carvalho Chehab 5071d6fea64SMauro Carvalho Chehab name = args.get('struct', "") 5081d6fea64SMauro Carvalho Chehab purpose = args.get('purpose', "") 5091d6fea64SMauro Carvalho Chehab declaration = args.get('definition', "") 5101d6fea64SMauro Carvalho Chehab dtype = args.get('type', "struct") 511c3597ab2SMauro Carvalho Chehab ln = args.get('declaration_start_line', 0) 5121d6fea64SMauro Carvalho Chehab 5131d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 5141d6fea64SMauro Carvalho Chehab parameterdescs = args.get('parameterdescs', {}) 5151d6fea64SMauro Carvalho Chehab parameterdesc_start_lines = args.get('parameterdesc_start_lines', {}) 5161d6fea64SMauro Carvalho Chehab 5174fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:{dtype}:: {name}\n\n" 5181d6fea64SMauro Carvalho Chehab 5191d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 5201d6fea64SMauro Carvalho Chehab 5211d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 5221d6fea64SMauro Carvalho Chehab self.lineprefix += " " 5231d6fea64SMauro Carvalho Chehab 5241d6fea64SMauro Carvalho Chehab self.output_highlight(purpose) 5254fa5e411SMauro Carvalho Chehab self.data += "\n" 5261d6fea64SMauro Carvalho Chehab 5274fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 5284fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Definition**::\n\n" 5291d6fea64SMauro Carvalho Chehab 5301d6fea64SMauro Carvalho Chehab self.lineprefix = self.lineprefix + " " 5311d6fea64SMauro Carvalho Chehab 5321d6fea64SMauro Carvalho Chehab declaration = declaration.replace("\t", self.lineprefix) 5331d6fea64SMauro Carvalho Chehab 5344fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}{dtype} {name}" + ' {' + "\n" 5354fa5e411SMauro Carvalho Chehab self.data += f"{declaration}{self.lineprefix}" + "};\n\n" 5361d6fea64SMauro Carvalho Chehab 5371d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5384fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Members**\n\n" 5391d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 5401d6fea64SMauro Carvalho Chehab if not parameter or parameter.startswith("#"): 5411d6fea64SMauro Carvalho Chehab continue 5421d6fea64SMauro Carvalho Chehab 5431d6fea64SMauro Carvalho Chehab parameter_name = parameter.split("[", maxsplit=1)[0] 5441d6fea64SMauro Carvalho Chehab 5451d6fea64SMauro Carvalho Chehab if parameterdescs.get(parameter_name) == KernelDoc.undescribed: 5461d6fea64SMauro Carvalho Chehab continue 5471d6fea64SMauro Carvalho Chehab 5481d6fea64SMauro Carvalho Chehab self.print_lineno(parameterdesc_start_lines.get(parameter_name, 0)) 5491d6fea64SMauro Carvalho Chehab 5504fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{parameter}``\n" 5511d6fea64SMauro Carvalho Chehab 5521d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5531d6fea64SMauro Carvalho Chehab self.output_highlight(parameterdescs[parameter_name]) 5541d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5551d6fea64SMauro Carvalho Chehab 5564fa5e411SMauro Carvalho Chehab self.data += "\n" 5571d6fea64SMauro Carvalho Chehab 5584fa5e411SMauro Carvalho Chehab self.data += "\n" 5591d6fea64SMauro Carvalho Chehab 5601d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 5611d6fea64SMauro Carvalho Chehab self.out_section(args) 5621d6fea64SMauro Carvalho Chehab 5631d6fea64SMauro Carvalho Chehab 5641d6fea64SMauro Carvalho Chehabclass ManFormat(OutputFormat): 5651d6fea64SMauro Carvalho Chehab """Consts and functions used by man pages output""" 5661d6fea64SMauro Carvalho Chehab 5671d6fea64SMauro Carvalho Chehab highlights = ( 5681d6fea64SMauro Carvalho Chehab (type_constant, r"\1"), 5691d6fea64SMauro Carvalho Chehab (type_constant2, r"\1"), 5701d6fea64SMauro Carvalho Chehab (type_func, r"\\fB\1\\fP"), 5711d6fea64SMauro Carvalho Chehab (type_enum, r"\\fI\1\\fP"), 5721d6fea64SMauro Carvalho Chehab (type_struct, r"\\fI\1\\fP"), 5731d6fea64SMauro Carvalho Chehab (type_typedef, r"\\fI\1\\fP"), 5741d6fea64SMauro Carvalho Chehab (type_union, r"\\fI\1\\fP"), 5751d6fea64SMauro Carvalho Chehab (type_param, r"\\fI\1\\fP"), 5761d6fea64SMauro Carvalho Chehab (type_param_ref, r"\\fI\1\2\\fP"), 5771d6fea64SMauro Carvalho Chehab (type_member, r"\\fI\1\2\3\\fP"), 5781d6fea64SMauro Carvalho Chehab (type_fallback, r"\\fI\1\\fP") 5791d6fea64SMauro Carvalho Chehab ) 5801d6fea64SMauro Carvalho Chehab blankline = "" 5811d6fea64SMauro Carvalho Chehab 58291d00bd5SMauro Carvalho Chehab date_formats = [ 58391d00bd5SMauro Carvalho Chehab "%a %b %d %H:%M:%S %Z %Y", 58491d00bd5SMauro Carvalho Chehab "%a %b %d %H:%M:%S %Y", 58591d00bd5SMauro Carvalho Chehab "%Y-%m-%d", 58691d00bd5SMauro Carvalho Chehab "%b %d %Y", 58791d00bd5SMauro Carvalho Chehab "%B %d %Y", 58891d00bd5SMauro Carvalho Chehab "%m %d %Y", 58991d00bd5SMauro Carvalho Chehab ] 59091d00bd5SMauro Carvalho Chehab 5912ab867a4SMauro Carvalho Chehab def __init__(self, modulename): 5921d6fea64SMauro Carvalho Chehab """ 5931d6fea64SMauro Carvalho Chehab Creates class variables. 5941d6fea64SMauro Carvalho Chehab 5951d6fea64SMauro Carvalho Chehab Not really mandatory, but it is a good coding style and makes 5961d6fea64SMauro Carvalho Chehab pylint happy. 5971d6fea64SMauro Carvalho Chehab """ 5981d6fea64SMauro Carvalho Chehab 5991d6fea64SMauro Carvalho Chehab super().__init__() 6002ab867a4SMauro Carvalho Chehab self.modulename = modulename 6011d6fea64SMauro Carvalho Chehab 60291d00bd5SMauro Carvalho Chehab dt = None 60391d00bd5SMauro Carvalho Chehab tstamp = os.environ.get("KBUILD_BUILD_TIMESTAMP") 60491d00bd5SMauro Carvalho Chehab if tstamp: 60591d00bd5SMauro Carvalho Chehab for fmt in self.date_formats: 60691d00bd5SMauro Carvalho Chehab try: 60791d00bd5SMauro Carvalho Chehab dt = datetime.strptime(tstamp, fmt) 60891d00bd5SMauro Carvalho Chehab break 60991d00bd5SMauro Carvalho Chehab except ValueError: 61091d00bd5SMauro Carvalho Chehab pass 61191d00bd5SMauro Carvalho Chehab 61291d00bd5SMauro Carvalho Chehab if not dt: 6131d6fea64SMauro Carvalho Chehab dt = datetime.now() 6141d6fea64SMauro Carvalho Chehab 6151d6fea64SMauro Carvalho Chehab self.man_date = dt.strftime("%B %Y") 6161d6fea64SMauro Carvalho Chehab 6171d6fea64SMauro Carvalho Chehab def output_highlight(self, block): 618485f6f79SMauro Carvalho Chehab """ 619485f6f79SMauro Carvalho Chehab Outputs a C symbol that may require being highlighted with 620485f6f79SMauro Carvalho Chehab self.highlights variable using troff syntax 621485f6f79SMauro Carvalho Chehab """ 6221d6fea64SMauro Carvalho Chehab 6231d6fea64SMauro Carvalho Chehab contents = self.highlight_block(block) 6241d6fea64SMauro Carvalho Chehab 6251d6fea64SMauro Carvalho Chehab if isinstance(contents, list): 6261d6fea64SMauro Carvalho Chehab contents = "\n".join(contents) 6271d6fea64SMauro Carvalho Chehab 6281d6fea64SMauro Carvalho Chehab for line in contents.strip("\n").split("\n"): 629*04a383ceSMauro Carvalho Chehab line = KernRe(r"^\s*").sub("", line) 630408269aeSMauro Carvalho Chehab if not line: 631408269aeSMauro Carvalho Chehab continue 6321d6fea64SMauro Carvalho Chehab 633408269aeSMauro Carvalho Chehab if line[0] == ".": 6344fa5e411SMauro Carvalho Chehab self.data += "\\&" + line + "\n" 6351d6fea64SMauro Carvalho Chehab else: 6364fa5e411SMauro Carvalho Chehab self.data += line + "\n" 6371d6fea64SMauro Carvalho Chehab 6381d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 6391d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 6401d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 6411d6fea64SMauro Carvalho Chehab 6429cbc2d3bSMauro Carvalho Chehab if not self.check_doc(name, args): 643408269aeSMauro Carvalho Chehab return 644408269aeSMauro Carvalho Chehab 6452ab867a4SMauro Carvalho Chehab self.data += f'.TH "{self.modulename}" 9 "{self.modulename}" "{self.man_date}" "API Manual" LINUX' + "\n" 6461d6fea64SMauro Carvalho Chehab 6471d6fea64SMauro Carvalho Chehab for section in sectionlist: 6484fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 6491d6fea64SMauro Carvalho Chehab self.output_highlight(sections.get(section)) 6501d6fea64SMauro Carvalho Chehab 6511d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 6521d6fea64SMauro Carvalho Chehab """output function in man""" 6531d6fea64SMauro Carvalho Chehab 6541d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 6551d6fea64SMauro Carvalho Chehab parameterdescs = args.get('parameterdescs', {}) 6561d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 6571d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 6581d6fea64SMauro Carvalho Chehab 65978ea748fSMauro Carvalho Chehab self.data += f'.TH "{args["function"]}" 9 "{args["function"]}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n" 6601d6fea64SMauro Carvalho Chehab 6614fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 6624fa5e411SMauro Carvalho Chehab self.data += f"{args['function']} \\- {args['purpose']}\n" 6631d6fea64SMauro Carvalho Chehab 6644fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 6651d6fea64SMauro Carvalho Chehab if args.get('functiontype', ''): 66678ea748fSMauro Carvalho Chehab self.data += f'.B "{args["functiontype"]}" {args["function"]}' + "\n" 6671d6fea64SMauro Carvalho Chehab else: 66878ea748fSMauro Carvalho Chehab self.data += f'.B "{args["function"]}' + "\n" 6691d6fea64SMauro Carvalho Chehab 6701d6fea64SMauro Carvalho Chehab count = 0 6711d6fea64SMauro Carvalho Chehab parenth = "(" 6721d6fea64SMauro Carvalho Chehab post = "," 6731d6fea64SMauro Carvalho Chehab 6741d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 6751d6fea64SMauro Carvalho Chehab if count == len(parameterlist) - 1: 6761d6fea64SMauro Carvalho Chehab post = ");" 6771d6fea64SMauro Carvalho Chehab 6781d6fea64SMauro Carvalho Chehab dtype = args['parametertypes'].get(parameter, "") 6791d6fea64SMauro Carvalho Chehab if function_pointer.match(dtype): 6801d6fea64SMauro Carvalho Chehab # Pointer-to-function 6814fa5e411SMauro Carvalho Chehab self.data += f'".BI "{parenth}{function_pointer.group(1)}" " ") ({function_pointer.group(2)}){post}"' + "\n" 6821d6fea64SMauro Carvalho Chehab else: 683*04a383ceSMauro Carvalho Chehab dtype = KernRe(r'([^\*])$').sub(r'\1 ', dtype) 6841d6fea64SMauro Carvalho Chehab 6854fa5e411SMauro Carvalho Chehab self.data += f'.BI "{parenth}{dtype}" "{post}"' + "\n" 6861d6fea64SMauro Carvalho Chehab count += 1 6871d6fea64SMauro Carvalho Chehab parenth = "" 6881d6fea64SMauro Carvalho Chehab 6891d6fea64SMauro Carvalho Chehab if parameterlist: 6904fa5e411SMauro Carvalho Chehab self.data += ".SH ARGUMENTS\n" 6911d6fea64SMauro Carvalho Chehab 6921d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 6931d6fea64SMauro Carvalho Chehab parameter_name = re.sub(r'\[.*', '', parameter) 6941d6fea64SMauro Carvalho Chehab 6954fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 6961d6fea64SMauro Carvalho Chehab self.output_highlight(parameterdescs.get(parameter_name, "")) 6971d6fea64SMauro Carvalho Chehab 6981d6fea64SMauro Carvalho Chehab for section in sectionlist: 6994fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section.upper()}"' + "\n" 7001d6fea64SMauro Carvalho Chehab self.output_highlight(sections[section]) 7011d6fea64SMauro Carvalho Chehab 7021d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 7031d6fea64SMauro Carvalho Chehab 7041d6fea64SMauro Carvalho Chehab name = args.get('enum', '') 7051d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 7061d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 7071d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 7081d6fea64SMauro Carvalho Chehab 7092ab867a4SMauro Carvalho Chehab self.data += f'.TH "{self.modulename}" 9 "enum {args["enum"]}" "{self.man_date}" "API Manual" LINUX' + "\n" 7101d6fea64SMauro Carvalho Chehab 7114fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 7124fa5e411SMauro Carvalho Chehab self.data += f"enum {args['enum']} \\- {args['purpose']}\n" 7131d6fea64SMauro Carvalho Chehab 7144fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 7154fa5e411SMauro Carvalho Chehab self.data += f"enum {args['enum']}" + " {\n" 7161d6fea64SMauro Carvalho Chehab 7171d6fea64SMauro Carvalho Chehab count = 0 7181d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 7194fa5e411SMauro Carvalho Chehab self.data += f'.br\n.BI " {parameter}"' + "\n" 7201d6fea64SMauro Carvalho Chehab if count == len(parameterlist) - 1: 7214fa5e411SMauro Carvalho Chehab self.data += "\n};\n" 7221d6fea64SMauro Carvalho Chehab else: 7234fa5e411SMauro Carvalho Chehab self.data += ", \n.br\n" 7241d6fea64SMauro Carvalho Chehab 7251d6fea64SMauro Carvalho Chehab count += 1 7261d6fea64SMauro Carvalho Chehab 7274fa5e411SMauro Carvalho Chehab self.data += ".SH Constants\n" 7281d6fea64SMauro Carvalho Chehab 7291d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 730*04a383ceSMauro Carvalho Chehab parameter_name = KernRe(r'\[.*').sub('', parameter) 7314fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 7321d6fea64SMauro Carvalho Chehab self.output_highlight(args['parameterdescs'].get(parameter_name, "")) 7331d6fea64SMauro Carvalho Chehab 7341d6fea64SMauro Carvalho Chehab for section in sectionlist: 7354fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 7361d6fea64SMauro Carvalho Chehab self.output_highlight(sections[section]) 7371d6fea64SMauro Carvalho Chehab 7381d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 7392ab867a4SMauro Carvalho Chehab module = self.modulename 7401d6fea64SMauro Carvalho Chehab typedef = args.get('typedef') 7411d6fea64SMauro Carvalho Chehab purpose = args.get('purpose') 7421d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 7431d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 7441d6fea64SMauro Carvalho Chehab 7454fa5e411SMauro Carvalho Chehab self.data += f'.TH "{module}" 9 "{typedef}" "{self.man_date}" "API Manual" LINUX' + "\n" 7461d6fea64SMauro Carvalho Chehab 7474fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 7484fa5e411SMauro Carvalho Chehab self.data += f"typedef {typedef} \\- {purpose}\n" 7491d6fea64SMauro Carvalho Chehab 7501d6fea64SMauro Carvalho Chehab for section in sectionlist: 7514fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 7521d6fea64SMauro Carvalho Chehab self.output_highlight(sections.get(section)) 7531d6fea64SMauro Carvalho Chehab 7541d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 7552ab867a4SMauro Carvalho Chehab module = self.modulename 7561d6fea64SMauro Carvalho Chehab struct_type = args.get('type') 7571d6fea64SMauro Carvalho Chehab struct_name = args.get('struct') 7581d6fea64SMauro Carvalho Chehab purpose = args.get('purpose') 7591d6fea64SMauro Carvalho Chehab definition = args.get('definition') 7601d6fea64SMauro Carvalho Chehab sectionlist = args.get('sectionlist', []) 7611d6fea64SMauro Carvalho Chehab parameterlist = args.get('parameterlist', []) 7621d6fea64SMauro Carvalho Chehab sections = args.get('sections', {}) 7631d6fea64SMauro Carvalho Chehab parameterdescs = args.get('parameterdescs', {}) 7641d6fea64SMauro Carvalho Chehab 7654fa5e411SMauro Carvalho Chehab self.data += f'.TH "{module}" 9 "{struct_type} {struct_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 7661d6fea64SMauro Carvalho Chehab 7674fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 7684fa5e411SMauro Carvalho Chehab self.data += f"{struct_type} {struct_name} \\- {purpose}\n" 7691d6fea64SMauro Carvalho Chehab 7701d6fea64SMauro Carvalho Chehab # Replace tabs with two spaces and handle newlines 7711d6fea64SMauro Carvalho Chehab declaration = definition.replace("\t", " ") 772*04a383ceSMauro Carvalho Chehab declaration = KernRe(r"\n").sub('"\n.br\n.BI "', declaration) 7731d6fea64SMauro Carvalho Chehab 7744fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 7754fa5e411SMauro Carvalho Chehab self.data += f"{struct_type} {struct_name} " + "{" + "\n.br\n" 7764fa5e411SMauro Carvalho Chehab self.data += f'.BI "{declaration}\n' + "};\n.br\n\n" 7771d6fea64SMauro Carvalho Chehab 7784fa5e411SMauro Carvalho Chehab self.data += ".SH Members\n" 7791d6fea64SMauro Carvalho Chehab for parameter in parameterlist: 7801d6fea64SMauro Carvalho Chehab if parameter.startswith("#"): 7811d6fea64SMauro Carvalho Chehab continue 7821d6fea64SMauro Carvalho Chehab 7831d6fea64SMauro Carvalho Chehab parameter_name = re.sub(r"\[.*", "", parameter) 7841d6fea64SMauro Carvalho Chehab 7851d6fea64SMauro Carvalho Chehab if parameterdescs.get(parameter_name) == KernelDoc.undescribed: 7861d6fea64SMauro Carvalho Chehab continue 7871d6fea64SMauro Carvalho Chehab 7884fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 7891d6fea64SMauro Carvalho Chehab self.output_highlight(parameterdescs.get(parameter_name)) 7901d6fea64SMauro Carvalho Chehab 7911d6fea64SMauro Carvalho Chehab for section in sectionlist: 7924fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 7931d6fea64SMauro Carvalho Chehab self.output_highlight(sections.get(section)) 794