+ for (;;) {
+ unsigned act = 0;
+
+ enum {
+ A_STEP = 1u,
+ A_TEST = 2u,
+ A_EVENT = 4u,
+ A_ENDTEST = 8u,
+ A_ENDSTEP = 16u,
+ A_DONE = 32u
+ };
+
+ /* --- Call the procedure and decide what to do next --- */
+
+ rc = proc(rq, &ev, ctx);
+ switch (rc) {
+ case PGEN_TRY:
+ if (proc == test)
+ rq = PGEN_TRY;
+ else {
+ act |= A_EVENT;
+ proc = test; ctx = tctx;
+ rq = PGEN_BEGIN;
+ }
+ break;
+ case PGEN_PASS:
+ act |= A_TEST | A_EVENT;
+ if (proc == test)
+ rq = PGEN_TRY;
+ else {
+ proc = test; ctx = tctx;
+ rq = PGEN_BEGIN;
+ }
+ break;
+ case PGEN_FAIL:
+ act |= A_STEP;
+ if (proc == test) {
+ act |= A_ENDTEST | A_EVENT;
+ proc = step; ctx = sctx;
+ }
+ rq = PGEN_TRY;
+ break;
+ case PGEN_DONE:
+ act |= A_EVENT | A_DONE | A_ENDSTEP;
+ if (proc == test)
+ act |= A_ENDTEST;
+ break;
+ case PGEN_ABORT:
+ act |= A_EVENT | A_DONE;
+ if (proc == test || rq == PGEN_TRY)
+ act |= A_ENDSTEP;
+ if (proc == test && rq == PGEN_BEGIN)
+ act |= A_ENDTEST;
+ break;
+ default:
+ assert(((void)"Invalid response from function", 0));
+ break;
+ }