X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/618cbc92aa4274a62296cd6ed417d8597f50bd05..f5a133608a72a96b2023024043dc00480192bcc7:/key.c diff --git a/key.c b/key.c index 474b659..017c973 100644 --- a/key.c +++ b/key.c @@ -1015,46 +1015,48 @@ static const gmap_ops keydatastruct_gmops = { keydatastruct_gmdelentry }; +static int populate_struct(key_data *kd, PyObject *map) +{ + PyObject *it = 0, *name = 0, *val = 0; + const char *p; + int rc = -1; + + if (!PyMapping_Check(map)) TYERR("subkeys must be an iterable mapping"); + if ((it = PyObject_GetIter(map)) == 0) goto end; + while ((name = PyIter_Next(it)) != 0) { + if ((p = TEXT_STR(name)) == 0 || + (val = PyObject_GetItem(map, name)) == 0) + goto end; + if (!KEYDATA_PYCHECK(val)) + TYERR("subkey objects must be instances of KeyData"); + if (key_structfind(kd, p)) VALERR("duplicate tag"); + key_structset(kd, p, KEYDATA_KD(val)); + Py_DECREF(name); name = 0; + Py_DECREF(val); val = 0; + } + if (PyErr_Occurred()) goto end; + rc = 0; +end: + Py_XDECREF(it); Py_XDECREF(name); Py_XDECREF(val); + return (rc); +} + static PyObject *keydatastruct_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { PyObject *sub = 0; - PyObject *it = 0, *name = 0, *val = 0; - char *p; keydata_pyobj *me = 0; key_data *kd = 0; - static const char *const kwlist[] = { "subkeys", 0 }; - Py_XINCREF(arg); Py_XINCREF(kw); - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O:new", KWLIST, &sub)) - goto end; + if (!PyArg_ParseTuple(arg, "|O:new", &sub)) goto end; kd = key_newstruct(); - if (sub) { - if (!PyMapping_Check(sub)) - TYERR("subkeys must be an iterable mapping"); - if ((it = PyObject_GetIter(sub)) == 0) - goto end; - while ((name = PyIter_Next(it)) != 0) { - if ((p = TEXT_STR(name)) == 0 || - (val = PyObject_GetItem(sub, name)) == 0) - goto end; - if (!KEYDATA_PYCHECK(val)) - TYERR("subkey objects must be subclasses of KeyData"); - key_structset(kd, p, KEYDATA_KD(val)); - Py_DECREF(name); name = 0; - Py_DECREF(val); val = 0; - } - if (PyErr_Occurred()) - goto end; - Py_DECREF(it); it = 0; - } + if (sub && populate_struct(kd, sub)) goto end; + if (kw && populate_struct(kd, kw)) goto end; me = (keydata_pyobj *)ty->tp_alloc(ty, 0); me->gmops = &keydatastruct_gmops; - me->kd = kd; + me->kd = kd; kd = 0; end: - if (kd && !me) key_drop(kd); - Py_XDECREF(name); Py_XDECREF(val); Py_XDECREF(it); - Py_XDECREF(arg); Py_XDECREF(kw); + if (kd) key_drop(kd); return ((PyObject *)me); } @@ -1299,6 +1301,21 @@ static void key_pydealloc(PyObject *me) FREEOBJ(me); } +static Py_hash_t key_pyhash(PyObject *me) + { return ((Py_hash_t)KEY_K(me)); } + +static PyObject *key_pyrichcompare(PyObject *me, PyObject *you, int op) +{ + if (!KEY_PYCHECK(you)) RETURN_NOTIMPL; + switch (op) { + case Py_EQ: return (getbool(KEY_K(me) == KEY_K(you))); + case Py_NE: return (getbool(KEY_K(me) == KEY_K(you))); + default: TYERR("ordering makes no sense"); + } +end: + return (0); +} + static PyObject *kmeth_delete(PyObject *me) { int err; @@ -1521,7 +1538,7 @@ static const PyTypeObject key_pytype_skel = { 0, /* @tp_as_number@ */ 0, /* @tp_as_sequence@ */ 0, /* @tp_as_mapping@ */ - 0, /* @tp_hash@ */ + key_pyhash, /* @tp_hash@ */ 0, /* @tp_call@ */ 0, /* @tp_str@ */ 0, /* @tp_getattro@ */ @@ -1535,7 +1552,7 @@ static const PyTypeObject key_pytype_skel = { 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ - 0, /* @tp_richcompare@ */ + key_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ @@ -1631,7 +1648,6 @@ static PyObject *keyfile_pynew(PyTypeObject *ty, keyfile_pyobj *rc = 0; static const char *const kwlist[] = { "file", "how", "report", 0 }; - Py_XINCREF(arg); Py_XINCREF(kw); if (!PyArg_ParseTupleAndKeywords(arg, kw, "s|iO:new", KWLIST, &file, &how, &ri.func)) goto end; @@ -1654,7 +1670,6 @@ end: rc = 0; } done: - Py_XDECREF(arg); Py_XDECREF(kw); return ((PyObject *)rc); } @@ -1687,7 +1702,6 @@ static PyObject *kfmeth_mergeline(PyObject *me, PyObject *arg, PyObject *kw) int lno, rc; static const char *const kwlist[] = { "name", "lno", "line", "report", 0 }; - Py_XINCREF(arg); Py_XINCREF(kw); if (!PyArg_ParseTupleAndKeywords(arg, kw, "sis|O:merge", KWLIST, &file, &lno, &line, &ri.func)) goto end; @@ -1698,11 +1712,9 @@ static PyObject *kfmeth_mergeline(PyObject *me, PyObject *arg, PyObject *kw) goto end; if (rc != 0) KEYERR(rc); - Py_XDECREF(arg); Py_XDECREF(kw); RETURN_ME; end: - Py_XDECREF(arg); Py_XDECREF(kw); return (0); }