chiark / gitweb /
@@@ tvec wip
authorMark Wooding <mdw@distorted.org.uk>
Mon, 26 Jun 2023 12:48:58 +0000 (13:48 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 26 Jun 2023 12:48:58 +0000 (13:48 +0100)
hash/t/hash-test.c
test/t/tvec-test.c
test/tests.at
test/tvec-types.c
test/tvec.h
utils/t/bits-test.c
utils/t/versioncmp-test.c

index 756232d78b3f9670e49de06beb4e3d30d8fd30fa..1718a98f03ddd731ed056159ca9b9040948552d4 100644 (file)
@@ -109,18 +109,18 @@ static const struct tvec_regdef unihash_regs[] = {
   { "k", RK, &tvty_uint, 0, { &tvrange_u32 } },
   { "m", RM, &tvty_bytes, 0 },
   { "h", RH, &tvty_uint, 0, { &tvrange_u32 } },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 
 static const struct tvec_regdef crc32_regs[] = {
   { "m", RM, &tvty_bytes, 0 },
   { "h", RH, &tvty_uint, 0, { &tvrange_u32 } },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 
 static const struct tvec_regdef bench_regs[] = {
   { "msz", RM, &tvty_buffer, TVRF_ID },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 
 static const struct tvec_bench crc32_bench =
@@ -133,7 +133,7 @@ static const struct tvec_test tests[] = {
   { "unihash", unihash_regs, &step_testenv, test_unihash },
   { "crc32-bench", bench_regs, &crc32_bench._env, bench_crc32 },
   { "unihash-bench", bench_regs, &unihash_bench._env, bench_unihash },
-  { 0, 0, 0, 0 }
+  TVEC_ENDTESTS
 };
 
 static const struct tvec_config testconfig =
index 78f730f34534eb588d7e76e704180f1a3b36be3d..91c4529998f7f0dbc11574bc01e609881dbfba2f 100644 (file)
@@ -136,47 +136,227 @@ enum {
 #define DEFREG(name, i, ty, argslot, argval) i,
   TYPEREGS(DEFREG)
 #undef DEFREG
-  NSER,
+  NTY,
 
-  /* Standard outputs. */
-  RRC = NSER,                          /* return code from deserialize */
-
-  /* Additional diagnostic outputs. */
-  RSER,                                        /* serialized data */
+  /* Outputs. */
+  RRC = NTY,                           /* return code from deserialize */
+  RSEROUT,                             /* serialized output */
 
   NROUT,
 
-  /* Some additional inputs. */
-  RSAB = NROUT,                                /* which register to sabotage */
+  /* Alternative outputs. */
+  RVOUT = 0,                           /* output/copy value */
+  RLEFT,                               /* size data remaining in input */
 
-  NREG,
+  /* Additional inputs. */
+  RSAB = NROUT,                                /* which register to sabotage */
+  RV,                                  /* input value */
+  RSER,                                        /* serialized input */
 
-  /* Single register for copy tests. */
-  RV = 0
+  NREG
 };
 
-/*----- Serialization test ------------------------------------------------*/
+/*----- Common execution environment --------------------------------------*/
 
 struct test_context {
   struct tvec_state *tv;
+  unsigned f;
+#define SF_SHOW 1u
 };
 
-static int capture_setup(struct tvec_state *tv,
+static int common_setup(struct tvec_state *tv,
                         const struct tvec_env *env, void *pctx, void *ctx)
-  { struct test_context *tctx = ctx; tctx->tv = tv; return (0); }
+{
+  struct test_context *tctx = ctx;
+
+  tctx->tv = tv;
+  tctx->f = 0;
+  return (0);
+}
+
+static int common_set(struct tvec_state *tv, const char *name,
+                     const struct tvec_env *env, void *ctx)
+{
+  struct test_context *tctx = ctx;
+  union tvec_regval rv;
+  static const struct tvec_regdef rd =
+    { "@show", -1, &tvty_ienum, 0, { &tvenum_bool } };
+
+  if (STRCMP(name, ==, "@show")) {
+    if (tvty_ienum.parse(&rv, &rd, tv)) return (-1);
+    if (tctx) {
+      if (rv.i) tctx->f |= SF_SHOW;
+      else tctx->f &= ~SF_SHOW;
+    }
+    return (1);
+  } else
+    return (0);
+}
+
+static void common_run(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
+{
+  struct test_context *tctx = ctx;
+  unsigned f = tctx->f;
+
+  fn(tv->in, tv->out, tctx);
+  if (tvec_checkregs(tv)) { tvec_fail(tv, 0); f |= SF_SHOW; }
+  if (f&SF_SHOW) tvec_mismatch(tv, TVMF_IN | TVMF_OUT);
+}
+
+static void common_after(struct tvec_state *tv, void *ctx)
+  { struct test_context *tctx = ctx; tctx->f = 0; }
 
-static void capture_run(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
+static const struct tvec_env common_testenv = {
+  sizeof(struct test_context),
+  common_setup, common_set,
+  0, common_run, common_after,
+  0
+};
+
+/*----- Single-type copy tests --------------------------------------------*/
+
+static void test_copy_simple
+  (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
+  { out->v = in->v; }
+
+static void test_copy_string
+  (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);
+}
+
+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);
+}
+
+#define test_copy_int test_copy_simple
+#define test_copy_uint test_copy_simple
+#define test_copy_ienum test_copy_simple
+#define test_copy_uenum test_copy_simple
+#define test_copy_fenum test_copy_simple
+#define test_copy_penum test_copy_simple
+#define test_copy_char test_copy_simple
+#define test_copy_flags test_copy_simple
+#define test_copy_float test_copy_simple
+#define test_copy_fltish test_copy_simple
+#define test_copy_buffer test_copy_bytes
+
+#define COPYREG(name, i, ty, argslot, argval)                          \
+       static DSGINIT(const) struct tvec_regdef name##_copyregs[] = {  \
+         { #name, RVOUT, &tvty_##ty, 0, DSGINIT({ .argslot = argval }) }, \
+         { 0 }                                                         \
+       };
+TYPEREGS(COPYREG)
+#undef COPYREG
+
+/*----- Single-type serialization tests -----------------------------------*/
+
+static void setup_regdef(struct tvec_regdef *rd, unsigned i,
+                        struct tvec_state *tv)
+{
+  const struct tvec_regdef *r;
+
+  for (r = tv->test->regs; r->name; r++) if (r->i == i) goto found;
+  tvec_error(tv, "internel: register definition not found"); exit(2);
+found:
+  rd[0] = *r; rd[1].name = 0;
+}
+
+static void test_single_serialize
+  (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
+{
+  struct test_context *tctx = ctx;
+  struct tvec_state *tv = tctx->tv;
+  struct tvec_regdef rd[2];
+  dbuf b = DBUF_INIT;
+  int rc;
+
+  setup_regdef(rd, RV, tv);
+  rc = tvec_serialize(tv->in, DBUF_BUF(&b), rd, NREG,
+                     sizeof(struct tvec_reg));
+  out[RRC].v.i = rc;
+  if (rc)
+    out[RSEROUT].f &= ~TVRF_LIVE;
+  else {
+    tvec_allocbytes(&out[RSEROUT].v, BLEN(DBUF_BUF(&b)));
+    memcpy(out[RSEROUT].v.bytes.p, BBASE(DBUF_BUF(&b)), BLEN(DBUF_BUF(&b)));
+  }
+}
+
+static void test_single_deserialize
+  (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
+{
+  struct test_context *tctx = ctx;
+  struct tvec_state *tv = tctx->tv;
+  struct tvec_regdef rd[2];
+  buf b;
+  int rc;
+
+  setup_regdef(rd, RV, tv);
+  buf_init(&b, in[RSER].v.bytes.p, in[RSER].v.bytes.sz);
+  rc = tvec_deserialize(tv->out, &b, rd, NREG, sizeof(struct tvec_reg));
+  out[RRC].v.i = rc;
+  if (rc) out[RVOUT].f &= ~TVRF_LIVE;
+}
+
+#define SERREG(name, i, ty, argslot, argval)                           \
+       static DSGINIT(const) struct tvec_regdef name##_serregs[] = {   \
+         { #name, RV,  &tvty_##ty, 0, DSGINIT({ .argslot = argval }) }, \
+         { "buf", RSEROUT, &tvty_bytes },                              \
+         { "rc", RRC,  &tvty_int,      TVRF_OPT,       { &tvrange_int } }, \
+         TVEC_ENDREGS                                                  \
+       };                                                              \
+       static DSGINIT(const) struct tvec_regdef name##_deserregs[] = { \
+         { "buf", RSER, &tvty_bytes },                                 \
+         { #name, RVOUT, &tvty_##ty, 0, DSGINIT({ .argslot = argval }) }, \
+         { "left", RLEFT, &tvty_uint,  TVRF_OPT,      { &tvrange_size } }, \
+         { "rc", RRC,  &tvty_int,      TVRF_OPT,       { &tvrange_int } }, \
+         TVEC_ENDREGS                                                  \
+       };
+TYPEREGS(SERREG)
+#undef SERREG
+
+static int before_single_serialize(struct tvec_state *tv, void *ctx)
 {
   if (!(tv->in[RRC].f&TVRF_LIVE)) {
-    tv->in[RRC].f |= TVRF_LIVE; tv->in[RRC].v.i = 0;
+    tv->in[RRC].v.i = 0; tv->in[RRC].f |= TVRF_LIVE;
     tv->out[RRC].f |= TVRF_LIVE;
   }
-  fn(tv->in, tv->out, ctx); tvec_check(tv, 0);
+  return (0);
 }
-static const struct tvec_env capture_testenv =
-  { sizeof(struct test_context), capture_setup, 0, 0, capture_run, 0, 0 };
 
-static void test_serialization
+static int before_single_deserialize(struct tvec_state *tv, void *ctx)
+{
+  if (!(tv->in[RRC].f&TVRF_LIVE)) {
+    tv->in[RRC].v.i = 0; tv->in[RRC].f |= TVRF_LIVE;
+    tv->out[RRC].f |= TVRF_LIVE;
+  }
+  if (!(tv->in[RLEFT].f&TVRF_LIVE)) {
+    tv->in[RLEFT].v.u = 0; tv->in[RLEFT].f |= TVRF_LIVE;
+    tv->out[RLEFT].f |= TVRF_LIVE;
+  }
+  return (0);
+}
+
+static const struct tvec_env single_serialize_testenv = {
+  sizeof(struct test_context),
+  common_setup, common_set,
+  before_single_serialize, common_run, common_after,
+  0
+}, single_deserialize_testenv = {
+  sizeof(struct test_context),
+  common_setup, common_set,
+  before_single_deserialize, common_run, common_after,
+  0
+};
+
+/*----- Multi-type serialization test -------------------------------------*/
+
+static void test_multi_serialize
   (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
 {
   struct test_context *tctx = ctx;
@@ -186,15 +366,15 @@ static void test_serialization
   dbuf b = DBUF_INIT;
 
   if (tvec_serialize(tv->in, DBUF_BUF(&b), tv->test->regs,
-                    NSER, sizeof(struct tvec_reg)))
-    { out[NSER].v.i = -1; goto end; }
-  tvec_allocbytes(&out[RSER].v, DBLEN(&b));
-  memcpy(out[RSER].v.bytes.p, DBBASE(&b), DBLEN(&b));
-  out[RSER].f |= TVRF_LIVE;
+                    NTY, sizeof(struct tvec_reg)))
+    { out[RRC].v.i = -1; goto end; }
+  tvec_allocbytes(&out[RSEROUT].v, DBLEN(&b));
+  memcpy(out[RSEROUT].v.bytes.p, DBBASE(&b), DBLEN(&b));
+  out[RSEROUT].f |= TVRF_LIVE;
   buf_flip(DBUF_BUF(&b));
 
   if (tvec_deserialize(tv->out, DBUF_BUF(&b), tv->test->regs,
-                      NSER, sizeof(struct tvec_reg)))
+                      NTY, sizeof(struct tvec_reg)))
     { out[RRC].v.i = -2; goto end; }
   if (BLEFT(&b._b))
     { out[RRC].v.i = -3; goto end; }
@@ -225,129 +405,61 @@ end:
   dbuf_destroy(&b);
 }
 
-static const struct tvec_iassoc type_assocs[] = {
+static const struct tvec_iassoc reg_assocs[] = {
   { "none",            -1 },
 #define DEFASSOC(name, i, ty, argslot, argval) { #name, i },
   TYPEREGS(DEFASSOC)
 #undef DEFASSOC
   { 0,                 0 }
 };
-static const struct tvec_ienuminfo type_enum = { "regty", type_assocs, 0 };
+static const struct tvec_ienuminfo reg_enum = { "reg", reg_assocs, 0 };
 
-static DSGINIT(const) struct tvec_regdef test_regs[] = {
+static DSGINIT(const) struct tvec_regdef multi_serialize_regs[] = {
 #define DEFREG(name, i, ty, argslot, argval)                           \
   { #name,     i,      &tvty_##ty,     TVRF_OPT,                       \
                                            DSGINIT({ .argslot = argval }) },
   TYPEREGS(DEFREG)
 #undef DEFREG
+
   { "rc",      RRC,    &tvty_int,      TVRF_OPT,       { &tvrange_int } },
-  { "serialized", RSER,        &tvty_bytes,    TVRF_OPT },
-  { "sabotage",        RSAB,   &tvty_ienum,    TVRF_OPT,       { &type_enum } },
+  { "serialized", RSEROUT, &tvty_bytes,        TVRF_OPT },
+  { "sabotage",        RSAB,   &tvty_ienum,    TVRF_OPT,       { &reg_enum } },
 
-  { 0 }
+  TVEC_ENDREGS
 };
 
-/*----- Single-type copy tests --------------------------------------------*/
-
-static void test_copy_simple
-  (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
-  { out->v = in->v; }
-
-static void test_copy_string
-  (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);
-}
-
-static void test_copy_bytes
-  (const struct tvec_reg *in, struct tvec_reg *out, void *ctx)
+static int before_multi_serialize(struct tvec_state *tv, void *ctx)
 {
-  tvec_allocstring(&out->v, in->v.str.sz);
-  memcpy(out->v.str.p, in->v.str.p, in->v.str.sz);
+  if (!(tv->in[RRC].f&TVRF_LIVE)) {
+    tv->in[RRC].v.i = 0; tv->in[RRC].f |= TVRF_LIVE;
+    tv->out[RRC].f |= TVRF_LIVE;
+  }
+  return (0);
 }
 
-#define test_copy_int test_copy_simple
-#define test_copy_uint test_copy_simple
-#define test_copy_ienum test_copy_simple
-#define test_copy_uenum test_copy_simple
-#define test_copy_fenum test_copy_simple
-#define test_copy_penum test_copy_simple
-#define test_copy_char test_copy_simple
-#define test_copy_flags test_copy_simple
-#define test_copy_float test_copy_simple
-#define test_copy_fltish test_copy_simple
-#define test_copy_buffer test_copy_bytes
-
-#define SINGLEREG(name, i, ty, argslot, argval)                                \
-       DSGINIT(const) struct tvec_regdef name##_regs[] = {             \
-         { #name, RV, &tvty_##ty, 0, DSGINIT({ .argslot = argval }) }, \
-         { 0 }                                                         \
-       };
-TYPEREGS(SINGLEREG)
-#undef SINGLEREG
-
-struct singlectx {
-  unsigned f;
-#define SF_SHOW 1u
+static const struct tvec_env multi_serialize_testenv = {
+  sizeof(struct test_context),
+  common_setup, common_set,
+  before_multi_serialize, common_run, common_after,
+  0
 };
 
-static int single_setup(struct tvec_state *tv, const struct tvec_env *env,
-                       void *pctx, void *ctx)
-  { struct singlectx *s = ctx; s->f = 0; return (0); }
-
-static int single_set(struct tvec_state *tv, const char *name,
-                     const struct tvec_env *env, void *ctx)
-{
-  struct singlectx *s = ctx;
-  union tvec_regval rv;
-  static const struct tvec_regdef rd =
-    { "@show", -1, &tvty_ienum, 0, { &tvenum_bool } };
-
-  if (STRCMP(name, ==, "@show")) {
-    if (tvty_ienum.parse(&rv, &rd, tv)) return (-1);
-    if (s) {
-      if (rv.i) s->f |= SF_SHOW;
-      else s->f &= ~SF_SHOW;
-    }
-    return (1);
-  } else
-    return (0);
-}
-
-static void single_run(struct tvec_state *tv, tvec_testfn *fn, void *ctx)
-{
-  struct singlectx *s = ctx;
-  unsigned f = s->f;
-
-  fn(tv->in, tv->out, 0);
-  if (tvec_checkregs(tv)) { tvec_fail(tv, 0); f |= SF_SHOW; }
-  if (f&SF_SHOW) tvec_mismatch(tv, TVMF_IN | TVMF_OUT);
-}
-
-static void single_after(struct tvec_state *tv, void *ctx)
-  { struct singlectx *s = ctx; s->f = 0; }
-
-static const struct tvec_env single_testenv =
-  { sizeof(struct singlectx),
-    single_setup,
-    single_set,
-    0,
-    single_run,
-    single_after,
-    0 };
-
 /*----- Front end ---------------------------------------------------------*/
 
 static const struct tvec_test tests[] = {
-  { "types",   test_regs,      &capture_testenv,       test_serialization },
-
-#define DEFCOPY(name, i, ty, argslot, argval)                          \
-  { #name,     name##_regs,    &single_testenv,        test_copy_##name },
-  TYPEREGS(DEFCOPY)
-#undef DEFCOPY
-
-  { 0 }
+  { "multi",   multi_serialize_regs, &multi_serialize_testenv,
+                                               test_multi_serialize },
+
+#define DEFSINGLE(name, i, ty, argslot, argval)                                \
+  { "copy-" #name, name##_copyregs,    &common_testenv, test_copy_##name }, \
+  { "serialize-" #name, name##_serregs,        &single_serialize_testenv, \
+                                               test_single_serialize }, \
+  { "deserialize-" #name, name##_deserregs, &single_deserialize_testenv, \
+                                               test_single_deserialize },
+  TYPEREGS(DEFSINGLE)
+#undef DEFSINGLE
+
+  TVEC_ENDTESTS
 };
 
 static const struct tvec_config testconfig = {
@@ -359,8 +471,10 @@ int main(int argc, char *argv[])
 {
 #if __STDC_VERSION__x < 199901
 #  define POKE(name, i, ty, argslot, argval)                           \
-       test_regs[i].arg.argslot = argval;                              \
-       name##_regs->arg.argslot = argval;
+       multi_serialize_regs[i].arg.argslot = argval;                   \
+       name##_copyregs->arg.argslot = argval;                          \
+       name##_serregs->arg.argslot = argval;                           \
+       name##_deserregs->arg.argslot = argval;
   TYPEREGS(POKE)
 #  undef POKE
 #endif
index d823872ab3ce17a321d69c9dc235359744259bd1..9a890da37ac5b5ae6bf5a2f6506f8dfa199f850d 100644 (file)
@@ -50,13 +50,13 @@ dnl test_parse(TY, IN, OUT)
 m4_define([test_parse], [
 AT_DATA([tv],
 [;;; -*-conf-*-
-@<:@$1@:>@
+@<:@copy-$1@:>@
 $1 = $2
 @show = t
 ])
 check_template([BUILDDIR/t/tvec.t -fh tv], [0],
 [left_pad([matched $1], [17]) = $3
-$1: ok
+copy-$1: ok
 PASSED all 1 test in 1 group
 ])])
 
@@ -64,18 +64,18 @@ dnl test_parserr(TY, IN, LNO, ERR)
 m4_define([test_parserr], [
 AT_DATA([tv],
 [;;; -*-conf-*-
-@<:@$1@:>@
+@<:@copy-$1@:>@
 $1 = $2
 ])
 check_template([BUILDDIR/t/tvec.t -fh tv], [2],
 [tv:$3: $4
-tv:={N:\d+}: required register `$1' not set in test `$1'
-$1: skipped: no tests to run
+tv:={N:\d+}: required register `$1' not set in test `copy-$1'
+copy-$1: skipped: no tests to run
 PASSED 0 tests in 0 groups (1 skipped)
 ERRORS found in input; tests may not have run correctly
 ],
 [tvec.t: tv:$3: $4
-tvec.t: tv:={N:\d+}: required register `$1' not set in test `$1'
+tvec.t: tv:={N:\d+}: required register `$1' not set in test `copy-$1'
 ])])
 
 ###--------------------------------------------------------------------------
@@ -214,7 +214,7 @@ AT_CLEANUP
 AT_SETUP([tvec serialize])
 
 AT_DATA([tv],
-[@<:@types@:>@
+[@<:@multi@:>@
 
 int = -2
 uint = 7
index 1984a1e3744f21802f3ebbadb0d15e856a0ab9ac..9709b6032401b3762aa0a469598ddd145b1d5b01 100644 (file)
@@ -358,7 +358,7 @@ static void format_floating(const struct gprintf_ops *gops, void *go,
 static int eqish_floating_p(double x, double y,
                            const struct tvec_floatinfo *fi)
 {
-  double xx, yy, t;
+  double t;
 
   if (NANP(x)) return (NANP(y)); else if (NANP(y)) return (0);
   if (INFP(x)) return (x == y); else if (INFP(y)) return (0);
index 03c3ba462c3786f1926a3f0f0fe4ab13dee605ca..7f19f50b02d37907500acd46ed7b2dfd7f2ae27a 100644 (file)
@@ -169,6 +169,7 @@ struct tvec_regdef {
 #define TVRF_ID 2u                     /*   part of test identity  */
   union tvec_misc arg;                 /* extra detail for the type */
 };
+#define TVEC_ENDREGS { 0, 0, 0, 0, { 0 } }
 
 /* @TVEC_GREG(vec, i, regsz)@
  *
@@ -389,7 +390,7 @@ struct tvec_test {
   const struct tvec_env *env;          /* environment to run test in */
   tvec_testfn *fn;                     /* test function */
 };
-
+#define TVEC_ENDTESTS { 0, 0, 0, 0 }
 
 enum {
   /* Register output dispositions. */
@@ -1355,7 +1356,7 @@ struct tvec_floatinfo {
  *
  *               * If @f&TVFF_EQMASK@ is @TVFF_RELDELTA@, then %$x$% matches
  *                 %$y$% when %$|1 - y/x| < \delta$%.  (Note that this
- *                 criterion is asymmetric
+ *                 criterion is asymmetric FIXME
  *
  *             The @TVEC_CLAIM_FLOAT@ macro is similar, only it (a)
  *             identifies the file and line number of the call site
index a49990e15ea3cfc0ce1c8c8aab7e30f4270089d4..b4a515b0278544141b1bfce7572e2bec8d302a20 100644 (file)
@@ -75,13 +75,13 @@ static const struct tvec_regdef shift_regs[] = {
   { "x", RX, &tvty_bytes, 0, { &ur_eight } },
   { "n", RN, &tvty_uint, 0, { &ur_shift } },
   { "z", RZ, &tvty_bytes, 0, { &ur_eight } },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 static const struct tvec_regdef arith_regs[] = {
   { "x", RX, &tvty_bytes, 0, { &ur_eight } },
   { "y", RY, &tvty_bytes, 0, { &ur_eight } },
   { "z", RZ, &tvty_bytes, 0, { &ur_eight } },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 
 static const struct tvec_test tests[] = {
@@ -91,7 +91,7 @@ static const struct tvec_test tests[] = {
   { "ror64", shift_regs, 0, test_ROR },
   { "add64", arith_regs, 0, test_ADD },
   { "sub64", arith_regs, 0, test_SUB },
-  { 0, 0, 0, 0 }
+  TVEC_ENDTESTS
 };
 
 static const struct tvec_config testconfig =
index e7244c609a8700f815cb6abda01dd047c455d7d8..5e13e155e5f0f7685fb7ae544b7e784e74cba4e3 100644 (file)
@@ -54,12 +54,12 @@ static const struct tvec_regdef versioncmp_regs[] = {
   { "v0", RV0, &tvty_string, 0 },
   { "v1", RV1, &tvty_string, 0 },
   { "rc", RRC, &tvty_int, 0, { &cmp_range } },
-  { 0, 0, 0, 0 }
+  TVEC_ENDREGS
 };
 
 static const struct tvec_test tests[] = {
   { "versioncmp", versioncmp_regs, &swap_testenv, test_versioncmp },
-  { 0, 0, 0, 0 }
+  TVEC_ENDTESTS
 };
 
 static const struct tvec_config testconfig =