#!/usr/bin/env python import sys class CType: def __init__(self, name): self.name = name def __str__(self): return self.name class GMPAPI: def __init__(self, ret_ty, name, *params, **kw): out = kw.get("out", [0]) inout = kw.get("inout", []) mixed = kw.get("mixed", False) custom = kw.get("custom", False) self.name = name self.ret_ty = ret_ty self.params = params self.inout_params = inout self.custom_test = custom # most functions with return results dont need extra out params # set mixed to true to check both the return value and an out param if self.ret_ty != void and not mixed: self.out_params = [] else: self.out_params = out # param location of the output result def is_write_only(self, pos): if pos in self.out_params and pos not in self.inout_params: return True return False def __str__(self): return "{} {}({})".format( self.ret_ty, self.name, ",".join(map(str, self.params)) ) def __repr__(self): return str(self) void = CType("void") voidp = CType("void *") charp = CType("char *") iint = CType("int") size_t = CType("size_t") size_tp = CType("size_t*") ilong = CType("long") ulong = CType("unsigned long") mpz_t = CType("mpz_t") mpq_t = CType("mpq_t") apis = [ GMPAPI(void, "mpz_abs", mpz_t, mpz_t), GMPAPI(void, "mpz_add", mpz_t, mpz_t, mpz_t), GMPAPI(iint, "mpz_cmp_si", mpz_t, ilong), GMPAPI(iint, "mpz_cmpabs", mpz_t, mpz_t), GMPAPI(iint, "mpz_cmp", mpz_t, mpz_t), GMPAPI(void, "mpz_mul", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_neg", mpz_t, mpz_t), GMPAPI(void, "mpz_set_si", mpz_t, ilong), GMPAPI(void, "mpz_set", mpz_t, mpz_t), GMPAPI(void, "mpz_sub", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_swap", mpz_t, mpz_t, out=[0, 1], inout=[0, 1]), GMPAPI(iint, "mpz_sgn", mpz_t), GMPAPI(void, "mpz_addmul", mpz_t, mpz_t, mpz_t, inout=[0]), GMPAPI(void, "mpz_divexact", mpz_t, mpz_t, mpz_t), GMPAPI(iint, "mpz_divisible_p", mpz_t, mpz_t), GMPAPI(void, "mpz_submul", mpz_t, mpz_t, mpz_t, inout=[0]), GMPAPI(void, "mpz_set_ui", mpz_t, ulong), GMPAPI(void, "mpz_add_ui", mpz_t, mpz_t, ulong), GMPAPI(void, "mpz_divexact_ui", mpz_t, mpz_t, ulong), GMPAPI(void, "mpz_mul_ui", mpz_t, mpz_t, ulong), GMPAPI(void, "mpz_pow_ui", mpz_t, mpz_t, ulong), GMPAPI(void, "mpz_sub_ui", mpz_t, mpz_t, ulong), GMPAPI(void, "mpz_cdiv_q", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_fdiv_q", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_fdiv_r", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_tdiv_q", mpz_t, mpz_t, mpz_t), GMPAPI(ulong, "mpz_fdiv_q_ui", mpz_t, mpz_t, ulong, out=[0], mixed=True), GMPAPI(ilong, "mpz_get_si", mpz_t), GMPAPI(ulong, "mpz_get_ui", mpz_t), GMPAPI(void, "mpz_gcd", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_lcm", mpz_t, mpz_t, mpz_t), GMPAPI(void, "mpz_mul_2exp", mpz_t, mpz_t, ulong), GMPAPI( void, "mpz_export", voidp, size_tp, iint, size_t, iint, size_t, mpz_t, custom=True, ), # The mpz_import signature is a bit of a lie, but it is ok because it is custom GMPAPI( void, "mpz_import", voidp, size_t, iint, size_t, iint, size_t, mpz_t, custom=True, ), GMPAPI(size_t, "mpz_sizeinbase", mpz_t, iint), GMPAPI(charp, "mpz_get_str", charp, iint, mpz_t), # mpq functions GMPAPI(iint, "mpq_set_str", mpq_t, charp, iint, out=[0], mixed=True), GMPAPI(void, "mpq_canonicalize", mpq_t, inout=[0]), GMPAPI(iint, "mpq_cmp", mpq_t, mpq_t), GMPAPI(void, "mpq_mul", mpq_t, mpq_t, mpq_t), GMPAPI(void, "mpq_set", mpq_t, mpq_t), GMPAPI(void, "mpq_set_ui", mpq_t, ulong, ulong), GMPAPI(iint, "mpq_sgn", mpq_t), GMPAPI(charp, "mpq_get_str", charp, iint, mpq_t), ] def get_api(name): for a in apis: if a.name == name: return a raise RuntimeError("Unknown api: {}".format(name))