*/
unsigned f; /* flags */
-#define TVRF_LIVE 1u /* used in current test */
+#define TVRF_SEEN 1u /* assignment seen in file */
+#define TVRF_LIVE 2u /* used in current test */
union tvec_regval v; /* register value */
};
const struct tvec_regty *ty; /* register type descriptor */
unsigned i; /* register index */
unsigned f; /* flags */
-#define TVRF_OPT 1u /* optional register */
-#define TVRF_ID 2u /* part of test identity */
+#define TVRF_UNSET 1u /* register may be marked unset */
+#define TVRF_OPT 2u /* register need not be assigned */
+#define TVRF_ID 4u /* part of test identity */
union tvec_misc arg; /* extra detail for the type */
};
#define TVEC_ENDREGS { 0, 0, 0, 0, { 0 } }
void (*init)(union tvec_regval */*rv*/, const struct tvec_regdef */*rd*/);
/* Initialize the value in @*rv@. This will be called before any other
- * function acting on the value, including @release@.
+ * function acting on the value, including @release@. Following @init@,
+ * the register value must be valid to use for all other type entry
+ * points.
*/
void (*release)(union tvec_regval */*rv*/,
const struct tvec_regdef */*rd*/);
- /* Release any resources associated with the value in @*rv@. */
+ /* Release any resources associated with the value in @*rv@. The
+ * register value may be left in an invalid state.
+ */
int (*eq)(const union tvec_regval */*rv0*/,
const union tvec_regval */*rv1*/,
#define TVEC_CLAIMEQ_UINT(tv, u0, u1) \
(tvec_claimeq_uint(tv, u0, u1, __FILE__, __LINE__, #u0 " /= " #u1))
+/*----- Size type ---------------------------------------------------------*/
+
+/* A size is an unsigned integer followed by an optional unit specifier
+ * consisting of an SI unit prefix and (optionally) the letter `B'.
+ */
+
+extern const struct tvec_regty tvty_size;
+
+/* --- @tvec_claimeq_size@ --- *
+ *
+ * Arguments: @struct tvec_state *tv@ = test-vector state
+ * @unsigned long sz0, sz1@ = two sizes
+ * @const char *file@, @unsigned @lno@ = calling file and line
+ * @const char *expr@ = the expression to quote on failure
+ *
+ * Returns: Nonzero if @sz0@ and @sz1@ are equal, otherwise zero.
+ *
+ * Use: Check that values of @u0@ and @u1@ are equal. As for
+ * @tvec_claim@ above, a test case is automatically begun and
+ * ended if none is already underway. If the values are
+ * unequal, then @tvec_fail@ is called, quoting @expr@, and the
+ * mismatched values are dumped: @u0@ is printed as the output
+ * value and @u1@ is printed as the input reference.
+ *
+ * The @TVEC_CLAIM_SIZE@ macro is similar, only it (a)
+ * identifies the file and line number of the call site
+ * automatically, and (b) implicitly quotes the source text of
+ * the @u0@ and @u1@ arguments in the failure message.
+ */
+
+int tvec_claimeq_size(struct tvec_state *tv,
+ unsigned long sz0, unsigned long sz1,
+ const char *file, unsigned lno, const char *expr);
+#define TVEC_CLAIMEQ_UINT(tv, u0, u1) \
+ (tvec_claimeq_uint(tv, u0, u1, __FILE__, __LINE__, #u0 " /= " #u1))
+
/*----- Floating-point type -----------------------------------------------*/
/* Floating-point values are either NaN (%|#nan|%, if supported by the
* @const char *file@, @unsigned @lno@ = calling file and line
* @const char *expr@ = the expression to quote on failure
*
- * Returns: Nonzero if @f0@ and @u1@ are sufficiently close, otherwise
+ * Returns: Nonzero if @f0@ and @f1@ are sufficiently close, otherwise
* zero.
*
* Use: Check that values of @f0@ and @f1@ are sufficiently close.
* %$y$% when %$|x - y| < \delta$%.
*
* * If @f&TVFF_EQMASK@ is @TVFF_RELDELTA@, then %$x$% matches
- * %$y$% when %$|1 - y/x| < \delta$%. (Note that this
- * criterion is asymmetric FIXME
+ * %$y$% when %$|1 - x/y| < \delta$%. (Note that this
+ * criterion is asymmetric. Write %$x \approx_\delta y$%
+ * if and only if %$|1 - x/y < \delta$%. Then, for example,
+ * if %$y/(1 + \delta) < x < y (1 - \delta)$%, then
+ * %$x \approx_\delta y$%, but %$y \not\approx_\delta x$%.)
*
* The @TVEC_CLAIM_FLOAT@ macro is similar, only it (a)
* identifies the file and line number of the call site
const char */*file*/, unsigned /*lno*/,
const char */*expr*/);
#define TVEC_CLAIMEQISH_FLOAT(tv, f0, f1, f, delta) \
- (tvec_claimeqish_float(tv, f0, f1, f, delta, , __FILE__, __LINE__, \
+ (tvec_claimeqish_float(tv, f0, f1, f, delta, __FILE__, __LINE__, \
#f0 " /= " #f1 " (+/- " #delta ")"))
/* --- @tvec_claimeq_float@, @TVEC_CLAIMEQ_FLOAT@ --- *
/* 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;
extern int tvec_parsedurunit(double */*scale_out*/,
const char **/*p_inout*/);
+/* --- @tvec_claimeqish_duration@, @TVEC_CLAIMEQISH_DURATION@ --- *
+ *
+ * Arguments: @struct tvec_state *tv@ = test-vector state
+ * @double to, t1@ = two durations
+ * @unsigned f@ = flags (@TVFF_...@)
+ * @double delta@ = maximum tolerable difference
+ * @const char *file@, @unsigned @lno@ = calling file and line
+ * @const char *expr@ = the expression to quote on failure
+ *
+ * Returns: Nonzero if @t0@ and @t1@ are sufficiently close, otherwise
+ * zero.
+ *
+ * Use: Check that values of @t0@ and @t1@ are sufficiently close.
+ * This is essentially the same as @tvec_claimeqish_float@, only
+ * it dumps the values as durations on a mismatch.
+ *
+ * The @TVEC_CLAIM_FLOAT@ macro is similar, only it (a)
+ * identifies the file and line number of the call site
+ * automatically, and (b) implicitly quotes the source text of
+ * the @t0@ and @t1@ arguments (and @delta@) in the failure
+ * message.
+ */
+
+extern int tvec_claimeqish_duration(struct tvec_state */*tv*/,
+ double /*t0*/, double /*t1*/,
+ unsigned /*f*/, double /*delta*/,
+ const char */*file*/, unsigned /*lno*/,
+ const char */*expr*/);
+#define TVEC_CLAIMEQISH_DURATION(tv, t0, t1, f, delta) \
+ (tvec_claimeqish_duration(tv, t0, t1, f, delta, __FILE__, __LINE__, \
+ #t0 " /= " #t1 " (+/- " #delta ")"))
+
+/* --- @tvec_claimeq_duration@, @TVEC_CLAIMEQ_DURATION@ --- *
+ *
+ * Arguments: @struct tvec_state *tv@ = test-vector state
+ * @double t0, t1@ = two durations
+ * @const char *file@, @unsigned @lno@ = calling file and line
+ * @const char *expr@ = the expression to quote on failure
+ *
+ * Returns: Nonzero if @t0@ and @t1@ are identical, otherwise zero.
+ *
+ * Use: Check that values of @t0@ and @t1@ are identical. The
+ * function is exactly equivalent to @tvec_claimeqish_duration@
+ * with @f == TVFF_EXACT@; the macro is similarly like
+ * @TVEC_CLAIMEQISH_DURATION@ with @f == TVFF_EXACT@, except
+ * that it doesn't bother to quote a delta.
+ */
+
+int tvec_claimeq_duration(struct tvec_state */*tv*/,
+ double /*t0*/, double /*t1*/,
+ const char */*file*/, unsigned /*lno*/,
+ const char */*expr*/);
+#define TVEC_CLAIMEQ_DURATION(tv, t0, t1) \
+ (tvec_claimeq_float(tv, t0, t1, __FILE__, __LINE__, #t0 " /= " #t1))
+
/*----- Enumerated types --------------------------------------------------*/
/* An enumeration describes a set of values of some underlying type, each of