X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/31ff254edd8d9c6927a67838ec4418ad8ba42652..ebe7d65db55a09676d4435bc74b65d1f68603130:/key.c diff --git a/key.c b/key.c index e3b5615..82bbb19 100644 --- a/key.c +++ b/key.c @@ -51,7 +51,7 @@ static PyObject *kxmeth___init__(PyObject *me, PyObject *arg) if (PyObject_SetAttrString(me, "err", x)) goto end; Py_DECREF(x); x = 0; - x = PyString_FromString(key_strerror(err)); if (!x) goto end; + x = TEXT_FROMSTR(key_strerror(err)); if (!x) goto end; if (PyObject_SetAttrString(me, "errstring", x)) goto end; Py_DECREF(x); x = 0; @@ -87,9 +87,9 @@ static PyObject *kxmeth___str__(PyObject *me, PyObject *arg) if (err >= 0 && err < N(tab)) errtag = tab[err]; else errtag = ""; if ((x = PyObject_GetAttrString(me, "errstring")) == 0 || - (errstr = PyString_AsString(x)) == 0) + (errstr = TEXT_STR(x)) == 0) goto done; - rc = PyString_FromFormat("%s (%ld): %s", errtag, -err, errstr); + rc = TEXT_FORMAT("%s (%ld): %s", errtag, -err, errstr); done: Py_XDECREF(x); @@ -181,7 +181,7 @@ static int convfilter(PyObject *x, void *p) int err; int rc = 0; - if ((fs = PyString_AsString(x)) != 0) { + if ((fs = TEXT_STR(x)) != 0) { if ((err = key_readflags(fs, &end, &f->f, &f->m)) != 0) KEYERR(err); if (*end) @@ -220,7 +220,7 @@ static int convflags(PyObject *x, void *p) return (1); else { PyErr_Clear(); - if ((fs = PyString_AsString(x)) != 0) { + if ((fs = TEXT_STR(x)) != 0) { if ((err = key_readflags(fs, &end, f, 0)) != 0) KEYERR(err); if (*end) @@ -261,7 +261,7 @@ static PyObject *kdmeth_writeflags(PyObject *me, PyObject *arg) if (!PyArg_ParseTuple(arg, "O&:key_writeflags", convuint, &f)) return (0); key_writeflags(f, &d); - rc = PyString_FromStringAndSize(d.buf, d.len); + rc = TEXT_FROMSTRLEN(d.buf, d.len); dstr_destroy(&d); return (rc); } @@ -338,7 +338,7 @@ static PyObject *kdmeth_write(PyObject *me, PyObject *arg, PyObject *kw) convfilter, &f)) return (0); key_write(KEYDATA_KD(me), &d, &f); - rc = PyString_FromStringAndSize(d.buf, d.len); + rc = TEXT_FROMSTRLEN(d.buf, d.len); dstr_destroy(&d); return (rc); } @@ -377,14 +377,13 @@ end: static PyObject *kdmeth_lock(PyObject *me, PyObject *arg) { - char *p; - Py_ssize_t n; + struct bin pp; PyObject *rc = 0; key_data *kd; - if (!PyArg_ParseTuple(arg, "s#:lock", &p, &n)) + if (!PyArg_ParseTuple(arg, "O&:lock", convbin, &pp)) goto end; - key_lock(&kd, KEYDATA_KD(me), p, n); + key_lock(&kd, KEYDATA_KD(me), pp.p, pp.sz); rc = keydata_pywrap(kd); end: return (rc); @@ -406,14 +405,13 @@ end: static PyObject *kdmeth_decode(PyObject *me, PyObject *arg) { - const char *p; - Py_ssize_t n; + struct bin in; key_data *kd; PyObject *rc = 0; - if (!PyArg_ParseTuple(arg, "s#:decode", &p, &n)) goto end; - if ((kd = key_decode(p, n)) == 0) KEYERR(KERR_MALFORMED); - rc = keydata_pywrap(kd); + if (!PyArg_ParseTuple(arg, "O&:decode", convbin, &in)) goto end; + if ((kd = key_decode(in.p, in.sz)) == 0) KEYERR(KERR_MALFORMED); + rc = keydata_pywrap(kd); end: return (rc); } @@ -446,7 +444,7 @@ static const PyGetSetDef keydata_pygetset[] = { }; static const PyTypeObject keydata_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyData", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -496,17 +494,16 @@ static const PyTypeObject keydata_pytype_skel = { static PyObject *keydatabin_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - char *p; - Py_ssize_t n; + struct bin in; unsigned f = 0; keydata_pyobj *me = 0; static const char *const kwlist[] = { "key", "flags", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#|O&:new", KWLIST, - &p, &n, convflags, &f)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST, + convbin, &in, convflags, &f)) goto end; me = (keydata_pyobj *)ty->tp_alloc(ty, 0); - me->kd = key_newbinary(f & ~KF_ENCMASK, p, n); + me->kd = key_newbinary(f & ~KF_ENCMASK, in.p, in.sz); end: return ((PyObject *)me); } @@ -523,7 +520,7 @@ static const PyGetSetDef keydatabin_pygetset[] = { }; static const PyTypeObject keydatabin_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataBinary", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -573,17 +570,16 @@ static const PyTypeObject keydatabin_pytype_skel = { static PyObject *keydataenc_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - char *p; - Py_ssize_t n; + struct bin in; unsigned f = 0; keydata_pyobj *me = 0; static const char *const kwlist[] = { "key", "flags", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#|O&:new", KWLIST, - &p, &n, convflags, &f)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST, + convbin, &in, convflags, &f)) goto end; me = (keydata_pyobj *)ty->tp_alloc(ty, 0); - me->kd = key_newencrypted(f & ~KF_ENCMASK, p, n); + me->kd = key_newencrypted(f & ~KF_ENCMASK, in.p, in.sz); end: return ((PyObject *)me); } @@ -599,9 +595,8 @@ end: static PyObject *kdemeth_lock(PyObject *me, PyObject *arg) { - char *hunoz; - Py_ssize_t hukairz; - if (!PyArg_ParseTuple(arg, "s#:lock", &hunoz, &hukairz)) goto end; + struct bin hunoz; + if (!PyArg_ParseTuple(arg, "O&:lock", convbin, &hunoz)) goto end; KEYERR(KERR_WRONGTYPE); end: return (0); @@ -625,15 +620,14 @@ end: static PyObject *kdemeth_unlock(PyObject *me, PyObject *arg) { - char *p; - Py_ssize_t n; + struct bin pp; int err; PyObject *rc = 0; key_data *kd; - if (!PyArg_ParseTuple(arg, "s#:unlock", &p, &n)) + if (!PyArg_ParseTuple(arg, "O&:unlock", convbin, &pp)) goto end; - if ((err = key_unlock(&kd, KEYDATA_KD(me), p, n)) != 0) + if ((err = key_unlock(&kd, KEYDATA_KD(me), pp.p, pp.sz)) != 0) KEYERR(err); rc = keydata_pywrap(kd); end: @@ -660,7 +654,7 @@ static const PyGetSetDef keydataenc_pygetset[] = { }; static const PyTypeObject keydataenc_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataEncrypted", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -736,7 +730,7 @@ static const PyGetSetDef keydatamp_pygetset[] = { }; static const PyTypeObject keydatamp_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataMP", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -801,7 +795,7 @@ end: } static PyObject *kdsget_str(PyObject *me, void *hunoz) - { return (PyString_FromString(KEYDATA_KD(me)->u.p)); } + { return (TEXT_FROMSTR(KEYDATA_KD(me)->u.p)); } static const PyGetSetDef keydatastr_pygetset[] = { #define GETSETNAME(op, name) kds##op##_##name @@ -811,7 +805,7 @@ static const PyGetSetDef keydatastr_pygetset[] = { }; static const PyTypeObject keydatastr_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataString", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -891,7 +885,7 @@ static const PyGetSetDef keydataec_pygetset[] = { }; static const PyTypeObject keydataec_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataECPt", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -945,7 +939,7 @@ static void *keydatastruct_gmlookup(PyObject *me, PyObject *k, unsigned *f) key_struct *ks; assert((kd->e&KF_ENCMASK) == KENC_STRUCT); - if ((tag = PyString_AsString(k)) == 0) return (0); + if ((tag = TEXT_STR(k)) == 0) return (0); if (f) { key_split(&kd); KEYDATA_KD(me) = kd; } ks = sym_find(&kd->u.s, tag, -1, f ? sizeof(key_struct) : 0, f); if (ks && f && !*f) ks->k = 0; @@ -964,7 +958,7 @@ static void *keydatastruct_gmiternext(PyObject *me, void *i) { return (sym_next(i)); } static PyObject *keydatastruct_gmentrykey(PyObject *me, void *e) - { key_struct *ks = e; return (PyString_FromString(SYM_NAME(ks))); } + { key_struct *ks = e; return (TEXT_FROMSTR(SYM_NAME(ks))); } static PyObject *keydatastruct_gmentryvalue(PyObject *me, void *e) { @@ -1021,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 = PyString_AsString(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); } @@ -1074,7 +1070,7 @@ static const PyMappingMethods keydatastruct_pymapping = { }; static const PyTypeObject keydatastruct_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyDataStructured", /* @tp_name@ */ sizeof(keydata_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1125,7 +1121,7 @@ static const PyTypeObject keydatastruct_pytype_skel = { static void *keyattrs_gmlookup(PyObject *me, PyObject *k, unsigned *f) { - char *name = PyString_AsString(k); + char *name = TEXT_STR(k); key_attr *a = 0; if (!name) goto end; @@ -1143,10 +1139,10 @@ static void *keyattrs_gmiternext(PyObject *me, void *i) { return (sym_next(i)); } static PyObject *keyattrs_gmentrykey(PyObject *me, void *e) - { return (PyString_FromString(SYM_NAME(e))); } + { return (TEXT_FROMSTR(SYM_NAME(e))); } static PyObject *keyattrs_gmentryvalue(PyObject *me, void *e) - { return (PyString_FromString(((key_attr *)e)->p)); } + { return (TEXT_FROMSTR(((key_attr *)e)->p)); } static int keyattrs_gmsetentry(PyObject *me, void *e, PyObject *val) { @@ -1155,8 +1151,8 @@ static int keyattrs_gmsetentry(PyObject *me, void *e, PyObject *val) Py_ssize_t n; int rc = -1; - if (!PyString_Check(val)) TYERR("expected string"); - p = PyString_AS_STRING(val); n = PyString_GET_SIZE(val); + if (!TEXT_CHECK(val)) TYERR("expected string"); + TEXT_PTRLEN(val, p, n); if (n > 255) VALERR("attribute too long"); if (memchr(p, 0, n)) VALERR("attribute must not contain nul"); if (a->p) xfree(a->p); @@ -1216,7 +1212,7 @@ static const PyMappingMethods keyattrs_pymapping = { }; static const PyTypeObject keyattrs_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyAttributes", /* @tp_name@ */ sizeof(keyattrs_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1305,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; @@ -1337,27 +1348,21 @@ end: return (0); } -static PyObject *kmeth_extract(PyObject *me, PyObject *arg, PyObject *kw) +static PyObject *kmeth_extractline(PyObject *me, PyObject *arg, PyObject *kw) { key_filter f = { 0, 0 }; - PyObject *file; - PyObject *nameobj; - char *name; - FILE *fp; - static const char *const kwlist[] = { "file", "filter", 0 }; - - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O&:extract", KWLIST, - &PyFile_Type, &file, - convfilter, &f) || - (fp = PyFile_AsFile(file)) == 0 || - (nameobj = PyFile_Name(file)) == 0 || - (name = PyString_AsString(nameobj)) == 0) + dstr d = DSTR_INIT; + PyObject *rc = 0; + static const char *const kwlist[] = { "filter", 0 }; + + if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:extract", KWLIST, + convfilter, &f)) goto end; - if (key_extract(KEY_KF(me), KEY_K(me), fp, &f)) - OSERR(name); - RETURN_ME; + key_extractline(KEY_KF(me), KEY_K(me), &d, &f); + rc = TEXT_FROMSTRLEN(d.buf, d.len); end: - return (0); + dstr_destroy(&d); + return (rc); } static PyObject *kmeth_fingerprint(PyObject *me, @@ -1378,7 +1383,7 @@ static PyObject *kget_id(PyObject *me, void *hunoz) static PyObject *kget_file(PyObject *me, void *hunoz) { RETURN_OBJ(KEY_KFOBJ(me)); } static PyObject *kget_type(PyObject *me, void *hunoz) - { return (PyString_FromString(KEY_K(me)->type)); } + { return (TEXT_FROMSTR(KEY_K(me)->type)); } static PyObject *kget_exptime(PyObject *me, void *hunoz) { return (getulong(KEY_K(me)->exp)); } static PyObject *kget_deltime(PyObject *me, void *hunoz) @@ -1449,7 +1454,7 @@ static PyObject *kget_fulltag(PyObject *me, void *hunoz) PyObject *rc; key_fulltag(KEY_K(me), &d); - rc = PyString_FromStringAndSize(d.buf, d.len); + rc = TEXT_FROMSTRLEN(d.buf, d.len); dstr_destroy(&d); return (rc); } @@ -1457,7 +1462,7 @@ static PyObject *kget_fulltag(PyObject *me, void *hunoz) static PyObject *kget_tag(PyObject *me, void *hunoz) { if (!KEY_K(me)->tag) RETURN_NONE; - return (PyString_FromString(KEY_K(me)->tag)); + return (TEXT_FROMSTR(KEY_K(me)->tag)); } static int kset_tag(PyObject *me, PyObject *x, void *hunoz) { @@ -1465,7 +1470,7 @@ static int kset_tag(PyObject *me, PyObject *x, void *hunoz) char *tag; if (!x || x == Py_None) tag = 0; - else if ((tag = PyString_AsString(x)) == 0) goto end; + else if ((tag = TEXT_STR(x)) == 0) goto end; if ((err = key_settag(KEY_KF(me), KEY_K(me), tag)) != 0) KEYERR(err); return (0); end: @@ -1475,7 +1480,7 @@ end: static PyObject *kget_comment(PyObject *me, void *hunoz) { if (!KEY_K(me)->c) RETURN_NONE; - return (PyString_FromString(KEY_K(me)->c)); + return (TEXT_FROMSTR(KEY_K(me)->c)); } static int kset_comment(PyObject *me, PyObject *x, void *hunoz) { @@ -1483,7 +1488,7 @@ static int kset_comment(PyObject *me, PyObject *x, void *hunoz) char *c; if (!x || x == Py_None) c = 0; - else if ((c = PyString_AsString(x)) == 0) goto end; + else if ((c = TEXT_STR(x)) == 0) goto end; if ((err = key_setcomment(KEY_KF(me), KEY_K(me), c)) != 0) KEYERR(err); return (0); end: @@ -1495,7 +1500,7 @@ static const PyMethodDef key_pymethods[] = { NAMETH(delete, "KEY.delete()") NAMETH(expire, "KEY.expire()") METH (used, "KEY.used(TIME)") - KWMETH(extract, "KEY.extract(FILE, [filter = ])") + KWMETH(extractline, "KEY.extractline([filter = ])") KWMETH(fingerprint, "KEY.fingerprint(HASH, [filter = '-secret'])") #undef METHNAME { 0 } @@ -1519,7 +1524,7 @@ static const PyGetSetDef key_pygetset[] = { }; static const PyTypeObject key_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "Key", /* @tp_name@ */ sizeof(key_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -1533,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@ */ @@ -1547,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@ */ @@ -1578,7 +1583,7 @@ static key *bytag(PyObject *me, PyObject *tagobj) k = key_byid(KEYFILE_KF(me), id); else { PyErr_Clear(); - if ((tag = PyString_AsString(tagobj)) == 0) + if ((tag = TEXT_STR(tagobj)) == 0) goto end; k = key_bytag(KEYFILE_KF(me), tag); } @@ -1625,7 +1630,7 @@ static void pythonreporter(const char *file, int line, if (ri->stop) return; - if (!ri->func) + if (ri->func == Py_None) key_moan(file, line, msg, 0); else if ((res = PyObject_CallFunction(ri->func, "sis", file, line, msg)) == 0) @@ -1637,17 +1642,16 @@ static void pythonreporter(const char *file, int line, static PyObject *keyfile_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - struct reportinfo ri = { 0, 0 }; + struct reportinfo ri = { Py_None, 0 }; char *file = 0; unsigned how = KOPEN_READ; 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; - if (ri.func && !PyCallable_Check(ri.func)) + if (ri.func != Py_None && !PyCallable_Check(ri.func)) TYERR("reporter function not callable"); if ((rc = (keyfile_pyobj *)ty->tp_alloc(ty, 0)) == 0) goto end; @@ -1666,7 +1670,6 @@ end: rc = 0; } done: - Py_XDECREF(arg); Py_XDECREF(kw); return ((PyObject *)rc); } @@ -1692,73 +1695,81 @@ end: return (0); } -static PyObject *kfmeth_merge(PyObject *me, PyObject *arg, PyObject *kw) +static PyObject *kfmeth_mergeline(PyObject *me, PyObject *arg, PyObject *kw) { - struct reportinfo ri = { 0, 0 }; - char *name; - PyObject *x = 0; - FILE *fp = 0; - int rc; - static const char *const kwlist[] = { "file", "report", 0 }; + struct reportinfo ri = { Py_None, 0 }; + const char *file, *line; + int lno, rc; + static const char *const kwlist[] = { "name", "lno", "line", "report", 0 }; - Py_XINCREF(arg); Py_XINCREF(kw); - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O:merge", KWLIST, - &PyFile_Type, &x, &ri.func)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "sis|O:merge", KWLIST, + &file, &lno, &line, &ri.func)) goto end; - if (ri.func && !PyCallable_Check(ri.func)) + if (ri.func != Py_None && !PyCallable_Check(ri.func)) TYERR("reporter function not callable"); - if ((fp = PyFile_AsFile(x)) == 0) - goto end; - x = PyFile_Name(x); - if ((name = PyString_AsString(x)) == 0) - goto end; - rc = key_merge(KEYFILE_KF(me), name, fp, pythonreporter, &ri); + rc = key_mergeline(KEYFILE_KF(me), file, lno, line, pythonreporter, &ri); if (ri.stop) goto end; if (rc != 0) KEYERR(rc); - Py_XDECREF(arg); Py_XDECREF(kw); RETURN_ME; end: - Py_XDECREF(arg); Py_XDECREF(kw); 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) @@ -1812,7 +1823,7 @@ end: } static PyObject *kfget_name(PyObject *me, void *hunoz) - { return (PyString_FromString(KEYFILE_KF(me)->name)); } + { return (TEXT_FROMSTR(KEYFILE_KF(me)->name)); } static PyObject *kfget_modifiedp(PyObject *me, void *hunoz) { return (getbool(KEYFILE_KF(me)->f & KF_MODIFIED)); } static PyObject *kfget_writep(PyObject *me, void *hunoz) @@ -1823,12 +1834,13 @@ static PyObject *kfget_filep(PyObject *me, void *hunoz) static const PyMethodDef keyfile_pymethods[] = { #define METHNAME(func) kfmeth_##func NAMETH(save, "KF.save()") - KWMETH(merge, "KF.merge(FILE, [report = ])") + KWMETH(mergeline, "KF.mergeline(NAME, LNO, LINE, " + "[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 @@ -1852,7 +1864,7 @@ static const PyMappingMethods keyfile_pymapping = { }; static const PyTypeObject keyfile_pytype_skel = { - PyObject_HEAD_INIT(0) 0, /* Header */ + PyVarObject_HEAD_INIT(0, 0) /* Header */ "KeyFile", /* @tp_name@ */ sizeof(keyfile_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */