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""" 8*245f1ab2SMauro Carvalho ChehabClasses to implement output filters to print kernel-doc documentation. 91d6fea64SMauro Carvalho Chehab 10*245f1ab2SMauro Carvalho ChehabThe implementation uses a virtual base class ``OutputFormat``. It 115f88f44dSRandy Dunlapcontains 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 15*245f1ab2SMauro Carvalho Chehabof output, e.g. ``RestFormat`` and ``ManFormat`` classes. 16*245f1ab2SMauro Carvalho Chehab 17*245f1ab2SMauro Carvalho ChehabCurrently, there are output classes for ReST and man/troff. 181d6fea64SMauro Carvalho Chehab""" 191d6fea64SMauro Carvalho Chehab 201d6fea64SMauro Carvalho Chehabimport os 211d6fea64SMauro Carvalho Chehabimport re 221d6fea64SMauro Carvalho Chehabfrom datetime import datetime 231d6fea64SMauro Carvalho Chehab 24992a9df4SJonathan Corbetfrom kdoc.kdoc_parser import KernelDoc, type_param 25992a9df4SJonathan Corbetfrom kdoc.kdoc_re import KernRe 261d6fea64SMauro Carvalho Chehab 271d6fea64SMauro Carvalho Chehab 2804a383ceSMauro Carvalho Chehabfunction_pointer = KernRe(r"([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)", cache=False) 291d6fea64SMauro Carvalho Chehab 301d6fea64SMauro Carvalho Chehab# match expressions used to find embedded type information 3104a383ceSMauro Carvalho Chehabtype_constant = KernRe(r"\b``([^\`]+)``\b", cache=False) 3204a383ceSMauro Carvalho Chehabtype_constant2 = KernRe(r"\%([-_*\w]+)", cache=False) 3304a383ceSMauro Carvalho Chehabtype_func = KernRe(r"(\w+)\(\)", cache=False) 3404a383ceSMauro Carvalho Chehabtype_param_ref = KernRe(r"([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False) 351d6fea64SMauro Carvalho Chehab 361d6fea64SMauro Carvalho Chehab# Special RST handling for func ptr params 3704a383ceSMauro Carvalho Chehabtype_fp_param = KernRe(r"\@(\w+)\(\)", cache=False) 381d6fea64SMauro Carvalho Chehab 391d6fea64SMauro Carvalho Chehab# Special RST handling for structs with func ptr params 4004a383ceSMauro Carvalho Chehabtype_fp_param2 = KernRe(r"\@(\w+->\S+)\(\)", cache=False) 411d6fea64SMauro Carvalho Chehab 4204a383ceSMauro Carvalho Chehabtype_env = KernRe(r"(\$\w+)", cache=False) 4304a383ceSMauro Carvalho Chehabtype_enum = KernRe(r"\&(enum\s*([_\w]+))", cache=False) 4404a383ceSMauro Carvalho Chehabtype_struct = KernRe(r"\&(struct\s*([_\w]+))", cache=False) 4504a383ceSMauro Carvalho Chehabtype_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False) 4604a383ceSMauro Carvalho Chehabtype_union = KernRe(r"\&(union\s*([_\w]+))", cache=False) 4704a383ceSMauro Carvalho Chehabtype_member = KernRe(r"\&([_\w]+)(\.|->)([_\w]+)", cache=False) 4804a383ceSMauro Carvalho Chehabtype_fallback = KernRe(r"\&([_\w]+)", cache=False) 4904a383ceSMauro Carvalho Chehabtype_member_func = type_member + KernRe(r"\(\)", cache=False) 501d6fea64SMauro Carvalho Chehab 511d6fea64SMauro Carvalho Chehab 521d6fea64SMauro Carvalho Chehabclass OutputFormat: 53485f6f79SMauro Carvalho Chehab """ 54485f6f79SMauro Carvalho Chehab Base class for OutputFormat. If used as-is, it means that only 55485f6f79SMauro Carvalho Chehab warnings will be displayed. 56485f6f79SMauro Carvalho Chehab """ 57485f6f79SMauro Carvalho Chehab 581d6fea64SMauro Carvalho Chehab # output mode. 59*245f1ab2SMauro Carvalho Chehab OUTPUT_ALL = 0 #: Output all symbols and doc sections. 60*245f1ab2SMauro Carvalho Chehab OUTPUT_INCLUDE = 1 #: Output only specified symbols. 61*245f1ab2SMauro Carvalho Chehab OUTPUT_EXPORTED = 2 #: Output exported symbols. 62*245f1ab2SMauro Carvalho Chehab OUTPUT_INTERNAL = 3 #: Output non-exported symbols. 631d6fea64SMauro Carvalho Chehab 64*245f1ab2SMauro Carvalho Chehab #: Highlights to be used in ReST format. 651d6fea64SMauro Carvalho Chehab highlights = [] 661d6fea64SMauro Carvalho Chehab 67*245f1ab2SMauro Carvalho Chehab #: Blank line character. 68*245f1ab2SMauro Carvalho Chehab blankline = "" 69*245f1ab2SMauro Carvalho Chehab 701d6fea64SMauro Carvalho Chehab def __init__(self): 71*245f1ab2SMauro Carvalho Chehab """Declare internal vars and set mode to ``OUTPUT_ALL``.""" 721d6fea64SMauro Carvalho Chehab 731d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_ALL 741d6fea64SMauro Carvalho Chehab self.enable_lineno = None 751d6fea64SMauro Carvalho Chehab self.nosymbol = {} 761d6fea64SMauro Carvalho Chehab self.symbol = None 7716740c29SMauro Carvalho Chehab self.function_table = None 781d6fea64SMauro Carvalho Chehab self.config = None 790873e554SMauro Carvalho Chehab self.no_doc_sections = False 801d6fea64SMauro Carvalho Chehab 814fa5e411SMauro Carvalho Chehab self.data = "" 824fa5e411SMauro Carvalho Chehab 831d6fea64SMauro Carvalho Chehab def set_config(self, config): 84485f6f79SMauro Carvalho Chehab """ 85485f6f79SMauro Carvalho Chehab Setup global config variables used by both parser and output. 86485f6f79SMauro Carvalho Chehab """ 87485f6f79SMauro Carvalho Chehab 881d6fea64SMauro Carvalho Chehab self.config = config 891d6fea64SMauro Carvalho Chehab 901d6fea64SMauro Carvalho Chehab def set_filter(self, export, internal, symbol, nosymbol, function_table, 910873e554SMauro Carvalho Chehab enable_lineno, no_doc_sections): 921d6fea64SMauro Carvalho Chehab """ 935f88f44dSRandy Dunlap Initialize filter variables according to the requested mode. 941d6fea64SMauro Carvalho Chehab 951d6fea64SMauro Carvalho Chehab Only one choice is valid between export, internal and symbol. 961d6fea64SMauro Carvalho Chehab 971d6fea64SMauro Carvalho Chehab The nosymbol filter can be used on all modes. 981d6fea64SMauro Carvalho Chehab """ 991d6fea64SMauro Carvalho Chehab 1001d6fea64SMauro Carvalho Chehab self.enable_lineno = enable_lineno 1010873e554SMauro Carvalho Chehab self.no_doc_sections = no_doc_sections 10216740c29SMauro Carvalho Chehab self.function_table = function_table 1031d6fea64SMauro Carvalho Chehab 1041d6fea64SMauro Carvalho Chehab if symbol: 1051d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_INCLUDE 1061d6fea64SMauro Carvalho Chehab elif export: 1071d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_EXPORTED 1081d6fea64SMauro Carvalho Chehab elif internal: 1091d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_INTERNAL 1101d6fea64SMauro Carvalho Chehab else: 1111d6fea64SMauro Carvalho Chehab self.out_mode = self.OUTPUT_ALL 1121d6fea64SMauro Carvalho Chehab 1131d6fea64SMauro Carvalho Chehab if nosymbol: 1141d6fea64SMauro Carvalho Chehab self.nosymbol = set(nosymbol) 1151d6fea64SMauro Carvalho Chehab 1161d6fea64SMauro Carvalho Chehab 1171d6fea64SMauro Carvalho Chehab def highlight_block(self, block): 1181d6fea64SMauro Carvalho Chehab """ 1191d6fea64SMauro Carvalho Chehab Apply the RST highlights to a sub-block of text. 1201d6fea64SMauro Carvalho Chehab """ 1211d6fea64SMauro Carvalho Chehab 1221d6fea64SMauro Carvalho Chehab for r, sub in self.highlights: 1231d6fea64SMauro Carvalho Chehab block = r.sub(sub, block) 1241d6fea64SMauro Carvalho Chehab 1251d6fea64SMauro Carvalho Chehab return block 1261d6fea64SMauro Carvalho Chehab 1279cbc2d3bSMauro Carvalho Chehab def out_warnings(self, args): 128485f6f79SMauro Carvalho Chehab """ 129485f6f79SMauro Carvalho Chehab Output warnings for identifiers that will be displayed. 130485f6f79SMauro Carvalho Chehab """ 131485f6f79SMauro Carvalho Chehab 132bd5628bfSJonathan Corbet for log_msg in args.warnings: 13316740c29SMauro Carvalho Chehab self.config.warning(log_msg) 1349cbc2d3bSMauro Carvalho Chehab 1359cbc2d3bSMauro Carvalho Chehab def check_doc(self, name, args): 136*245f1ab2SMauro Carvalho Chehab """Check if DOC should be output.""" 1371d6fea64SMauro Carvalho Chehab 1380873e554SMauro Carvalho Chehab if self.no_doc_sections: 1390873e554SMauro Carvalho Chehab return False 1400873e554SMauro Carvalho Chehab 141408269aeSMauro Carvalho Chehab if name in self.nosymbol: 142408269aeSMauro Carvalho Chehab return False 143408269aeSMauro Carvalho Chehab 1441d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_ALL: 1459cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1461d6fea64SMauro Carvalho Chehab return True 1471d6fea64SMauro Carvalho Chehab 1481d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_INCLUDE: 1491d6fea64SMauro Carvalho Chehab if name in self.function_table: 1509cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1511d6fea64SMauro Carvalho Chehab return True 1521d6fea64SMauro Carvalho Chehab 1531d6fea64SMauro Carvalho Chehab return False 1541d6fea64SMauro Carvalho Chehab 1559cbc2d3bSMauro Carvalho Chehab def check_declaration(self, dtype, name, args): 156485f6f79SMauro Carvalho Chehab """ 157485f6f79SMauro Carvalho Chehab Checks if a declaration should be output or not based on the 158485f6f79SMauro Carvalho Chehab filtering criteria. 159485f6f79SMauro Carvalho Chehab """ 160485f6f79SMauro Carvalho Chehab 1611d6fea64SMauro Carvalho Chehab if name in self.nosymbol: 1621d6fea64SMauro Carvalho Chehab return False 1631d6fea64SMauro Carvalho Chehab 1641d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_ALL: 1659cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1661d6fea64SMauro Carvalho Chehab return True 1671d6fea64SMauro Carvalho Chehab 1681d6fea64SMauro Carvalho Chehab if self.out_mode in [self.OUTPUT_INCLUDE, self.OUTPUT_EXPORTED]: 1691d6fea64SMauro Carvalho Chehab if name in self.function_table: 1701d6fea64SMauro Carvalho Chehab return True 1711d6fea64SMauro Carvalho Chehab 1721d6fea64SMauro Carvalho Chehab if self.out_mode == self.OUTPUT_INTERNAL: 1731d6fea64SMauro Carvalho Chehab if dtype != "function": 1749cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1751d6fea64SMauro Carvalho Chehab return True 1761d6fea64SMauro Carvalho Chehab 1771d6fea64SMauro Carvalho Chehab if name not in self.function_table: 1789cbc2d3bSMauro Carvalho Chehab self.out_warnings(args) 1791d6fea64SMauro Carvalho Chehab return True 1801d6fea64SMauro Carvalho Chehab 1811d6fea64SMauro Carvalho Chehab return False 1821d6fea64SMauro Carvalho Chehab 1831d6fea64SMauro Carvalho Chehab def msg(self, fname, name, args): 184485f6f79SMauro Carvalho Chehab """ 185*245f1ab2SMauro Carvalho Chehab Handles a single entry from kernel-doc parser. 186485f6f79SMauro Carvalho Chehab """ 187485f6f79SMauro Carvalho Chehab 1884fa5e411SMauro Carvalho Chehab self.data = "" 1891d6fea64SMauro Carvalho Chehab 190bd5628bfSJonathan Corbet dtype = args.type 1911d6fea64SMauro Carvalho Chehab 1921d6fea64SMauro Carvalho Chehab if dtype == "doc": 1931d6fea64SMauro Carvalho Chehab self.out_doc(fname, name, args) 1944fa5e411SMauro Carvalho Chehab return self.data 1951d6fea64SMauro Carvalho Chehab 1969cbc2d3bSMauro Carvalho Chehab if not self.check_declaration(dtype, name, args): 1974fa5e411SMauro Carvalho Chehab return self.data 1981d6fea64SMauro Carvalho Chehab 1991d6fea64SMauro Carvalho Chehab if dtype == "function": 2001d6fea64SMauro Carvalho Chehab self.out_function(fname, name, args) 2014fa5e411SMauro Carvalho Chehab return self.data 2021d6fea64SMauro Carvalho Chehab 2031d6fea64SMauro Carvalho Chehab if dtype == "enum": 2041d6fea64SMauro Carvalho Chehab self.out_enum(fname, name, args) 2054fa5e411SMauro Carvalho Chehab return self.data 2061d6fea64SMauro Carvalho Chehab 2071045ec38SMauro Carvalho Chehab if dtype == "var": 2081045ec38SMauro Carvalho Chehab self.out_var(fname, name, args) 2091045ec38SMauro Carvalho Chehab return self.data 2101045ec38SMauro Carvalho Chehab 2111d6fea64SMauro Carvalho Chehab if dtype == "typedef": 2121d6fea64SMauro Carvalho Chehab self.out_typedef(fname, name, args) 2134fa5e411SMauro Carvalho Chehab return self.data 2141d6fea64SMauro Carvalho Chehab 2151d6fea64SMauro Carvalho Chehab if dtype in ["struct", "union"]: 2161d6fea64SMauro Carvalho Chehab self.out_struct(fname, name, args) 2174fa5e411SMauro Carvalho Chehab return self.data 2181d6fea64SMauro Carvalho Chehab 2191d6fea64SMauro Carvalho Chehab # Warn if some type requires an output logic 2205f88f44dSRandy Dunlap self.config.log.warning("doesn't know how to output '%s' block", 2211d6fea64SMauro Carvalho Chehab dtype) 2221d6fea64SMauro Carvalho Chehab 2234fa5e411SMauro Carvalho Chehab return None 2241d6fea64SMauro Carvalho Chehab 2251d6fea64SMauro Carvalho Chehab # Virtual methods to be overridden by inherited classes 226485f6f79SMauro Carvalho Chehab # At the base class, those do nothing. 227104e0a68SMauro Carvalho Chehab def set_symbols(self, symbols): 228*245f1ab2SMauro Carvalho Chehab """Get a list of all symbols from kernel_doc.""" 229104e0a68SMauro Carvalho Chehab 2301d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 231*245f1ab2SMauro Carvalho Chehab """Outputs a DOC block.""" 2321d6fea64SMauro Carvalho Chehab 2331d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 234*245f1ab2SMauro Carvalho Chehab """Outputs a function.""" 2351d6fea64SMauro Carvalho Chehab 2361d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 237*245f1ab2SMauro Carvalho Chehab """Outputs an enum.""" 2381d6fea64SMauro Carvalho Chehab 2391045ec38SMauro Carvalho Chehab def out_var(self, fname, name, args): 240*245f1ab2SMauro Carvalho Chehab """Outputs a variable.""" 2411045ec38SMauro Carvalho Chehab 2421d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 243*245f1ab2SMauro Carvalho Chehab """Outputs a typedef.""" 2441d6fea64SMauro Carvalho Chehab 2451d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 246*245f1ab2SMauro Carvalho Chehab """Outputs a struct.""" 2471d6fea64SMauro Carvalho Chehab 2481d6fea64SMauro Carvalho Chehab 2491d6fea64SMauro Carvalho Chehabclass RestFormat(OutputFormat): 250*245f1ab2SMauro Carvalho Chehab """Consts and functions used by ReST output.""" 2511d6fea64SMauro Carvalho Chehab 252*245f1ab2SMauro Carvalho Chehab #: Highlights to be used in ReST format 2531d6fea64SMauro Carvalho Chehab highlights = [ 2541d6fea64SMauro Carvalho Chehab (type_constant, r"``\1``"), 2551d6fea64SMauro Carvalho Chehab (type_constant2, r"``\1``"), 2561d6fea64SMauro Carvalho Chehab 2571d6fea64SMauro Carvalho Chehab # Note: need to escape () to avoid func matching later 2581d6fea64SMauro Carvalho Chehab (type_member_func, r":c:type:`\1\2\3\\(\\) <\1>`"), 2591d6fea64SMauro Carvalho Chehab (type_member, r":c:type:`\1\2\3 <\1>`"), 2601d6fea64SMauro Carvalho Chehab (type_fp_param, r"**\1\\(\\)**"), 2611d6fea64SMauro Carvalho Chehab (type_fp_param2, r"**\1\\(\\)**"), 2621d6fea64SMauro Carvalho Chehab (type_func, r"\1()"), 2631d6fea64SMauro Carvalho Chehab (type_enum, r":c:type:`\1 <\2>`"), 2641d6fea64SMauro Carvalho Chehab (type_struct, r":c:type:`\1 <\2>`"), 2651d6fea64SMauro Carvalho Chehab (type_typedef, r":c:type:`\1 <\2>`"), 2661d6fea64SMauro Carvalho Chehab (type_union, r":c:type:`\1 <\2>`"), 2671d6fea64SMauro Carvalho Chehab 2681d6fea64SMauro Carvalho Chehab # in rst this can refer to any type 2691d6fea64SMauro Carvalho Chehab (type_fallback, r":c:type:`\1`"), 2701d6fea64SMauro Carvalho Chehab (type_param_ref, r"**\1\2**") 2711d6fea64SMauro Carvalho Chehab ] 272*245f1ab2SMauro Carvalho Chehab 2731d6fea64SMauro Carvalho Chehab blankline = "\n" 2741d6fea64SMauro Carvalho Chehab 275*245f1ab2SMauro Carvalho Chehab #: Sphinx literal block regex. 27604a383ceSMauro Carvalho Chehab sphinx_literal = KernRe(r'^[^.].*::$', cache=False) 277*245f1ab2SMauro Carvalho Chehab 278*245f1ab2SMauro Carvalho Chehab #: Sphinx code block regex. 27904a383ceSMauro Carvalho Chehab sphinx_cblock = KernRe(r'^\.\.\ +code-block::', cache=False) 2801d6fea64SMauro Carvalho Chehab 2811d6fea64SMauro Carvalho Chehab def __init__(self): 2821d6fea64SMauro Carvalho Chehab """ 2831d6fea64SMauro Carvalho Chehab Creates class variables. 2841d6fea64SMauro Carvalho Chehab 2851d6fea64SMauro Carvalho Chehab Not really mandatory, but it is a good coding style and makes 2861d6fea64SMauro Carvalho Chehab pylint happy. 2871d6fea64SMauro Carvalho Chehab """ 2881d6fea64SMauro Carvalho Chehab 2891d6fea64SMauro Carvalho Chehab super().__init__() 2901d6fea64SMauro Carvalho Chehab self.lineprefix = "" 2911d6fea64SMauro Carvalho Chehab 2921d6fea64SMauro Carvalho Chehab def print_lineno(self, ln): 293*245f1ab2SMauro Carvalho Chehab """Outputs a line number.""" 2941d6fea64SMauro Carvalho Chehab 295c3597ab2SMauro Carvalho Chehab if self.enable_lineno and ln is not None: 296c3597ab2SMauro Carvalho Chehab ln += 1 2974fa5e411SMauro Carvalho Chehab self.data += f".. LINENO {ln}\n" 2981d6fea64SMauro Carvalho Chehab 2991d6fea64SMauro Carvalho Chehab def output_highlight(self, args): 300485f6f79SMauro Carvalho Chehab """ 301485f6f79SMauro Carvalho Chehab Outputs a C symbol that may require being converted to ReST using 302*245f1ab2SMauro Carvalho Chehab the self.highlights variable. 303485f6f79SMauro Carvalho Chehab """ 304485f6f79SMauro Carvalho Chehab 3051d6fea64SMauro Carvalho Chehab input_text = args 3061d6fea64SMauro Carvalho Chehab output = "" 3071d6fea64SMauro Carvalho Chehab in_literal = False 3081d6fea64SMauro Carvalho Chehab litprefix = "" 3091d6fea64SMauro Carvalho Chehab block = "" 3101d6fea64SMauro Carvalho Chehab 3111d6fea64SMauro Carvalho Chehab for line in input_text.strip("\n").split("\n"): 3121d6fea64SMauro Carvalho Chehab 3131d6fea64SMauro Carvalho Chehab # If we're in a literal block, see if we should drop out of it. 3141d6fea64SMauro Carvalho Chehab # Otherwise, pass the line straight through unmunged. 3151d6fea64SMauro Carvalho Chehab if in_literal: 3161d6fea64SMauro Carvalho Chehab if line.strip(): # If the line is not blank 3171d6fea64SMauro Carvalho Chehab # If this is the first non-blank line in a literal block, 3181d6fea64SMauro Carvalho Chehab # figure out the proper indent. 3191d6fea64SMauro Carvalho Chehab if not litprefix: 32004a383ceSMauro Carvalho Chehab r = KernRe(r'^(\s*)') 3211d6fea64SMauro Carvalho Chehab if r.match(line): 3221d6fea64SMauro Carvalho Chehab litprefix = '^' + r.group(1) 3231d6fea64SMauro Carvalho Chehab else: 3241d6fea64SMauro Carvalho Chehab litprefix = "" 3251d6fea64SMauro Carvalho Chehab 3261d6fea64SMauro Carvalho Chehab output += line + "\n" 32704a383ceSMauro Carvalho Chehab elif not KernRe(litprefix).match(line): 3281d6fea64SMauro Carvalho Chehab in_literal = False 3291d6fea64SMauro Carvalho Chehab else: 3301d6fea64SMauro Carvalho Chehab output += line + "\n" 3311d6fea64SMauro Carvalho Chehab else: 3321d6fea64SMauro Carvalho Chehab output += line + "\n" 3331d6fea64SMauro Carvalho Chehab 3341d6fea64SMauro Carvalho Chehab # Not in a literal block (or just dropped out) 3351d6fea64SMauro Carvalho Chehab if not in_literal: 3361d6fea64SMauro Carvalho Chehab block += line + "\n" 3371d6fea64SMauro Carvalho Chehab if self.sphinx_literal.match(line) or self.sphinx_cblock.match(line): 3381d6fea64SMauro Carvalho Chehab in_literal = True 3391d6fea64SMauro Carvalho Chehab litprefix = "" 3401d6fea64SMauro Carvalho Chehab output += self.highlight_block(block) 3411d6fea64SMauro Carvalho Chehab block = "" 3421d6fea64SMauro Carvalho Chehab 3431d6fea64SMauro Carvalho Chehab # Handle any remaining block 3441d6fea64SMauro Carvalho Chehab if block: 3451d6fea64SMauro Carvalho Chehab output += self.highlight_block(block) 3461d6fea64SMauro Carvalho Chehab 3471d6fea64SMauro Carvalho Chehab # Print the output with the line prefix 3481d6fea64SMauro Carvalho Chehab for line in output.strip("\n").split("\n"): 3494fa5e411SMauro Carvalho Chehab self.data += self.lineprefix + line + "\n" 3501d6fea64SMauro Carvalho Chehab 351408269aeSMauro Carvalho Chehab def out_section(self, args, out_docblock=False): 3521d6fea64SMauro Carvalho Chehab """ 3531d6fea64SMauro Carvalho Chehab Outputs a block section. 3541d6fea64SMauro Carvalho Chehab 3551d6fea64SMauro Carvalho Chehab This could use some work; it's used to output the DOC: sections, and 3561d6fea64SMauro Carvalho Chehab starts by putting out the name of the doc section itself, but that 3571d6fea64SMauro Carvalho Chehab tends to duplicate a header already in the template file. 3581d6fea64SMauro Carvalho Chehab """ 3598d733875SJonathan Corbet for section, text in args.sections.items(): 3601d6fea64SMauro Carvalho Chehab # Skip sections that are in the nosymbol_table 3611d6fea64SMauro Carvalho Chehab if section in self.nosymbol: 3621d6fea64SMauro Carvalho Chehab continue 3631d6fea64SMauro Carvalho Chehab 364408269aeSMauro Carvalho Chehab if out_docblock: 3659235ec5eSMauro Carvalho Chehab if not self.out_mode == self.OUTPUT_INCLUDE: 3664fa5e411SMauro Carvalho Chehab self.data += f".. _{section}:\n\n" 3679235ec5eSMauro Carvalho Chehab self.data += f'{self.lineprefix}**{section}**\n\n' 3689235ec5eSMauro Carvalho Chehab else: 3694fa5e411SMauro Carvalho Chehab self.data += f'{self.lineprefix}**{section}**\n\n' 3701d6fea64SMauro Carvalho Chehab 3718d733875SJonathan Corbet self.print_lineno(args.section_start_lines.get(section, 0)) 3728d733875SJonathan Corbet self.output_highlight(text) 3734fa5e411SMauro Carvalho Chehab self.data += "\n" 3744fa5e411SMauro Carvalho Chehab self.data += "\n" 3751d6fea64SMauro Carvalho Chehab 3761d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 3779cbc2d3bSMauro Carvalho Chehab if not self.check_doc(name, args): 3781d6fea64SMauro Carvalho Chehab return 379408269aeSMauro Carvalho Chehab self.out_section(args, out_docblock=True) 3801d6fea64SMauro Carvalho Chehab 3811d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 3821d6fea64SMauro Carvalho Chehab 3831d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 3841d6fea64SMauro Carvalho Chehab signature = "" 3851d6fea64SMauro Carvalho Chehab 3861d6fea64SMauro Carvalho Chehab func_macro = args.get('func_macro', False) 3871d6fea64SMauro Carvalho Chehab if func_macro: 388a0db2051SJonathan Corbet signature = name 3891d6fea64SMauro Carvalho Chehab else: 3901d6fea64SMauro Carvalho Chehab if args.get('functiontype'): 3911d6fea64SMauro Carvalho Chehab signature = args['functiontype'] + " " 392a0db2051SJonathan Corbet signature += name + " (" 3931d6fea64SMauro Carvalho Chehab 394bd5628bfSJonathan Corbet ln = args.declaration_start_line 3951d6fea64SMauro Carvalho Chehab count = 0 396de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 3971d6fea64SMauro Carvalho Chehab if count != 0: 3981d6fea64SMauro Carvalho Chehab signature += ", " 3991d6fea64SMauro Carvalho Chehab count += 1 400de6f7ac9SJonathan Corbet dtype = args.parametertypes.get(parameter, "") 4011d6fea64SMauro Carvalho Chehab 4021d6fea64SMauro Carvalho Chehab if function_pointer.search(dtype): 4031d6fea64SMauro Carvalho Chehab signature += function_pointer.group(1) + parameter + function_pointer.group(3) 4041d6fea64SMauro Carvalho Chehab else: 4051d6fea64SMauro Carvalho Chehab signature += dtype 4061d6fea64SMauro Carvalho Chehab 4071d6fea64SMauro Carvalho Chehab if not func_macro: 4081d6fea64SMauro Carvalho Chehab signature += ")" 4091d6fea64SMauro Carvalho Chehab 410c3597ab2SMauro Carvalho Chehab self.print_lineno(ln) 4111d6fea64SMauro Carvalho Chehab if args.get('typedef') or not args.get('functiontype'): 412a0db2051SJonathan Corbet self.data += f".. c:macro:: {name}\n\n" 4131d6fea64SMauro Carvalho Chehab 4141d6fea64SMauro Carvalho Chehab if args.get('typedef'): 4154fa5e411SMauro Carvalho Chehab self.data += " **Typedef**: " 4161d6fea64SMauro Carvalho Chehab self.lineprefix = "" 4171d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', "")) 4184fa5e411SMauro Carvalho Chehab self.data += "\n\n**Syntax**\n\n" 4194fa5e411SMauro Carvalho Chehab self.data += f" ``{signature}``\n\n" 4201d6fea64SMauro Carvalho Chehab else: 4214fa5e411SMauro Carvalho Chehab self.data += f"``{signature}``\n\n" 4221d6fea64SMauro Carvalho Chehab else: 4234fa5e411SMauro Carvalho Chehab self.data += f".. c:function:: {signature}\n\n" 4241d6fea64SMauro Carvalho Chehab 4251d6fea64SMauro Carvalho Chehab if not args.get('typedef'): 4261d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 4271d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4281d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', "")) 4294fa5e411SMauro Carvalho Chehab self.data += "\n" 4301d6fea64SMauro Carvalho Chehab 4311d6fea64SMauro Carvalho Chehab # Put descriptive text into a container (HTML <div>) to help set 4321d6fea64SMauro Carvalho Chehab # function prototypes apart 4331d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4341d6fea64SMauro Carvalho Chehab 435de6f7ac9SJonathan Corbet if args.parameterlist: 4364fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 4374fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Parameters**\n\n" 4381d6fea64SMauro Carvalho Chehab 439de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 44004a383ceSMauro Carvalho Chehab parameter_name = KernRe(r'\[.*').sub('', parameter) 441de6f7ac9SJonathan Corbet dtype = args.parametertypes.get(parameter, "") 4421d6fea64SMauro Carvalho Chehab 4431d6fea64SMauro Carvalho Chehab if dtype: 4444fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{dtype}``\n" 4451d6fea64SMauro Carvalho Chehab else: 4464fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{parameter}``\n" 4471d6fea64SMauro Carvalho Chehab 448de6f7ac9SJonathan Corbet self.print_lineno(args.parameterdesc_start_lines.get(parameter_name, 0)) 4491d6fea64SMauro Carvalho Chehab 4501d6fea64SMauro Carvalho Chehab self.lineprefix = " " 451de6f7ac9SJonathan Corbet if parameter_name in args.parameterdescs and \ 452de6f7ac9SJonathan Corbet args.parameterdescs[parameter_name] != KernelDoc.undescribed: 4531d6fea64SMauro Carvalho Chehab 454de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs[parameter_name]) 4554fa5e411SMauro Carvalho Chehab self.data += "\n" 4561d6fea64SMauro Carvalho Chehab else: 4574fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}*undescribed*\n\n" 4581d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4591d6fea64SMauro Carvalho Chehab 4601d6fea64SMauro Carvalho Chehab self.out_section(args) 4611d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 4621d6fea64SMauro Carvalho Chehab 4631d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 4641d6fea64SMauro Carvalho Chehab 4651d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 466bd5628bfSJonathan Corbet ln = args.declaration_start_line 4671d6fea64SMauro Carvalho Chehab 4684fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:enum:: {name}\n\n" 4691d6fea64SMauro Carvalho Chehab 4701d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 4711d6fea64SMauro Carvalho Chehab self.lineprefix = " " 4721d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', '')) 4734fa5e411SMauro Carvalho Chehab self.data += "\n" 4741d6fea64SMauro Carvalho Chehab 4754fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 4761d6fea64SMauro Carvalho Chehab outer = self.lineprefix + " " 4771d6fea64SMauro Carvalho Chehab self.lineprefix = outer + " " 4784fa5e411SMauro Carvalho Chehab self.data += f"{outer}**Constants**\n\n" 4791d6fea64SMauro Carvalho Chehab 480de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 4814fa5e411SMauro Carvalho Chehab self.data += f"{outer}``{parameter}``\n" 4821d6fea64SMauro Carvalho Chehab 483de6f7ac9SJonathan Corbet if args.parameterdescs.get(parameter, '') != KernelDoc.undescribed: 484de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs[parameter]) 4851d6fea64SMauro Carvalho Chehab else: 4864fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}*undescribed*\n\n" 4874fa5e411SMauro Carvalho Chehab self.data += "\n" 4881d6fea64SMauro Carvalho Chehab 4891d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 4901d6fea64SMauro Carvalho Chehab self.out_section(args) 4911d6fea64SMauro Carvalho Chehab 4921045ec38SMauro Carvalho Chehab def out_var(self, fname, name, args): 4931045ec38SMauro Carvalho Chehab oldprefix = self.lineprefix 4941045ec38SMauro Carvalho Chehab ln = args.declaration_start_line 4951045ec38SMauro Carvalho Chehab full_proto = args.other_stuff["full_proto"] 4961045ec38SMauro Carvalho Chehab 4971045ec38SMauro Carvalho Chehab self.lineprefix = " " 4981045ec38SMauro Carvalho Chehab 499bdd1cf87SMauro Carvalho Chehab self.data += f"\n\n.. c:macro:: {name}\n\n{self.lineprefix}``{full_proto}``\n\n" 5001045ec38SMauro Carvalho Chehab 5011045ec38SMauro Carvalho Chehab self.print_lineno(ln) 5021045ec38SMauro Carvalho Chehab self.output_highlight(args.get('purpose', '')) 5031045ec38SMauro Carvalho Chehab self.data += "\n" 5041045ec38SMauro Carvalho Chehab 5051045ec38SMauro Carvalho Chehab if args.other_stuff["default_val"]: 5061045ec38SMauro Carvalho Chehab self.data += f'{self.lineprefix}**Initialization**\n\n' 5071045ec38SMauro Carvalho Chehab self.output_highlight(f'default: ``{args.other_stuff["default_val"]}``') 5081045ec38SMauro Carvalho Chehab 5091045ec38SMauro Carvalho Chehab self.out_section(args) 5101045ec38SMauro Carvalho Chehab 5111d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 5121d6fea64SMauro Carvalho Chehab 5131d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 514bd5628bfSJonathan Corbet ln = args.declaration_start_line 5151d6fea64SMauro Carvalho Chehab 5164fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:type:: {name}\n\n" 5171d6fea64SMauro Carvalho Chehab 5181d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 5191d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5201d6fea64SMauro Carvalho Chehab 5211d6fea64SMauro Carvalho Chehab self.output_highlight(args.get('purpose', '')) 5221d6fea64SMauro Carvalho Chehab 5234fa5e411SMauro Carvalho Chehab self.data += "\n" 5241d6fea64SMauro Carvalho Chehab 5251d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 5261d6fea64SMauro Carvalho Chehab self.out_section(args) 5271d6fea64SMauro Carvalho Chehab 5281d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 5291d6fea64SMauro Carvalho Chehab 5301d6fea64SMauro Carvalho Chehab purpose = args.get('purpose', "") 5311d6fea64SMauro Carvalho Chehab declaration = args.get('definition', "") 532bd5628bfSJonathan Corbet dtype = args.type 533bd5628bfSJonathan Corbet ln = args.declaration_start_line 5341d6fea64SMauro Carvalho Chehab 5354fa5e411SMauro Carvalho Chehab self.data += f"\n\n.. c:{dtype}:: {name}\n\n" 5361d6fea64SMauro Carvalho Chehab 5371d6fea64SMauro Carvalho Chehab self.print_lineno(ln) 5381d6fea64SMauro Carvalho Chehab 5391d6fea64SMauro Carvalho Chehab oldprefix = self.lineprefix 5401d6fea64SMauro Carvalho Chehab self.lineprefix += " " 5411d6fea64SMauro Carvalho Chehab 5421d6fea64SMauro Carvalho Chehab self.output_highlight(purpose) 5434fa5e411SMauro Carvalho Chehab self.data += "\n" 5441d6fea64SMauro Carvalho Chehab 5454fa5e411SMauro Carvalho Chehab self.data += ".. container:: kernelindent\n\n" 5464fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Definition**::\n\n" 5471d6fea64SMauro Carvalho Chehab 5481d6fea64SMauro Carvalho Chehab self.lineprefix = self.lineprefix + " " 5491d6fea64SMauro Carvalho Chehab 5501d6fea64SMauro Carvalho Chehab declaration = declaration.replace("\t", self.lineprefix) 5511d6fea64SMauro Carvalho Chehab 5524fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}{dtype} {name}" + ' {' + "\n" 5534fa5e411SMauro Carvalho Chehab self.data += f"{declaration}{self.lineprefix}" + "};\n\n" 5541d6fea64SMauro Carvalho Chehab 5551d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5564fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}**Members**\n\n" 557de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 5581d6fea64SMauro Carvalho Chehab if not parameter or parameter.startswith("#"): 5591d6fea64SMauro Carvalho Chehab continue 5601d6fea64SMauro Carvalho Chehab 5611d6fea64SMauro Carvalho Chehab parameter_name = parameter.split("[", maxsplit=1)[0] 5621d6fea64SMauro Carvalho Chehab 563de6f7ac9SJonathan Corbet if args.parameterdescs.get(parameter_name) == KernelDoc.undescribed: 5641d6fea64SMauro Carvalho Chehab continue 5651d6fea64SMauro Carvalho Chehab 566de6f7ac9SJonathan Corbet self.print_lineno(args.parameterdesc_start_lines.get(parameter_name, 0)) 5671d6fea64SMauro Carvalho Chehab 5684fa5e411SMauro Carvalho Chehab self.data += f"{self.lineprefix}``{parameter}``\n" 5691d6fea64SMauro Carvalho Chehab 5701d6fea64SMauro Carvalho Chehab self.lineprefix = " " 571de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs[parameter_name]) 5721d6fea64SMauro Carvalho Chehab self.lineprefix = " " 5731d6fea64SMauro Carvalho Chehab 5744fa5e411SMauro Carvalho Chehab self.data += "\n" 5751d6fea64SMauro Carvalho Chehab 5764fa5e411SMauro Carvalho Chehab self.data += "\n" 5771d6fea64SMauro Carvalho Chehab 5781d6fea64SMauro Carvalho Chehab self.lineprefix = oldprefix 5791d6fea64SMauro Carvalho Chehab self.out_section(args) 5801d6fea64SMauro Carvalho Chehab 5811d6fea64SMauro Carvalho Chehab 5821d6fea64SMauro Carvalho Chehabclass ManFormat(OutputFormat): 583*245f1ab2SMauro Carvalho Chehab """Consts and functions used by man pages output.""" 5841d6fea64SMauro Carvalho Chehab 5851d6fea64SMauro Carvalho Chehab highlights = ( 5861d6fea64SMauro Carvalho Chehab (type_constant, r"\1"), 5871d6fea64SMauro Carvalho Chehab (type_constant2, r"\1"), 5881d6fea64SMauro Carvalho Chehab (type_func, r"\\fB\1\\fP"), 5891d6fea64SMauro Carvalho Chehab (type_enum, r"\\fI\1\\fP"), 5901d6fea64SMauro Carvalho Chehab (type_struct, r"\\fI\1\\fP"), 5911d6fea64SMauro Carvalho Chehab (type_typedef, r"\\fI\1\\fP"), 5921d6fea64SMauro Carvalho Chehab (type_union, r"\\fI\1\\fP"), 5931d6fea64SMauro Carvalho Chehab (type_param, r"\\fI\1\\fP"), 5941d6fea64SMauro Carvalho Chehab (type_param_ref, r"\\fI\1\2\\fP"), 5951d6fea64SMauro Carvalho Chehab (type_member, r"\\fI\1\2\3\\fP"), 5961d6fea64SMauro Carvalho Chehab (type_fallback, r"\\fI\1\\fP") 5971d6fea64SMauro Carvalho Chehab ) 5981d6fea64SMauro Carvalho Chehab blankline = "" 5991d6fea64SMauro Carvalho Chehab 600*245f1ab2SMauro Carvalho Chehab #: Allowed timestamp formats. 60191d00bd5SMauro Carvalho Chehab date_formats = [ 60291d00bd5SMauro Carvalho Chehab "%a %b %d %H:%M:%S %Z %Y", 60391d00bd5SMauro Carvalho Chehab "%a %b %d %H:%M:%S %Y", 60491d00bd5SMauro Carvalho Chehab "%Y-%m-%d", 60591d00bd5SMauro Carvalho Chehab "%b %d %Y", 60691d00bd5SMauro Carvalho Chehab "%B %d %Y", 60791d00bd5SMauro Carvalho Chehab "%m %d %Y", 60891d00bd5SMauro Carvalho Chehab ] 60991d00bd5SMauro Carvalho Chehab 6102ab867a4SMauro Carvalho Chehab def __init__(self, modulename): 6111d6fea64SMauro Carvalho Chehab """ 6121d6fea64SMauro Carvalho Chehab Creates class variables. 6131d6fea64SMauro Carvalho Chehab 6141d6fea64SMauro Carvalho Chehab Not really mandatory, but it is a good coding style and makes 6151d6fea64SMauro Carvalho Chehab pylint happy. 6161d6fea64SMauro Carvalho Chehab """ 6171d6fea64SMauro Carvalho Chehab 6181d6fea64SMauro Carvalho Chehab super().__init__() 6192ab867a4SMauro Carvalho Chehab self.modulename = modulename 620104e0a68SMauro Carvalho Chehab self.symbols = [] 6211d6fea64SMauro Carvalho Chehab 62291d00bd5SMauro Carvalho Chehab dt = None 62391d00bd5SMauro Carvalho Chehab tstamp = os.environ.get("KBUILD_BUILD_TIMESTAMP") 62491d00bd5SMauro Carvalho Chehab if tstamp: 62591d00bd5SMauro Carvalho Chehab for fmt in self.date_formats: 62691d00bd5SMauro Carvalho Chehab try: 62791d00bd5SMauro Carvalho Chehab dt = datetime.strptime(tstamp, fmt) 62891d00bd5SMauro Carvalho Chehab break 62991d00bd5SMauro Carvalho Chehab except ValueError: 63091d00bd5SMauro Carvalho Chehab pass 63191d00bd5SMauro Carvalho Chehab 63291d00bd5SMauro Carvalho Chehab if not dt: 6331d6fea64SMauro Carvalho Chehab dt = datetime.now() 6341d6fea64SMauro Carvalho Chehab 6351d6fea64SMauro Carvalho Chehab self.man_date = dt.strftime("%B %Y") 6361d6fea64SMauro Carvalho Chehab 637104e0a68SMauro Carvalho Chehab def arg_name(self, args, name): 638104e0a68SMauro Carvalho Chehab """ 639104e0a68SMauro Carvalho Chehab Return the name that will be used for the man page. 640104e0a68SMauro Carvalho Chehab 641104e0a68SMauro Carvalho Chehab As we may have the same name on different namespaces, 642104e0a68SMauro Carvalho Chehab prepend the data type for all types except functions and typedefs. 643104e0a68SMauro Carvalho Chehab 644104e0a68SMauro Carvalho Chehab The doc section is special: it uses the modulename. 645104e0a68SMauro Carvalho Chehab """ 646104e0a68SMauro Carvalho Chehab 647104e0a68SMauro Carvalho Chehab dtype = args.type 648104e0a68SMauro Carvalho Chehab 649104e0a68SMauro Carvalho Chehab if dtype == "doc": 650104e0a68SMauro Carvalho Chehab return self.modulename 651104e0a68SMauro Carvalho Chehab 652104e0a68SMauro Carvalho Chehab if dtype in ["function", "typedef"]: 653104e0a68SMauro Carvalho Chehab return name 654104e0a68SMauro Carvalho Chehab 655104e0a68SMauro Carvalho Chehab return f"{dtype} {name}" 656104e0a68SMauro Carvalho Chehab 657104e0a68SMauro Carvalho Chehab def set_symbols(self, symbols): 658104e0a68SMauro Carvalho Chehab """ 659104e0a68SMauro Carvalho Chehab Get a list of all symbols from kernel_doc. 660104e0a68SMauro Carvalho Chehab 661104e0a68SMauro Carvalho Chehab Man pages will uses it to add a SEE ALSO section with other 662104e0a68SMauro Carvalho Chehab symbols at the same file. 663104e0a68SMauro Carvalho Chehab """ 664104e0a68SMauro Carvalho Chehab self.symbols = symbols 665104e0a68SMauro Carvalho Chehab 666104e0a68SMauro Carvalho Chehab def out_tail(self, fname, name, args): 667*245f1ab2SMauro Carvalho Chehab """Adds a tail for all man pages.""" 668104e0a68SMauro Carvalho Chehab 669104e0a68SMauro Carvalho Chehab # SEE ALSO section 6702bd22194SMauro Carvalho Chehab self.data += f'.SH "SEE ALSO"' + "\n.PP\n" 6712bd22194SMauro Carvalho Chehab self.data += (f"Kernel file \\fB{args.fname}\\fR\n") 672104e0a68SMauro Carvalho Chehab if len(self.symbols) >= 2: 673104e0a68SMauro Carvalho Chehab cur_name = self.arg_name(args, name) 674104e0a68SMauro Carvalho Chehab 675104e0a68SMauro Carvalho Chehab related = [] 676104e0a68SMauro Carvalho Chehab for arg in self.symbols: 677104e0a68SMauro Carvalho Chehab out_name = self.arg_name(arg, arg.name) 678104e0a68SMauro Carvalho Chehab 679104e0a68SMauro Carvalho Chehab if cur_name == out_name: 680104e0a68SMauro Carvalho Chehab continue 681104e0a68SMauro Carvalho Chehab 682104e0a68SMauro Carvalho Chehab related.append(f"\\fB{out_name}\\fR(9)") 683104e0a68SMauro Carvalho Chehab 684104e0a68SMauro Carvalho Chehab self.data += ",\n".join(related) + "\n" 685104e0a68SMauro Carvalho Chehab 686104e0a68SMauro Carvalho Chehab # TODO: does it make sense to add other sections? Maybe 687104e0a68SMauro Carvalho Chehab # REPORTING ISSUES? LICENSE? 688104e0a68SMauro Carvalho Chehab 689104e0a68SMauro Carvalho Chehab def msg(self, fname, name, args): 690104e0a68SMauro Carvalho Chehab """ 691104e0a68SMauro Carvalho Chehab Handles a single entry from kernel-doc parser. 692104e0a68SMauro Carvalho Chehab 693104e0a68SMauro Carvalho Chehab Add a tail at the end of man pages output. 694104e0a68SMauro Carvalho Chehab """ 695104e0a68SMauro Carvalho Chehab super().msg(fname, name, args) 696104e0a68SMauro Carvalho Chehab self.out_tail(fname, name, args) 697104e0a68SMauro Carvalho Chehab 698104e0a68SMauro Carvalho Chehab return self.data 699104e0a68SMauro Carvalho Chehab 7001d6fea64SMauro Carvalho Chehab def output_highlight(self, block): 701485f6f79SMauro Carvalho Chehab """ 702485f6f79SMauro Carvalho Chehab Outputs a C symbol that may require being highlighted with 703*245f1ab2SMauro Carvalho Chehab self.highlights variable using troff syntax. 704485f6f79SMauro Carvalho Chehab """ 7051d6fea64SMauro Carvalho Chehab 7061d6fea64SMauro Carvalho Chehab contents = self.highlight_block(block) 7071d6fea64SMauro Carvalho Chehab 7081d6fea64SMauro Carvalho Chehab if isinstance(contents, list): 7091d6fea64SMauro Carvalho Chehab contents = "\n".join(contents) 7101d6fea64SMauro Carvalho Chehab 7111d6fea64SMauro Carvalho Chehab for line in contents.strip("\n").split("\n"): 71204a383ceSMauro Carvalho Chehab line = KernRe(r"^\s*").sub("", line) 713408269aeSMauro Carvalho Chehab if not line: 714408269aeSMauro Carvalho Chehab continue 7151d6fea64SMauro Carvalho Chehab 716408269aeSMauro Carvalho Chehab if line[0] == ".": 7174fa5e411SMauro Carvalho Chehab self.data += "\\&" + line + "\n" 7181d6fea64SMauro Carvalho Chehab else: 7194fa5e411SMauro Carvalho Chehab self.data += line + "\n" 7201d6fea64SMauro Carvalho Chehab 7211d6fea64SMauro Carvalho Chehab def out_doc(self, fname, name, args): 7229cbc2d3bSMauro Carvalho Chehab if not self.check_doc(name, args): 723408269aeSMauro Carvalho Chehab return 724408269aeSMauro Carvalho Chehab 725104e0a68SMauro Carvalho Chehab out_name = self.arg_name(args, name) 726104e0a68SMauro Carvalho Chehab 727104e0a68SMauro Carvalho Chehab self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 7281d6fea64SMauro Carvalho Chehab 7298d733875SJonathan Corbet for section, text in args.sections.items(): 7304fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 7318d733875SJonathan Corbet self.output_highlight(text) 7321d6fea64SMauro Carvalho Chehab 7331d6fea64SMauro Carvalho Chehab def out_function(self, fname, name, args): 7341d6fea64SMauro Carvalho Chehab 735104e0a68SMauro Carvalho Chehab out_name = self.arg_name(args, name) 736104e0a68SMauro Carvalho Chehab 737104e0a68SMauro Carvalho Chehab self.data += f'.TH "{name}" 9 "{out_name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n" 7381d6fea64SMauro Carvalho Chehab 7394fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 740a0db2051SJonathan Corbet self.data += f"{name} \\- {args['purpose']}\n" 7411d6fea64SMauro Carvalho Chehab 7424fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 7431d6fea64SMauro Carvalho Chehab if args.get('functiontype', ''): 744a0db2051SJonathan Corbet self.data += f'.B "{args["functiontype"]}" {name}' + "\n" 7451d6fea64SMauro Carvalho Chehab else: 746a0db2051SJonathan Corbet self.data += f'.B "{name}' + "\n" 7471d6fea64SMauro Carvalho Chehab 7481d6fea64SMauro Carvalho Chehab count = 0 7491d6fea64SMauro Carvalho Chehab parenth = "(" 7501d6fea64SMauro Carvalho Chehab post = "," 7511d6fea64SMauro Carvalho Chehab 752de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 753de6f7ac9SJonathan Corbet if count == len(args.parameterlist) - 1: 7541d6fea64SMauro Carvalho Chehab post = ");" 7551d6fea64SMauro Carvalho Chehab 756de6f7ac9SJonathan Corbet dtype = args.parametertypes.get(parameter, "") 7571d6fea64SMauro Carvalho Chehab if function_pointer.match(dtype): 7581d6fea64SMauro Carvalho Chehab # Pointer-to-function 7594fa5e411SMauro Carvalho Chehab self.data += f'".BI "{parenth}{function_pointer.group(1)}" " ") ({function_pointer.group(2)}){post}"' + "\n" 7601d6fea64SMauro Carvalho Chehab else: 76104a383ceSMauro Carvalho Chehab dtype = KernRe(r'([^\*])$').sub(r'\1 ', dtype) 7621d6fea64SMauro Carvalho Chehab 7634fa5e411SMauro Carvalho Chehab self.data += f'.BI "{parenth}{dtype}" "{post}"' + "\n" 7641d6fea64SMauro Carvalho Chehab count += 1 7651d6fea64SMauro Carvalho Chehab parenth = "" 7661d6fea64SMauro Carvalho Chehab 767de6f7ac9SJonathan Corbet if args.parameterlist: 7684fa5e411SMauro Carvalho Chehab self.data += ".SH ARGUMENTS\n" 7691d6fea64SMauro Carvalho Chehab 770de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 7711d6fea64SMauro Carvalho Chehab parameter_name = re.sub(r'\[.*', '', parameter) 7721d6fea64SMauro Carvalho Chehab 7734fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 774de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs.get(parameter_name, "")) 7751d6fea64SMauro Carvalho Chehab 7768d733875SJonathan Corbet for section, text in args.sections.items(): 7774fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section.upper()}"' + "\n" 7788d733875SJonathan Corbet self.output_highlight(text) 7791d6fea64SMauro Carvalho Chehab 7801d6fea64SMauro Carvalho Chehab def out_enum(self, fname, name, args): 781104e0a68SMauro Carvalho Chehab out_name = self.arg_name(args, name) 782104e0a68SMauro Carvalho Chehab 783104e0a68SMauro Carvalho Chehab self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 7841d6fea64SMauro Carvalho Chehab 7854fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 786a0db2051SJonathan Corbet self.data += f"enum {name} \\- {args['purpose']}\n" 7871d6fea64SMauro Carvalho Chehab 7884fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 789a0db2051SJonathan Corbet self.data += f"enum {name}" + " {\n" 7901d6fea64SMauro Carvalho Chehab 7911d6fea64SMauro Carvalho Chehab count = 0 792de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 7934fa5e411SMauro Carvalho Chehab self.data += f'.br\n.BI " {parameter}"' + "\n" 794de6f7ac9SJonathan Corbet if count == len(args.parameterlist) - 1: 7954fa5e411SMauro Carvalho Chehab self.data += "\n};\n" 7961d6fea64SMauro Carvalho Chehab else: 7974fa5e411SMauro Carvalho Chehab self.data += ", \n.br\n" 7981d6fea64SMauro Carvalho Chehab 7991d6fea64SMauro Carvalho Chehab count += 1 8001d6fea64SMauro Carvalho Chehab 8014fa5e411SMauro Carvalho Chehab self.data += ".SH Constants\n" 8021d6fea64SMauro Carvalho Chehab 803de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 80404a383ceSMauro Carvalho Chehab parameter_name = KernRe(r'\[.*').sub('', parameter) 8054fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 806de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs.get(parameter_name, "")) 8071d6fea64SMauro Carvalho Chehab 8088d733875SJonathan Corbet for section, text in args.sections.items(): 8094fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 8108d733875SJonathan Corbet self.output_highlight(text) 8111d6fea64SMauro Carvalho Chehab 8121045ec38SMauro Carvalho Chehab def out_var(self, fname, name, args): 8131045ec38SMauro Carvalho Chehab out_name = self.arg_name(args, name) 8141045ec38SMauro Carvalho Chehab full_proto = args.other_stuff["full_proto"] 8151045ec38SMauro Carvalho Chehab 8161045ec38SMauro Carvalho Chehab self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 8171045ec38SMauro Carvalho Chehab 8181045ec38SMauro Carvalho Chehab self.data += ".SH NAME\n" 819bdd1cf87SMauro Carvalho Chehab self.data += f"{name} \\- {args['purpose']}\n" 8201045ec38SMauro Carvalho Chehab 8211045ec38SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 8221045ec38SMauro Carvalho Chehab self.data += f"{full_proto}\n" 8231045ec38SMauro Carvalho Chehab 8241045ec38SMauro Carvalho Chehab if args.other_stuff["default_val"]: 8251045ec38SMauro Carvalho Chehab self.data += f'.SH "Initialization"' + "\n" 8261045ec38SMauro Carvalho Chehab self.output_highlight(f'default: {args.other_stuff["default_val"]}') 8271045ec38SMauro Carvalho Chehab 8281045ec38SMauro Carvalho Chehab for section, text in args.sections.items(): 8291045ec38SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 8301045ec38SMauro Carvalho Chehab self.output_highlight(text) 8311045ec38SMauro Carvalho Chehab 8321d6fea64SMauro Carvalho Chehab def out_typedef(self, fname, name, args): 8332ab867a4SMauro Carvalho Chehab module = self.modulename 8341d6fea64SMauro Carvalho Chehab purpose = args.get('purpose') 835104e0a68SMauro Carvalho Chehab out_name = self.arg_name(args, name) 8361d6fea64SMauro Carvalho Chehab 837104e0a68SMauro Carvalho Chehab self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 8381d6fea64SMauro Carvalho Chehab 8394fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 840a0db2051SJonathan Corbet self.data += f"typedef {name} \\- {purpose}\n" 8411d6fea64SMauro Carvalho Chehab 8428d733875SJonathan Corbet for section, text in args.sections.items(): 8434fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 8448d733875SJonathan Corbet self.output_highlight(text) 8451d6fea64SMauro Carvalho Chehab 8461d6fea64SMauro Carvalho Chehab def out_struct(self, fname, name, args): 8472ab867a4SMauro Carvalho Chehab module = self.modulename 8481d6fea64SMauro Carvalho Chehab purpose = args.get('purpose') 8491d6fea64SMauro Carvalho Chehab definition = args.get('definition') 850104e0a68SMauro Carvalho Chehab out_name = self.arg_name(args, name) 8511d6fea64SMauro Carvalho Chehab 852104e0a68SMauro Carvalho Chehab self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n" 8531d6fea64SMauro Carvalho Chehab 8544fa5e411SMauro Carvalho Chehab self.data += ".SH NAME\n" 855a0db2051SJonathan Corbet self.data += f"{args.type} {name} \\- {purpose}\n" 8561d6fea64SMauro Carvalho Chehab 8571d6fea64SMauro Carvalho Chehab # Replace tabs with two spaces and handle newlines 8581d6fea64SMauro Carvalho Chehab declaration = definition.replace("\t", " ") 85904a383ceSMauro Carvalho Chehab declaration = KernRe(r"\n").sub('"\n.br\n.BI "', declaration) 8601d6fea64SMauro Carvalho Chehab 8614fa5e411SMauro Carvalho Chehab self.data += ".SH SYNOPSIS\n" 862a0db2051SJonathan Corbet self.data += f"{args.type} {name} " + "{" + "\n.br\n" 8634fa5e411SMauro Carvalho Chehab self.data += f'.BI "{declaration}\n' + "};\n.br\n\n" 8641d6fea64SMauro Carvalho Chehab 8654fa5e411SMauro Carvalho Chehab self.data += ".SH Members\n" 866de6f7ac9SJonathan Corbet for parameter in args.parameterlist: 8671d6fea64SMauro Carvalho Chehab if parameter.startswith("#"): 8681d6fea64SMauro Carvalho Chehab continue 8691d6fea64SMauro Carvalho Chehab 8701d6fea64SMauro Carvalho Chehab parameter_name = re.sub(r"\[.*", "", parameter) 8711d6fea64SMauro Carvalho Chehab 872de6f7ac9SJonathan Corbet if args.parameterdescs.get(parameter_name) == KernelDoc.undescribed: 8731d6fea64SMauro Carvalho Chehab continue 8741d6fea64SMauro Carvalho Chehab 8754fa5e411SMauro Carvalho Chehab self.data += f'.IP "{parameter}" 12' + "\n" 876de6f7ac9SJonathan Corbet self.output_highlight(args.parameterdescs.get(parameter_name)) 8771d6fea64SMauro Carvalho Chehab 8788d733875SJonathan Corbet for section, text in args.sections.items(): 8794fa5e411SMauro Carvalho Chehab self.data += f'.SH "{section}"' + "\n" 8808d733875SJonathan Corbet self.output_highlight(text) 881