X-Git-Url: https://git.distorted.org.uk/~mdw/pyke/blobdiff_plain/0156e4020eb3b13a1b9bcfa9887eb922ba5d9fa2..8526bbd230c598da6c4890fc8888546f3365b84b:/util.c diff --git a/util.c b/util.c index 8a0c06c..027033e 100644 --- a/util.c +++ b/util.c @@ -28,6 +28,8 @@ #include "catacomb-python.h" +/* #undef HAVE_LONG_LONG */ + /*----- External values ---------------------------------------------------*/ static PyObject *modname = 0; @@ -42,6 +44,35 @@ PyObject *getulong(unsigned long w) return (PyLong_FromUnsignedLong(w)); } +#ifndef HAVE_LONG_LONG +static PyObject *i32 = 0; +static int init_i32(void) + { if (!i32 && (i32 = PyInt_FromLong(32)) == 0) return (-1); return (0); } +#endif + +PyObject *getk64(kludge64 u) +{ +#ifdef HAVE_LONG_LONG + return (PyLong_FromUnsignedLongLong(GET64(unsigned PY_LONG_LONG, u))); +#else + PyObject *i = 0, *j = 0, *t; + PyObject *rc = 0; + + if (init_i32()) goto end; + if ((i = PyLong_FromUnsignedLong(HI64(u))) == 0) goto end; + if ((t = PyNumber_InPlaceLshift(i, i32)) == 0) goto end; + Py_DECREF(i); i = t; + if ((j = PyLong_FromUnsignedLong(LO64(u))) == 0) goto end; + if ((t = PyNumber_InPlaceOr(i, j)) == 0) goto end; + Py_DECREF(i); i = t; + if ((rc = PyNumber_Int(i)) == 0) goto end; +end: + if (i) Py_DECREF(i); + if (j) Py_DECREF(j); + return (rc); +#endif +} + PyObject *getbool(int b) { if (b) RETURN_TRUE; @@ -60,6 +91,7 @@ int convulong(PyObject *o, void *pp) unsigned long *p = pp; PyObject *t; + if (!o) VALERR("can't delete"); if (PyInt_Check(o)) { i = PyInt_AS_LONG(o); if (i < 0) VALERR("must be nonnegative"); @@ -75,15 +107,32 @@ end: return (0); } +#ifdef HAVE_UINT64 +# define CONVu64(n) do { \ + kludge64 k; \ + uint64 t; \ + if (!convk64(o, &k)) goto end; \ + t = GET64(uint64, k); \ + if (t > MASK##n) VALERR("out of range"); \ + *p = t; \ + } while (0) +#else +# define CONVu64(n) assert(!"shouldn't be possible") +#endif + #define CONVU_(n) \ int convu##n(PyObject *o, void *pp) \ { \ unsigned long u; \ uint##n *p = pp; \ \ - if (!convulong(o, &u)) goto end; \ - if (u > MASK##n) VALERR("out of range"); \ - *p = u; \ + if (MASK##n > ULONG_MAX) \ + CONVu64(n); \ + else { \ + if (!convulong(o, &u)) goto end; \ + if (u > MASK##n) VALERR("out of range"); \ + *p = u; \ + } \ return (1); \ end: \ return (0); \ @@ -103,6 +152,42 @@ end: return (0); } +int convk64(PyObject *o, void *pp) +{ + PyObject *i = 0; + int rc = 0; +#if HAVE_LONG_LONG + unsigned PY_LONG_LONG t; +#else + PyObject *t; + uint32 lo, hi; +#endif + + if (!o) VALERR("can't delete"); +#if HAVE_LONG_LONG + if ((i = PyNumber_Long(o)) == 0) goto end; + t = PyLong_AsUnsignedLongLong(i); + if (t == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) goto end; + ASSIGN64(*(kludge64 *)pp, t); +#else + if (init_i32()) goto end; + if ((i = PyNumber_Int(o)) == 0) goto end; + lo = PyInt_AsUnsignedLongMask(i); + if ((t = PyNumber_InPlaceRshift(i, i32)) == 0) goto end; + Py_DECREF(i); i = t; + hi = PyInt_AsUnsignedLongMask(i); + if ((t = PyNumber_InPlaceRshift(i, i32)) == 0) goto end; + Py_DECREF(i); i = t; + if (PyObject_IsTrue(i)) VALERR("out of range"); + SET64(*(kludge64 *)pp, hi, lo); +#endif + rc = 1; + +end: + if (i) Py_DECREF(i); + return (rc); +} + int convmpw(PyObject *o, void *pp) { unsigned long u; @@ -131,8 +216,11 @@ end: int convbool(PyObject *o, void *pp) { + if (!o) VALERR("can't delete"); *(int *)pp = PyObject_IsTrue(o); return (1); +end: + return (0); } /*----- Type messing ------------------------------------------------------*/ @@ -178,9 +266,9 @@ void typeready(PyTypeObject *ty) PyDict_SetItemString(ty->tp_dict, "__module__", modname); } -PyTypeObject *inittype(PyTypeObject *tyskel) +PyTypeObject *inittype(PyTypeObject *tyskel, PyTypeObject *meta) { - PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0); + PyTypeObject *ty = newtype(meta, tyskel, 0); ty->tp_flags |= Py_TPFLAGS_HEAPTYPE; typeready(ty); return (ty); @@ -226,8 +314,8 @@ PyMethodDef *donemethods(void) /*----- Exceptions --------------------------------------------------------*/ -PyObject * mkexc(PyObject *mod, PyObject *base, - const char *name, PyMethodDef *mm) +PyObject *mkexc(PyObject *mod, PyObject *base, + const char *name, PyMethodDef *mm) { PyObject *nameobj = 0; PyObject *dict = 0; @@ -413,7 +501,7 @@ PySequenceMethods gmap_pysequence = { 0 /* @sq_inplace_repeat@ */ }; -int gmap_pysize(PyObject *me) +Py_ssize_t gmap_pysize(PyObject *me) { PyObject *i = 0, *x = 0; int rc = -1;