diff options
Diffstat (limited to 'comm/third_party/botan/src/scripts/ffi_decls.py')
-rwxr-xr-x | comm/third_party/botan/src/scripts/ffi_decls.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/scripts/ffi_decls.py b/comm/third_party/botan/src/scripts/ffi_decls.py new file mode 100755 index 0000000000..b336e61f53 --- /dev/null +++ b/comm/third_party/botan/src/scripts/ffi_decls.py @@ -0,0 +1,113 @@ +#!/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_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', 'uint8_t']: # hack + 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)) + +GROUP = None + +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_group = fn_name.split('_')[1] + if fn_group == 'privkey': + fn_group = 'pubkey' # hack + + global GROUP + + if fn_group != GROUP: + if fn_group in ['rng', 'hash', 'mac', 'cipher', 'block', 'mp', 'pubkey', 'pk', 'x509', 'hotp', 'totp', 'fpe']: + print("\n # ", fn_group.upper()) + else: + print("") + GROUP = fn_group + + + fn_args = [] + + 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) + + decl = " ffi_api(dll.%s," % (fn_name) + if len(fn_args) > 4: + decl += "\n " + else: + decl += ' ' + + decl += '[' + ', '.join(fn_args) + '])' + + print(decl) + +ast = parse_file(ffi_header, use_cpp=True, cpp_args=['-Ibuild/include', '-std=c89', '-DBOTAN_DLL=']) +v = FuncDefVisitor() +v.visit(ast) |