Return `long' objects when `int' is requested but the value won't fit.
[catacomb-python] / mp.c
diff --git a/mp.c b/mp.c
index 1177a60..f5f4320 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -163,7 +163,7 @@ PyObject *gf_pywrap(mp *x)
   return ((PyObject *)z);
 }
 
-int mp_tolong_checked(mp *x, long *l)
+int mp_tolong_checked(mp *x, long *l, int must)
 {
   static mp *longmin = 0, *longmax = 0;
   int rc = -1;
@@ -172,8 +172,10 @@ int mp_tolong_checked(mp *x, long *l)
     longmin = mp_fromlong(MP_NEW, LONG_MIN);
     longmax = mp_fromlong(MP_NEW, LONG_MAX);
   }
-  if (MP_CMP(x, <, longmin) || MP_CMP(x, >, longmax))
-    VALERR("mp out of range for int");
+  if (MP_CMP(x, <, longmin) || MP_CMP(x, >, longmax)) {
+    if (must) VALERR("mp out of range for int");
+    else goto end;
+  }
   *l = mp_tolong(x);
   rc = 0;
 end:
@@ -362,7 +364,7 @@ static PyObject *mp_pyid(PyObject *x) { RETURN_OBJ(x); }
     PyObject *z = 0;                                                   \
     long n;                                                            \
     if (pre##binop(x, y, &xx, &yy)) RETURN_NOTIMPL;                    \
-    if (mp_tolong_checked(yy, &n)) goto end;                           \
+    if (mp_tolong_checked(yy, &n, 1)) goto end;                                \
     if (n < 0)                                                         \
       z = pre##_pywrap(mp_##rname(MP_NEW, xx, -n));                    \
     else                                                               \
@@ -483,8 +485,8 @@ static int mp_pynonzerop(PyObject *x) { return !MP_ZEROP(MP_X(x)); }
 static PyObject *mp_pyint(PyObject *x)
 {
   long l;
-  if (mp_tolong_checked(MP_X(x), &l)) return (0);
-  return (PyInt_FromLong(l));
+  if (!mp_tolong_checked(MP_X(x), &l, 0)) return (PyInt_FromLong(l));
+  else return mp_topylong(MP_X(x));
 }
 static PyObject *mp_pylong(PyObject *x)
   { return (mp_topylong(MP_X(x))); }
@@ -848,7 +850,7 @@ static PyNumberMethods mp_pynumber = {
 
 static PyTypeObject mp_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MP",                       /* @tp_name@ */
+  "MP",                                        /* @tp_name@ */
   sizeof(mp_pyobj),                    /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -921,7 +923,7 @@ static PyObject *meth__MP_fromstring(PyObject *me,
   if (!good_radix_p(r, 1)) VALERR("bad radix");
   sc.buf = p; sc.lim = p + len;
   if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0)
-    SYNERR("bad integer");
+    VALERR("bad integer");
   z = Py_BuildValue("(Ns#)", mp_pywrap(zz), sc.buf, (int)(sc.lim - sc.buf));
 end:
   return (z);
@@ -1060,7 +1062,7 @@ static PyMethodDef mpmul_pymethods[] = {
 
 static PyTypeObject *mpmul_pytype, mpmul_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MPMul",                    /* @tp_name@ */
+  "MPMul",                             /* @tp_name@ */
   sizeof(mpmul_pyobj),                 /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -1309,17 +1311,17 @@ static PyGetSetDef mpmont_pygetset[] = {
 
 static PyMethodDef mpmont_pymethods[] = {
 #define METHNAME(name) mmmeth_##name
-  METH (int,           "M.out(X) -> XR")
+  METH (int,           "M.int(X) -> XR")
   METH (mul,           "M.mul(XR, YR) -> ZR where Z = X Y")
   METH (expr,          "M.expr(XR, N) -> ZR where Z = X^N mod M.m")
   METH (mexpr,         "\
-B.mexp([(XR0, N0), (XR1, N1), ...]) = ZR where Z = X0^N0 X1^N1 mod B.m\n\
+M.mexpr([(XR0, N0), (XR1, N1), ...]) = ZR where Z = X0^N0 X1^N1 ... mod M.m\n\
 \t(the list may be flattened if this more convenient.)")
   METH (reduce,        "M.reduce(XR) -> X")
   METH (ext,           "M.ext(XR) -> X")
   METH (exp,           "M.exp(X, N) -> X^N mod M.m")
   METH (mexp,          "\
-B.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 mod B.m\n\
+M.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 ... mod M.m\n\
 \t(the list may be flattened if this more convenient.)")
 #undef METHNAME
   { 0 }
@@ -1327,7 +1329,7 @@ B.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 mod B.m\n\
 
 static PyTypeObject *mpmont_pytype, mpmont_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MPMont",                   /* @tp_name@ */
+  "MPMont",                            /* @tp_name@ */
   sizeof(mpmont_pyobj),                        /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -1458,7 +1460,7 @@ static PyMethodDef mpbarrett_pymethods[] = {
   METH (reduce,        "B.reduce(X) -> X mod B.m")
   METH (exp,           "B.exp(X, N) -> X^N mod B.m")
   METH (mexp,          "\
-B.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 mod B.m\n\
+B.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 ... mod B.m\n\
 \t(the list may be flattened if this more convenient.)")
 #undef METHNAME
   { 0 }
@@ -1466,7 +1468,7 @@ B.mexp([(X0, N0), (X1, N1), ...]) = X0^N0 X1^N1 mod B.m\n\
 
 static PyTypeObject *mpbarrett_pytype, mpbarrett_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MPBarrett",                        /* @tp_name@ */
+  "MPBarrett",                         /* @tp_name@ */
   sizeof(mpbarrett_pyobj),             /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -1594,7 +1596,7 @@ static PyMethodDef mpreduce_pymethods[] = {
 
 static PyTypeObject *mpreduce_pytype, mpreduce_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MPReduce",                 /* @tp_name@ */
+  "MPReduce",                          /* @tp_name@ */
   sizeof(mpreduce_pyobj),              /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -1763,7 +1765,7 @@ static PyMethodDef mpcrt_pymethods[] = {
 
 static PyTypeObject *mpcrt_pytype, mpcrt_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.MPCRT",                    /* @tp_name@ */
+  "MPCRT",                             /* @tp_name@ */
   sizeof(mpcrt_pyobj),                 /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -2045,7 +2047,7 @@ static PyNumberMethods gf_pynumber = {
 
 static PyTypeObject gf_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.GF",                       /* @tp_name@ */
+  "GF",                                        /* @tp_name@ */
   sizeof(mp_pyobj),                    /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -2123,7 +2125,7 @@ static PyObject *meth__GF_fromstring(PyObject *me,
   if ((zz = mp_read(MP_NEW, r, &mptext_stringops, &sc)) == 0 ||
       MP_NEGP(zz)) {
     if (zz) MP_DROP(zz);
-    SYNERR("bad binary polynomial");
+    VALERR("bad binary polynomial");
   }
   z = Py_BuildValue("(Ns#)", gf_pywrap(zz), sc.buf, (int)(sc.lim - sc.buf));
 end:
@@ -2268,7 +2270,7 @@ static PyMethodDef gfreduce_pymethods[] = {
 
 static PyTypeObject *gfreduce_pytype, gfreduce_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.GFReduce",                 /* @tp_name@ */
+  "GFReduce",                          /* @tp_name@ */
   sizeof(gfreduce_pyobj),              /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */
 
@@ -2402,7 +2404,7 @@ static PyMethodDef gfn_pymethods[] = {
 
 static PyTypeObject gfn_pytype_skel = {
   PyObject_HEAD_INIT(0) 0,             /* Header */
-  "catacomb.GFN",                      /* @tp_name@ */
+  "GFN",                               /* @tp_name@ */
   sizeof(gfn_pyobj),                   /* @tp_basicsize@ */
   0,                                   /* @tp_itemsize@ */