+ /* A test function. It should read inputs from @in@ and write outputs to
+ * @out@. The @TVRF_LIVE@ is set on inputs which are actually present, and
+ * on outputs which are wanted to test. A test function can set additional
+ * `gratuitous outputs' by setting @TVRF_LIVE@ on them; clearing
+ * @TVRF_LIVE@ on a wanted output causes a mismatch.
+ *
+ * A test function may be called zero or more times by the environment. In
+ * particular, it may be called multiple times, though usually by prior
+ * arrangement with the environment.
+ *
+ * The @ctx@ is supplied by the environment's @run@ function (see below).
+ * The default environment calls the test function once, with a null
+ * @ctx@. There is no expectation that the environment's context has
+ * anything to do with the test function's context.
+ */
+
+struct tvec_env {
+ /* A test environment sets things up for and arranges to run the test.
+ *
+ * The caller is responsible for allocating storage for the environment's
+ * context, based on the @ctxsz@ slot, and freeing it later; this space is
+ * passed in as the @ctx@ parameter to the remaining functions; if @ctxsz@
+ * is zero then @ctx@ is null.
+ */
+
+ size_t ctxsz; /* environment context size */
+
+ int (*setup)(struct tvec_state */*tv*/, const struct tvec_env */*env*/,
+ void */*pctx*/, void */*ctx*/);
+ /* Initialize the context; called at the start of a test group. Return
+ * zero on success, or @-1@ on failure. If setup fails, the context is
+ * freed, and the test group is skipped.
+ */
+
+ int (*set)(struct tvec_state */*tv*/, const char */*var*/,
+ const struct tvec_env */*env*/, void */*ctx*/);
+ /* Called when the parser finds a %|@var|%' setting to parse and store
+ * the value. If @setup@ failed, this is still called (so as to skip the
+ * value), but @ctx@ is null.
+ */
+
+ int (*before)(struct tvec_state */*tv*/, void */*ctx*/);
+ /* Called prior to running a test. This is the right place to act on any
+ * `%|@var|%' settings. Return zero on success or @-1@ on failure (which
+ * causes the test to be skipped). This function is never called if the
+ * test group is skipped.
+ */
+
+ void (*run)(struct tvec_state */*tv*/, tvec_testfn */*fn*/, void */*ctx*/);
+ /* Run the test. It should either call @tvec_skip@, or run @fn@ one or
+ * more times. In the latter case, it is responsible for checking the
+ * outputs, and calling @tvec_fail@ as necessary; @tvec_checkregs@ will
+ * check the register values against the supplied test vector, while
+ * @tvec_check@ does pretty much everything necessary. This function is
+ * never called if the test group is skipped.
+ */
+
+ void (*after)(struct tvec_state */*tv*/, void */*ctx*/);
+ /* Called after running or skipping a test. Typical actions involve
+ * resetting whatever things were established by @set@. This function is
+ * never called if the test group is skipped.
+ */
+
+ void (*teardown)(struct tvec_state */*tv*/, void */*ctx*/);
+ /* Tear down the environment: called at the end of a test group. If the
+ * setup failed, then this function is still called, with a null @ctx@.
+ */
+};