/*----- Header files ------------------------------------------------------*/
+#include "tv.h"
#include "tvec.h"
+#include <sys/select.h>
+#include <sys/time.h>
+
/*----- Register definitions ----------------------------------------------*/
static const struct tvec_iassoc ienum_assocs[] = {
_(fenum, RFE, fenum, p, &fenum_info) \
_(penum, RPE, penum, p, &penum_info) \
_(flags, RF, flags, p, &attr_info) \
- _(string, RSTR, string, p, &range_32) \
+ _(text, RTXT, text, p, &range_32) \
_(bytes, RBY, bytes, p, &tvrange_byte) \
_(buffer, RBUF, buffer, p, 0)
tctx->f = 0;
}
-static int common_set(struct tvec_state *tv, const char *name,
- const struct tvec_env *env, void *ctx)
+static int common_set(struct tvec_state *tv, const char *name, void *ctx)
{
struct test_context *tctx = ctx;
union tvec_regval rv;
(const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
{ out->v = in->v; }
-static void test_copy_string
+static void test_copy_text
(const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
{
- tvec_allocstring(&out->v, in->v.str.sz);
- memcpy(out->v.str.p, in->v.str.p, in->v.str.sz);
+ tvec_alloctext(&out->v, in->v.text.sz);
+ memcpy(out->v.text.p, in->v.text.p, in->v.text.sz);
}
static void test_copy_bytes
(const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
{
- tvec_allocstring(&out->v, in->v.str.sz);
- memcpy(out->v.str.p, in->v.str.p, in->v.str.sz);
+ tvec_allocbytes(&out->v, in->v.bytes.sz);
+ memcpy(out->v.bytes.p, in->v.bytes.p, in->v.bytes.sz);
}
#define test_copy_int test_copy_simple
? 0
: (/*unconst*/ void *)
((const struct tvec_penuminfo *)rd->arg.p)->av[0].p;
- else if (rd->ty == &tvty_string)
- { if (rv->str.sz) rv->str.p[0] ^= 1; }
+ else if (rd->ty == &tvty_text)
+ { if (rv->text.sz) rv->text.p[0] ^= 1; }
else if (rd->ty == &tvty_bytes)
{ if (rv->bytes.sz) rv->bytes.p[0] ^= 1; }
}
/*----- Crash test --------------------------------------------------------*/
-static void test_crash(const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
+static void test_crash(const struct tvec_reg *in, struct tvec_reg *out,
+ void *ctx)
{
out[RVOUT].v.u = in[RV].v.u;
if (in[RSAB].v.i) abort();
TVEC_ENDREGS
};
+/*----- Sleep test --------------------------------------------------------*/
+
+static void test_sleep(const struct tvec_reg *in, struct tvec_reg *out,
+ void *ctx)
+{
+ struct timeval now, when, tv;
+ int rc;
+
+ rc = gettimeofday(&now, 0); assert(!rc);
+ tv.tv_sec = in[RV].v.f; tv.tv_usec = 1e6*(in[RV].v.f - tv.tv_sec);
+
+ TV_ADD(&when, &now, &tv);
+ for (;;) {
+ rc = select(0, 0, 0, 0, &tv); assert(!rc);
+ rc = gettimeofday(&now, 0); assert(!rc);
+ if (TV_CMP(&now, >=, &when)) break;
+ TV_SUB(&tv, &when, &now);
+ }
+ out[RVOUT].v.f = in[RV].v.f;
+}
+
+static const struct tvec_timeoutenv sleep_subenv =
+ { TVEC_TIMEOUTINIT(ITIMER_REAL, 0.25) };
+static const struct tvec_remotefork sleep_testenv =
+ { TVEC_REMOTEFORK(&sleep_subenv._env, 0) };
+
+static const struct tvec_regdef sleep_regs[] = {
+ { "time", RV, &tvty_float, 0, { &tvflt_nonneg } },
+ { "z", RVOUT, &tvty_float, 0, { &tvflt_nonneg } },
+ TVEC_ENDREGS
+};
+
/*----- Front end ---------------------------------------------------------*/
static const struct tvec_test tests[] = {
TYPEREGS(DEFSINGLE)
#undef DEFSINGLE
- { "crash", crash_regs, &crash_testenv._env, test_crash } ,
+ { "crash", crash_regs, &crash_testenv._env, test_crash },
+ { "sleep", sleep_regs, &sleep_testenv._env, test_sleep },
TVEC_ENDTESTS
};