X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/blobdiff_plain/e56eb7d60c3d0929e952cad2d9ea2c711bd52593..183e9cd31b1ac2f14b86c5de6ac2643b8a4364a2:/util.c diff --git a/util.c b/util.c index c1d0ad8..7118bfb 100644 --- a/util.c +++ b/util.c @@ -1,6 +1,4 @@ /* -*-c-*- - * - * $Id$ * * Miscellaneous utilities (not Catacomb-specific) * @@ -30,6 +28,10 @@ #include "catacomb-python.h" +/*----- External values ---------------------------------------------------*/ + +static PyObject *modname = 0; + /*----- Conversions -------------------------------------------------------*/ PyObject *getulong(unsigned long w) @@ -40,6 +42,29 @@ PyObject *getulong(unsigned long w) return (PyLong_FromUnsignedLong(w)); } +static PyObject *i32 = 0; +static int init_i32(void) + { if (!i32 && (i32 = PyInt_FromLong(32)) == 0) return (-1); return (0); } + +PyObject *getk64(kludge64 u) +{ + 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); +} + PyObject *getbool(int b) { if (b) RETURN_TRUE; @@ -58,6 +83,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"); @@ -101,6 +127,29 @@ end: return (0); } +int convk64(PyObject *o, void *pp) +{ + PyObject *i = 0, *t; + int rc = 0; + uint32 lo, hi; + + if (!o) VALERR("can't delete"); + 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); + rc = 1; +end: + if (i) Py_DECREF(i); + return (rc); +} + int convmpw(PyObject *o, void *pp) { unsigned long u; @@ -129,8 +178,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 ------------------------------------------------------*/ @@ -165,16 +217,22 @@ void *newtype(PyTypeObject *metaty, ty->ht_name = PyString_FromString(ty->ht_type.tp_name); if (ty->ht_name) ty->ht_type.tp_name = PyString_AS_STRING(ty->ht_name); - PyObject_INIT(&ty->ht_type, metaty); + DISCARD(PyObject_INIT(&ty->ht_type, metaty)); Py_INCREF(metaty); return (ty); } -PyTypeObject *inittype(PyTypeObject *tyskel) +void typeready(PyTypeObject *ty) { - PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0); - ty->tp_flags |= Py_TPFLAGS_HEAPTYPE; PyType_Ready(ty); + PyDict_SetItemString(ty->tp_dict, "__module__", modname); +} + +PyTypeObject *inittype(PyTypeObject *tyskel, PyTypeObject *meta) +{ + PyTypeObject *ty = newtype(meta, tyskel, 0); + ty->tp_flags |= Py_TPFLAGS_HEAPTYPE; + typeready(ty); return (ty); } @@ -218,8 +276,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; @@ -405,7 +463,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; @@ -636,6 +694,7 @@ PyMethodDef gmap_pymethods[] = { void util_pyinit(void) { + modname = PyString_FromString("catacomb"); INITTYPE(itemiter, root); INITTYPE(valiter, root); }