X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/blobdiff_plain/11cb3d97caae1888a6d6ae63ff6e2dea9f7cce01..f1b0cf0da6b3bcc530d7f72982278510d94f6456:/util.c diff --git a/util.c b/util.c index 86b7aba..7118bfb 100644 --- a/util.c +++ b/util.c @@ -1,13 +1,11 @@ /* -*-c-*- - * - * $Id$ * * Miscellaneous utilities (not Catacomb-specific) * * (c) 2005 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the Python interface to Catacomb. * @@ -15,12 +13,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * Catacomb/Python is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Catacomb/Python; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -30,17 +28,42 @@ #include "catacomb-python.h" +/*----- External values ---------------------------------------------------*/ + +static PyObject *modname = 0; + /*----- Conversions -------------------------------------------------------*/ -#define GETU_(n) \ - PyObject *getu##n(uint##n w) \ - { \ - if (w <= MASK##n) \ - return (PyInt_FromLong(w)); \ - else \ - return (PyLong_FromUnsignedLong(w)); \ - } -DOUINTSZ(GETU_) +PyObject *getulong(unsigned long w) +{ + if (w <= LONG_MAX) + return (PyInt_FromLong(w)); + else + 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) { @@ -60,9 +83,10 @@ 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) TYERR("must be nonnegative"); + if (i < 0) VALERR("must be nonnegative"); *p = i; } else { if ((t = PyNumber_Long(o)) == 0) goto end; @@ -82,7 +106,7 @@ end: uint##n *p = pp; \ \ if (!convulong(o, &u)) goto end; \ - if (u > MASK##n) TYERR("out of range"); \ + if (u > MASK##n) VALERR("out of range"); \ *p = u; \ return (1); \ end: \ @@ -96,20 +120,43 @@ int convuint(PyObject *o, void *pp) unsigned *p = pp; if (!convulong(o, &u)) goto end; - if (u > UINT_MAX) TYERR("out of range"); + if (u > UINT_MAX) VALERR("out of range"); *p = u; return (1); 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; unsigned *p = pp; if (!convulong(o, &u)) goto end; - if (u > MPW_MAX) TYERR("out of range"); + if (u > MPW_MAX) VALERR("out of range"); *p = u; return (1); end: @@ -122,7 +169,7 @@ int convszt(PyObject *o, void *pp) size_t *p = pp; if (!convulong(o, &u)) goto end; - if (u > ~(size_t)0) TYERR("out of range"); + if (u > ~(size_t)0) VALERR("out of range"); *p = u; return (1); end: @@ -131,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 ------------------------------------------------------*/ @@ -147,13 +197,13 @@ void *newtype(PyTypeObject *metaty, (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0)); if (!skel) skel = &emptytype; memcpy(ty, skel, sizeof(*skel)); - if (ty->type.tp_base) Py_INCREF(ty->type.tp_base); + if (ty->ht_type.tp_base) Py_INCREF(ty->ht_type.tp_base); #define COPY(blah) do { \ - if (ty->type.tp_as_##blah) { \ + if (ty->ht_type.tp_as_##blah) { \ memcpy(&ty->as_##blah, \ - ty->type.tp_as_##blah, \ + ty->ht_type.tp_as_##blah, \ sizeof(ty->as_##blah)); \ - ty->type.tp_as_##blah = &ty->as_##blah; \ + ty->ht_type.tp_as_##blah = &ty->as_##blah; \ } \ } while (0) COPY(number); @@ -162,21 +212,27 @@ void *newtype(PyTypeObject *metaty, COPY(buffer); #undef COPY if (name) - ty->name = PyString_FromString(name); - else if (ty->type.tp_name) - ty->name = PyString_FromString(ty->type.tp_name); - if (ty->name) - ty->type.tp_name = PyString_AS_STRING(ty->name); - PyObject_INIT(&ty->type, metaty); + ty->ht_name = PyString_FromString(name); + else if (ty->ht_type.tp_name) + 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); + 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); } @@ -220,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; @@ -280,7 +336,7 @@ static void iter_pydealloc(PyObject *me) static PyObject *itemiter_pynext(PyObject *me) { PyObject *k = 0, *v = 0, *rc = 0; - + if ((k = PyIter_Next(ITER_I(me))) != 0 && (v = PyObject_GetItem(ITER_MAP(me), k)) != 0) rc = Py_BuildValue("(OO)", k, v); @@ -339,7 +395,7 @@ static PyTypeObject itemiter_pytype_skel = { static PyObject *valiter_pynext(PyObject *me) { PyObject *k = 0, *rc = 0; - + if ((k = PyIter_Next(ITER_I(me))) != 0) rc = PyObject_GetItem(ITER_MAP(me), k); Py_XDECREF(k); @@ -405,9 +461,9 @@ PySequenceMethods gmap_pysequence = { PyMapping_HasKey, /* @sq_contains@ */ 0, /* @sq_inplace_concat@ */ 0 /* @sq_inplace_repeat@ */ -}; +}; -int gmap_pysize(PyObject *me) +Py_ssize_t gmap_pysize(PyObject *me) { PyObject *i = 0, *x = 0; int rc = -1; @@ -456,7 +512,7 @@ PyObject *gmapmeth_values(PyObject *me, PyObject *arg) (l = PyList_New(0)) == 0 || (i = PyObject_GetIter(me)) == 0) goto done; - while ((k = PyIter_Next(i)) != 0) { + while ((k = PyIter_Next(i)) != 0) { if ((v = PyObject_GetItem(me, k)) == 0 || PyList_Append(l, v)) err = -1; @@ -636,13 +692,14 @@ PyMethodDef gmap_pymethods[] = { /*----- Initialization ----------------------------------------------------*/ -void util_init(void) +void util_pyinit(void) { + modname = PyString_FromString("catacomb"); INITTYPE(itemiter, root); INITTYPE(valiter, root); } -void util_insert(PyObject *mod) +void util_pyinsert(PyObject *mod) { INSERT("ItemIter", itemiter_pytype); INSERT("ValueIter", valiter_pytype);