Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def find_type_r(self, ID, node):
if type(node) is c_ast.FuncDef:
for param in node.decl.type.args.params:
t = self.find_type_r(ID, param)
if t is not None:
return t
elif type(node) is c_ast.Compound:
for c in node.block_items:
t = self.find_type_r(ID, c)
if t is not None:
return t
elif type(node) is c_ast.Struct:
return node.name
elif type(node) is c_ast.Decl:
if node.name == ID: # if name matches
return self.find_type_r(ID, node.type)
elif type(node) is c_ast.TypeDecl:
if node.declname == ID: # if name matches
return self.find_type_r(ID, node.type)
elif type(node) is c_ast.IdentifierType:
return node.names[0]
elif type(node) is c_ast.RFTemplateKeyword:
return node.name
elif type(node) is c_ast.StructRef:
return self.find_struct_member_type(node.name, node.field)
elif type(node) is c_ast.PtrDecl:
# for now no special pointer handling. Just add the asterisk in the
# type string
return self.find_type_r(ID, node.type) + "*"
The last external node of the string is used, to allow earlier typedefs
for used types.
expand_struct=True will spell out struct definitions recursively.
expand_typedef=True will expand typedef'd types.
"""
parser = c_parser.CParser()
try:
node = parser.parse(c_decl, filename='')
except c_parser.ParseError:
e = sys.exc_info()[1]
return "Parse error:" + str(e)
if (not isinstance(node, c_ast.FileAST) or
not isinstance(node.ext[-1], c_ast.Decl)
):
return "Not a valid declaration"
try:
expanded = expand_struct_typedef(node.ext[-1], node,
expand_struct=expand_struct,
expand_typedef=expand_typedef)
except Exception as e:
return "Not a valid declaration: " + str(e)
return _explain_decl_node(expanded)
def decl(name, type):
return node.Decl(name, [], [], [], type, None, None)
decls_0_tail.declname = spec['type'][-1].names[0]
del spec['type'][-1]
for decl in decls:
assert decl['decl'] is not None
if is_typedef:
declaration = c_ast.Typedef(
name=None,
quals=spec['qual'],
storage=spec['storage'],
#funcspec=spec['function'],
type=decl['decl'],
coord=decl['decl'].coord)
else:
declaration = c_ast.Decl(
name=None,
quals=spec['qual'],
storage=spec['storage'],
funcspec=spec['function'],
type=decl['decl'],
init=decl.get('init'),
bitsize=decl.get('bitsize'),
coord=decl['decl'].coord)
if isinstance(declaration.type,
(c_ast.Struct, c_ast.Union, c_ast.IdentifierType)):
fixed_decl = declaration
else:
fixed_decl = self._fix_decl_name_type(declaration, spec['type'])
# Add the type name defined by typedef to a
# now feed preprocessor. Create temp file and write our code into it.
with tempfile.NamedTemporaryFile('w+t') as temp_file:
# to enable use of already known types in header, we should generate C definitions for them and include
# before header code. We should skip them in generated AST.
temp_file.write(self._generateTypedefsCode(parse_context) + '\n\n')
temp_file.write(text)
temp_file.flush()
try:
ast = pycparser.parse_file(temp_file.name, use_cpp=True, cpp_path=self.cppPath, cpp_args=self.cppArgs)
except pycparser.plyparser.ParseError as err:
raise ParseError(str(err))
# now process AST
for ext in ast.ext:
if isinstance(ext, pycparser.c_ast.Decl):
if isinstance(ext.type, pycparser.c_ast.Struct):
# something like 'struct A { int x; }'
self._processStruct(parse_context, ext.type)
elif isinstance(ext.type, pycparser.c_ast.TypeDecl) and isinstance(ext.type.type, pycparser.c_ast.Struct):
# something like 'struct A { int x; } my_var;'
self._processStruct(parse_context, ext.type.type)
elif isinstance(ext, pycparser.c_ast.Typedef):
self._processTypedef(parse_context, ext)
return parse_context
self._process_macros(macros)
# find the first "__dotdotdot__" and use that as a separator
# between the repeated typedefs and the real csource
iterator = iter(ast.ext)
for decl in iterator:
if decl.name == '__dotdotdot__':
break
else:
assert 0
current_decl = None
#
try:
self._inside_extern_python = '__cffi_extern_python_stop'
for decl in iterator:
current_decl = decl
if isinstance(decl, pycparser.c_ast.Decl):
self._parse_decl(decl)
elif isinstance(decl, pycparser.c_ast.Typedef):
if not decl.name:
raise CDefError("typedef does not declare any name",
decl)
quals = 0
if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType) and
decl.type.type.names[-1].startswith('__dotdotdot')):
realtype = self._get_unknown_type(decl)
elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and
isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and
isinstance(decl.type.type.type,
pycparser.c_ast.IdentifierType) and
decl.type.type.type.names[-1].startswith('__dotdotdot')):
realtype = self._get_unknown_ptr_type(decl)
else:
c_ast.Decl: self.ast_to_typeid_decl,
c_ast.Typename: self.ast_to_typeid_typename,
c_ast.FuncDecl: self.ast_to_typeid_funcdecl,
c_ast.Enum: self.ast_to_typeid_enum,
c_ast.PtrDecl: self.ast_to_typeid_ptrdecl,
c_ast.EllipsisParam: self.ast_to_typeid_ellipsisparam,
c_ast.ArrayDecl: self.ast_to_typeid_arraydecl,
}
self.ast_parse_rules = {
c_ast.Struct: self.ast_parse_struct,
c_ast.Union: self.ast_parse_union,
c_ast.Typedef: self.ast_parse_typedef,
c_ast.TypeDecl: self.ast_parse_typedecl,
c_ast.IdentifierType: self.ast_parse_identifiertype,
c_ast.Decl: self.ast_parse_decl,
c_ast.PtrDecl: self.ast_parse_ptrdecl,
c_ast.Enum: self.ast_parse_enum,
c_ast.ArrayDecl: self.ast_parse_arraydecl,
c_ast.FuncDecl: self.ast_parse_funcdecl,
c_ast.FuncDef: self.ast_parse_funcdef,
c_ast.Pragma: self.ast_parse_pragma,
}
decls_0_tail = decls_0_tail.type
if decls_0_tail.declname is None:
decls_0_tail.declname = spec['type'][-1].names[0]
del spec['type'][-1]
for decl in decls:
assert decl['decl'] is not None
if is_typedef:
declaration = c_ast.Typedef(
name=None,
quals=spec['qual'],
storage=spec['storage'],
type=decl['decl'],
coord=decl['decl'].coord)
else:
declaration = c_ast.Decl(
name=None,
quals=spec['qual'],
storage=spec['storage'],
funcspec=spec['function'],
type=decl['decl'],
init=decl.get('init'),
bitsize=decl.get('bitsize'),
coord=decl['decl'].coord)
if isinstance(declaration.type,
(c_ast.Struct, c_ast.Union, c_ast.IdentifierType)):
fixed_decl = declaration
else:
fixed_decl = self._fix_decl_name_type(declaration, spec['type'])
# Add the type name defined by typedef to a