Skip to content

Instantly share code, notes, and snippets.

@nokotan
Created February 26, 2021 16:32
Show Gist options
  • Save nokotan/43aaad63d9d1c243134adfad2ac48cba to your computer and use it in GitHub Desktop.
Save nokotan/43aaad63d9d1c243134adfad2ac48cba to your computer and use it in GitHub Desktop.
Extract Comments in C/C++ Source File
#!/usr/bin/python3
from clang.cindex import Index, Config, CursorKind
import json as JsonUtil
import os, io, sys
class MyTreeWalker:
def __init__(self):
self.namespace = []
def walkThroughClass(self, cursor, visitor):
if cursor.kind == CursorKind.CXX_METHOD:
name = "::".join(self.namespace + [ cursor.spelling ])
visitor.visitClassFunction(name, cursor)
elif cursor.kind in ( CursorKind.STRUCT_DECL, CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE ):
self.namespace += [ cursor.spelling ]
name = "::".join(self.namespace + [ cursor.spelling ])
visitor.visitClassDefinition(name, cursor)
for child in cursor.get_children():
self.walkThroughClass(child, visitor)
self.namespace.pop()
def walkThrough(self, cursor, visitor):
if cursor.kind == CursorKind.NAMESPACE:
self.namespace += [ cursor.spelling ]
for child in cursor.get_children():
self.walkThrough(child, visitor)
self.namespace.pop()
elif cursor.kind in ( CursorKind.STRUCT_DECL, CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE ):
self.namespace += [ cursor.spelling ]
name = "::".join(self.namespace + [ cursor.spelling ])
visitor.visitClassDefinition(name, cursor)
for child in cursor.get_children():
self.walkThroughClass(child, visitor)
self.namespace.pop()
elif cursor.kind == CursorKind.FUNCTION_DECL:
name = "::".join(self.namespace + [ cursor.spelling ])
visitor.visitGlobalFunction(name, cursor)
def startWalk(self, cursor, visitor):
if cursor.kind == CursorKind.TRANSLATION_UNIT:
for child in cursor.get_children():
self.walkThrough(child, visitor)
class JsonGeneratingVisitor:
def __init__(self, stream: io.TextIOBase):
self.stream = stream
self.definitions = []
def visitGlobalFunction(self, name: str, cursor):
comment = cursor.raw_comment
mangledName = cursor.mangled_name
if mangledName and comment:
self.definitions.append({ "name": mangledName, "comment": comment })
def visitClassDefinition(self, name, cursor):
pass
def visitClassFunction(self, name, cursor):
comment = cursor.raw_comment
mangledName = cursor.mangled_name
if mangledName and comment:
self.definitions.append({ "name": mangledName, "comment": comment })
def flush(self):
JsonSerialized = JsonUtil.dumps(self.definitions, ensure_ascii=False, indent=2)
self.stream.write(JsonSerialized)
class Executor:
def __init__(self, walker, generator):
self.walker = walker
self.generator = generator
self.libClangPath = os.environ.get("EMSDK") + "/upstream/lib/"
self.path = None
self.args = None
def run(self):
Config.set_library_path(self.libClangPath)
index = Index.create()
tree = index.parse(self.path, args=self.args)
self.walker.startWalk(tree.cursor, self.generator)
self.generator.flush()
def main(argv):
path = argv[1]
args = argv[2:]
executor = Executor(MyTreeWalker(), JsonGeneratingVisitor(sys.stdout))
executor.path = path
executor.args = args
executor.run()
if __name__ == "__main__":
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment