[PATCH 2/6] autodoc: extract doc from the C files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a tool which parse comment from source files and
extract kerneldoc-like documentation from them.

Note: this is rather quite crude, support only generic 'blocs'
      and doc for functions; it has no support for anything else.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 Documentation/sphinx/cdoc.py | 180 +++++++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100755 Documentation/sphinx/cdoc.py

diff --git a/Documentation/sphinx/cdoc.py b/Documentation/sphinx/cdoc.py
new file mode 100755
index 000000000..ba875242a
--- /dev/null
+++ b/Documentation/sphinx/cdoc.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+# SPDX_License-Identifier: MIT
+#
+# Copyright (C) 2018 Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
+#
+
+"""Extract doc-comments from C files"""
+
+import re
+
+__version__  = '0.0'
+
+
+class Lines:
+	def __init__(self, lines):
+		self.index = 0
+		self.lines = lines
+		self.last = None
+		self.back = False
+
+	def __iter__(self):
+		return self
+
+	def memo(self):
+		return (self.index, self.last)
+
+	def __next__(self):
+		if not self.back:
+			self.last = next(self.lines).rstrip()
+			self.index += 1
+		else:
+			self.back = False
+		return self.memo()
+	def next(self):
+		return self.__next__()
+
+	def undo(self):
+		self.back = True
+
+def readline_cont(lines):
+	(lineno, line) = next(lines)
+	while line[-1] == '\\':
+		del line[-1]
+		line = line.rstrip()
+		(n, l) = next(lines)
+		line += ' ' + l.lstrip()
+	return (lineno, line)
+
+def readline_until(lines, delim):
+	try:
+		(lineno, line) = next(lines)
+		if line == '':
+			raise StopIteration
+		while line[-1] not in delim:
+			(n, l) = next(lines)
+			line += ' ' + l.lstrip()
+	except:
+		line = ''
+	return (lineno, line)
+
+
+def process_block(lines):
+	info = { }
+	args = []
+	tags = []
+	desc = []
+	state = 0
+
+	(n, l) = lines.memo()
+	#print('processing line ' + str(n) + ': ' + l)
+
+	## is it a single line comment ?
+	m = re.match(r"^/\*\*\s+(.+[^\s])\s*\*/$", l)	# /** (.*) */
+	if not m:
+		m = re.match(r"^///\s+(.+[^\s])\s*$", l)	# /// (.*)
+	if m:
+		info['type'] = 'single'
+		info['desc'] = (n, m.group(1))
+		return info
+
+	## read the multi line comment
+	for (n, l) in lines:
+		#print('state %d: %4d: %s' % (state, n, l))
+		m = re.match(r"^( \*|///?) ?(.*)", l)
+		if not m:
+			lines.undo()
+			break
+		if l == ' */':
+			break
+		l = m.group(2)
+
+		if state == 0:
+			info['short'] = (n ,l)
+			state = 1
+		elif state == 1:
+			if l != '':
+				lines.undo()
+				state = 2
+		elif state == 2 or state == 5:
+			m = re.match(r"^@([\w-]*)(:?\s*)(.*)", l)
+			if m:
+				tag = m.group(1)
+				sep = m.group(2)
+				## FIXME/ warn if sep != ': '
+				l = m.group(3)
+				## FIXME: try multi-line ???
+				if state == 2:
+					args.append((n, tag, l))
+				if state == 5:
+					tags.append((n, tag, l))
+			else:
+				lines.undo()
+				if state == 2:
+					state = 3
+		elif state == 3:
+			if l != '':
+				desc = [n, l]
+				state = 4
+		elif state == 4:
+			if len(l) and l[0] == '@':
+				lines.undo()
+				state = 5
+			else:
+				desc.append(l)
+		else:
+			print('??? %4d: %s' % (n , l))
+
+	## fill the info
+	if len(args):
+		info['args'] = args
+	if len(desc):
+		info['desc'] = desc
+	if len(tags):
+		info['tags'] = tags
+
+	## read the item (function only for now)
+	(n, line) = readline_until(lines, (')', ';'))
+	if len(line):
+		line.rstrip(';')
+		#print('function: %4d: %s' % (n, line))
+		info['type'] = 'func'
+		info['func'] = (n, line)
+	else:
+		info['type'] = 'bloc'
+
+	return info
+
+def process_file(f):
+	docs = []
+	lines = Lines(f)
+	for (n, l) in lines:
+		#print("%4d: %s" % (n, l))
+		if l.startswith('/**') or l.startswith('///'):
+			info = process_block(lines)
+			docs.append(info)
+
+	return docs
+
+
+if __name__ == '__main__':
+	""" extract the doc from stdin """
+	import sys
+
+	res = process_file(sys.stdin)
+	for info in res:
+		print('###');
+		print('type: %s' % (info.get('type', '???')))
+		val = info.get('short', None)
+		if val:
+			print('short:%4d: %s' % val)
+		for val in info.get('args', []):
+			print('para: %4d: @%s: %s' % val)
+		val = info.get('desc', None)
+		if val:
+			n = val[0]
+			print('desc: %4d:\n\t%s' % (n, '\n\t'.join(val[1:])))
+		for val in info.get('tags', []):
+			print('tags: %4d: @%s: %s' % val)
+
+# vim: tabstop=4
-- 
2.17.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux