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(self.ret_ty, self.name, ",".join(
39            map(str, self.params))))
40
41    def __repr__(self):
42        return str(self)
43
44
45void = CType("void")
46voidp = CType("void *")
47charp = CType("char *")
48iint = CType("int")
49size_t = CType("size_t")
50size_tp = CType("size_t*")
51ilong = CType("long")
52ulong = CType("unsigned long")
53mpz_t = CType("mpz_t")
54mpq_t = CType("mpq_t")
55
56apis = [
57    GMPAPI(void, "mpz_abs", mpz_t, mpz_t),
58    GMPAPI(void, "mpz_add", mpz_t, mpz_t, mpz_t),
59    GMPAPI(iint, "mpz_cmp_si", mpz_t, ilong),
60    GMPAPI(iint, "mpz_cmpabs", mpz_t, mpz_t),
61    GMPAPI(iint, "mpz_cmp", mpz_t, mpz_t),
62    GMPAPI(void, "mpz_mul", mpz_t, mpz_t, mpz_t),
63    GMPAPI(void, "mpz_neg", mpz_t, mpz_t),
64    GMPAPI(void, "mpz_set_si", mpz_t, ilong),
65    GMPAPI(void, "mpz_set", mpz_t, mpz_t),
66    GMPAPI(void, "mpz_sub", mpz_t, mpz_t, mpz_t),
67    GMPAPI(void, "mpz_swap", mpz_t, mpz_t, out=[0, 1], inout=[0, 1]),
68    GMPAPI(iint, "mpz_sgn", mpz_t),
69    GMPAPI(void, "mpz_addmul", mpz_t, mpz_t, mpz_t, inout=[0]),
70    GMPAPI(void, "mpz_divexact", mpz_t, mpz_t, mpz_t),
71    GMPAPI(iint, "mpz_divisible_p", mpz_t, mpz_t),
72    GMPAPI(void, "mpz_submul", mpz_t, mpz_t, mpz_t, inout=[0]),
73    GMPAPI(void, "mpz_set_ui", mpz_t, ulong),
74    GMPAPI(void, "mpz_add_ui", mpz_t, mpz_t, ulong),
75    GMPAPI(void, "mpz_divexact_ui", mpz_t, mpz_t, ulong),
76    GMPAPI(void, "mpz_mul_ui", mpz_t, mpz_t, ulong),
77    GMPAPI(void, "mpz_pow_ui", mpz_t, mpz_t, ulong),
78    GMPAPI(void, "mpz_sub_ui", mpz_t, mpz_t, ulong),
79    GMPAPI(void, "mpz_cdiv_q", mpz_t, mpz_t, mpz_t),
80    GMPAPI(void, "mpz_fdiv_q", mpz_t, mpz_t, mpz_t),
81    GMPAPI(void, "mpz_fdiv_r", mpz_t, mpz_t, mpz_t),
82    GMPAPI(void, "mpz_tdiv_q", mpz_t, mpz_t, mpz_t),
83    GMPAPI(ulong, "mpz_fdiv_q_ui", mpz_t, mpz_t, ulong, out=[0], mixed=True),
84    GMPAPI(ilong, "mpz_get_si", mpz_t),
85    GMPAPI(ulong, "mpz_get_ui", mpz_t),
86    GMPAPI(void, "mpz_gcd", mpz_t, mpz_t, mpz_t),
87    GMPAPI(void, "mpz_lcm", mpz_t, mpz_t, mpz_t),
88    GMPAPI(void, "mpz_mul_2exp", mpz_t, mpz_t, ulong),
89    GMPAPI(
90        void,
91        "mpz_export",
92        voidp,
93        size_tp,
94        iint,
95        size_t,
96        iint,
97        size_t,
98        mpz_t,
99        custom=True),
100    # The mpz_import signature is a bit of a lie, but it is ok because it is custom
101    GMPAPI(
102        void,
103        "mpz_import",
104        voidp,
105        size_t,
106        iint,
107        size_t,
108        iint,
109        size_t,
110        mpz_t,
111        custom=True),
112    GMPAPI(size_t, "mpz_sizeinbase", mpz_t, iint),
113    GMPAPI(charp, "mpz_get_str", charp, iint, mpz_t),
114
115    # mpq functions
116    GMPAPI(iint, "mpq_set_str", mpq_t, charp, iint, out=[0], mixed=True),
117    GMPAPI(void, "mpq_canonicalize", mpq_t, inout=[0]),
118    GMPAPI(iint, "mpq_cmp", mpq_t, mpq_t),
119    GMPAPI(void, "mpq_mul", mpq_t, mpq_t, mpq_t),
120    GMPAPI(void, "mpq_set", mpq_t, mpq_t),
121    GMPAPI(void, "mpq_set_ui", mpq_t, ulong, ulong),
122    GMPAPI(iint, "mpq_sgn", mpq_t),
123    GMPAPI(charp, "mpq_get_str", charp, iint, mpq_t),
124]
125
126
127def get_api(name):
128    for a in apis:
129        if a.name == name:
130            return a
131    raise RuntimeError("Unknown api: {}".format(name))
132