mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
1695 lines
44 KiB
Python
1695 lines
44 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import sys
|
||
|
import os
|
||
|
|
||
|
try:
|
||
|
from pycparser import c_ast # NOQA
|
||
|
except ImportError:
|
||
|
sys.stderr.write(
|
||
|
'\nThe pycparser library is missing, '
|
||
|
'please run "pip install pycparser" to install it.\n'
|
||
|
)
|
||
|
sys.stderr.flush()
|
||
|
sys.exit(-500)
|
||
|
|
||
|
from pycparser.c_generator import CGenerator
|
||
|
from collections import OrderedDict
|
||
|
|
||
|
import doc_builder # NOQA
|
||
|
|
||
|
generator = CGenerator()
|
||
|
|
||
|
doc_builder.EMIT_WARNINGS = False
|
||
|
# doc_builder.DOXYGEN_OUTPUT = False
|
||
|
|
||
|
|
||
|
BASIC_TYPES = [
|
||
|
'float',
|
||
|
'double',
|
||
|
'long',
|
||
|
'ulong',
|
||
|
'unsigned long',
|
||
|
'long double',
|
||
|
'signed long double',
|
||
|
'unsigned long double',
|
||
|
'long long',
|
||
|
'signed long long',
|
||
|
'unsigned long long',
|
||
|
'int',
|
||
|
'uint',
|
||
|
'signed int',
|
||
|
'unsigned int',
|
||
|
'long int',
|
||
|
'signed long int',
|
||
|
'unsigned long int',
|
||
|
'short'
|
||
|
'ushort',
|
||
|
'signed short',
|
||
|
'unsigned short',
|
||
|
'void',
|
||
|
'char',
|
||
|
'uchar',
|
||
|
'signed char',
|
||
|
'unsigned char',
|
||
|
'bool'
|
||
|
]
|
||
|
|
||
|
STDLIB_TYPES = [
|
||
|
'size_t',
|
||
|
'uint8_t',
|
||
|
'uint16_t',
|
||
|
'uint32_t',
|
||
|
'uint64_t',
|
||
|
'int8_t',
|
||
|
'int16_t',
|
||
|
'int32_t',
|
||
|
'int64_t',
|
||
|
'va_list',
|
||
|
'uintptr_t',
|
||
|
'intptr_t',
|
||
|
]
|
||
|
|
||
|
enums = {}
|
||
|
functions = {}
|
||
|
structures = {}
|
||
|
unions = {}
|
||
|
typedefs = {}
|
||
|
macros = {}
|
||
|
|
||
|
FILTER_PRIVATE = False
|
||
|
|
||
|
|
||
|
def filter_node(n):
|
||
|
if hasattr(n, 'coord') and n.coord is not None:
|
||
|
if 'fake_libc_include' in n.coord.file:
|
||
|
return True
|
||
|
if FILTER_PRIVATE and '_private.h' not in n.coord.file:
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
|
||
|
class ArrayDecl(c_ast.ArrayDecl):
|
||
|
|
||
|
def process(self):
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if self.dim is None:
|
||
|
dim = None
|
||
|
else:
|
||
|
dim = generator.visit(self.dim)
|
||
|
|
||
|
if isinstance(self.type, TypeDecl):
|
||
|
res = self.type.to_dict()
|
||
|
res['json_type'] = 'array'
|
||
|
res['dim'] = dim
|
||
|
res['quals'].extend(self.dim_quals)
|
||
|
return res
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'array'),
|
||
|
('dim', dim),
|
||
|
('quals', self.dim_quals)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Constant(c_ast.Constant):
|
||
|
|
||
|
def process(self):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
return self.value
|
||
|
|
||
|
|
||
|
collected_types = []
|
||
|
|
||
|
forward_decls = {}
|
||
|
|
||
|
|
||
|
class Decl(c_ast.Decl):
|
||
|
|
||
|
def process(self):
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if self.name and self.name == '_silence_gcc_warning':
|
||
|
return None
|
||
|
|
||
|
if not self.name:
|
||
|
try:
|
||
|
name = self.type.name
|
||
|
except AttributeError:
|
||
|
name = None
|
||
|
|
||
|
if name:
|
||
|
if name == '_silence_gcc_warning':
|
||
|
return None
|
||
|
else:
|
||
|
name = self.name
|
||
|
|
||
|
if isinstance(self.parent, (Struct, Union)):
|
||
|
if self.bitsize:
|
||
|
bitsize = self.bitsize.to_dict()
|
||
|
else:
|
||
|
bitsize = None
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'field'),
|
||
|
('bitsize', bitsize)
|
||
|
])
|
||
|
elif isinstance(self.parent, FuncDecl):
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'arg'),
|
||
|
])
|
||
|
elif isinstance(self.type, Enum):
|
||
|
res = self.type.to_dict()
|
||
|
res['name'] = name
|
||
|
|
||
|
elif isinstance(self.type, (FuncDef, FuncDecl)):
|
||
|
res = self.type.to_dict()
|
||
|
res['name'] = name
|
||
|
|
||
|
else:
|
||
|
if isinstance(self.type, (Struct, Union)):
|
||
|
res = self.type.to_dict()
|
||
|
|
||
|
if 'quals' in res:
|
||
|
res['quals'].extend(self.quals)
|
||
|
else:
|
||
|
res['quals'] = self.quals
|
||
|
|
||
|
if res['json_type'] == 'forward_decl':
|
||
|
if res['name'] and res['name'] not in forward_decls:
|
||
|
forward_decls[res['name']] = res
|
||
|
|
||
|
return None
|
||
|
|
||
|
return res
|
||
|
|
||
|
if self.name:
|
||
|
name = self.name
|
||
|
else:
|
||
|
name = self.type.name
|
||
|
|
||
|
doc_search = get_var_docs(name) # NOQA
|
||
|
|
||
|
if doc_search is None:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = doc_search.description
|
||
|
|
||
|
if (
|
||
|
isinstance(self.type, PtrDecl) and
|
||
|
isinstance(self.type.type, FuncDecl)
|
||
|
):
|
||
|
type_dict = self.type.type.to_dict()
|
||
|
type_dict['json_type'] = 'function_pointer'
|
||
|
|
||
|
if docstring:
|
||
|
type_dict['docstring'] = docstring
|
||
|
|
||
|
if 'quals' in type_dict:
|
||
|
type_dict['quals'].extend(self.quals)
|
||
|
else:
|
||
|
type_dict['quals'] = self.quals
|
||
|
|
||
|
return type_dict
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'variable'),
|
||
|
('docstring', docstring),
|
||
|
('quals', self.quals),
|
||
|
('storage', self.storage)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class EllipsisParam(c_ast.EllipsisParam):
|
||
|
|
||
|
def process(self):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', '...'),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'ellipsis'),
|
||
|
('json_type', 'special_type')
|
||
|
])),
|
||
|
('json_type', 'arg'),
|
||
|
('docstring', None)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return '...'
|
||
|
|
||
|
|
||
|
member_namespace = {}
|
||
|
|
||
|
|
||
|
class Enum(c_ast.Enum):
|
||
|
|
||
|
def process(self):
|
||
|
name = self.name
|
||
|
parent = self.parent
|
||
|
|
||
|
while parent is not None and name is None:
|
||
|
try:
|
||
|
name = parent.name
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
parent = parent.parent
|
||
|
|
||
|
if name and name not in collected_types:
|
||
|
collected_types.append(name)
|
||
|
|
||
|
for item in (self.values or []):
|
||
|
item.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
if self.values:
|
||
|
self.values.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if self.name:
|
||
|
doc_search = get_enum_docs(self.name) # NOQA
|
||
|
|
||
|
if doc_search is None:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = doc_search.description
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
members = []
|
||
|
value_num = 0
|
||
|
|
||
|
for item in (self.values or []):
|
||
|
item_dict = item.to_dict()
|
||
|
try:
|
||
|
code = generator.visit(item.value)
|
||
|
|
||
|
try:
|
||
|
value = eval("bytearray([b'" + code + "'])[0]")
|
||
|
except: # NOQA
|
||
|
index = code.find('L')
|
||
|
|
||
|
while index >= 1:
|
||
|
if code[index - 1].isdigit():
|
||
|
code = list(code)
|
||
|
code.pop(index)
|
||
|
code = ''.join(code)
|
||
|
|
||
|
index = code.find('L', index + 1)
|
||
|
|
||
|
value = eval(code, member_namespace)
|
||
|
|
||
|
member_namespace[item_dict['name']] = value
|
||
|
|
||
|
value_num = value + 1
|
||
|
|
||
|
code = f'0x{hex(value)[2:].upper()}'
|
||
|
value = code
|
||
|
except: # NOQA
|
||
|
value = f'0x{hex(value_num)[2:].upper()}'
|
||
|
member_namespace[item_dict['name']] = value_num
|
||
|
value_num += 1
|
||
|
|
||
|
item_dict['value'] = value
|
||
|
members.append(item_dict)
|
||
|
|
||
|
hex_len = len(hex(value_num)[2:])
|
||
|
for member in members:
|
||
|
member['value'] = (
|
||
|
f'0x{hex(int(member["value"], 16))[2:].zfill(hex_len).upper()}'
|
||
|
)
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'int'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])),
|
||
|
('json_type', 'enum'),
|
||
|
('docstring', docstring),
|
||
|
('members', members)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Enumerator(c_ast.Enumerator):
|
||
|
|
||
|
def process(self):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
parent_name = self.parent.name
|
||
|
parent = self.parent
|
||
|
|
||
|
while parent is not None and parent_name is None:
|
||
|
try:
|
||
|
parent_name = parent.name
|
||
|
except AttributeError:
|
||
|
continue
|
||
|
|
||
|
parent = parent.parent
|
||
|
|
||
|
if parent_name and parent_name.startswith('_'):
|
||
|
if parent_name[1:] in collected_types:
|
||
|
type_ = OrderedDict([
|
||
|
('name', parent_name[1:]),
|
||
|
('json_type', 'lvgl_type')
|
||
|
])
|
||
|
elif parent_name in collected_types:
|
||
|
type_ = OrderedDict([
|
||
|
('name', parent_name),
|
||
|
('json_type', 'lvgl_type')
|
||
|
])
|
||
|
else:
|
||
|
type_ = OrderedDict([
|
||
|
('name', 'int'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])
|
||
|
|
||
|
elif parent_name and parent_name in collected_types:
|
||
|
type_ = OrderedDict([
|
||
|
('name', parent_name),
|
||
|
('json_type', 'lvgl_type')
|
||
|
])
|
||
|
else:
|
||
|
type_ = OrderedDict([
|
||
|
('name', 'int'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])
|
||
|
|
||
|
doc_search = get_enum_item_docs(self.name) # NOQA
|
||
|
|
||
|
if doc_search is None:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = doc_search.description
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', type_),
|
||
|
('json_type', 'enum_member'),
|
||
|
('docstring', docstring)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class EnumeratorList(c_ast.EnumeratorList):
|
||
|
|
||
|
def process(self, indent):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
for item in (self.enumerators or []):
|
||
|
item.parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
pass
|
||
|
|
||
|
|
||
|
def is_type(obj, type_):
|
||
|
if isinstance(obj, list):
|
||
|
return type_ == 'typedef'
|
||
|
|
||
|
return obj['json_type'] == type_
|
||
|
|
||
|
|
||
|
found_types = {}
|
||
|
|
||
|
get_enum_item_docs = None
|
||
|
get_enum_docs = None
|
||
|
get_func_docs = None
|
||
|
get_var_docs = None
|
||
|
get_union_docs = None
|
||
|
get_struct_docs = None
|
||
|
get_typedef_docs = None
|
||
|
get_macro_docs = None
|
||
|
get_macros = None
|
||
|
|
||
|
|
||
|
_enums = {}
|
||
|
_functions = {}
|
||
|
_structures = {}
|
||
|
_unions = {}
|
||
|
_typedefs = {}
|
||
|
_variables = {}
|
||
|
_function_pointers = {}
|
||
|
_forward_decls = {}
|
||
|
|
||
|
|
||
|
class FileAST(c_ast.FileAST):
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
def setup_docs(self, temp_directory): # NOQA
|
||
|
global get_enum_item_docs
|
||
|
global get_enum_docs
|
||
|
global get_func_docs
|
||
|
global get_var_docs
|
||
|
global get_union_docs
|
||
|
global get_struct_docs
|
||
|
global get_typedef_docs
|
||
|
global get_macro_docs
|
||
|
global get_macros
|
||
|
|
||
|
docs = doc_builder.XMLSearch(temp_directory)
|
||
|
|
||
|
get_enum_item_docs = docs.get_enum_item
|
||
|
get_enum_docs = docs.get_enum
|
||
|
get_func_docs = docs.get_function
|
||
|
get_var_docs = docs.get_variable
|
||
|
get_union_docs = docs.get_union
|
||
|
get_struct_docs = docs.get_structure
|
||
|
get_typedef_docs = docs.get_typedef
|
||
|
get_macro_docs = docs.get_macro
|
||
|
get_macros = docs.get_macros
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
items = []
|
||
|
|
||
|
# This code block is to handle how pycparser handles forward
|
||
|
# declarations and combining the forward declarations with the actual
|
||
|
# types so any information that is contained in the type gets properly
|
||
|
# attached to the forward declaration
|
||
|
forward_struct_decls = {}
|
||
|
|
||
|
for item in self.ext[:]:
|
||
|
if (
|
||
|
isinstance(item, Decl) and
|
||
|
item.name is None and
|
||
|
isinstance(
|
||
|
item.type,
|
||
|
(Struct, Union)
|
||
|
) and
|
||
|
item.type.name is not None
|
||
|
):
|
||
|
if item.type.decls is None:
|
||
|
forward_struct_decls[item.type.name] = [item]
|
||
|
else:
|
||
|
if item.type.name in forward_struct_decls:
|
||
|
decs = forward_struct_decls[item.type.name]
|
||
|
if len(decs) == 2:
|
||
|
decl, td = decs
|
||
|
|
||
|
if FILTER_PRIVATE:
|
||
|
if (
|
||
|
'_private.h' not in decl.coord.file and
|
||
|
'_private.h' not in td.coord.file and
|
||
|
'_private.h' not in item.coord.file
|
||
|
):
|
||
|
continue
|
||
|
|
||
|
if decl.type.decls and '_private.h' in decl.coord.file:
|
||
|
decl.name = decl.type.name
|
||
|
self.ext.remove(item)
|
||
|
elif item.type.decls and '_private.h' in item.coord.file:
|
||
|
item.name = item.type.name
|
||
|
self.ext.remove(decl)
|
||
|
|
||
|
self.ext.remove(td)
|
||
|
else:
|
||
|
td.type.type.decls = item.type.decls[:]
|
||
|
|
||
|
self.ext.remove(decl)
|
||
|
self.ext.remove(item)
|
||
|
elif (
|
||
|
isinstance(item, Typedef) and
|
||
|
isinstance(item.type, TypeDecl) and
|
||
|
item.name and
|
||
|
item.type.declname and
|
||
|
item.name == item.type.declname and
|
||
|
isinstance(
|
||
|
item.type.type,
|
||
|
(Struct, Union)
|
||
|
) and
|
||
|
item.type.type.decls is None
|
||
|
):
|
||
|
if item.type.type.name in forward_struct_decls:
|
||
|
forward_struct_decls[item.type.type.name].append(item)
|
||
|
############################
|
||
|
|
||
|
for item in self.ext:
|
||
|
if filter_node(item):
|
||
|
continue
|
||
|
try:
|
||
|
item.parent = self
|
||
|
items.append(item)
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
enums = [] # NOQA
|
||
|
functions = [] # NOQA
|
||
|
structures = [] # NOQA
|
||
|
unions = [] # NOQA
|
||
|
typedefs = [] # NOQA
|
||
|
variables = []
|
||
|
function_pointers = []
|
||
|
forward_decl = []
|
||
|
|
||
|
no_enum_name_count = 1
|
||
|
|
||
|
for itm in items:
|
||
|
itm.process()
|
||
|
item = itm.to_dict()
|
||
|
|
||
|
if item is None:
|
||
|
continue
|
||
|
|
||
|
if is_type(item, 'typedef'):
|
||
|
typedefs.append(item)
|
||
|
_typedefs[itm.name] = item
|
||
|
elif is_type(item, 'function_pointer'):
|
||
|
function_pointers.append(item)
|
||
|
_function_pointers[item['name']] = item
|
||
|
elif is_type(item, 'function'):
|
||
|
functions.append(item)
|
||
|
_functions[item['name']] = item
|
||
|
elif is_type(item, 'struct'):
|
||
|
structures.append(item)
|
||
|
_structures[item['name']] = item
|
||
|
elif is_type(item, 'union'):
|
||
|
unions.append(item)
|
||
|
_unions[item['name']] = item
|
||
|
elif is_type(item, 'enum'):
|
||
|
enums.append(item)
|
||
|
|
||
|
if item['name'] is None:
|
||
|
item['name'] = f'NO_NAME_{no_enum_name_count}'
|
||
|
no_enum_name_count += 1
|
||
|
|
||
|
_enums[item['name']] = item
|
||
|
elif is_type(item, 'variable'):
|
||
|
variables.append(item)
|
||
|
_variables[item['name']] = item
|
||
|
elif is_type(item, 'forward_decl'):
|
||
|
forward_decl.append(item)
|
||
|
_forward_decls[item['name']] = item
|
||
|
else:
|
||
|
print('UNKNOWN TYPE:')
|
||
|
print(item)
|
||
|
print(item.to_dict())
|
||
|
|
||
|
for tdef_name in _typedefs.keys():
|
||
|
if '_' + tdef_name in _enums:
|
||
|
enum_dict = _enums['_' + tdef_name]
|
||
|
for member in enum_dict['members']:
|
||
|
member['type']['name'] = tdef_name
|
||
|
member['type']['json_type'] = 'lvgl_type'
|
||
|
else:
|
||
|
if tdef_name.endswith('_t'):
|
||
|
td_name = tdef_name[:-2].upper()
|
||
|
else:
|
||
|
td_name = tdef_name.upper()
|
||
|
|
||
|
for en_name, enum_dict in _enums.items():
|
||
|
if not en_name.startswith('NO_NAME_'):
|
||
|
continue
|
||
|
|
||
|
member_names = [
|
||
|
member['name']
|
||
|
for member in enum_dict['members']
|
||
|
if not member['name'].startswith('_')
|
||
|
]
|
||
|
|
||
|
if not member_names:
|
||
|
continue
|
||
|
|
||
|
c_name = os.path.commonprefix(member_names)
|
||
|
c_name = "_".join(c_name.split("_")[:-1])
|
||
|
if c_name != td_name:
|
||
|
continue
|
||
|
|
||
|
for member in enum_dict['members']:
|
||
|
member['type']['name'] = tdef_name
|
||
|
member['type']['json_type'] = 'lvgl_type'
|
||
|
break
|
||
|
|
||
|
for enm in enums:
|
||
|
if enm['name'].startswith('NO_NAME_'):
|
||
|
enm['name'] = None
|
||
|
|
||
|
res = {
|
||
|
'enums': enums,
|
||
|
'functions': functions,
|
||
|
'function_pointers': function_pointers,
|
||
|
'structures': structures,
|
||
|
'unions': unions,
|
||
|
'variables': variables,
|
||
|
'typedefs': [],
|
||
|
'forward_decls': forward_decl,
|
||
|
'macros': []
|
||
|
}
|
||
|
|
||
|
for typedef in typedefs:
|
||
|
if isinstance(typedef, list):
|
||
|
typedef, obj_dict = typedef
|
||
|
if obj_dict['json_type'] == 'struct':
|
||
|
res['structures'].append(obj_dict)
|
||
|
elif obj_dict['json_type'] == 'union':
|
||
|
res['unions'].append(obj_dict)
|
||
|
elif obj_dict['json_type'] == 'enum':
|
||
|
res['enums'].append(obj_dict)
|
||
|
|
||
|
res['typedefs'].append(typedef)
|
||
|
|
||
|
for macro in get_macros(): # NOQA
|
||
|
macro_type = OrderedDict([
|
||
|
('name', macro.name),
|
||
|
('json_type', 'macro'),
|
||
|
('docstring', macro.description),
|
||
|
('params', macro.params),
|
||
|
('initializer', macro.initializer)
|
||
|
])
|
||
|
|
||
|
res['macros'].append(macro_type)
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class FuncDecl(c_ast.FuncDecl):
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
type_ = self.type
|
||
|
while isinstance(type_, PtrDecl):
|
||
|
type_ = type_.type
|
||
|
|
||
|
try:
|
||
|
name = type_.name
|
||
|
except AttributeError:
|
||
|
name = None
|
||
|
parent = self.parent
|
||
|
while parent is not None and name is None:
|
||
|
try:
|
||
|
name = parent.name
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
parent = parent.parent
|
||
|
|
||
|
return name
|
||
|
|
||
|
def process(self):
|
||
|
name = self.name
|
||
|
if name and name not in collected_types:
|
||
|
collected_types.append(name)
|
||
|
|
||
|
for arg in (self.args or []):
|
||
|
arg.process()
|
||
|
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
for arg in (self.args or []):
|
||
|
arg.parent = self
|
||
|
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if self.name:
|
||
|
doc_search = get_func_docs(self.name) # NOQA
|
||
|
if doc_search is None:
|
||
|
docstring = ''
|
||
|
ret_docstring = ''
|
||
|
else:
|
||
|
docstring = doc_search.description
|
||
|
ret_docstring = doc_search.res_description
|
||
|
|
||
|
if docstring is None:
|
||
|
docstring = ''
|
||
|
if ret_docstring is None:
|
||
|
ret_docstring = ''
|
||
|
|
||
|
else:
|
||
|
doc_search = None
|
||
|
docstring = ''
|
||
|
ret_docstring = ''
|
||
|
|
||
|
args = []
|
||
|
|
||
|
for arg in (self.args or []):
|
||
|
arg = arg.to_dict()
|
||
|
if arg['name'] and doc_search is not None:
|
||
|
for doc_arg in doc_search.args:
|
||
|
if doc_arg.name == arg['name']:
|
||
|
if doc_arg.description is None:
|
||
|
arg['docstring'] = ''
|
||
|
else:
|
||
|
arg['docstring'] = doc_arg.description
|
||
|
break
|
||
|
else:
|
||
|
arg['docstring'] = ''
|
||
|
else:
|
||
|
arg['docstring'] = ''
|
||
|
|
||
|
args.append(arg)
|
||
|
|
||
|
type_dict = OrderedDict([
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'ret_type'),
|
||
|
('docstring', ret_docstring)
|
||
|
])
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', type_dict),
|
||
|
('json_type', 'function'),
|
||
|
('docstring', docstring),
|
||
|
('args', args)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class FuncDef(c_ast.FuncDef):
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return None
|
||
|
|
||
|
def process(self):
|
||
|
self.decl.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
self.decl.parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
return self.decl.to_dict()
|
||
|
|
||
|
|
||
|
class IdentifierType(c_ast.IdentifierType):
|
||
|
|
||
|
def process(self):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return ' '.join(self.names)
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
name = ' '.join(self.names)
|
||
|
|
||
|
if name in BASIC_TYPES:
|
||
|
json_type = 'primitive_type'
|
||
|
elif name in STDLIB_TYPES:
|
||
|
json_type = 'stdlib_type'
|
||
|
elif name in collected_types:
|
||
|
json_type = 'lvgl_type'
|
||
|
elif name.startswith('_') and name[1:] in collected_types:
|
||
|
name = name[1:]
|
||
|
json_type = 'lvgl_type'
|
||
|
elif name.startswith('_lv_') or name.startswith('lv_'):
|
||
|
json_type = 'lvgl_type'
|
||
|
else:
|
||
|
json_type = 'unknown_type'
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('json_type', json_type),
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class ParamList(c_ast.ParamList):
|
||
|
|
||
|
def process(self):
|
||
|
pass
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
for param in (self.params or []):
|
||
|
param.parent = value
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
pass
|
||
|
|
||
|
|
||
|
class PtrDecl(c_ast.PtrDecl):
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return None
|
||
|
|
||
|
def process(self):
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if isinstance(self.type, FuncDecl):
|
||
|
type_dict = self.type.to_dict()
|
||
|
type_dict['json_type'] = 'function_pointer'
|
||
|
res = type_dict
|
||
|
else:
|
||
|
res = OrderedDict([
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'pointer')
|
||
|
])
|
||
|
|
||
|
if 'quals' in res:
|
||
|
res['quals'].extend(self.quals)
|
||
|
else:
|
||
|
res['quals'] = self.quals
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Struct(c_ast.Struct):
|
||
|
|
||
|
def process(self):
|
||
|
for decl in (self.decls or []):
|
||
|
decl.process()
|
||
|
|
||
|
name = self.name
|
||
|
parent = self.parent
|
||
|
while parent is not None and name is None:
|
||
|
name = parent.name
|
||
|
parent = parent.parent
|
||
|
|
||
|
if name and name not in collected_types:
|
||
|
collected_types.append(name)
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
for decl in (self.decls or []):
|
||
|
decl.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if not self.decls:
|
||
|
name = self.name
|
||
|
if not name:
|
||
|
self.name = self.parent.name
|
||
|
|
||
|
if name:
|
||
|
struct_doc = get_struct_docs(name) # NOQA
|
||
|
if struct_doc:
|
||
|
docstring = struct_doc.description
|
||
|
else:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'struct'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])),
|
||
|
('json_type', 'forward_decl'),
|
||
|
('docstring', docstring),
|
||
|
])
|
||
|
|
||
|
else:
|
||
|
if self.name:
|
||
|
struct_doc = get_struct_docs(self.name) # NOQA
|
||
|
elif self.parent.name:
|
||
|
struct_doc = get_struct_docs(self.parent.name) # NOQA
|
||
|
else:
|
||
|
struct_doc = None
|
||
|
|
||
|
if struct_doc is not None:
|
||
|
docstring = struct_doc.description
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
fields = []
|
||
|
|
||
|
for field in self.decls:
|
||
|
field = field.to_dict()
|
||
|
|
||
|
if struct_doc is not None:
|
||
|
for field_doc in struct_doc.fields:
|
||
|
if field_doc.name == field['name']:
|
||
|
field_docstring = field_doc.description
|
||
|
break
|
||
|
else:
|
||
|
field_docstring = ''
|
||
|
else:
|
||
|
field_docstring = ''
|
||
|
|
||
|
field['docstring'] = field_docstring
|
||
|
field['json_type'] = 'field'
|
||
|
fields.append(field)
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'struct'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])),
|
||
|
('json_type', 'struct'),
|
||
|
('docstring', docstring),
|
||
|
('fields', fields)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class TypeDecl(c_ast.TypeDecl):
|
||
|
|
||
|
@property
|
||
|
def name(self):
|
||
|
return self.declname
|
||
|
|
||
|
def process(self):
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
parent = value
|
||
|
|
||
|
while parent is not None:
|
||
|
try:
|
||
|
if parent.declname == self.declname:
|
||
|
break
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
try:
|
||
|
if parent.name == self.declname:
|
||
|
break
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
parent = parent.parent
|
||
|
|
||
|
if parent is None:
|
||
|
self._parent = value
|
||
|
|
||
|
self.type.parent = self
|
||
|
else:
|
||
|
self.type.parent = parent
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if self.parent is None:
|
||
|
res = self.type.to_dict()
|
||
|
if self.declname is not None and not self.type.name:
|
||
|
res['name'] = self.declname
|
||
|
|
||
|
elif isinstance(self.type, (Union, Struct)):
|
||
|
res = self.type.to_dict()
|
||
|
|
||
|
if not self.type.name and self.declname:
|
||
|
res['name'] = self.declname
|
||
|
else:
|
||
|
res = OrderedDict([
|
||
|
('name', self.declname),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', str(type(self))),
|
||
|
])
|
||
|
|
||
|
res['quals'] = self.quals
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Typedef(c_ast.Typedef):
|
||
|
|
||
|
def process(self):
|
||
|
if self._parent is None:
|
||
|
self.type.parent = self
|
||
|
|
||
|
self.type.process()
|
||
|
|
||
|
if self.name and self.name not in collected_types:
|
||
|
collected_types.append(self.name)
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
self.type.parent = self
|
||
|
|
||
|
@property
|
||
|
def is_struct(self):
|
||
|
return (
|
||
|
isinstance(self.type, TypeDecl) and
|
||
|
isinstance(self.type.type, Struct)
|
||
|
)
|
||
|
|
||
|
@property
|
||
|
def is_union(self):
|
||
|
return (
|
||
|
isinstance(self.type, TypeDecl) and
|
||
|
isinstance(self.type.type, Union)
|
||
|
)
|
||
|
|
||
|
def get_struct_union(self):
|
||
|
res = self.type.type.to_dict()
|
||
|
if not self.type.type.name and self.type.name:
|
||
|
res['name'] = self.type.name
|
||
|
elif not self.type.type.name:
|
||
|
res['name'] = self.name
|
||
|
|
||
|
return res
|
||
|
|
||
|
def to_dict(self):
|
||
|
doc_search = get_typedef_docs(self.name) # NOQA
|
||
|
|
||
|
if doc_search is None:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = doc_search.description
|
||
|
|
||
|
if (
|
||
|
isinstance(self.type, PtrDecl) and
|
||
|
isinstance(self.type.type, FuncDecl)
|
||
|
):
|
||
|
type_dict = self.type.type.to_dict()
|
||
|
type_dict['json_type'] = 'function_pointer'
|
||
|
type_dict['name'] = self.name
|
||
|
if 'quals' in type_dict:
|
||
|
type_dict['quals'].extend(self.quals)
|
||
|
else:
|
||
|
type_dict['quals'] = self.quals
|
||
|
|
||
|
if (
|
||
|
'docstring' not in type_dict or
|
||
|
not type_dict['docstring']
|
||
|
):
|
||
|
type_dict['docstring'] = docstring
|
||
|
|
||
|
return type_dict
|
||
|
|
||
|
if isinstance(self.type, TypeDecl):
|
||
|
type_dict = self.type.type.to_dict()
|
||
|
|
||
|
if type_dict['name'] is None:
|
||
|
if self.name is not None:
|
||
|
type_dict['name'] = self.name
|
||
|
else:
|
||
|
raise RuntimeError(str(type_dict))
|
||
|
|
||
|
if 'quals' in type_dict:
|
||
|
type_dict['quals'].extend(self.quals)
|
||
|
else:
|
||
|
type_dict['quals'] = self.quals
|
||
|
|
||
|
type_dict['quals'].extend(self.type.quals)
|
||
|
|
||
|
if 'docstring' not in type_dict:
|
||
|
type_dict['docstring'] = ''
|
||
|
|
||
|
if not type_dict['docstring']:
|
||
|
type_dict['docstring'] = docstring
|
||
|
|
||
|
if type_dict['name'] in _structures:
|
||
|
_structures[type_dict['name']]['name'] = self.name
|
||
|
|
||
|
if 'quals' in _structures[type_dict['name']]:
|
||
|
_structures[type_dict['name']]['quals'].extend(
|
||
|
type_dict['quals']
|
||
|
)
|
||
|
else:
|
||
|
_structures[type_dict['name']]['quals'] = type_dict['quals']
|
||
|
|
||
|
if (
|
||
|
type_dict['docstring'] and
|
||
|
not _structures[type_dict['name']]['docstring']
|
||
|
):
|
||
|
_structures[type_dict['name']]['docstring'] = (
|
||
|
type_dict['docstring']
|
||
|
)
|
||
|
|
||
|
return None
|
||
|
|
||
|
if type_dict['name'] in _unions:
|
||
|
_unions[type_dict['name']]['name'] = self.name
|
||
|
|
||
|
if 'quals' in _unions[type_dict['name']]:
|
||
|
_unions[type_dict['name']]['quals'].extend(
|
||
|
type_dict['quals']
|
||
|
)
|
||
|
else:
|
||
|
_unions[type_dict['name']]['quals'] = type_dict['quals']
|
||
|
|
||
|
if (
|
||
|
type_dict['docstring'] and
|
||
|
not _structures[type_dict['name']]['docstring']
|
||
|
):
|
||
|
_structures[type_dict['name']]['docstring'] = (
|
||
|
type_dict['docstring']
|
||
|
)
|
||
|
|
||
|
return None
|
||
|
|
||
|
if type_dict['name'] in _enums:
|
||
|
if self.name is not None:
|
||
|
type_dict = self.type.to_dict()
|
||
|
|
||
|
res = OrderedDict(
|
||
|
[
|
||
|
('name', self.name),
|
||
|
('type', type_dict),
|
||
|
('json_type', 'typedef'),
|
||
|
('docstring', docstring),
|
||
|
('quals', self.quals)
|
||
|
]
|
||
|
)
|
||
|
return res
|
||
|
|
||
|
if 'quals' in _enums[type_dict['name']]:
|
||
|
_enums[type_dict['name']]['quals'].extend(
|
||
|
type_dict['quals']
|
||
|
)
|
||
|
else:
|
||
|
_enums[type_dict['name']]['quals'] = type_dict['quals']
|
||
|
|
||
|
if (
|
||
|
type_dict['docstring'] and
|
||
|
not _enums[type_dict['name']]['docstring']
|
||
|
):
|
||
|
_enums[type_dict['name']]['docstring'] = (
|
||
|
type_dict['docstring']
|
||
|
)
|
||
|
|
||
|
return None
|
||
|
|
||
|
if not type_dict['name']:
|
||
|
type_dict['name'] = self.name
|
||
|
return type_dict
|
||
|
|
||
|
if type_dict['name'] and type_dict['name'][1:] == self.name:
|
||
|
type_dict['name'] = self.name
|
||
|
return type_dict
|
||
|
|
||
|
if type_dict['name'] and type_dict['name'] == self.name:
|
||
|
return type_dict
|
||
|
|
||
|
if isinstance(self.type.type, (Struct, Union)):
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', OrderedDict([
|
||
|
('name', self.type.type.name),
|
||
|
('json_type', 'lvgl_type')
|
||
|
])),
|
||
|
('json_type', 'typedef'),
|
||
|
('docstring', docstring),
|
||
|
('quals', self.quals + self.type.quals)
|
||
|
])
|
||
|
|
||
|
return [res, self.type.type.to_dict()]
|
||
|
|
||
|
elif isinstance(self.type.type, Enum):
|
||
|
if self.type.type.name:
|
||
|
type_dict = self.type.type.to_dict()
|
||
|
|
||
|
if not type_dict['docstring']:
|
||
|
type_dict['docstring'] = docstring
|
||
|
docstring = ''
|
||
|
|
||
|
if not type_dict['name']:
|
||
|
if self.type.name:
|
||
|
type_dict['name'] = self.type.name
|
||
|
else:
|
||
|
type_dict['name'] = self.name
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', OrderedDict([
|
||
|
('name', type_dict['name']),
|
||
|
('json_type', 'lvgl_type')
|
||
|
])),
|
||
|
('json_type', 'typedef'),
|
||
|
('docstring', docstring),
|
||
|
])
|
||
|
|
||
|
return [res, type_dict]
|
||
|
|
||
|
type_dict = self.type.to_dict()
|
||
|
|
||
|
if 'quals' in type_dict:
|
||
|
type_dict['quals'].extend(self.quals)
|
||
|
else:
|
||
|
type_dict['quals'] = self.quals
|
||
|
|
||
|
if (
|
||
|
docstring and
|
||
|
'docstring' in type_dict and
|
||
|
not type_dict['docstring']
|
||
|
):
|
||
|
type_dict['docstring'] = docstring
|
||
|
|
||
|
if 'name' in type_dict and type_dict['name']:
|
||
|
if type_dict['name'] == self.name:
|
||
|
return type_dict
|
||
|
if type_dict['name'][1:] == self.name:
|
||
|
type_dict['name'] = self.name
|
||
|
return type_dict
|
||
|
|
||
|
quals = type_dict['quals']
|
||
|
del type_dict['quals']
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', type_dict),
|
||
|
('json_type', 'typedef'),
|
||
|
('docstring', docstring),
|
||
|
('quals', quals)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Typename(c_ast.Typename):
|
||
|
|
||
|
def process(self):
|
||
|
self.type.process()
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
self.type.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if not self.name and isinstance(self.type, IdentifierType):
|
||
|
res = self.type.to_dict()
|
||
|
res['quals'] = self.quals
|
||
|
|
||
|
elif isinstance(self.parent, FuncDecl):
|
||
|
if self.name and self.parent.name:
|
||
|
func_docs = get_func_docs(self.parent.name) # NOQA
|
||
|
|
||
|
if func_docs is not None:
|
||
|
for arg in func_docs.args:
|
||
|
if arg.name and arg.name == self.name:
|
||
|
docstring = arg.description
|
||
|
break
|
||
|
else:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', 'arg'),
|
||
|
('docstring', docstring),
|
||
|
('quals', self.quals)
|
||
|
])
|
||
|
else:
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', self.type.to_dict()),
|
||
|
('json_type', str(type(self))),
|
||
|
('quals', self.quals)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
class Union(c_ast.Union):
|
||
|
|
||
|
def process(self):
|
||
|
for field in (self.decls or []):
|
||
|
field.process()
|
||
|
|
||
|
name = self.name
|
||
|
parent = self.parent
|
||
|
while parent is not None and name is None:
|
||
|
try:
|
||
|
name = parent.name
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
|
||
|
parent = parent.parent
|
||
|
|
||
|
if name and name not in collected_types:
|
||
|
collected_types.append(name)
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
super().__init__(*args, **kwargs)
|
||
|
self._parent = None
|
||
|
|
||
|
@property
|
||
|
def parent(self):
|
||
|
return self._parent
|
||
|
|
||
|
@parent.setter
|
||
|
def parent(self, value):
|
||
|
self._parent = value
|
||
|
|
||
|
for decl in (self.decls or []):
|
||
|
decl.parent = self
|
||
|
|
||
|
def to_dict(self):
|
||
|
if filter_node(self):
|
||
|
return None
|
||
|
|
||
|
if not self.decls:
|
||
|
name = self.name
|
||
|
if not name:
|
||
|
self.name = self.parent.name
|
||
|
|
||
|
if name:
|
||
|
union_doc = get_union_docs(name) # NOQA
|
||
|
if union_doc:
|
||
|
docstring = union_doc.description
|
||
|
else:
|
||
|
docstring = ''
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', name),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'union'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])),
|
||
|
('json_type', 'forward_decl'),
|
||
|
('docstring', docstring),
|
||
|
])
|
||
|
else:
|
||
|
if self.name:
|
||
|
union_doc = get_union_docs(self.name) # NOQA
|
||
|
elif self.parent.name:
|
||
|
union_doc = get_union_docs(self.parent.name) # NOQA
|
||
|
else:
|
||
|
union_doc = None
|
||
|
|
||
|
if union_doc is not None:
|
||
|
docstring = union_doc.description
|
||
|
else:
|
||
|
docstring = ''
|
||
|
|
||
|
fields = []
|
||
|
|
||
|
for field in self.decls:
|
||
|
field = field.to_dict()
|
||
|
|
||
|
if union_doc is not None:
|
||
|
for field_doc in union_doc.fields:
|
||
|
if field_doc.name == field['name']:
|
||
|
field_docstring = field_doc.description
|
||
|
break
|
||
|
else:
|
||
|
field_docstring = ''
|
||
|
else:
|
||
|
field_docstring = ''
|
||
|
|
||
|
field['docstring'] = field_docstring
|
||
|
field['json_type'] = 'field'
|
||
|
fields.append(field)
|
||
|
|
||
|
res = OrderedDict([
|
||
|
('name', self.name),
|
||
|
('type', OrderedDict([
|
||
|
('name', 'union'),
|
||
|
('json_type', 'primitive_type')
|
||
|
])),
|
||
|
('json_type', 'union'),
|
||
|
('docstring', docstring),
|
||
|
('fields', fields)
|
||
|
])
|
||
|
|
||
|
return res
|
||
|
|
||
|
|
||
|
for cls in (
|
||
|
ArrayDecl,
|
||
|
Constant,
|
||
|
Decl,
|
||
|
EllipsisParam,
|
||
|
Enum,
|
||
|
Enumerator,
|
||
|
EnumeratorList,
|
||
|
EnumeratorList,
|
||
|
FileAST,
|
||
|
FuncDecl,
|
||
|
FuncDef,
|
||
|
IdentifierType,
|
||
|
ParamList,
|
||
|
PtrDecl,
|
||
|
Struct,
|
||
|
TypeDecl,
|
||
|
Typedef,
|
||
|
Typename,
|
||
|
Union
|
||
|
):
|
||
|
cls_name = cls.__name__
|
||
|
setattr(getattr(sys.modules['pycparser.c_parser'], 'c_ast'), cls_name, cls)
|