summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/scripts/ffi_decls.py
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/scripts/ffi_decls.py')
-rwxr-xr-xcomm/third_party/botan/src/scripts/ffi_decls.py113
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)