X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/11cb3d97caae1888a6d6ae63ff6e2dea9f7cce01..95ba7bc6afb98c9337779b5d7ce5822bd90d3c31:/catacomb.c diff --git a/catacomb.c b/catacomb.c index 65d3985..c1e91ff 100644 --- a/catacomb.c +++ b/catacomb.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id$ - * * Where the fun begins * * (c) 2004 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. @@ -32,27 +30,6 @@ /*----- Main code ---------------------------------------------------------*/ -static const struct nameval consts[] = { -#define C(x) { #x, 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(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 } -}; - PyObject *mexp_common(PyObject *me, PyObject *arg, size_t efsz, PyObject *(*id)(PyObject *), @@ -65,11 +42,12 @@ PyObject *mexp_common(PyObject *me, PyObject *arg, PyObject *qq, *x, *y, *z = 0; char *v = 0, *vv; - if (PyTuple_Size(arg) == 1) - arg = PyTuple_GetItem(arg, 0); + if (PyTuple_GET_SIZE(arg) == 1) + arg = PyTuple_GET_ITEM(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; @@ -119,13 +97,195 @@ end: return (z); } +int convmpw(PyObject *o, void *pp) +{ + unsigned long u; + unsigned *p = pp; + + if (!convulong(o, &u)) goto end; + if (u > MPW_MAX) VALERR("out of range"); + *p = u; + return (1); +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); int i; for (i = 0; i < NPRIME; i++) - PyList_SetItem(v, i, PyInt_FromLong(primetab[i])); + PyList_SET_ITEM(v, i, PyInt_FromLong(primetab[i])); return (v); } @@ -134,27 +294,46 @@ static PyObject *meth__ego(PyObject *me, PyObject *arg) char *argv0; if (!PyArg_ParseTuple(arg, "s:_ego", &argv0)) return (0); - if (strcmp(QUIS, "") == 0) + if (STRCMP(QUIS, ==, "")) ego(argv0); RETURN_NONE; } -static PyMethodDef methods[] = { +static const PyMethodDef methods[] = { #define METHNAME(func) meth_##func - METH (_ego, "_ego(ARGV0)") + METH (_ego, "_ego(ARGV0)") #undef METHNAME { 0 } }; -void init_base(void) +static void init_random(void) +{ +#if PY_VERSION_HEX >= 0x02060000 + char *seed; + uint32 r; + + if (!Py_HashRandomizationFlag) return; + seed = getenv("PYTHONHASHSEED"); + if (!seed || STRCMP(seed, ==, "random")) r = GR_WORD(&rand_global); + else r = strtoul(seed, 0, 0); + if (!r) r = 0xe011f220; /* zero doesn't work well */ + unihash_setkey(&unihash_global, r); +#endif +} + +EXPORT void init_base(void) { PyObject *mod; + + modname = TEXT_FROMSTR("catacomb"); addmethods(methods); INIT_MODULES; + INITTYPE(thingtab, root); + init_random(); mod = Py_InitModule("catacomb._base", donemethods()); INSERT_MODULES; + INSERT("_MiscTable", thingtab_pytype); INSERT("smallprimes", smallprimes()); - setconstants(mod, consts); } /*----- That's all, folks -------------------------------------------------*/