#include <catacomb/blkc.h>
#include <catacomb/gcipher.h>
+#include <catacomb/gaead.h>
#include <catacomb/ghash.h>
#include <catacomb/gmac.h>
#include <catacomb/md5.h>
goto end; \
} while (0)
#define VALERR(str) EXCERR(PyExc_ValueError, str)
+ #define OVFERR(str) EXCERR(PyExc_OverflowError, str)
#define TYERR(str) EXCERR(PyExc_TypeError, str)
+#define IXERR(str) EXCERR(PyExc_IndexError, str)
#define ZDIVERR(str) EXCERR(PyExc_ZeroDivisionError, str)
#define SYSERR(str) EXCERR(PyExc_SystemError, str)
#define NIERR(str) EXCERR(PyExc_NotImplementedError, str)
PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); \
goto end; \
} while (0)
- #define PGENERR do { pgenerr(); goto end; } while (0)
+ #define PGENERR(exc) do { pgenerr(exc); goto end; } while (0)
#define CONVFUNC(ty, cty, ext) \
int conv##ty(PyObject *o, void *p) \
} while (0)
#define INITTYPE(ty, base) INITTYPE_META(ty, base, type)
- #define INSERT(name, ob) do { \
+ extern PyObject *home_module;
+
+ #define INSERT(name, ob) do { \
PyObject *_o = (PyObject *)(ob); \
Py_INCREF(_o); \
PyModule_AddObject(mod, name, _o); \
return (d); \
}
- struct nameval { const char *name; unsigned long value; };
+#define KWLIST (/*unconst*/ char **)kwlist
+
+ struct nameval { const char *name; unsigned f; unsigned long value; };
+ #define CF_SIGNED 1u
extern void setconstants(PyObject *, const struct nameval *);
extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
extern PyObject *getk64(kludge64);
extern void *newtype(PyTypeObject *, const PyTypeObject *, const char *);
+ struct excinfo { PyObject *ty, *val, *tb; };
+ #define EXCINFO_INIT { 0, 0, 0 }
+
extern PyObject *mkexc(PyObject *, PyObject *, const char *, PyMethodDef *);
+ #define INIT_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); _exc->ty = _exc->val = _exc->tb = 0; \
+ } while (0)
+ #define RELEASE_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ Py_XDECREF(_exc->ty); _exc->ty = 0; \
+ Py_XDECREF(_exc->val); _exc->val = 0; \
+ Py_XDECREF(_exc->tb); _exc->tb = 0; \
+ } while (0)
+ #define STASH_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ PyErr_Fetch(&_exc->ty, &_exc->val, &_exc->tb); \
+ PyErr_NormalizeException(&_exc->ty, &_exc->val, &_exc->tb); \
+ } while (0)
+ #define RESTORE_EXCINFO(exc) do { \
+ struct excinfo *_exc = (exc); \
+ PyErr_Restore(_exc->ty, _exc->val, _exc->tb); \
+ _exc->ty = _exc->val = _exc->tb = 0; \
+ } while (0)
+ extern void report_lost_exception(struct excinfo *, const char *, ...);
+ extern void report_lost_exception_v(struct excinfo *, const char *, va_list);
+ extern void stash_exception(struct excinfo *, const char *, ...);
+ extern void restore_exception(struct excinfo *, const char *, ...);
+
extern void typeready(PyTypeObject *);
extern PyTypeObject *inittype(PyTypeObject *, PyTypeObject *);
extern void addmethods(const PyMethodDef *);
extern int convgf(PyObject *, void *);
extern PyObject *mp_pywrap(mp *);
extern PyObject *gf_pywrap(mp *);
+ extern long mphash(mp *);
extern mp *mp_frompyobject(PyObject *, int);
extern PyObject *mp_topystring(mp *, int,
const char *, const char *, const char *);
#define FE_FOBJ(o) ((PyObject *)(o)->ob_type)
#define FE_X(o) (((fe_pyobj *)(o))->x)
extern PyObject *fe_pywrap(PyObject *, mp *);
- extern mp *getfe(field *, PyObject *);
typedef struct fe_pyobj {
PyObject_HEAD
extern PyTypeObject *gccipher_pytype;
#define GCCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gccipher_pytype)
#define GCCIPHER_CC(o) (((gccipher_pyobj *)(o))->cc)
-#define GCCIPHER_F(o) (((gccipher_pyobj *)(o))->f)
extern PyObject *gccipher_pywrap(gccipher *);
extern int convgccipher(PyObject *, void *);
-extern int convgcipher(PyObject *, void *);
typedef struct gcipher_pyobj {
PyObject_HEAD
- unsigned f;
gcipher *c;
} gcipher_pyobj;
extern PyTypeObject *gcipher_pytype;
#define GCIPHER_PYCHECK(o) PyObject_TypeCheck((o), gcipher_pytype)
#define GCIPHER_C(o) (((gcipher_pyobj *)(o))->c)
-#define GCIPHER_F(o) (((gcipher_pyobj *)(o))->f)
-extern PyObject *gcipher_pywrap(PyObject *, gcipher *, unsigned);
+extern PyObject *gcipher_pywrap(PyObject *, gcipher *);
extern int convgcipher(PyObject *, void *);
+typedef struct gcaead_pyobj {
+ PyHeapTypeObject ty;
+ gcaead *aec;
+ struct gcaeadaad_pyobj *aad;
+ struct gcaeadenc_pyobj *enc;
+ struct gcaeaddec_pyobj *dec;
+} gcaead_pyobj;
+
+extern PyTypeObject *gcaead_pytype;
+#define GCAEAD_PYCHECK(o) PyObject_TypeCheck((o), gcaead_pytype)
+#define GCAEAD_AEC(o) (((gcaead_pyobj *)(o))->aec)
+#define GCAEAD_AAD(o) (((gcaead_pyobj *)(o))->aad)
+#define GCAEAD_ENC(o) (((gcaead_pyobj *)(o))->enc)
+#define GCAEAD_DEC(o) (((gcaead_pyobj *)(o))->dec)
+extern PyObject *gcaead_pywrap(gcaead *);
+extern int convgcaead(PyObject *, void *);
+
+typedef struct gaeadkey_pyobj {
+ PyObject_HEAD
+ gaead_key *k;
+} gaeadkey_pyobj;
+
+extern PyTypeObject *gaeadkey_pytype;
+#define GAEADKEY_PYCHECK(o) PyObject_TypeCheck((o), gaeadkey_pytype)
+#define GAEADKEY_K(o) (((gaeadkey_pyobj *)(o))->k)
+extern PyObject *gaeadkey_pywrap(PyObject *, gaead_key *);
+extern int convgaeadkey(PyObject *, void *);
+
+typedef struct gcaeadaad_pyobj {
+ PyHeapTypeObject ty;
+ gcaead_pyobj *key;
+} gcaeadaad_pyobj;
+#define GCAEADAAD_KEY(o) (((gcaeadaad_pyobj *)(o))->key)
+extern PyTypeObject *gcaeadaad_pytype;
+
+typedef struct gaeadaad_pyobj {
+ PyObject_HEAD
+ gaead_aad *a;
+ unsigned f;
+#define AEADF_DEAD 32768u
+ size_t hsz, hlen;
+} gaeadaad_pyobj;
+
+extern PyTypeObject *gaeadaad_pytype;
+#define GAEADAAD_PYCHECK(o) PyObject_TypeCheck((o), gaeadaad_pytype)
+#define GAEADAAD_A(o) (((gaeadaad_pyobj *)(o))->a)
+#define GAEADAAD_F(o) (((gaeadaad_pyobj *)(o))->f)
+#define GAEADAAD_HSZ(o) (((gaeadaad_pyobj *)(o))->hsz)
+#define GAEADAAD_HLEN(o) (((gaeadaad_pyobj *)(o))->hlen)
+extern PyObject *gaeadaad_pywrap(PyObject *, gaead_aad *, unsigned, size_t);
+extern int convgaeadaad(PyObject *, void *);
+
+typedef struct gcaeadenc_pyobj {
+ PyHeapTypeObject ty;
+ gcaead_pyobj *key;
+} gcaeadenc_pyobj;
+#define GCAEADENC_KEY(o) (((gcaeadenc_pyobj *)(o))->key)
+extern PyTypeObject *gcaeadenc_pytype;
+
+typedef struct gaeadenc_pyobj {
+ PyObject_HEAD
+ gaead_enc *e;
+ gaeadaad_pyobj *aad;
+ unsigned f;
+ size_t hsz, msz, tsz;
+ size_t mlen;
+} gaeadenc_pyobj;
+
+extern PyTypeObject *gaeadenc_pytype;
+#define GAEADENC_PYCHECK(o) PyObject_TypeCheck((o), gaeadenc_pytype)
+#define GAEADENC_AAD(o) (((gaeadenc_pyobj *)(o))->aad)
+#define GAEADENC_E(o) (((gaeadenc_pyobj *)(o))->e)
+#define GAEADENC_F(o) (((gaeadenc_pyobj *)(o))->f)
+#define GAEADENC_HSZ(o) (((gaeadenc_pyobj *)(o))->hsz)
+#define GAEADENC_MSZ(o) (((gaeadenc_pyobj *)(o))->msz)
+#define GAEADENC_TSZ(o) (((gaeadenc_pyobj *)(o))->tsz)
+#define GAEADENC_MLEN(o) (((gaeadenc_pyobj *)(o))->mlen)
+extern PyObject *gaeadenc_pywrap(PyObject *, gaead_enc *, unsigned,
+ size_t, size_t, size_t);
+extern int convgaeadenc(PyObject *, void *);
+
+typedef struct gcaeaddec_pyobj {
+ PyHeapTypeObject ty;
+ gcaead_pyobj *key;
+} gcaeaddec_pyobj;
+#define GCAEADDEC_KEY(o) (((gcaeaddec_pyobj *)(o))->key)
+extern PyTypeObject *gcaeaddec_pytype;
+
+typedef struct gaeaddec_pyobj {
+ PyObject_HEAD
+ gaead_dec *d;
+ gaeadaad_pyobj *aad;
+ unsigned f;
+ size_t hsz, csz, tsz;
+ size_t clen;
+} gaeaddec_pyobj;
+
+extern PyTypeObject *gaeaddec_pytype;
+#define GAEADDEC_PYCHECK(o) PyObject_TypeCheck((o), gaeaddec_pytype)
+#define GAEADDEC_AAD(o) (((gaeaddec_pyobj *)(o))->aad)
+#define GAEADDEC_D(o) (((gaeaddec_pyobj *)(o))->d)
+#define GAEADDEC_F(o) (((gaeaddec_pyobj *)(o))->f)
+#define GAEADDEC_HSZ(o) (((gaeaddec_pyobj *)(o))->hsz)
+#define GAEADDEC_CSZ(o) (((gaeaddec_pyobj *)(o))->csz)
+#define GAEADDEC_TSZ(o) (((gaeaddec_pyobj *)(o))->tsz)
+#define GAEADDEC_CLEN(o) (((gaeaddec_pyobj *)(o))->clen)
+extern PyObject *gaeaddec_pywrap(PyObject *, gaead_dec *, unsigned,
+ size_t, size_t, size_t);
+extern int convgaeaddec(PyObject *, void *);
+
typedef struct gchash_pyobj {
PyHeapTypeObject ty;
gchash *ch;
extern PyTypeObject *gchash_pytype;
#define GCHASH_PYCHECK(o) PyObject_TypeCheck((o), gchash_pytype)
#define GCHASH_CH(o) (((gchash_pyobj *)(o))->ch)
-#define GCHASH_F(o) (((gchash_pyobj *)(o))->f)
extern PyObject *gchash_pywrap(gchash *);
extern int convgchash(PyObject *, void *);
typedef struct ghash_pyobj {
PyObject_HEAD
- unsigned f;
ghash *h;
} ghash_pyobj;
extern PyObject *sha_pyobj, *has160_pyobj;
#define GHASH_PYCHECK(o) PyObject_TypeCheck((o), ghash_pytype)
#define GHASH_H(o) (((ghash_pyobj *)(o))->h)
-#define GHASH_F(o) (((ghash_pyobj *)(o))->f)
-extern PyObject *ghash_pywrap(PyObject *, ghash *, unsigned);
+extern PyObject *ghash_pywrap(PyObject *, ghash *);
extern int convghash(PyObject *, void *);
extern int convgmhash(PyObject *, void *);
typedef struct gmac_pyobj {
PyHeapTypeObject ty;
- unsigned f;
gmac *m;
} gmac_pyobj;
#define GMAC_PYCHECK(o) PyObject_TypeCheck((o), gmac_pytype)
#define GMAC_M(o) (((gmac_pyobj *)(o))->m)
#define GMAC_F(o) (((gmac_pyobj *)(o))->f)
-extern PyObject *gmac_pywrap(PyObject *, gmac *, unsigned);
+extern PyObject *gmac_pywrap(PyObject *, gmac *);
extern int convgmac(PyObject *, void *);
/*----- Key generation ----------------------------------------------------*/
#define PGEV_PYCHECK(o) PyObject_TypeCheck(o, pgev_pytype)
#define PGEV_PG(o) (&((pgev_pyobj *)(o))->pg)
+ typedef struct pypgev {
+ pgev ev;
+ PyObject *obj;
+ struct excinfo *exc;
+ } pypgev;
+
extern int convpgev(PyObject *, void *);
- extern void droppgev(pgev *);
- extern void pgenerr(void);
+ extern void droppgev(pypgev *);
+ extern void pgenerr(struct excinfo *exc);
/*----- That's all, folks -------------------------------------------------*/
/*----- Main code ---------------------------------------------------------*/
static const struct nameval consts[] = {
- #define C(x) { #x, x }
+ #define CF(f, x) { #x, f, x }
+ #define C(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x }
C(FTY_PRIME), C(FTY_BINARY),
C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
C(PGEN_ABORT),
C(MPW_MAX),
+ C(RAND_IBITS),
C(PMODE_READ), C(PMODE_VERIFY),
C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
- C(KEXP_FOREVER), C(KEXP_EXPIRE),
+ CF(0, KEXP_FOREVER), CF(0, KEXP_EXPIRE),
C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
C(ED25519_KEYSZ), C(ED25519_PUBSZ), C(ED25519_SIGSZ),
C(ED25519_MAXPERSOSZ),
C(ED448_KEYSZ), C(ED448_PUBSZ), C(ED448_SIGSZ), C(ED448_MAXPERSOSZ),
+ C(AEADF_PCHSZ), C(AEADF_PCMSZ), C(AEADF_PCTSZ),
+ C(AEADF_AADNDEP), C(AEADF_AADFIRST), C(AEADF_NOAAD),
#define ENTRY(tag, val, str) C(KERR_##tag),
KEY_ERRORS(ENTRY)
#undef ENTRY
#undef C
+ #undef CF
{ 0 }
};
arg = PyTuple_GetItem(arg, 0);
Py_INCREF(arg);
if (!PySequence_Check(arg)) TYERR("not a sequence");
- n = PySequence_Size(arg); if (!n) { z = id(me); goto end; }
+ n = PySequence_Size(arg); if (n < 0) goto end;
+ if (!n) { z = id(me); goto end; }
x = PySequence_GetItem(arg, 0);
if (PySequence_Check(x))
flat = 0;
#include "catacomb-python.h"
+ /* #undef HAVE_LONG_LONG */
+
/*----- External values ---------------------------------------------------*/
static PyObject *modname = 0;
+ PyObject *home_module = 0;
/*----- Conversions -------------------------------------------------------*/
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 (i) Py_DECREF(i);
if (j) Py_DECREF(j);
return (rc);
+ #endif
}
PyObject *getbool(int b)
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); \
int convk64(PyObject *o, void *pp)
{
- PyObject *i = 0, *t;
+ 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);
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);
void setconstants(PyObject *mod, const struct nameval *c)
{
PyObject *x;
+ unsigned long u;
while (c->name) {
- if (c->value > LONG_MAX)
- x = PyLong_FromUnsignedLong(c->value);
- else
- x = PyInt_FromLong(c->value);
- PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x);
- c++;
+ u = c->value;
+ if (u <= LONG_MAX) x = PyInt_FromLong(u);
+ else if (c->f&CF_SIGNED) x = PyInt_FromLong(-1 - (long)(ULONG_MAX - u));
+ else x = PyLong_FromUnsignedLong(u);
+ PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x); c++;
}
}
PyObject *func = 0;
PyObject *meth = 0;
- if ((nameobj = PyString_FromFormat("%s.%s",
- PyModule_GetName(mod),
- name)) == 0 ||
- (dict = PyDict_New()) == 0 ||
- (exc = PyErr_NewException(PyString_AS_STRING(nameobj),
- base, dict)) == 0)
- goto fail;
+ if ((dict = PyDict_New()) == 0) goto fail;
if (mm) {
while (mm->ml_name) {
}
}
+ if ((nameobj = PyString_FromFormat("%s.%s",
+ PyModule_GetName(mod),
+ name)) == 0 ||
+ (exc = PyErr_NewException(PyString_AS_STRING(nameobj),
+ base, dict)) == 0)
+ goto fail;
+
done:
Py_XDECREF(nameobj);
Py_XDECREF(dict);
goto done;
}
+ void report_lost_exception_v(struct excinfo *exc,
+ const char *why, va_list ap)
+ {
+ PyObject *hookfn = 0;
+ PyObject *whyobj = 0;
+ PyObject *obj = 0;
+
+ /* Make sure we start out without a pending exception, or this will get
+ * really confusing.
+ */
+ assert(!PyErr_Occurred());
+
+ /* Format the explanation. */
+ if (why) whyobj = PyString_FromFormatV(why, ap);
+ else { whyobj = Py_None; Py_INCREF(whyobj); }
+
+ /* Find our home module's `lostexchook' function. This won't work if
+ * there's no module, or the function isn't defined, or it's `None'.
+ */
+ if (!home_module) goto sys;
+ hookfn = PyObject_GetAttrString(home_module, "lostexchook");
+ if (hookfn == Py_None) goto sys;
+ else if (hookfn) ;
+ else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto ouch;
+ else { PyErr_Clear(); goto sys; }
+
+ /* Call the hook function. */
+ obj = PyObject_CallFunction(hookfn, "(OOOO)",
+ whyobj, exc->ty, exc->val, exc->tb);
+ if (!obj) goto ouch;
+ goto end;
+
+ /* Something went wrong reporting the problem. */
+ ouch:
+ PySys_WriteStderr("\n!!! FAILURE REPORTING LOST EXCEPTION\n");
+ PyErr_Print();
+ /* drop through... */
+
+ /* There was no hook, so try to do something sensible using
+ * `sys.excepthook'.
+ */
+ sys:
+ PySys_WriteStderr("\n!!! LOST EXCEPTION: %s\n",
+ PyString_AS_STRING(whyobj));
+ RESTORE_EXCINFO(exc);
+ PyErr_Print();
+ /* drop through... */
+
+ /* Clean up afterwards. */
+ end:
+ Py_XDECREF(hookfn);
+ Py_XDECREF(whyobj);
+ Py_XDECREF(obj);
+ }
+
+ void report_lost_exception(struct excinfo *exc, const char *why, ...)
+ {
+ va_list ap;
+
+ va_start(ap, why);
+ report_lost_exception_v(exc, why, ap);
+ va_end(ap);
+ }
+
+ void stash_exception(struct excinfo *exc, const char *why, ...)
+ {
+ va_list ap;
+ struct excinfo stash;
+
+ if (!exc->ty)
+ STASH_EXCINFO(exc);
+ else {
+ va_start(ap, why);
+ STASH_EXCINFO(&stash);
+ report_lost_exception_v(&stash, why, ap);
+ va_end(ap);
+ }
+ }
+
+ void restore_exception(struct excinfo *exc, const char *why, ...)
+ {
+ va_list ap;
+ struct excinfo stash;
+
+ if (!PyErr_Occurred())
+ RESTORE_EXCINFO(exc);
+ else {
+ va_start(ap, why);
+ STASH_EXCINFO(&stash);
+ report_lost_exception_v(exc, why, ap);
+ RESTORE_EXCINFO(&stash);
+ va_end(ap);
+ }
+ }
+
/*----- Generic dictionary methods ----------------------------------------*/
static PyTypeObject *itemiter_pytype, *valiter_pytype;
Py_TPFLAGS_BASETYPE,
/* @tp_doc@ */
- "Iterates over the items of a mapping.",
+ "Iterates over the keys of a mapping.",
0, /* @tp_traverse@ */
0, /* @tp_clear@ */
Py_TPFLAGS_BASETYPE,
/* @tp_doc@ */
- "Iterates over the items of a mapping.",
+ "Iterates over the values of a mapping.",
0, /* @tp_traverse@ */
0, /* @tp_clear@ */
Py_ssize_t gmap_pysize(PyObject *me)
{
PyObject *i = 0, *x = 0;
- int rc = -1;
- int n = 0;
+ Py_ssize_t rc = -1, n = 0;
if ((i = PyObject_GetIter(me)) == 0) goto done;
while ((x = PyIter_Next(i)) != 0) { n++; Py_DECREF(x); x = 0; }
return (rc);
}
-static char *def_kwlist[] = { "key", "default", 0 };
+static const char *const def_kwlist[] = { "key", "default", 0 };
PyObject *gmapmeth_get(PyObject *me, PyObject *arg, PyObject *kw)
{
PyObject *k, *def = Py_None, *v;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:get",
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:get", def_kwlist, &k, &def))
++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:get",
+ (/*unconst*/ char **)def_kwlist,
+ &k, &def))
return (0);
if ((v = PyObject_GetItem(me, k)) != 0) return (v);
PyErr_Clear();
{
PyObject *k, *def = Py_None, *v;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:setdefault",
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:setdefault",
- def_kwlist, &k, &def))
+ (/*unconst*/ char **)def_kwlist,
+ &k, &def))
return (0);
if ((v = PyObject_GetItem(me, k)) != 0) return (v);
PyErr_Clear();
{
PyObject *k, *def = 0, *v;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:pop",
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:pop", def_kwlist, &k, &def))
++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:pop",
+ (/*unconst*/ char **)def_kwlist,
+ &k, &def))
return (0);
if ((v = PyObject_GetItem(me, k)) != 0) {
PyObject_DelItem(me, k);
return (v);
- }
- PyErr_Clear();
- RETURN_OBJ(def);
+ } else if (def) {
+ PyErr_Clear();
+ RETURN_OBJ(def);
+ } else
+ return (0);
}
PyObject *gmapmeth_update(PyObject *me, PyObject *arg)
PyObject *i = 0, *k = 0, *v = 0, *rc = 0;
if (!PyArg_ParseTuple(arg, ":popitem") ||
- (i = PyObject_GetIter(me)))
+ (i = PyObject_GetIter(me)) == 0)
goto end;
if ((k = PyIter_Next(i)) == 0) {
if (!PyErr_Occurred()) VALERR("popitem(): mapping is empty");
/*----- Initialization ----------------------------------------------------*/
+ static PyObject *meth__set_home_module(PyObject *me, PyObject *arg)
+ {
+ PyObject *mod;
+
+ if (!PyArg_ParseTuple(arg, "O!:_set_home_module", &PyModule_Type, &mod))
+ return (0);
+ Py_XDECREF(home_module); home_module = mod; Py_INCREF(home_module);
+ RETURN_NONE;
+ }
+
+ static const PyMethodDef methods[] = {
+ #define METHNAME(func) meth_##func
+ METH (_set_home_module, "_set_home_module(MOD)")
+ #undef METHNAME
+ { 0 }
+ };
+
void util_pyinit(void)
{
modname = PyString_FromString("catacomb");
INITTYPE(itemiter, root);
INITTYPE(valiter, root);
+ addmethods(methods);
}
void util_pyinsert(PyObject *mod)