+/*----- Event handling ----------------------------------------------------*
+ *
+ * Different programs and architectures will want to show progress of prime
+ * searches and similar processes in different ways. Of course, for simple
+ * searches, it's possible to use the @pfilt@ and @rabin@ functions and
+ * maintain control over the general control flow throughout the search.
+ *
+ * For more complex cases, this sort of control is undesirable. It's
+ * possible to specify an event handler which is informed in abstract about
+ * the search. The event handler can also request the search be aborted.
+ */
+
+/* --- Event code constants --- *
+ *
+ * You're allowed to rely on the values of @PGEN_DONE@ and @PGEN_ABORT@.
+ */
+
+enum {
+ PGEN_BEGIN = 1, /* Search for value begins */
+ PGEN_TRY, /* A new candidate has appeared */
+ PGEN_FAIL, /* The candidate failed the test */
+ PGEN_PASS, /* The candidate passed a test */
+ PGEN_DONE = 0, /* A good value has been found */
+ PGEN_ABORT = -1 /* The search has been aborted */
+};
+
+/* --- Event information --- *
+ *
+ * Note that the pseudorandom number generator supplied is not
+ * cryptographically strong.
+ */
+
+typedef struct pgen_event {
+ const char *name; /* Which quantity is being found */
+ mp *m; /* Current value under test */
+ unsigned steps; /* Number of candidates left */
+ unsigned tests; /* Tests left before passing */
+ grand *r; /* Source of random numbers */
+} pgen_event;
+
+/*----- Prime search parameters -------------------------------------------*
+ *
+ * The prime search is parameterized in a large number of ways, although this
+ * isn't so much of a surprise given the different sorts of properties
+ * required from prime numbers in cryptographic applications.
+ *
+ * There are two main things which need to be configured: stepping, and
+ * testing. (Filtering is done as part of stepping.)
+ *
+ * The functions here provide a toolkit for constructing stepping and testing
+ * routines. In a lot of cases, the functions can be used directly; in
+ * others, simple bits of glue need be written.
+ *
+ * Two types of functions are defined: steppers and testers, but their
+ * interfaces are substantially similar. Each is given a request code, a
+ * context block and an event block. It is meant to update its context and
+ * the event block and return an event code.
+ *
+ * A call with a request of @PGEN_BEGIN@ asks the stepper or tester to
+ * initialize itself using the information in its event block and context. A
+ * return of @PGEN_FAIL@ reports an immediate failure; @PGEN_ABORT@ reports a
+ * fatal problem; @PGEN_DONE@ reports immediate success. @PGEN_TRY@ reports
+ * successful initialization and requests test iterations.
+ *
+ * A call to a stepper with a request of @PGEN_TRY@ asks it to step to the
+ * next possible candidate, replacing the value @m@ in the event block with
+ * the new candidate. A call to a tester with a request of @PGEN_TRY@
+ * runs one pass of the test. It should return @PGEN_FAIL@ to report a
+ * failure, @PGEN_PASS@ to report a success and request another iteration,
+ * @PGEN_DONE@ to report final acceptance and @PGEN_ABORT@ to terminate the
+ * search unsuccessfully. Note that even if the search is aborted, a
+ * shutdown request is still made.
+ *
+ * A call with a request of @PGEN_DONE@ closes down the stepper or tester.
+ * After a successful initialization (i.e., a return of something other than
+ * @PGEN_ABORT@), a shutdown call is guaranteed. The return code is ignored.
+ */