134 lines · python
1#!/usr/bin/env python2 3import sys4 5 6class CType:7 def __init__(self, name):8 self.name = name9 10 def __str__(self):11 return self.name12 13 14class GMPAPI:15 def __init__(self, ret_ty, name, *params, **kw):16 out = kw.get("out", [0])17 inout = kw.get("inout", [])18 mixed = kw.get("mixed", False)19 custom = kw.get("custom", False)20 self.name = name21 self.ret_ty = ret_ty22 self.params = params23 self.inout_params = inout24 self.custom_test = custom25 # most functions with return results dont need extra out params26 # set mixed to true to check both the return value and an out param27 if self.ret_ty != void and not mixed:28 self.out_params = []29 else:30 self.out_params = out # param location of the output result31 32 def is_write_only(self, pos):33 if pos in self.out_params and pos not in self.inout_params:34 return True35 return False36 37 def __str__(self):38 return "{} {}({})".format(39 self.ret_ty, self.name, ",".join(map(str, self.params))40 )41 42 def __repr__(self):43 return str(self)44 45 46void = CType("void")47voidp = CType("void *")48charp = CType("char *")49iint = CType("int")50size_t = CType("size_t")51size_tp = CType("size_t*")52ilong = CType("long")53ulong = CType("unsigned long")54mpz_t = CType("mpz_t")55mpq_t = CType("mpq_t")56 57apis = [58 GMPAPI(void, "mpz_abs", mpz_t, mpz_t),59 GMPAPI(void, "mpz_add", mpz_t, mpz_t, mpz_t),60 GMPAPI(iint, "mpz_cmp_si", mpz_t, ilong),61 GMPAPI(iint, "mpz_cmpabs", mpz_t, mpz_t),62 GMPAPI(iint, "mpz_cmp", mpz_t, mpz_t),63 GMPAPI(void, "mpz_mul", mpz_t, mpz_t, mpz_t),64 GMPAPI(void, "mpz_neg", mpz_t, mpz_t),65 GMPAPI(void, "mpz_set_si", mpz_t, ilong),66 GMPAPI(void, "mpz_set", mpz_t, mpz_t),67 GMPAPI(void, "mpz_sub", mpz_t, mpz_t, mpz_t),68 GMPAPI(void, "mpz_swap", mpz_t, mpz_t, out=[0, 1], inout=[0, 1]),69 GMPAPI(iint, "mpz_sgn", mpz_t),70 GMPAPI(void, "mpz_addmul", mpz_t, mpz_t, mpz_t, inout=[0]),71 GMPAPI(void, "mpz_divexact", mpz_t, mpz_t, mpz_t),72 GMPAPI(iint, "mpz_divisible_p", mpz_t, mpz_t),73 GMPAPI(void, "mpz_submul", mpz_t, mpz_t, mpz_t, inout=[0]),74 GMPAPI(void, "mpz_set_ui", mpz_t, ulong),75 GMPAPI(void, "mpz_add_ui", mpz_t, mpz_t, ulong),76 GMPAPI(void, "mpz_divexact_ui", mpz_t, mpz_t, ulong),77 GMPAPI(void, "mpz_mul_ui", mpz_t, mpz_t, ulong),78 GMPAPI(void, "mpz_pow_ui", mpz_t, mpz_t, ulong),79 GMPAPI(void, "mpz_sub_ui", mpz_t, mpz_t, ulong),80 GMPAPI(void, "mpz_cdiv_q", mpz_t, mpz_t, mpz_t),81 GMPAPI(void, "mpz_fdiv_q", mpz_t, mpz_t, mpz_t),82 GMPAPI(void, "mpz_fdiv_r", mpz_t, mpz_t, mpz_t),83 GMPAPI(void, "mpz_tdiv_q", mpz_t, mpz_t, mpz_t),84 GMPAPI(ulong, "mpz_fdiv_q_ui", mpz_t, mpz_t, ulong, out=[0], mixed=True),85 GMPAPI(ilong, "mpz_get_si", mpz_t),86 GMPAPI(ulong, "mpz_get_ui", mpz_t),87 GMPAPI(void, "mpz_gcd", mpz_t, mpz_t, mpz_t),88 GMPAPI(void, "mpz_lcm", mpz_t, mpz_t, mpz_t),89 GMPAPI(void, "mpz_mul_2exp", mpz_t, mpz_t, ulong),90 GMPAPI(91 void,92 "mpz_export",93 voidp,94 size_tp,95 iint,96 size_t,97 iint,98 size_t,99 mpz_t,100 custom=True,101 ),102 # The mpz_import signature is a bit of a lie, but it is ok because it is custom103 GMPAPI(104 void,105 "mpz_import",106 voidp,107 size_t,108 iint,109 size_t,110 iint,111 size_t,112 mpz_t,113 custom=True,114 ),115 GMPAPI(size_t, "mpz_sizeinbase", mpz_t, iint),116 GMPAPI(charp, "mpz_get_str", charp, iint, mpz_t),117 # mpq functions118 GMPAPI(iint, "mpq_set_str", mpq_t, charp, iint, out=[0], mixed=True),119 GMPAPI(void, "mpq_canonicalize", mpq_t, inout=[0]),120 GMPAPI(iint, "mpq_cmp", mpq_t, mpq_t),121 GMPAPI(void, "mpq_mul", mpq_t, mpq_t, mpq_t),122 GMPAPI(void, "mpq_set", mpq_t, mpq_t),123 GMPAPI(void, "mpq_set_ui", mpq_t, ulong, ulong),124 GMPAPI(iint, "mpq_sgn", mpq_t),125 GMPAPI(charp, "mpq_get_str", charp, iint, mpq_t),126]127 128 129def get_api(name):130 for a in apis:131 if a.name == name:132 return a133 raise RuntimeError("Unknown api: {}".format(name))134