X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/52db206f983882381e87eaa3fe56e5a9ba2e0d74..85b62bfa0154f30a9359831663f45e8f6bbe3fe6:/key.c diff --git a/key.c b/key.c index 5ad05a9..2ec8a61 100644 --- a/key.c +++ b/key.c @@ -1015,44 +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 }; - 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); + if (kd) key_drop(kd); return ((PyObject *)me); } @@ -1714,40 +1718,58 @@ end: return (0); } -static PyObject *kfmeth_byid(PyObject *me, PyObject *arg) +static PyObject *kfmeth_byid(PyObject *me, PyObject *arg, PyObject *kw) { uint32 id; key *k; + PyObject *failp = Py_True; PyObject *rc = 0; + static const char *const kwlist[] = { "id", "fail", 0 }; - if (!PyArg_ParseTuple(arg, "O&:byid", convu32, &id)) goto end; - if ((k = key_byid(KEYFILE_KF(me), id)) == 0) KEYERR(KERR_NOTFOUND); - rc = key_pywrap(me, k); + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O:byid", KWLIST, + convu32, &id, &failp)) + goto end; + if ((k = key_byid(KEYFILE_KF(me), id)) != 0) rc = key_pywrap(me, k); + else if (PyObject_IsTrue(failp)) KEYERR(KERR_NOTFOUND); + else RETURN_NONE; end: return (rc); } -static PyObject *kfmeth_bytype(PyObject *me, PyObject *arg) +static PyObject *kfmeth_bytype(PyObject *me, PyObject *arg, PyObject *kw) { char *type; key *k; + PyObject *failp = Py_True; PyObject *rc = 0; + static const char *const kwlist[] = { "type", "fail", 0 }; - if (!PyArg_ParseTuple(arg, "s:bytype", &type)) goto end; - if ((k = key_bytype(KEYFILE_KF(me), type)) == 0) RETURN_NONE; - rc = key_pywrap(me, k); + if (!PyArg_ParseTupleAndKeywords(arg, kw, "s|O:bytype", KWLIST, + &type, &failp)) + goto end; + if ((k = key_bytype(KEYFILE_KF(me), type)) != 0) rc = key_pywrap(me, k); + else if (PyObject_IsTrue(failp)) KEYERR(KERR_NOTFOUND); + else RETURN_NONE; end: return (rc); } -static PyObject *kfmeth_bytag(PyObject *me, PyObject *arg) +static PyObject *kfmeth_bytag(PyObject *me, PyObject *arg, PyObject *kw) { PyObject *tagobj; key *k; + PyObject *failp = Py_True; + PyObject *rc = 0; + static const char *const kwlist[] = { "type", "fail", 0 }; - if (!PyArg_ParseTuple(arg, "O:bytag", &tagobj)) return (0); - if ((k = bytag(me, tagobj)) == 0) RETURN_NONE; - else return (key_pywrap(me, k)); + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:bytag", KWLIST, + &tagobj, &failp)) + goto end; + if ((k = bytag(me, tagobj)) != 0) rc = key_pywrap(me, k); + else if (PyObject_IsTrue(failp)) KEYERR(KERR_NOTFOUND); + else RETURN_NONE; +end: + return (rc); } static PyObject *kfmeth_newkey(PyObject *me, PyObject *arg, PyObject *kw) @@ -1816,9 +1838,9 @@ static const PyMethodDef keyfile_pymethods[] = { "[report = ])") KWMETH(newkey, "KF.newkey(ID, TYPE, [exptime = KEXP_FOREVER]) " "-> KEY") - METH (byid, "KF.byid(KEYID) -> KEY|None") - METH (bytype, "KF.bytype(TYPE) -> KEY|None") - METH (bytag, "KF.bytag(TAG) -> KEY|None") + KWMETH(byid, "KF.byid(KEYID, [fail = True]) -> KEY|None") + KWMETH(bytype, "KF.bytype(TYPE, [fail = True]) -> KEY|None") + KWMETH(bytag, "KF.bytag(TAG, [fail = True]) -> KEY|None") KWMETH(qtag, "KF.qtag(TAG, [new = KD]) -> FULLTAG, KEY, OLDKD") GMAP_ROMETHODS #undef METHNAME