struct tvec_env;
+typedef int tvec_setvarfn(struct tvec_state */*tv*/, const char */*var*/,
+ const union tvec_regval */*rv*/, void */*ctx*/);
+ /* Called after a variable is read. Return zero on success or %$-1$% on
+ * error. This function is never called if the test group is skipped.
+ */
+
+struct tvec_vardef {
+ size_t regsz; /* (minimum) register size */
+ tvec_setvarfn *setvar; /* function to set variable */
+ struct tvec_regdef def; /* register definition */
+};
+
typedef void tvec_envsetupfn(struct tvec_state */*tv*/,
const struct tvec_env */*env*/,
void */*pctx*/, void */*ctx*/);
* will not.
*/
-typedef int tvec_envsetfn(struct tvec_state */*tv*/,
- const char */*var*/, void */*ctx*/);
- /* Called when the parser finds a %|@var|%' setting to parse and store the
- * value. Return %$+1$% on success, %$0$% if the variable name was not
- * recognized, or %$-1$% on any other error (which should have been
- * reported via @tvec_error@).
+typedef const struct tvec_vardef *tvec_envfindvarfn
+ (struct tvec_state */*tv*/, const char */*name*/,
+ void **/*ctx_out*/, void */*ctx*/);
+ /* Called when the parser finds a %|@var|%' special variable. If a
+ * suitable variable was found, set @*ctx_out@ to a suitable context and
+ * return the variable definition; the context will be passed to the
+ * variable definition's @setvar@ function. If no suitable variable was
+ * found, then return null.
*/
typedef void tvec_envbeforefn(struct tvec_state */*tv*/, void */*ctx*/);
/* Called prior to running a test. This is the right place to act on any
* `%|@var|%' settings. If preparation fails, the function should call
* @tvec_skip@ with a suitable excuse. This function is never called if
- * the test group is skipped.
+ * the test group is skipped. It %%\emph{is}%% called if the test will be
+ * skipped due to erroneous test data. It should check the @TVSF_ACTIVE@
+ * flag if necessary.
*/
typedef void tvec_envrunfn(struct tvec_state */*tv*/,
typedef void tvec_envafterfn(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
- * %%\emph{is}%% called if the test group is skipped, so that the test
- * environment can reset variables set by the @set@ entry point. It should
- * check the @TVSF_SKIP@ flag if necessary.
+ * %%\emph{is}%% called if the test group is skipped or the test data is
+ * erroneous, so that the test environment can reset variables set by the
+ * @set@ entry point. It should check the @TVSF_SKIP@ flag if necessary.
*/
typedef void tvec_envteardownfn(struct tvec_state */*tv*/, void */*ctx*/);
size_t ctxsz; /* environment context size */
tvec_envsetupfn *setup; /* setup for group */
- tvec_envsetfn *set; /* set variable */
+ tvec_envfindvarfn *findvar; /* find variable */
tvec_envbeforefn *before; /* prepare for test */
tvec_envrunfn *run; /* run test function */
tvec_envafterfn *after; /* clean up after test */
*/
extern tvec_envsetupfn tvec_benchsetup;
-extern tvec_envsetfn tvec_benchset;
+extern tvec_envfindvarfn tvec_benchfindvar;
extern tvec_envbeforefn tvec_benchbefore;
extern tvec_envrunfn tvec_benchrun;
extern tvec_envafterfn tvec_benchafter;
#define TVEC_BENCHENV \
{ sizeof(struct tvec_benchctx), \
tvec_benchsetup, \
- tvec_benchset, \
+ tvec_benchfindvar, \
tvec_benchbefore, \
tvec_benchrun, \
tvec_benchafter, \
struct tvec_state *tv; /* test vector state */
struct tvec_remotecomms rc; /* communication state */
const struct tvec_remoteenv *re; /* environment configuration */
+ void *subctx; /* subenvironment context */
+ struct tvec_vardef vd; /* temporary variable definition */
unsigned ver; /* protocol version */
pid_t kid; /* child process id */
int errfd; /* child stderr descriptor */
dstr prgwant, progress; /* progress: wanted/reported */
unsigned exwant, exit; /* exit status wanted/reported */
#define TVRF_RCNMASK 0x0300u /* reconnection behaviour: */
-#define TVRCN_SKIP 0x0000u /* skip unless connected */
-#define TVRCN_DEMAND 0x0100u /* connect on demand */
+#define TVRCN_DEMAND 0x0000u /* connect on demand */
+#define TVRCN_SKIP 0x0100u /* skip unless connected */
#define TVRCN_FORCE 0x0200u /* force reconnection */
#define TVRF_MUFFLE 0x0400u /* muffle child stderr */
#define TVRF_SETEXIT 0x0800u /* set `@exit' */
struct tvec_remoteenv_slots {
tvec_connectfn *connect; /* connection function */
const struct tvec_env *env; /* subsidiary environment */
+ unsigned dflt_reconn; /* default reconnection */
};
struct tvec_remoteenv {
/* Remote environment. */
extern tvec_envsetupfn tvec_remotesetup;
-extern tvec_envsetfn tvec_remoteset;
+extern tvec_envfindvarfn tvec_remotefindvar;
+extern tvec_envbeforefn tvec_remotebefore;
extern tvec_envrunfn tvec_remoterun;
extern tvec_envafterfn tvec_remoteafter;
extern tvec_envteardownfn tvec_remoteteardown;
#define TVEC_REMOTEENV \
{ sizeof(struct tvec_remotectx), \
tvec_remotesetup, \
- tvec_remoteset, \
- 0, \
+ tvec_remotefindvar, \
+ tvec_remotebefore, \
tvec_remoterun, \
tvec_remoteafter, \
tvec_remoteteardown }
struct tvec_timeoutenv {
struct tvec_env _env;
- unsigned timer; /* the timer (@ITIMER_...@) */
+ int timer; /* the timer (@ITIMER_...@) */
double t; /* time to wait (in seconds) */
const struct tvec_env *env; /* subsidiary environment */
};
struct tvec_timeoutctx {
const struct tvec_timeoutenv *te; /* saved environment description */
- unsigned timer; /* timer code (as overridden) */
+ int timer; /* timer code (as overridden) */
double t; /* time to wait (as overridden) */
unsigned f; /* flags */
#define TVTF_SETTMO 1u /* set `@timeout' */
-#define TVTF_SETMASK (TVTF_SETTMO) /* mask of @TVTF_SET...@ */
+#define TVTF_SETTMR 2u /* set `@timer' */
+#define TVTF_SETMASK (TVTF_SETTMO | TVTF_SETTMR)
+ /* mask of @TVTF_SET...@ */
void *subctx;
};
extern tvec_envsetupfn tvec_timeoutsetup;
-extern tvec_envsetfn tvec_timeoutset;
+extern tvec_envfindvarfn tvec_timeoutfindvar;
extern tvec_envbeforefn tvec_timeoutbefore;
extern tvec_envrunfn tvec_timeoutrun;
extern tvec_envafterfn tvec_timeoutafter;
#define TVEC_TIMEOUTENV \
{ sizeof(struct tvec_timeoutctx), \
tvec_timeoutsetup, \
- tvec_timeoutset, \
+ tvec_timeoutfindvar, \
tvec_timeoutbefore, \
tvec_timeoutrun, \
tvec_timeoutafter, \
extern int tvec_syntax_v(struct tvec_state */*tv*/, int /*ch*/,
const char */*expect*/, va_list */*ap*/);
+/* --- @tvec_unkreg@ --- *
+ *
+ * Arguments: @struct tvec_state *tv@ = test-vector state
+ * @const char *name@ = register or pseudoregister name
+ *
+ * Returns: %$-1$%.
+ *
+ * Use: Reports an error that the register or pseudoregister is
+ * unrecognized.
+ */
+
+extern int tvec_unkreg(struct tvec_state */*tv*/, const char */*name*/);
+
/* --- @tvec_dupreg@ --- *
*
* Arguments: @struct tvec_state *tv@ = test-vector state
extern const struct tvec_floatinfo tvflt_finite, tvflt_nonneg;
+/*----- Durations ---------------------------------------------------------*/
+
+/* A duration measures a time interval in seconds. The input format consists
+ * of a nonnegative decimal floating-point number in @strtod@ format followed
+ * by an optional unit specification.
+ *
+ * No @tvec_claimeq_...@ function is provided for durations: use
+ * @tvec_claimeq_float@.
+ */
+
+extern const struct tvec_regty tvty_duration;
+
/*----- Enumerated types --------------------------------------------------*/
/* An enumeration describes a set of values of some underlying type, each of