1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-15 20:35:17 +03:00
opentx/radio/util/dump_ast_yaml.py
Raphael Coeffic 8b4d2b698d YAML storage (#7071)
YAML storage
2019-11-12 14:50:05 +01:00

182 lines
5.1 KiB
Python

#!/usr/bin/python
# vim: set fileencoding=utf-8
from clang.cindex import *
import asciitree # must be version 0.2
import sys
TOP_NODE_TYPES = [
CursorKind.ENUM_DECL,
CursorKind.STRUCT_DECL ]
CHILD_NODE_TYPES = [
CursorKind.FIELD_DECL,
CursorKind.UNION_DECL,
#CursorKind.STRUCT_DECL,
CursorKind.ENUM_CONSTANT_DECL ]
def filter_node(node):
if node is None:
return False
# # no node or no location
# if node is None or node.location is None or node.location.file is None:
# return False
# # not the main source file
# if node.location.file.name != sys.argv[1]:
# return False
if node.kind in CHILD_NODE_TYPES:
return True
return False
def get_struct_decl(node):
for c in node.get_children():
if c is not None and c.kind == CursorKind.STRUCT_DECL:
return c
return None
def node_children(node):
if node is None:
return []
if isinstance(node,list):
return node
if node.kind == CursorKind.FIELD_DECL:
if node.type.kind == TypeKind.ELABORATED:
return node_children(node.type.get_declaration())
elif node.type.kind == TypeKind.RECORD:
return list(c for c in node.type.get_fields())
elif node.type.kind == TypeKind.CONSTANTARRAY:
et = node.type.element_type
if et.kind == TypeKind.RECORD:
return list(c for c in et.get_fields())
elif node.type.kind == TypeKind.ENUM:
return node_children(node.type.get_declaration())
else:
print("{} {}".format(str(node.type.kind),node.spelling))
return list(c for c in node.get_children() if filter_node(c))
def get_array_size(f):
et = f.type.element_type
ec = f.type.element_count
if et.spelling == 'char':
return 'string({})'.format(ec)
else:
return '{} x {} bytes'.format(ec,et.get_size())
def get_field_size(f):
if f.is_bitfield():
return '{} bits'.format(f.get_bitfield_width())
elif f.type.kind == TypeKind.CONSTANTARRAY:
return get_array_size(f)
return '{} bytes'.format(f.type.get_size())
def print_field_decl(kind, text, f):
ft = ''
is_anon = f.is_anonymous()
if f.type.kind == TypeKind.RECORD:
decl = f.type.get_declaration()
if decl.kind == CursorKind.UNION_DECL:
if is_anon:
ft = 'anonymous union ({})'.format(decl.mangled_name)
else:
ft = 'union {}'.format(f.type.spelling)
elif decl.kind == CursorKind.STRUCT_DECL:
if is_anon:
ft = '{} anonymous struct'.format(f.kind)
else:
ft = 'struct {}'.format(f.type.spelling)
elif f.type.kind == TypeKind.TYPEDEF:
decl = f.type.get_canonical()
ft = decl.spelling
elif get_struct_decl(f) is not None:
ft = 'anon struct'
elif f.type.kind == TypeKind.CONSTANTARRAY:
et = f.type.element_type
ft = et.spelling
else:
ft = f.type.spelling
return '{} {} ({})'.format(ft, text, get_field_size(f))
def print_enum_decl(kind, text, e):
return '{} {} ({})'.format(kind, text, e.enum_value)
def print_union_decl(kind, text, f):
return '{} {} ({})'.format(kind, text, get_field_size(f))
def print_node(node):
if isinstance(node,list):
return 'ROOT'
text = node.spelling or node.displayname
kind = str(node.kind)[str(node.kind).index('.')+1:]
if CursorKind.FIELD_DECL == node.kind:
return print_field_decl(kind, text, node)
if CursorKind.ENUM_CONSTANT_DECL == node.kind:
return print_enum_decl(kind, text, node)
if CursorKind.UNION_DECL == node.kind:
return print_union_decl(kind, text, node)
return '{} {}'.format(kind, text)
def get_top_node(name, node):
for c in node.get_children():
if c.spelling == name:
# struct found
return c
print("get_top_node: '{}' not found!".format(name))
return None
def get_top_nodes(node):
l = list()
for c in node.get_children():
# no node or no location
if c is None or c.location is None or c.location.file is None:
continue
# not the main source file
if c.location.file.name != sys.argv[1]:
continue
if c.kind in TOP_NODE_TYPES:
# struct found
l.append(c)
return l
def print_top_node(name):
s = get_top_node(name, translation_unit.cursor)
if s is None:
return
print(asciitree.draw_tree(s, node_children, print_node))
def print_all():
s = get_top_nodes(translation_unit.cursor)
print(asciitree.draw_tree(s, node_children, print_node))
### Main ###
if len(sys.argv) < 3:
print("Usage: dump_ast_yaml.py [header file name] [top node] [additional compile args]")
sys.exit()
Config.set_library_file('/usr/local/Cellar/llvm/6.0.0/lib/libclang.dylib')
index = Index.create()
translation_unit = index.parse(sys.argv[1], ['-x', 'c++', '-std=c++11'] + sys.argv[3:])
print_top_node(sys.argv[2])
#print_top_node('CustomFunctionData')
#print_all()