text: #!/usr/bin/env python3
  
  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))
  