X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/d7ab1bab81155baa763449d5afa81e16df98dbe7..dad564fa66dd0ab52058f25a0eaf6a8e5b3c4316:/pgen.c diff --git a/pgen.c b/pgen.c index e201b62..9f9e1a2 100644 --- a/pgen.c +++ b/pgen.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id$ - * * Prime number generation * * (c) 2005 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. @@ -40,7 +38,7 @@ static PyObject *pfilt_pywrap(pfilt *f) o = PyObject_New(pfilt_pyobj, pfilt_pytype); o->f = *f; o->st = pfilt_step(f, 0); - return ((PyObject *)o); + return ((PyObject *)o); } static PyObject *pfilt_pymake(PyTypeObject *ty, PyObject *xobj) @@ -59,16 +57,16 @@ end: static PyObject *pfilt_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - char *kwlist[] = { "x", 0 }; + static const char *const kwlist[] = { "x", 0 }; PyObject *xobj; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:new", kwlist, &xobj)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:new", KWLIST, &xobj)) return (0); return (pfilt_pymake(ty, xobj)); } static void pfilt_pydealloc(PyObject *me) - { pfilt_destroy(PFILT_F(me)); PyObject_DEL(me); } + { pfilt_destroy(PFILT_F(me)); FREEOBJ(me); } static PyObject *pfmeth_step(PyObject *me, PyObject *arg) { @@ -122,14 +120,13 @@ static PyObject *pfilt_pyint(PyObject *me) long l; PyObject *rc = 0; - if (mp_tolong_checked(PFILT_F(me)->m, &l)) goto end; - rc = PyInt_FromLong(l); -end: + if (!mp_tolong_checked(PFILT_F(me)->m, &l, 0)) rc = PyInt_FromLong(l); + else rc = mp_topylong(PFILT_F(me)->m); return (rc); } static PyObject *pfilt_pylong(PyObject *me) - { return ((PyObject *)mp_topylong(PFILT_F(me)->m)); } + { return (mp_topylong(PFILT_F(me)->m)); } static PyObject *pfget_x(PyObject *me, void *hunoz) { return (mp_pywrap(MP_COPY(PFILT_F(me)->m))); } @@ -198,8 +195,8 @@ static PyNumberMethods pfilt_pynumber = { }; static PyTypeObject pfilt_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeFilter", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeFilter", /* @tp_name@ */ sizeof(pfilt_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -222,14 +219,14 @@ static PyTypeObject pfilt_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Small-primes filter.", +"PrimeFilter(X): small-primes filter.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ pfilt_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ pfilt_pygetset, /* @tp_getset@ */ @@ -241,7 +238,7 @@ static PyTypeObject pfilt_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ pfilt_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; @@ -259,9 +256,9 @@ static PyObject *rabin_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { mp *x = 0; rabin_pyobj *o = 0; - char *kwlist[] = { "x", 0 }; + static const char *const kwlist[] = { "x", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", kwlist, convmp, &x)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convmp, &x)) goto end; if (!MP_POSP(x) || MP_EVENP(x)) VALERR("must be positive and odd"); o = (rabin_pyobj *)ty->tp_alloc(ty, 0); @@ -273,7 +270,7 @@ end: static void rabin_pydealloc(PyObject *me) { rabin_destroy(RABIN_R(me)); - PyObject_DEL(me); + FREEOBJ(me); } static PyObject *rmeth_test(PyObject *me, PyObject *arg) @@ -331,8 +328,8 @@ static PyMethodDef rabin_pymethods[] = { }; static PyTypeObject rabin_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.RabinMiller", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "RabinMiller", /* @tp_name@ */ sizeof(rabin_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -355,14 +352,14 @@ static PyTypeObject rabin_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Rabin-Miller strong primality test.", +"RabinMiller(X): Rabin-Miller strong primality test.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ rabin_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ rabin_pygetset, /* @tp_getset@ */ @@ -374,7 +371,7 @@ static PyTypeObject rabin_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ rabin_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; @@ -382,6 +379,7 @@ static PyTypeObject rabin_pytype_skel = { typedef struct pgevent_pyobj { PyObject_HEAD + PyObject *r; pgen_event *ev; } pgevent_pyobj; @@ -391,18 +389,30 @@ static PyTypeObject *pgevent_pytype; static PyObject *pgevent_pywrap(pgen_event *ev) { pgevent_pyobj *o = PyObject_New(pgevent_pyobj, pgevent_pytype); - o->ev = ev; + o->ev = ev; o->r = 0; return ((PyObject *)o); } static CONVFUNC(pgevent, pgen_event *, PGEVENT_EV) -static void pgevent_kill(PyObject *me) { PGEVENT_EV(me) = 0; } -static void pgevent_pydealloc(PyObject *me) { PyObject_DEL(me); } +static void pgevent_kill(PyObject *me) +{ + pgevent_pyobj *ev = (pgevent_pyobj *)me; + + ev->ev = 0; + if (ev->r) GRAND_R(ev->r) = 0; +} + +static void pgevent_pydealloc(PyObject *me) +{ + pgevent_pyobj *ev = (pgevent_pyobj *)me; + if (ev->r) Py_DECREF(ev->r); + FREEOBJ(me); +} #define PGEVENT_CHECK(me) do { \ if (!PGEVENT_EV(me)) { \ - PyErr_SetString(PyExc_ValueError, "event object is dead"); \ + PyErr_SetString(PyExc_ValueError, "event object is no longer valid"); \ return (0); \ } \ } while (0) @@ -420,13 +430,20 @@ static PyObject *peget_tests(PyObject *me, void *hunoz) { PGEVENT_CHECK(me); return (PyInt_FromLong(PGEVENT_EV(me)->tests)); } static PyObject *peget_rng(PyObject *me, void *hunoz) - { PGEVENT_CHECK(me); return (grand_pywrap(PGEVENT_EV(me)->r, 0)); } +{ + pgevent_pyobj *ev = (pgevent_pyobj *)me; + + PGEVENT_CHECK(me); + if (!ev->r) ev->r = grand_pywrap(ev->ev->r, 0); + Py_INCREF(ev->r); return ((PyObject *)ev->r); +} static int peset_x(PyObject *me, PyObject *xobj, void *hunoz) { mp *x = 0; pgen_event *ev = PGEVENT_EV(me); int rc = -1; + if (!xobj) NIERR("__del__"); PGEVENT_CHECK(me); if ((x = getmp(xobj)) == 0) goto end; mp_drop(ev->m); @@ -449,8 +466,8 @@ static PyGetSetDef pgevent_pygetset[] = { }; static PyTypeObject pgevent_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeGenEvent", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeGenEvent", /* @tp_name@ */ sizeof(pgevent_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -480,7 +497,7 @@ static PyTypeObject pgevent_pytype_skel = { 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ pgevent_pygetset, /* @tp_getset@ */ @@ -492,7 +509,7 @@ static PyTypeObject pgevent_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ abstract_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; @@ -527,20 +544,19 @@ static PyTypeObject *pgtest_pytype; static int pgev_python(int rq, pgen_event *ev, void *p) { - PyObject *py = p; + pypgev *pg = p; PyObject *pyev = 0; PyObject *rc = 0; int st = PGEN_ABORT; long l; - char *meth[] = { - "pg_abort", "pg_done", "pg_begin", "pg_try", "pg_fail", "pg_pass" - }; + static const char *const meth[] = + { "pg_abort", "pg_done", "pg_begin", "pg_try", "pg_fail", "pg_pass" }; - Py_INCREF(py); rq++; if (rq > N(meth)) SYSERR("event code out of range"); pyev = pgevent_pywrap(ev); - if ((rc = PyObject_CallMethod(py, meth[rq], "(O)", pyev)) == 0) + if ((rc = PyObject_CallMethod(pg->obj, (/*unconst*/ char *)meth[rq], + "(O)", pyev)) == 0) goto end; if (rc == Py_None) st = PGEN_TRY; @@ -548,15 +564,16 @@ static int pgev_python(int rq, pgen_event *ev, void *p) goto end; else if (l < PGEN_ABORT || l > PGEN_PASS) VALERR("return code out of range"); - else + else st = l; end: + if (PyErr_Occurred()) + stash_exception(pg->exc, "exception from `pgen' handler"); if (pyev) { pgevent_kill(pyev); Py_DECREF(pyev); } Py_XDECREF(rc); - Py_DECREF(py); return (st); } @@ -571,24 +588,22 @@ static PyObject *pgev_pywrap(const pgev *pg) int convpgev(PyObject *o, void *p) { - pgev *pg = p; + pypgev *pg = p; if (PGEV_PYCHECK(o)) - *pg = *PGEV_PG(o); + pg->ev = *PGEV_PG(o); else { - pg->proc = pgev_python; - pg->ctx = o; - Py_INCREF(o); + pg->ev.proc = pgev_python; + pg->ev.ctx = pg; + pg->obj = o; Py_INCREF(o); } return (1); } -void droppgev(pgev *p) +void droppgev(pypgev *pg) { - if (p->proc == pgev_python) { - PyObject *py = p->ctx; - Py_DECREF(py); - } + if (pg->ev.proc == pgev_python) + { assert(pg->ev.ctx == pg); Py_DECREF(pg->obj); } } static PyObject *pgmeth_common(PyObject *me, PyObject *arg, int rq) @@ -619,23 +634,23 @@ static PyObject *pgev_stdev(pgen_proc *proc) static PyMethodDef pgev_pymethods[] = { #define METHNAME(name) pgmeth_##name - METH (pg_abort, "E.pg_abort() -> PGRC -- prime generation aborted") - METH (pg_done, "E.pg_done() -> PGRC -- prime generation finished") - METH (pg_begin, "E.pg_begin() -> PGRC -- commence stepping/testing") - METH (pg_try, "E.pg_try() -> PGRC -- found new candidate") - METH (pg_pass, "E.pg_pass() -> PGRC -- passed primality test") - METH (pg_fail, "E.pg_fail() -> PGRC -- failed primality test") + METH (pg_abort, "E.pg_abort(EV) -> PGRC -- prime generation aborted") + METH (pg_done, "E.pg_done(EV) -> PGRC -- prime generation finished") + METH (pg_begin, "E.pg_begin(EV) -> PGRC -- commence stepping/testing") + METH (pg_try, "E.pg_try(EV) -> PGRC -- found new candidate") + METH (pg_pass, "E.pg_pass(EV) -> PGRC -- passed primality test") + METH (pg_fail, "E.pg_fail(EV) -> PGRC -- failed primality test") #undef METHNAME { 0 } }; static PyTypeObject pgev_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeGenBuiltinHandler", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeGenBuiltinHandler", /* @tp_name@ */ sizeof(pgev_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ - _PyObject_Del, /* @tp_dealloc@ */ + 0, /* @tp_dealloc@ */ 0, /* @tp_print@ */ 0, /* @tp_getattr@ */ 0, /* @tp_setattr@ */ @@ -661,7 +676,7 @@ static PyTypeObject pgev_pytype_skel = { 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ pgev_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -673,7 +688,7 @@ static PyTypeObject pgev_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ abstract_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; @@ -681,9 +696,9 @@ static PyObject *pgstep_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { mpw s; pgstep_pyobj *rc = 0; - char *kwlist[] = { "step", 0 }; + static const char *const kwlist[] = { "step", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", kwlist, convmpw, &s)) + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convmpw, &s)) goto end; rc = (pgstep_pyobj *)ty->tp_alloc(ty, 0); rc->f.step = s; @@ -698,14 +713,14 @@ static PyObject *psget_step(PyObject *me, void *hunoz) static PyGetSetDef pgstep_pygetset[] = { #define GETSETNAME(op, name) ps##op##_##name - GET (step, "S.step -> step size for the stepper") + GET (step, "S.step -> step size for the stepper") #undef GETSETNAME { 0 } }; static PyTypeObject pgstep_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeGenStepper", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeGenStepper", /* @tp_name@ */ sizeof(pgstep_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -728,14 +743,14 @@ static PyTypeObject pgstep_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ - "Simple prime-number stepper with small-factors filter.", +"PrimeGenStepper(STEP): simple stepper with small-factors filter.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ pgstep_pygetset, /* @tp_getset@ */ @@ -747,7 +762,7 @@ static PyTypeObject pgstep_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ pgstep_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; @@ -755,9 +770,9 @@ static PyObject *pgjump_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { PyObject *o, *fobj; pgjump_pyobj *rc = 0; - char *kwlist[] = { "jump", 0 }; + static const char *const kwlist[] = { "jump", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:new", kwlist, &o) || + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O:new", KWLIST, &o) || (fobj = pfilt_pymake(pfilt_pytype, o)) == 0) goto end; rc = (pgjump_pyobj *)ty->tp_alloc(ty, 0); @@ -772,7 +787,7 @@ end: static void pgjump_pydealloc(PyObject *me) { Py_DECREF(PGJUMP_FOBJ(me)); - _PyObject_Del(me); + FREEOBJ(me); } static PyObject *pjget_jump(PyObject *me, void *hunoz) @@ -780,14 +795,14 @@ static PyObject *pjget_jump(PyObject *me, void *hunoz) static PyGetSetDef pgjump_pygetset[] = { #define GETSETNAME(op, name) pj##op##_##name - GET (jump, "S.jump -> jump size for the stepper") + GET (jump, "S.jump -> jump size for the stepper") #undef GETSETNAME { 0 } }; static PyTypeObject pgjump_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeGenJumper", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeGenJumper", /* @tp_name@ */ sizeof(pgjump_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -810,14 +825,14 @@ static PyTypeObject pgjump_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Stepper for larger steps, with small-factors filter.", +"PrimeGenJumper(JUMP): stepper for larger steps with small-factors filter.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ pgjump_pygetset, /* @tp_getset@ */ @@ -829,16 +844,16 @@ static PyTypeObject pgjump_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ pgjump_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; static PyObject *pgtest_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { pgtest_pyobj *rc = 0; - char *kwlist[] = { 0 }; + static const char *const kwlist[] = { 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", kwlist)) goto end; + if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) goto end; rc = (pgtest_pyobj *)ty->tp_alloc(ty, 0); rc->pg.proc = pgen_test; rc->pg.ctx = &rc->r; @@ -847,8 +862,8 @@ end: } static PyTypeObject pgtest_pytype_skel = { - PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */ - "catacomb.PrimeGenTester", /* @tp_name@ */ + PyObject_HEAD_INIT(0) 0, /* Header */ + "PrimeGenTester", /* @tp_name@ */ sizeof(pgtest_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -871,14 +886,14 @@ static PyTypeObject pgtest_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Rabin-Miller tester.", +"PrimeGenTester(): Rabin-Miller tester.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ @@ -890,16 +905,16 @@ static PyTypeObject pgtest_pytype_skel = { 0, /* @tp_init@ */ PyType_GenericAlloc, /* @tp_alloc@ */ pgtest_pynew, /* @tp_new@ */ - _PyObject_Del, /* @tp_free@ */ + 0, /* @tp_free@ */ 0 /* @tp_is_gc@ */ }; /*----- Prime generation functions ----------------------------------------*/ -void pgenerr(void) +void pgenerr(struct excinfo *exc) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, "prime generation failed"); + if (exc->ty) RESTORE_EXCINFO(exc); + else PyErr_SetString(PyExc_ValueError, "prime generation failed"); } static PyObject *meth_pgen(PyObject *me, PyObject *arg, PyObject *kw) @@ -910,30 +925,30 @@ static PyObject *meth_pgen(PyObject *me, PyObject *arg, PyObject *kw) char *p = "p"; pgen_filterctx fc = { 2 }; rabin tc; - pgev step = { 0 }, test = { 0 }, evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev step = { { 0 } }, test = { { 0 } }, evt = { { 0 } }; unsigned nsteps = 0, ntests = 0; - char *kwlist[] = { "start", "name", "stepper", "tester", "event", - "nsteps", "ntests", 0 }; + static const char *const kwlist[] = + { "start", "name", "stepper", "tester", "event", "nsteps", "ntests", 0 }; - step.proc = pgen_filter; step.ctx = &fc; - test.proc = pgen_test; test.ctx = &tc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&O&O&:pgen", kwlist, + step.exc = &exc; step.ev.proc = pgen_filter; step.ev.ctx = &fc; + test.exc = &exc; test.ev.proc = pgen_test; test.ev.ctx = &tc; + evt.exc = &exc; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&O&O&:pgen", KWLIST, convmp, &x, &p, convpgev, &step, convpgev, &test, convpgev, &evt, convuint, &nsteps, convuint, &ntests)) goto end; if (!ntests) ntests = rabin_iters(mp_bits(x)); - if ((r = pgen(p, MP_NEW, x, evt.proc, evt.ctx, - nsteps, step.proc, step.ctx, - ntests, test.proc, test.ctx)) == 0) - PGENERR; - if (PyErr_Occurred()) goto end; - rc = mp_pywrap(r); - r = 0; + if ((r = pgen(p, MP_NEW, x, evt.ev.proc, evt.ev.ctx, + nsteps, step.ev.proc, step.ev.ctx, + ntests, test.ev.proc, test.ev.ctx)) == 0) + PGENERR(&exc); + rc = mp_pywrap(r); r = 0; end: mp_drop(r); mp_drop(x); droppgev(&step); droppgev(&test); droppgev(&evt); - return (rc); + return (rc); } static PyObject *meth_strongprime_setup(PyObject *me, @@ -945,18 +960,21 @@ static PyObject *meth_strongprime_setup(PyObject *me, unsigned nbits; char *name = "p"; unsigned n = 0; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; PyObject *rc = 0; - char *kwlist[] = { "nbits", "name", "event", "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "nbits", "name", "event", "rng", "nsteps", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + evt.exc = &exc; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) goto end; if ((x = strongprime_setup(name, MP_NEW, &f, nbits, - r, n, evt.proc, evt.ctx)) == 0) - PGENERR; + r, n, evt.ev.proc, evt.ev.ctx)) == 0) + PGENERR(&exc); rc = Py_BuildValue("(NN)", mp_pywrap(x), pfilt_pywrap(&f)); x = 0; end: @@ -972,18 +990,21 @@ static PyObject *meth_strongprime(PyObject *me, PyObject *arg, PyObject *kw) unsigned nbits; char *name = "p"; unsigned n = 0; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; PyObject *rc = 0; - char *kwlist[] = { "nbits", "name", "event", "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "nbits", "name", "event", "rng", "nsteps", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + evt.exc = &exc; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) goto end; if ((x = strongprime(name, MP_NEW, nbits, - r, n, evt.proc, evt.ctx)) == 0) - PGENERR; + r, n, evt.ev.proc, evt.ev.ctx)) == 0) + PGENERR(&exc); rc = mp_pywrap(x); x = 0; end: @@ -995,24 +1016,27 @@ end: static PyObject *meth_limlee(PyObject *me, PyObject *arg, PyObject *kw) { char *p = "p"; - pgev ie = { 0 }, oe = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev ie = { { 0 } }, oe = { { 0 } }; unsigned ql, pl; grand *r = &rand_global; unsigned on = 0; size_t i, nf = 0; PyObject *rc = 0, *vec; - char *kwlist[] = { "pbits", "qbits", "name", "event", "ievent", - "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "pbits", "qbits", "name", "event", "ievent", "rng", "nsteps", 0 }; mp *x = 0, **v = 0; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|sO&O&O&O&:limlee", kwlist, + ie.exc = oe.exc = &exc; + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|sO&O&O&O&:limlee", KWLIST, convuint, &pl, convuint, &ql, &p, convpgev, &oe, convpgev, &ie, convgrand, &r, convuint, &on)) goto end; if ((x = limlee(p, MP_NEW, MP_NEW, ql, pl, r, on, - oe.proc, oe.ctx, ie.proc, ie.ctx, &nf, &v)) == 0) - PGENERR; + oe.ev.proc, oe.ev.ctx, ie.ev.proc, ie.ev.ctx, + &nf, &v)) == 0) + PGENERR(&exc);; vec = PyList_New(nf); for (i = 0; i < nf; i++) PyList_SetItem(vec, i, mp_pywrap(v[i])); @@ -1030,18 +1054,18 @@ static PyMethodDef methods[] = { METH (_PrimeFilter_smallfactor, "smallfactor(X) -> PGRC") METH (_RabinMiller_iters, "iters(NBITS) -> NITERS") KWMETH(pgen, "\ -pgen(START, [name = 'p', stepper = PrimeGenStepper(2),\n\ - tester = PrimeGenTester(), event = pgen_nullev,\n\ - nsteps = 0, ntests = RabinMiller.iters(START.nbits)]) -> P") +pgen(START, [name = 'p'[, [stepper = PrimeGenStepper(2)],\n\ + [tester = PrimeGenTester()], [event = pgen_nullev],\n\ + [nsteps = 0], [ntests = RabinMiller.iters(START.nbits)]) -> P") KWMETH(strongprime_setup, "\ -strongprime_setup(NBITS, [name = 'p', event = pgen_nullev,\n\ - rng = rand, nsteps = 0]) -> (START, JUMP)") +strongprime_setup(NBITS, [name = 'p'], [event = pgen_nullev],\n\ + [rng = rand], [nsteps = 0]) -> (START, JUMP)") KWMETH(strongprime, "\ -strongprime_setup(NBITS, [name = 'p', event = pgen_nullev,\n\ - rng = rand, nsteps = 0]) -> P") +strongprime(NBITS, [name = 'p'], [event = pgen_nullev],\n\ + [rng = rand], [nsteps = 0]) -> P") KWMETH(limlee, "\ -limlee(PBITS, QBITS, [name = 'p', event = pgen_nullev,\n\ - ievent = pgen_nullev, rng = rand, nsteps = 0]) -> (P, [Q, ...])") +limlee(PBITS, QBITS, [name = 'p'], [event = pgen_nullev],\n\ + [ievent = pgen_nullev], [rng = rand], [nsteps = 0]) -> (P, [Q, ...])") #undef METHNAME { 0 } };