X-Git-Url: https://git.distorted.org.uk/~mdw/pyke/blobdiff_plain/b6a86d2eeff0cc45053e38970493bf6108f53a4f..62058916b6c4b39764824d24be670525b7cdfd7a:/catacomb.c diff --git a/catacomb.c b/catacomb.c index 742ce5f..47a94dd 100644 --- a/catacomb.c +++ b/catacomb.c @@ -41,6 +41,16 @@ static void setconstants(PyObject *mod) C(PGEN_ABORT), C(MPW_MAX), C(PMODE_READ), C(PMODE_VERIFY), + C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE), + C(KEXP_FOREVER), C(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(KF_NONSECRET), + C(KF_BURN), C(KF_OPT), +#define ENTRY(tag, val, str) C(KERR_##tag), + KEY_ERRORS(ENTRY) +#undef ENTRY #undef C { 0 } }; @@ -56,13 +66,15 @@ static void setconstants(PyObject *mod) } } -PyObject *getu32(uint32 w) -{ - if (w <= 0x7fffffff) - return (PyInt_FromLong(w)); - else - return (PyLong_FromUnsignedLong(w)); -} +#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 *getbool(int b) { @@ -97,18 +109,20 @@ end: return (0); } -int convu32(PyObject *o, void *pp) -{ - unsigned long u; - uint32 *p = pp; - - if (!convulong(o, &u)) goto end; - if (u > 0xffffffff) TYERR("out of range"); - *p = u; - return (1); -end: - return (0); -} +#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) TYERR("out of range"); \ + *p = u; \ + return (1); \ + end: \ + return (0); \ + } +DOUINTSZ(CONVU_) int convuint(PyObject *o, void *pp) { @@ -221,6 +235,48 @@ end: return (z); } +PyObject * mkexc(PyObject *mod, PyObject *base, + const char *name, PyMethodDef *mm) +{ + PyObject *nameobj = 0; + PyObject *dict = 0; + PyObject *exc = 0; + 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 (mm) { + while (mm->ml_name) { + if ((func = PyCFunction_NewEx(mm, 0, mod)) == 0 || + (meth = PyMethod_New(func, 0, exc)) == 0 || + PyDict_SetItemString(dict, mm->ml_name, meth)) + goto fail; + Py_DECREF(func); func = 0; + Py_DECREF(meth); meth = 0; + mm++; + } + } + +done: + Py_XDECREF(nameobj); + Py_XDECREF(dict); + return (exc); + +fail: + Py_XDECREF(exc); + Py_XDECREF(func); + Py_XDECREF(meth); + exc = 0; + goto done; +} + DA_DECL(method_v, PyMethodDef); static method_v global_pymethods = DA_INIT; void addmethods(const PyMethodDef *m) @@ -236,13 +292,35 @@ void addmethods(const PyMethodDef *m) static const PyTypeObject emptytype = { 0 }; -void *newtype(PyTypeObject *metaty, const PyTypeObject *skel) +void *newtype(PyTypeObject *metaty, + const PyTypeObject *skel, + const char *name) { - PyTypeObject *ty = (PyTypeObject *)_PyObject_GC_Malloc(metaty, 0); + PyHeapTypeObject *ty = + (PyHeapTypeObject *)_PyObject_GC_Malloc(_PyObject_VAR_SIZE(metaty, 0)); if (!skel) skel = &emptytype; memcpy(ty, skel, sizeof(*skel)); - if (ty->tp_base) Py_INCREF(ty->tp_base); - PyObject_INIT(ty, metaty); + if (ty->type.tp_base) Py_INCREF(ty->type.tp_base); +#define COPY(blah) do { \ + if (ty->type.tp_as_##blah) { \ + memcpy(&ty->as_##blah, \ + ty->type.tp_as_##blah, \ + sizeof(ty->as_##blah)); \ + ty->type.tp_as_##blah = &ty->as_##blah; \ + } \ + } while (0) + COPY(number); + COPY(sequence); + COPY(mapping); + 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); Py_INCREF(metaty); return (ty); } @@ -259,15 +337,33 @@ static PyObject *smallprimes(void) PyTypeObject *inittype(PyTypeObject *tyskel) { - PyTypeObject *ty = newtype(&PyType_Type, tyskel); + PyTypeObject *ty = newtype(&PyType_Type, tyskel, 0); ty->tp_flags |= Py_TPFLAGS_HEAPTYPE; PyType_Ready(ty); return (ty); } +static PyObject *meth__ego(PyObject *me, PyObject *arg) +{ + char *argv0; + if (!PyArg_ParseTuple(arg, "s:_ego", &argv0)) + return (0); + if (strcmp(QUIS, "") == 0) + ego(argv0); + RETURN_NONE; +} + +static PyMethodDef methods[] = { +#define METHNAME(func) meth_##func + METH (_ego, "_ego(ARGV0)") +#undef METHNAME + { 0 } +}; + void init_base(void) { static const PyMethodDef mzero = { 0 }; PyObject *mod; + addmethods(methods); INIT_MODULES; DA_PUSH(&global_pymethods, mzero); mod = Py_InitModule("catacomb._base", DA(&global_pymethods));