diff options
Diffstat (limited to 'src/scripts/ffi_decls.py')
-rwxr-xr-x | src/scripts/ffi_decls.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/scripts/ffi_decls.py b/src/scripts/ffi_decls.py new file mode 100755 index 000000000..70bd8e2cf --- /dev/null +++ b/src/scripts/ffi_decls.py @@ -0,0 +1,89 @@ +#!/usr/bin/python + +""" +Automatically generate declarations for the FFI layer + +(C) 2019 Jack Lloyd + +Botan is released under the Simplified BSD License (see license.txt) +""" + +from pycparser import c_parser, c_ast, parse_file + +ffi_header = 'src/lib/ffi/ffi.h' + +def to_ctype(typ, is_ptr): + + if typ.startswith('botan_') and typ.endswith('_t'): + return 'c_void_p' + + if is_ptr is False: + if typ == 'uint32': + return 'c_uint32' + elif typ == 'size_t': + return 'c_size_t' + elif typ == 'uint8_t': + return 'c_uint8' + elif typ == 'uint32_t': + return 'c_uint32' + elif typ == 'uint64_t': + return 'c_uint64' + elif typ == 'int': + return 'c_int' + elif typ == 'unsigned': + return 'c_uint' + else: + if typ == 'void': + return 'c_void_p' + elif typ in ['char']: + return 'c_char_p' + elif typ == 'size_t': + return 'POINTER(c_size_t)' + elif typ == 'uint8_t': + return 'POINTER(c_uint8)' + elif typ == 'uint32_t': + return 'POINTER(c_uint32)' + elif typ == 'uint64_t': + return 'POINTER(c_uint64)' + elif typ == 'int': + return 'POINTER(c_int)' + + raise Exception("Unknown type %s/%d" % (typ, is_ptr)) + +class FuncDefVisitor(c_ast.NodeVisitor): + def visit_FuncDecl(self, node): + + if not isinstance(node.type, c_ast.TypeDecl): + #print("ignoring", node.type) + return + + if node.type.type.names != ['int']: + #print("ignoring", node.type) + return + + # all functions returning ints: + fn_name = node.type.declname + + fn_args = [fn_name] + + for param in node.args.params: + + is_ptr = False + typ = None + if isinstance(param.type, c_ast.PtrDecl): + is_ptr = True + typ = param.type.type.type.names[0] + elif isinstance(param.type, c_ast.ArrayDecl): + is_ptr = True + typ = param.type.type.type.names[0] + else: + typ = param.type.type.names[0] + + ctype = to_ctype(typ, is_ptr) + fn_args.append(ctype) + + print(fn_args) + +ast = parse_file(ffi_header, use_cpp=True, cpp_args=['-Ibuild/include', '-std=c89', '-DBOTAN_DLL=']) +v = FuncDefVisitor() +v.visit(ast) |