/* -*-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.
*
* 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.
#include "catacomb-python.h"
+/* #undef HAVE_LONG_LONG */
+
+/*----- External values ---------------------------------------------------*/
+
+static PyObject *modname = 0;
+
/*----- Conversions -------------------------------------------------------*/
PyObject *getulong(unsigned long w)
{
- if (w <= MASK32)
+ if (w <= LONG_MAX)
return (PyInt_FromLong(w));
else
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;
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");
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); \
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;
int convbool(PyObject *o, void *pp)
{
+ if (!o) VALERR("can't delete");
*(int *)pp = PyObject_IsTrue(o);
return (1);
+end:
+ return (0);
}
/*----- Type messing ------------------------------------------------------*/
(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);
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);
}
/*----- 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;
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);
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);
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;
(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;
/*----- 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);