Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: sphinx/kernel_abi: parse ABI files only once

Right now, the logic parses ABI files on 4 steps, one for each
directory. While this is fine in principle, by doing that, not
all symbol cross-references will be created.

Change the logic to do the parsing only once in order to get
a global dictionary to be used when creating ABI cross-references.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/5205c53838b6ea25f4cdd4cc1e3d17c0141e75a6.1739182025.git.mchehab+huawei@kernel.org

authored by

Mauro Carvalho Chehab and committed by
Jonathan Corbet
5d7871d7 98a4324a

+76 -59
+1 -1
Documentation/admin-guide/abi-obsolete.rst
··· 9 9 The description of the interface will document the reason why it is 10 10 obsolete and when it can be expected to be removed. 11 11 12 - .. kernel-abi:: ABI/obsolete 12 + .. kernel-abi:: obsolete
+1 -1
Documentation/admin-guide/abi-removed.rst
··· 3 3 ABI removed symbols 4 4 =================== 5 5 6 - .. kernel-abi:: ABI/removed 6 + .. kernel-abi:: removed
+1 -1
Documentation/admin-guide/abi-stable.rst
··· 12 12 Most interfaces (like syscalls) are expected to never change and always 13 13 be available. 14 14 15 - .. kernel-abi:: ABI/stable 15 + .. kernel-abi:: stable
+1 -1
Documentation/admin-guide/abi-testing.rst
··· 18 18 name to the description of these interfaces, so that the kernel 19 19 developers can easily notify them if any changes occur. 20 20 21 - .. kernel-abi:: ABI/testing 21 + .. kernel-abi:: testing
+59 -46
Documentation/sphinx/kernel_abi.py
··· 49 49 50 50 __version__ = "1.0" 51 51 52 + logger = logging.getLogger('kernel_abi') 53 + path = os.path.join(srctree, "Documentation/ABI") 54 + 55 + # Parse ABI symbols only once 56 + kernel_abi = AbiParser(path, logger=logger) 57 + kernel_abi.parse_abi() 58 + kernel_abi.check_issues() 52 59 53 60 def setup(app): 54 61 ··· 71 64 u"""KernelABI (``kernel-abi``) directive""" 72 65 73 66 required_arguments = 1 74 - optional_arguments = 2 67 + optional_arguments = 3 75 68 has_content = False 76 69 final_argument_whitespace = True 77 - logger = logging.getLogger('kernel_abi') 78 70 parser = None 79 71 80 72 option_spec = { 81 73 "debug": directives.flag, 74 + "no-symbols": directives.flag, 75 + "no-files": directives.flag, 82 76 } 83 77 84 78 def run(self): ··· 87 79 if not doc.settings.file_insertion_enabled: 88 80 raise self.warning("docutils: file insertion disabled") 89 81 90 - path = os.path.join(srctree, "Documentation", self.arguments[0]) 91 - self.parser = AbiParser(path, logger=self.logger) 92 - self.parser.parse_abi() 93 - self.parser.check_issues() 94 - 95 - node = self.nested_parse(None, self.arguments[0]) 96 - return node 97 - 98 - def nested_parse(self, data, fname): 99 82 env = self.state.document.settings.env 100 83 content = ViewList() 101 84 node = nodes.section() 102 85 103 - if data is not None: 104 - # Handles the .rst file 105 - for line in data.split("\n"): 106 - content.append(line, fname, 0) 86 + abi_type = self.arguments[0] 107 87 108 - self.do_parse(content, node) 109 - 88 + if "no-symbols" in self.options: 89 + show_symbols = False 110 90 else: 111 - # Handles the ABI parser content, symbol by symbol 91 + show_symbols = True 112 92 113 - old_f = fname 114 - n = 0 115 - for msg, f, ln in self.parser.doc(): 116 - msg_list = statemachine.string2lines(msg, tab_width, 117 - convert_whitespace=True) 118 - if "debug" in self.options: 119 - lines = [ 120 - "", "", ".. code-block:: rst", 121 - " :linenos:", "" 122 - ] 123 - for m in msg_list: 124 - lines.append(" " + m) 125 - else: 126 - lines = msg_list 93 + if "no-files" in self.options: 94 + show_file = False 95 + else: 96 + show_file = True 127 97 128 - for line in lines: 129 - # sphinx counts lines from 0 130 - content.append(line, f, ln - 1) 131 - n += 1 98 + tab_width = self.options.get('tab-width', 99 + self.state.document.settings.tab_width) 132 100 133 - if f != old_f: 134 - # Add the file to Sphinx build dependencies 135 - env.note_dependency(os.path.abspath(f)) 101 + old_f = None 102 + n = 0 103 + n_sym = 0 104 + for msg, f, ln in kernel_abi.doc(show_file=show_file, 105 + show_symbols=show_symbols, 106 + filter_path=abi_type): 107 + n_sym += 1 108 + msg_list = statemachine.string2lines(msg, tab_width, 109 + convert_whitespace=True) 110 + if "debug" in self.options: 111 + lines = [ 112 + "", "", ".. code-block:: rst", 113 + " :linenos:", "" 114 + ] 115 + for m in msg_list: 116 + lines.append(" " + m) 117 + else: 118 + lines = msg_list 136 119 137 - old_f = f 120 + for line in lines: 121 + # sphinx counts lines from 0 122 + content.append(line, f, ln - 1) 123 + n += 1 138 124 139 - # Sphinx doesn't like to parse big messages. So, let's 140 - # add content symbol by symbol 141 - if content: 142 - self.do_parse(content, node) 143 - content = ViewList() 125 + if f != old_f: 126 + # Add the file to Sphinx build dependencies 127 + env.note_dependency(os.path.abspath(f)) 144 128 145 - self.logger.info("%s: parsed %i lines" % (fname, n)) 129 + old_f = f 130 + 131 + # Sphinx doesn't like to parse big messages. So, let's 132 + # add content symbol by symbol 133 + if content: 134 + self.do_parse(content, node) 135 + content = ViewList() 136 + 137 + if show_symbols and not show_file: 138 + logger.verbose("%s ABI: %i symbols (%i ReST lines)" % (abi_type, n_sym, n)) 139 + elif not show_symbols and show_file: 140 + logger.verbose("%s ABI: %i files (%i ReST lines)" % (abi_type, n_sym, n)) 141 + else: 142 + logger.verbose("%s ABI: %i data (%i ReST lines)" % (abi_type, n_sym, n)) 146 143 147 144 return node.children 148 145
+13 -9
scripts/lib/abi/abi_parser.py
··· 266 266 def parse_readme(self, nametag, fname): 267 267 """Parse ABI README file""" 268 268 269 + nametag["what"] = ["ABI file contents"] 270 + nametag["path"] = "README" 269 271 with open(fname, "r", encoding="utf8", errors="backslashreplace") as fp: 270 - nametag["description"] = "```\n" 271 272 for line in fp: 272 - nametag["description"] += " " + line 273 + match = self.re_tag.match(line) 274 + if match: 275 + new = match.group(1).lower() 273 276 274 - nametag["description"] += "```\n" 277 + match = self.re_valid.search(new) 278 + if match: 279 + nametag["description"] += "\n:" + line 280 + continue 281 + 282 + nametag["description"] += line 275 283 276 284 def parse_file(self, fname, path, basename): 277 285 """Parse a single file""" ··· 467 459 continue 468 460 469 461 if filter_path: 470 - if filter_path == "README": 471 - if not names[0].endswith("README"): 472 - continue 473 - else: 474 - if v.get("path") != filter_path: 475 - continue 462 + if v.get("path") != filter_path: 463 + continue 476 464 477 465 msg = "" 478 466