1#!/usr/bin/env python 2 3import sys 4 5 6class CType: 7 def __init__(self, name): 8 self.name = name 9 10 def __str__(self): 11 return self.name 12 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 = name 21 self.ret_ty = ret_ty 22 self.params = params 23 self.inout_params = inout 24 self.custom_test = custom 25 # most functions with return results dont need extra out params 26 # set mixed to true to check both the return value and an out param 27 if self.ret_ty != void and not mixed: 28 self.out_params = [] 29 else: 30 self.out_params = out # param location of the output result 31 32 def is_write_only(self, pos): 33 if pos in self.out_params and pos not in self.inout_params: 34 return True 35 return False 36 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 custom 103 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 functions 118 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 a 133 raise RuntimeError("Unknown api: {}".format(name)) 134