History

docs: kernel-doc: add support to store output on a YAML file

Add a command line parameter and library support to optionally store: - KdocItem intermediate format after parsing; - man pages output; - rst output. inside a YAML file.

Mauro Carvalho Chehab committed 7 months ago

Commit 01d6d7b1 parent b37b3cb3 files · +107 −15Browse files

Showing the changes to tools/lib/python (2 of 3 files). Show all

Unified · Split

2 files
  1. tools/lib/python/kdoc/kdoc_files.py +41 −6
  2. tools/lib/python/kdoc/kdoc_parser.py +26 −1
tools/lib/python/kdoc/kdoc_files.py+41−6
@@ -16,6 +16,7 @@ import re · 15 unmodified lines
16from kdoc.kdoc_parser import KernelDoc16from kdoc.kdoc_parser import KernelDoc
17from kdoc.xforms_lists import CTransforms17from kdoc.xforms_lists import CTransforms
18from kdoc.kdoc_output import OutputFormat18from kdoc.kdoc_output import OutputFormat
19from kdoc.kdoc_yaml_file import KDocTestFile
19 20
20 21
21class GlobSourceFiles:22class GlobSourceFiles:
@@ -152,6 +153,12 @@ class KernelFiles(): · 130 unmodified lines
152 153
153 If not specified, defaults to use: ``logging.getLogger("kernel-doc")``154 If not specified, defaults to use: ``logging.getLogger("kernel-doc")``
154 155
156 ``yaml_file``
157 If defined, stores the output inside a YAML file.
158
159 ``yaml_content``
160 Defines what will be inside the YAML file.
161
155 Note:162 Note:
156 There are two type of parsers defined here:163 There are two type of parsers defined here:
157 164
@@ -181,7 +188,12 @@ class KernelFiles(): · 23 unmodified lines
181 if fname in self.files:188 if fname in self.files:
182 return189 return
183 190
184 doc = KernelDoc(self.config, fname, self.xforms)191 if self.test_file:
192 store_src = True
193 else:
194 store_src = False
195
196 doc = KernelDoc(self.config, fname, self.xforms, store_src=store_src)
185 export_table, entries = doc.parse_kdoc()197 export_table, entries = doc.parse_kdoc()
186 198
187 self.export_table[fname] = export_table199 self.export_table[fname] = export_table
@@ -191,6 +203,10 @@ class KernelFiles(): · 3 unmodified lines
191 203
192 self.results[fname] = entries204 self.results[fname] = entries
193 205
206 source = doc.get_source()
207 if source:
208 self.source[fname] = source
209
194 def process_export_file(self, fname):210 def process_export_file(self, fname):
195 """211 """
196 Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file.212 Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file.
@@ -220,7 +236,7 @@ class KernelFiles(): · 23 unmodified lines
220 def __init__(self, verbose=False, out_style=None, xforms=None,236 def __init__(self, verbose=False, out_style=None, xforms=None,
221 werror=False, wreturn=False, wshort_desc=False,237 werror=False, wreturn=False, wshort_desc=False,
222 wcontents_before_sections=False,238 wcontents_before_sections=False,
223 logger=None):239 yaml_file=None, yaml_content=None, logger=None):
224 """240 """
225 Initialize startup variables and parse all files.241 Initialize startup variables and parse all files.
226 """242 """
@@ -259,6 +275,11 @@ class KernelFiles(): · 32 unmodified lines
259 # Override log warning, as we want to count errors275 # Override log warning, as we want to count errors
260 self.config.warning = self.warning276 self.config.warning = self.warning
261 277
278 if yaml_file:
279 self.test_file = KDocTestFile(self.config, yaml_file, yaml_content)
280 else:
281 self.test_file = None
282
262 if xforms:283 if xforms:
263 self.xforms = xforms284 self.xforms = xforms
264 else:285 else:
@@ -273,6 +294,7 @@ class KernelFiles(): · 8 unmodified lines
273 294
274 self.errors = 0295 self.errors = 0
275 self.results = {}296 self.results = {}
297 self.source = {}
276 298
277 self.files = set()299 self.files = set()
278 self.export_files = set()300 self.export_files = set()
@@ -331,16 +353,29 @@ class KernelFiles(): · 52 unmodified lines
331 for s in symbol:353 for s in symbol:
332 function_table.add(s)354 function_table.add(s)
333 355
334 self.out_style.set_filter(export, internal, symbol, nosymbol,
335 function_table, enable_lineno,
336 no_doc_sections)
337
338 if fname not in self.results:356 if fname not in self.results:
339 self.config.log.warning("No kernel-doc for file %s", fname)357 self.config.log.warning("No kernel-doc for file %s", fname)
340 continue358 continue
341 359
342 symbols = self.results[fname]360 symbols = self.results[fname]
343 361
362 if self.test_file:
363 self.test_file.set_filter(export, internal, symbol, nosymbol,
364 function_table, enable_lineno,
365 no_doc_sections)
366
367 self.test_file.output_symbols(fname, symbols,
368 self.source.get(fname))
369
370 continue
371
372 self.out_style.set_filter(export, internal, symbol, nosymbol,
373 function_table, enable_lineno,
374 no_doc_sections)
375
344 msg = self.out_style.output_symbols(fname, symbols)376 msg = self.out_style.output_symbols(fname, symbols)
345 if msg:377 if msg:
346 yield fname, msg378 yield fname, msg
379
380 if self.test_file:
381 self.test_file.write()
tools/lib/python/kdoc/kdoc_parser.py+26−1
@@ -246,12 +246,13 @@ class KernelDoc: · 245 unmodified lines
246 #: String to write when a parameter is not described.246 #: String to write when a parameter is not described.
247 undescribed = "-- undescribed --"247 undescribed = "-- undescribed --"
248 248
249 def __init__(self, config, fname, xforms):249 def __init__(self, config, fname, xforms, store_src=False):
250 """Initialize internal variables"""250 """Initialize internal variables"""
251 251
252 self.fname = fname252 self.fname = fname
253 self.config = config253 self.config = config
254 self.xforms = xforms254 self.xforms = xforms
255 self.store_src = store_src
255 256
256 tokenizer_set_log(self.config.log, f"{self.fname}: CMatch: ")257 tokenizer_set_log(self.config.log, f"{self.fname}: CMatch: ")
257 258
@@ -264,6 +265,9 @@ class KernelDoc: · 6 unmodified lines
264 # Place all potential outputs into an array265 # Place all potential outputs into an array
265 self.entries = []266 self.entries = []
266 267
268 # When store_src is true, the kernel-doc source content is stored here
269 self.source = None
270
267 #271 #
268 # We need Python 3.7 for its "dicts remember the insertion272 # We need Python 3.7 for its "dicts remember the insertion
269 # order" guarantee273 # order" guarantee
@@ -1592,6 +1596,15 @@ class KernelDoc: · 1322 unmodified lines
1592 state.DOCBLOCK: process_docblock,1596 state.DOCBLOCK: process_docblock,
1593 }1597 }
1594 1598
1599 def get_source(self):
1600 """
1601 Return the file content of the lines handled by kernel-doc at the
1602 latest parse_kdoc() run.
1603
1604 Returns none if KernelDoc() was not initialized with store_src,
1605 """
1606 return self.source
1607
1595 def parse_kdoc(self):1608 def parse_kdoc(self):
1596 """1609 """
1597 Open and process each line of a C source file.1610 Open and process each line of a C source file.
@@ -1605,6 +1618,8 @@ class KernelDoc: · 7 unmodified lines
1605 prev = ""1618 prev = ""
1606 prev_ln = None1619 prev_ln = None
1607 export_table = set()1620 export_table = set()
1621 self.source = []
1622 self.state = state.NORMAL
1608 1623
1609 try:1624 try:
1610 with open(self.fname, "r", encoding="utf8",1625 with open(self.fname, "r", encoding="utf8",
@@ -1631,6 +1646,8 @@ class KernelDoc: · 20 unmodified lines
1631 ln, state.name[self.state],1646 ln, state.name[self.state],
1632 line)1647 line)
1633 1648
1649 prev_state = self.state
1650
1634 # This is an optimization over the original script.1651 # This is an optimization over the original script.
1635 # There, when export_file was used for the same file,1652 # There, when export_file was used for the same file,
1636 # it was read twice. Here, we use the already-existing1653 # it was read twice. Here, we use the already-existing
@@ -1641,6 +1658,14 @@ class KernelDoc: · 4 unmodified lines
1641 # Hand this line to the appropriate state handler1658 # Hand this line to the appropriate state handler
1642 self.state_actions[self.state](self, ln, line)1659 self.state_actions[self.state](self, ln, line)
1643 1660
1661 if self.store_src and prev_state != self.state or self.state != state.NORMAL:
1662 if self.state == state.NAME:
1663 # A "/**" was detected. Add a new source element
1664 self.source.append({"ln": ln, "data": line + "\n"})
1665 else:
1666 # Append to the existing one
1667 self.source[-1]["data"] += line + "\n"
1668
1644 self.emit_unused_warnings()1669 self.emit_unused_warnings()
1645 1670
1646 except OSError:1671 except OSError: