X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/930d78e3e2045f6f810c73edd81f44321b039ea5..f281293ca70de172b275ecb3224ea36839f2f830:/pgen.c diff --git a/pgen.c b/pgen.c index 5d42829..dd2d827 100644 --- a/pgen.c +++ b/pgen.c @@ -57,10 +57,10 @@ 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)); } @@ -134,7 +134,7 @@ static PyObject *pfget_x(PyObject *me, void *hunoz) static PyObject *pfget_status(PyObject *me, void *hunoz) { return (PyInt_FromLong(PFILT_ST(me))); } -static PyGetSetDef pfilt_pygetset[] = { +static const PyGetSetDef pfilt_pygetset[] = { #define GETSETNAME(op, name) pf##op##_##name GET (x, "F.x -> current position of filter") GET (status, "F.status -> primality status of filter") @@ -142,7 +142,7 @@ static PyGetSetDef pfilt_pygetset[] = { { 0 } }; -static PyMethodDef pfilt_pymethods[] = { +static const PyMethodDef pfilt_pymethods[] = { #define METHNAME(name) pfmeth_##name METH (step, "F.step(N)") METH (muladd, "F.muladd(M, A)") @@ -151,7 +151,7 @@ static PyMethodDef pfilt_pymethods[] = { { 0 } }; -static PyNumberMethods pfilt_pynumber = { +static const PyNumberMethods pfilt_pynumber = { 0, /* @nb_add@ */ 0, /* @nb_subtract@ */ 0, /* @nb_multiply@ */ @@ -206,7 +206,7 @@ static PyTypeObject pfilt_pytype_skel = { 0, /* @tp_setattr@ */ 0, /* @tp_compare@ */ 0, /* @tp_repr@ */ - &pfilt_pynumber, /* @tp_as_number@ */ + PYNUMBER(pfilt), /* @tp_as_number@ */ 0, /* @tp_as_sequence@ */ 0, /* @tp_as_mapping@ */ 0, /* @tp_hash@ */ @@ -219,7 +219,7 @@ static PyTypeObject pfilt_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Small-primes filter.", + "PrimeFilter(X): small-primes filter.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -227,9 +227,9 @@ static PyTypeObject pfilt_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - pfilt_pymethods, /* @tp_methods@ */ + PYMETHODS(pfilt), /* @tp_methods@ */ 0, /* @tp_members@ */ - pfilt_pygetset, /* @tp_getset@ */ + PYGETSET(pfilt), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -256,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); @@ -311,7 +311,7 @@ static PyObject *meth__RabinMiller_iters(PyObject *me, PyObject *arg) return (PyInt_FromLong(rabin_iters(n))); } -static PyGetSetDef rabin_pygetset[] = { +static const PyGetSetDef rabin_pygetset[] = { #define GETSETNAME(op, name) r##op##_##name GET (x, "R.x -> number under test") GET (niters, "R.niters -> suggested number of tests") @@ -319,7 +319,7 @@ static PyGetSetDef rabin_pygetset[] = { { 0 } }; -static PyMethodDef rabin_pymethods[] = { +static const PyMethodDef rabin_pymethods[] = { #define METHNAME(name) rmeth_##name METH (test, "R.test(W) -> PGST") METH (rtest, "R.rtest(W) -> PGST") @@ -352,7 +352,7 @@ 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@ */ @@ -360,9 +360,9 @@ static PyTypeObject rabin_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - rabin_pymethods, /* @tp_methods@ */ + PYMETHODS(rabin), /* @tp_methods@ */ 0, /* @tp_members@ */ - rabin_pygetset, /* @tp_getset@ */ + PYGETSET(rabin), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -379,6 +379,7 @@ static PyTypeObject rabin_pytype_skel = { typedef struct pgevent_pyobj { PyObject_HEAD + PyObject *r; pgen_event *ev; } pgevent_pyobj; @@ -388,18 +389,29 @@ 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) { FREEOBJ(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; + Py_XDECREF(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) @@ -417,7 +429,13 @@ 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) { @@ -435,7 +453,7 @@ end: return (rc); } -static PyGetSetDef pgevent_pygetset[] = { +static const PyGetSetDef pgevent_pygetset[] = { #define GETSETNAME(op, name) pe##op##_##name GET (name, "EV.name -> value being generated") GETSET(x, "EV.x -> value under test") @@ -471,7 +489,7 @@ static PyTypeObject pgevent_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Prime-generation event.", + "Prime-generation event.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -481,7 +499,7 @@ static PyTypeObject pgevent_pytype_skel = { 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ - pgevent_pygetset, /* @tp_getset@ */ + PYGETSET(pgevent), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -530,14 +548,14 @@ static int pgev_python(int rq, pgen_event *ev, void *p) 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" }; rq++; if (rq > N(meth)) SYSERR("event code out of range"); pyev = pgevent_pywrap(ev); - if ((rc = PyObject_CallMethod(pg->obj, 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; @@ -613,14 +631,14 @@ PGMETH(fail, FAIL) static PyObject *pgev_stdev(pgen_proc *proc) { pgev pg; pg.proc = proc; pg.ctx = 0; return (pgev_pywrap(&pg)); } -static PyMethodDef pgev_pymethods[] = { +static const PyMethodDef pgev_pymethods[] = { #define METHNAME(name) pgmeth_##name - 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") + METH (pg_abort, "E.pg_abort(EV) -> PGST -- prime generation aborted") + METH (pg_done, "E.pg_done(EV) -> PGST -- prime generation finished") + METH (pg_begin, "E.pg_begin(EV) -> PGST -- commence stepping/testing") + METH (pg_try, "E.pg_try(EV) -> PGST -- found new candidate") + METH (pg_pass, "E.pg_pass(EV) -> PGST -- passed primality test") + METH (pg_fail, "E.pg_fail(EV) -> PGST -- failed primality test") #undef METHNAME { 0 } }; @@ -650,7 +668,7 @@ static PyTypeObject pgev_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Built-in prime-generation event handler, base class.", + "Built-in prime-generation event handler, base class.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -658,7 +676,7 @@ static PyTypeObject pgev_pytype_skel = { 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ - pgev_pymethods, /* @tp_methods@ */ + PYMETHODS(pgev), /* @tp_methods@ */ 0, /* @tp_members@ */ 0, /* @tp_getset@ */ 0, /* @tp_base@ */ @@ -677,9 +695,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; @@ -692,7 +710,7 @@ end: static PyObject *psget_step(PyObject *me, void *hunoz) { return (PyInt_FromLong(PGSTEP_STEP(me))); } -static PyGetSetDef pgstep_pygetset[] = { +static const PyGetSetDef pgstep_pygetset[] = { #define GETSETNAME(op, name) ps##op##_##name GET (step, "S.step -> step size for the stepper") #undef GETSETNAME @@ -724,7 +742,7 @@ 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@ */ @@ -734,7 +752,7 @@ static PyTypeObject pgstep_pytype_skel = { 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ - pgstep_pygetset, /* @tp_getset@ */ + PYGETSET(pgstep), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -751,9 +769,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); @@ -774,7 +792,7 @@ static void pgjump_pydealloc(PyObject *me) static PyObject *pjget_jump(PyObject *me, void *hunoz) { RETURN_OBJ(PGJUMP_FOBJ(me)); } -static PyGetSetDef pgjump_pygetset[] = { +static const PyGetSetDef pgjump_pygetset[] = { #define GETSETNAME(op, name) pj##op##_##name GET (jump, "S.jump -> jump size for the stepper") #undef GETSETNAME @@ -806,7 +824,8 @@ 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@ */ @@ -816,7 +835,7 @@ static PyTypeObject pgjump_pytype_skel = { 0, /* @tp_iternext@ */ 0, /* @tp_methods@ */ 0, /* @tp_members@ */ - pgjump_pygetset, /* @tp_getset@ */ + PYGETSET(pgjump), /* @tp_getset@ */ 0, /* @tp_base@ */ 0, /* @tp_dict@ */ 0, /* @tp_descr_get@ */ @@ -832,9 +851,9 @@ static PyTypeObject pgjump_pytype_skel = { 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; @@ -867,7 +886,7 @@ static PyTypeObject pgtest_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Rabin-Miller tester.", + "PrimeGenTester(): Rabin-Miller tester.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -909,13 +928,13 @@ static PyObject *meth_pgen(PyObject *me, PyObject *arg, PyObject *kw) 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.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, + 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)) @@ -944,10 +963,11 @@ static PyObject *meth_strongprime_setup(PyObject *me, 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 }; evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) @@ -973,10 +993,11 @@ static PyObject *meth_strongprime(PyObject *me, PyObject *arg, PyObject *kw) 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 }; evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) @@ -1002,12 +1023,12 @@ static PyObject *meth_limlee(PyObject *me, PyObject *arg, PyObject *kw) 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; ie.exc = oe.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|sO&O&O&O&:limlee", kwlist, + 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)) @@ -1018,7 +1039,7 @@ static PyObject *meth_limlee(PyObject *me, PyObject *arg, PyObject *kw) PGENERR(&exc);; vec = PyList_New(nf); for (i = 0; i < nf; i++) - PyList_SetItem(vec, i, mp_pywrap(v[i])); + PyList_SET_ITEM(vec, i, mp_pywrap(v[i])); xfree(v); rc = Py_BuildValue("(NN)", mp_pywrap(x), vec); end: @@ -1028,23 +1049,24 @@ end: /*----- Global stuff ------------------------------------------------------*/ -static PyMethodDef methods[] = { +static const PyMethodDef methods[] = { #define METHNAME(name) meth_##name - 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") - KWMETH(strongprime_setup, "\ -strongprime_setup(NBITS, [name = 'p'], [event = pgen_nullev],\n\ - [rng = rand], [nsteps = 0]) -> (START, JUMP)") - KWMETH(strongprime, "\ -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, ...])") + 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") + KWMETH(strongprime_setup, + "strongprime_setup(NBITS, [name = 'p'], [event = pgen_nullev],\n" + " [rng = rand], [nsteps = 0]) -> (START, JUMP)") + KWMETH(strongprime, + "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, ...])") #undef METHNAME { 0 } };