X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/10e6f88a407ce04807b6ad76a81be553f8d7abaa..a375f639a8a0bc8ccbac44337126e19c06809768:/catacomb.c diff --git a/catacomb.c b/catacomb.c index d98d6ab..b3d7e52 100644 --- a/catacomb.c +++ b/catacomb.c @@ -30,38 +30,6 @@ /*----- Main code ---------------------------------------------------------*/ -static const struct nameval consts[] = { -#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), - 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(KF_NONSECRET), - C(KF_BURN), C(KF_OPT), - C(EC_XONLY), C(EC_YBIT), C(EC_LSB), C(EC_CMPR), C(EC_EXPLY), C(EC_SORT), - C(X25519_KEYSZ), C(X25519_PUBSZ), C(X25519_OUTSZ), - C(X448_KEYSZ), C(X448_PUBSZ), C(X448_OUTSZ), - 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 } -}; - PyObject *mexp_common(PyObject *me, PyObject *arg, size_t efsz, PyObject *(*id)(PyObject *), @@ -142,6 +110,175 @@ end: return (0); } +static PyTypeObject *thingtab_pytype; + +typedef struct thingentry { + sym_base _b; + PyObject *val; +} thingentry; +#define THING_VAL(x) (((thingentry *)(x))->val) + +typedef struct thingtab_pyobj { + GMAP_PYOBJ_HEAD + sym_table t; +} thingtab_pyobj; +#define THINGTAB_T(x) (&((thingtab_pyobj *)(x))->t) + +static void *thingtab_gmlookup(PyObject *me, PyObject *key, unsigned *f) +{ + const char *p; + + p = TEXT_STR(key); if (!p) return (0); + return (sym_find(THINGTAB_T(me), p, -1, 0, f)); +} + +static void thingtab_gmiterinit(PyObject *me, void *i) + { sym_mkiter(i, THINGTAB_T(me)); } + +static void *thingtab_gmiternext(PyObject *me, void *i) + { sym_iter *it = i; void *e; SYM_NEXT(it, e); return (e); } + +static PyObject *thingtab_gmentrykey(PyObject *me, void *e) + { return (TEXT_FROMSTR(SYM_NAME(e))); } + +static PyObject *thingtab_gmentryvalue(PyObject *me, void *e) + { PyObject *rc = THING_VAL(e); RETURN_OBJ(rc); } + +static const gmap_ops thingtab_gmops = { + sizeof(sym_iter), + thingtab_gmlookup, + thingtab_gmiterinit, + thingtab_gmiternext, + thingtab_gmentrykey, + thingtab_gmentryvalue +}; + +static Py_ssize_t thing_pysize(PyObject *me) + { return gmap_pysize_from_sym(THINGTAB_T(me)); } + +static const PyMappingMethods thingtab_pymapping = { + thing_pysize, + gmap_pylookup, + 0 +}; + +static thingtab_pyobj *make_thingtab(void) +{ + thingtab_pyobj *map = PyObject_NEW(thingtab_pyobj, thingtab_pytype); + + map->gmops = &thingtab_gmops; + sym_create(&map->t); + return (map); +} + +PyObject *make_algtab(const void *tab, size_t esz, + const char *(*namefn)(const void *), + PyObject *(*valfn)(const void *)) +{ + thingtab_pyobj *map = make_thingtab(); + const char *p = tab; + const char *name; + thingentry *e; + unsigned f; + + for (;;) { + name = namefn(p); if (!name) break; + e = sym_find(&map->t, name, -1, sizeof(*e), &f); assert(!f); + e->val = valfn(p); + p += esz; + } + return ((PyObject *)map); +} + +PyObject *make_grouptab(const void *tab, size_t esz, + const char *(*namefn)(const void *), + int (*ixfn)(const void *), PyObject *(*valfn)(int)) +{ + thingtab_pyobj *map = make_thingtab(); + struct { const char *name; int ix; } *ixtab = 0; + PyObject **valtab, **vv; + size_t i = 0, n = 0; + const char *p = tab; + const char *name; + thingentry *e; + unsigned f; + + for (;;) { + name = namefn(p); if (!name) break; + if (i >= n) { + if (!n) n = 16; + else n *= 2; + ixtab = xrealloc(ixtab, n*sizeof(*ixtab), i*sizeof(*ixtab)); + } + ixtab[i].name = name; ixtab[i].ix = ixfn(p); assert(ixtab[i].ix >= 0); + p += esz; i++; + } + n = i; + + valtab = xmalloc(n*sizeof(*valtab)); + for (i = 0; i < n; i++) valtab[i] = 0; + + for (i = 0; i < n; i++) { + e = sym_find(&map->t, ixtab[i].name, -1, sizeof(*e), &f); assert(!f); + vv = &valtab[ixtab[i].ix]; + if (*vv) Py_INCREF(*vv); + else *vv = valfn(ixtab[i].ix); + e->val = *vv; + } + + xfree(ixtab); xfree(valtab); + return ((PyObject *)map); +} + +static const PyTypeObject thingtab_pytype_skel = { + PyVarObject_HEAD_INIT(0, 0) /* Header */ + "_MiscTable", /* @tp_name@ */ + sizeof(thingtab_pyobj), /* @tp_basicsize@ */ + 0, /* @tp_itemsize@ */ + + 0, /* @tp_dealloc@ */ + 0, /* @tp_print@ */ + 0, /* @tp_getattr@ */ + 0, /* @tp_setattr@ */ + 0, /* @tp_compare@ */ + 0, /* @tp_repr@ */ + 0, /* @tp_as_number@ */ + PYSEQUENCE(gmap), /* @tp_as_sequence@ */ + PYMAPPING(thingtab), /* @tp_as_mapping@ */ + 0, /* @tp_hash@ */ + 0, /* @tp_call@ */ + 0, /* @tp_str@ */ + 0, /* @tp_getattro@ */ + 0, /* @tp_setattro@ */ + 0, /* @tp_as_buffer@ */ + Py_TPFLAGS_DEFAULT | /* @tp_flags@ */ + Py_TPFLAGS_BASETYPE, + + /* @tp_doc@ */ + "Class for tables of algorithms and abstract-group data.\n" + " Not instantiable by users.", + + 0, /* @tp_traverse@ */ + 0, /* @tp_clear@ */ + 0, /* @tp_richcompare@ */ + 0, /* @tp_weaklistoffset@ */ + gmap_pyiter, /* @tp_iter@ */ + 0, /* @tp_iternext@ */ + PYMETHODS(gmapro), /* @tp_methods@ */ + 0, /* @tp_members@ */ + 0, /* @tp_getset@ */ + 0, /* @tp_base@ */ + 0, /* @tp_dict@ */ + 0, /* @tp_descr_get@ */ + 0, /* @tp_descr_set@ */ + 0, /* @tp_dictoffset@ */ + 0, /* @tp_init@ */ + PyType_GenericAlloc, /* @tp_alloc@ */ + abstract_pynew, /* @tp_new@ */ + 0, /* @tp_free@ */ + 0 /* @tp_is_gc@ */ +}; + static PyObject *smallprimes(void) { PyObject *v = PyList_New(NPRIME); @@ -162,7 +299,7 @@ static PyObject *meth__ego(PyObject *me, PyObject *arg) RETURN_NONE; } -static PyMethodDef methods[] = { +static const PyMethodDef methods[] = { #define METHNAME(func) meth_##func METH (_ego, "_ego(ARGV0)") #undef METHNAME @@ -184,18 +321,42 @@ static void init_random(void) #endif } -EXPORT void init_base(void) +#ifdef PY3 +static PyModuleDef moddef = { + PyModuleDef_HEAD_INIT, + "catacomb._base", /* @m_name@ */ + "Low-level module for Catacomb bindings. Use `catacomb' instead.", + /* @m_doc@ */ + 0, /* @m_size@ */ + 0, /* @m_methods@ */ + 0, /* @m_slots@ */ + 0, /* @m_traverse@ */ + 0, /* @m_clear@ */ + 0 /* @m_free@ */ +}; +#endif + +EXPORT PyMODINIT_FUNC PY23(init_base, PyInit__base)(void) { PyObject *mod; - modname = PyString_FromString("catacomb"); + modname = TEXT_FROMSTR("catacomb"); addmethods(methods); INIT_MODULES; + INITTYPE(thingtab, root); init_random(); +#ifdef PY3 + moddef.m_methods = donemethods(); + mod = PyModule_Create(&moddef); +#else mod = Py_InitModule("catacomb._base", donemethods()); +#endif INSERT_MODULES; + INSERT("_MiscTable", thingtab_pytype); INSERT("smallprimes", smallprimes()); - setconstants(mod, consts); +#ifdef PY3 + return (mod); +#endif } /*----- That's all, folks -------------------------------------------------*/