*.c: Introduce a new input conversion for binary strings.
[catacomb-python] / mp.c
diff --git a/mp.c b/mp.c
index 2fc82b2..0da3a5e 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -45,12 +45,12 @@ mp *mp_frompylong(PyObject *obj)
   mp *x;
   mpw *p;
 
-  sz = l->ob_size;
+  sz = Py_SIZE(l);
   if (sz < 0) sz = -sz;
   assert(MPW_BITS >= SHIFT);
   bits = (unsigned long)sz * SHIFT;
   w = (bits + MPW_BITS - 1)/MPW_BITS;
-  x = mp_new(w, l->ob_size < 0 ? MP_NEG : 0);
+  x = mp_new(w, Py_SIZE(l) < 0 ? MP_NEG : 0);
   p = x->v;
   for (i = 0; i < sz; i++) {
     r |= (mpd)l->ob_digit[i] << b;
@@ -94,7 +94,7 @@ PyObject *mp_topylong(mp *x)
     l->ob_digit[i++] = r & MASK;
     r >>= SHIFT;
   }
-  l->ob_size = (x->f & MP_NEG) ? -sz : sz;
+  Py_SIZE(l) = (x->f & MP_NEG) ? -sz : sz;
   return ((PyObject *)l);
 }
 
@@ -238,7 +238,7 @@ mp *getmp(PyObject *o)
   if (!o) return (0);
   if ((x = tomp(o)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp",
-                o->ob_type->tp_name);
+                Py_TYPE(o)->tp_name);
   }
   return (x);
 }
@@ -257,7 +257,7 @@ mp *getgf(PyObject *o)
   if (!o) return (0);
   if ((x = tomp(o)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf",
-                o->ob_type->tp_name);
+                Py_TYPE(o)->tp_name);
   }
   return (x);
 }
@@ -536,7 +536,7 @@ static PyObject *mp_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   if (!good_radix_p(radix, 1)) VALERR("bad radix");
   if ((z = mp_frompyobject(x, radix)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to mp",
-                x->ob_type->tp_name);
+                Py_TYPE(x)->tp_name);
     goto end;
   }
   zz = (mp_pyobj *)ty->tp_alloc(ty, 0);
@@ -545,14 +545,14 @@ end:
   return ((PyObject *)zz);
 }
 
-long mphash(mp *x)
+Py_hash_t mphash(mp *x)
 {
   PyObject *l = mp_topylong(x);
-  long h = PyObject_Hash(l);
+  Py_hash_t h = PyObject_Hash(l);
   Py_DECREF(l); return (h);
 }
 
-static long mp_pyhash(PyObject *me) { return (mphash(MP_X(me))); }
+static Py_hash_t mp_pyhash(PyObject *me) { return (mphash(MP_X(me))); }
 
 static PyObject *mpmeth_jacobi(PyObject *me, PyObject *arg)
 {
@@ -723,13 +723,12 @@ STOREOP(storeb2c, 2c)
   static PyObject *ty##meth_frombuf(PyObject *me, PyObject *arg)       \
   {                                                                    \
     buf b;                                                             \
-    char *p;                                                           \
-    Py_ssize_t sz;                                                     \
+    struct bin in;                                                     \
     PyObject *rc = 0;                                                  \
     mp *x;                                                             \
                                                                        \
-    if (!PyArg_ParseTuple(arg, "s#:frombuf", &p, &sz)) goto end;       \
-    buf_init(&b, p, sz);                                               \
+    if (!PyArg_ParseTuple(arg, "O&:frombuf", convbin, &in)) goto end;  \
+    buf_init(&b, (/*unconst*/ void *)in.p, in.sz);                     \
     if ((x = buf_getmp(&b)) == 0) VALERR("malformed data");            \
     rc = Py_BuildValue("(NN)", ty##_pywrap(x),                         \
                       bytestring_pywrapbuf(&b));                       \
@@ -815,10 +814,9 @@ static PyObject *mpmeth_fibonacci(PyObject *me, PyObject *arg)
 #define LOADOP(pre, name)                                              \
   static PyObject *pre##meth_##name(PyObject *me, PyObject *arg)       \
   {                                                                    \
-    char *p;                                                           \
-    Py_ssize_t len;                                                    \
-    if (!PyArg_ParseTuple(arg, "s#:" #name, &p, &len)) return (0);     \
-    return (pre##_pywrap(mp_##name(MP_NEW, p, len)));                  \
+    struct bin in;                                                     \
+    if (!PyArg_ParseTuple(arg, "O&:" #name, convbin, &in)) return (0); \
+    return (pre##_pywrap(mp_##name(MP_NEW, in.p, in.sz)));             \
   }
 LOADOP(mp, loadl)
 LOADOP(mp, loadb)
@@ -931,8 +929,8 @@ static const PyNumberMethods mp_pynumber = {
   0,                                   /* @nb_inplace_true_divide@ */
 };
 
-static PyTypeObject mp_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mp_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MP",                                        /* @tp_name@ */
   sizeof(mp_pyobj),                    /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -995,6 +993,8 @@ static PyTypeObject mp_pytype_skel = {
 
 /*----- Products of small integers ----------------------------------------*/
 
+static PyTypeObject *mpmul_pytype;
+
 typedef struct mpmul_pyobj {
   PyObject_HEAD
   int livep;
@@ -1088,8 +1088,8 @@ static const PyMethodDef mpmul_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *mpmul_pytype, mpmul_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mpmul_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MPMul",                             /* @tp_name@ */
   sizeof(mpmul_pyobj),                 /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -1138,6 +1138,8 @@ static PyTypeObject *mpmul_pytype, mpmul_pytype_skel = {
 
 /*----- Montgomery reduction ----------------------------------------------*/
 
+static PyTypeObject *mpmont_pytype;
+
 typedef struct mpmont_pyobj {
   PyObject_HEAD
   mpmont mm;
@@ -1355,8 +1357,8 @@ static const PyMethodDef mpmont_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *mpmont_pytype, mpmont_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mpmont_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MPMont",                            /* @tp_name@ */
   sizeof(mpmont_pyobj),                        /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -1405,6 +1407,8 @@ static PyTypeObject *mpmont_pytype, mpmont_pytype_skel = {
 
 /*----- Barrett reduction -------------------------------------------------*/
 
+static PyTypeObject *mpbarrett_pytype;
+
 typedef struct mpbarrett_pyobj {
   PyObject_HEAD
   mpbarrett mb;
@@ -1494,8 +1498,8 @@ static const PyMethodDef mpbarrett_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *mpbarrett_pytype, mpbarrett_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mpbarrett_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MPBarrett",                         /* @tp_name@ */
   sizeof(mpbarrett_pyobj),             /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -1544,6 +1548,8 @@ static PyTypeObject *mpbarrett_pytype, mpbarrett_pytype_skel = {
 
 /*----- Nice prime reduction ----------------------------------------------*/
 
+static PyTypeObject *mpreduce_pytype;
+
 typedef struct mpreduce_pyobj {
   PyObject_HEAD
   mpreduce mr;
@@ -1622,8 +1628,8 @@ static const const PyMethodDef mpreduce_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *mpreduce_pytype, mpreduce_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mpreduce_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MPReduce",                          /* @tp_name@ */
   sizeof(mpreduce_pyobj),              /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -1672,6 +1678,8 @@ static PyTypeObject *mpreduce_pytype, mpreduce_pytype_skel = {
 
 /*----- Chinese Remainder Theorem solution --------------------------------*/
 
+static PyTypeObject *mpcrt_pytype;
+
 typedef struct mpcrt_pyobj {
   PyObject_HEAD
   mpcrt c;
@@ -1804,8 +1812,8 @@ static const PyMethodDef mpcrt_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *mpcrt_pytype, mpcrt_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject mpcrt_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "MPCRT",                             /* @tp_name@ */
   sizeof(mpcrt_pyobj),                 /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -1897,7 +1905,7 @@ static PyObject *gf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
   if (!good_radix_p(radix, 1)) VALERR("radix out of range");
   if ((z = mp_frompyobject(x, radix)) == 0) {
     PyErr_Format(PyExc_TypeError, "can't convert %.100s to gf",
-                x->ob_type->tp_name);
+                Py_TYPE(x)->tp_name);
     goto end;
   }
   if (MP_NEGP(z)) {
@@ -2104,8 +2112,8 @@ static const PyNumberMethods gf_pynumber = {
   0,                                   /* @nb_inplace_true_divide@ */
 };
 
-static PyTypeObject gf_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject gf_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "GF",                                        /* @tp_name@ */
   sizeof(mp_pyobj),                    /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -2169,6 +2177,8 @@ static PyTypeObject gf_pytype_skel = {
 
 /*----- Sparse poly reduction ---------------------------------------------*/
 
+static PyTypeObject *gfreduce_pytype;
+
 typedef struct gfreduce_pyobj {
   PyObject_HEAD
   gfreduce mr;
@@ -2303,8 +2313,8 @@ static const PyMethodDef gfreduce_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject *gfreduce_pytype, gfreduce_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject gfreduce_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "GFReduce",                          /* @tp_name@ */
   sizeof(gfreduce_pyobj),              /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -2353,14 +2363,14 @@ static PyTypeObject *gfreduce_pytype, gfreduce_pytype_skel = {
 
 /*----- Normal/poly transformation ----------------------------------------*/
 
+static PyTypeObject *gfn_pytype;
+
 typedef struct gfn_pyobj {
   PyObject_HEAD
   mp *p;
   gfn ntop, pton;
 } gfn_pyobj;
 
-static PyTypeObject *gfn_pytype, gfn_pytype_skel;
-
 #define GFN_P(o) (((gfn_pyobj *)(o))->p)
 #define GFN_PTON(o) (&((gfn_pyobj *)(o))->pton)
 #define GFN_NTOP(o) (&((gfn_pyobj *)(o))->ntop)
@@ -2441,8 +2451,8 @@ static const PyMethodDef gfn_pymethods[] = {
   { 0 }
 };
 
-static PyTypeObject gfn_pytype_skel = {
-  PyObject_HEAD_INIT(0) 0,             /* Header */
+static const PyTypeObject gfn_pytype_skel = {
+  PyVarObject_HEAD_INIT(0, 0)          /* Header */
   "GFN",                               /* @tp_name@ */
   sizeof(gfn_pyobj),                   /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
@@ -2492,6 +2502,11 @@ static PyTypeObject gfn_pytype_skel = {
 
 /*----- Glue --------------------------------------------------------------*/
 
+static const struct nameval consts[] = {
+  CONST(MPW_MAX),
+  { 0 }
+};
+
 void mp_pyinit(void)
 {
   INITTYPE(mp, root);
@@ -2516,6 +2531,7 @@ void mp_pyinsert(PyObject *mod)
   INSERT("GF", gf_pytype);
   INSERT("GFReduce", gfreduce_pytype);
   INSERT("GFN", gfn_pytype);
+  setconstants(mod, consts);
 }
 
 /*----- That's all, folks -------------------------------------------------*/