chiark / gitweb /
@@@ much mess, mostly manpages
[mLib] / test / tvec.h
index 293dccc0a90e70eb4a308033e40d9290c312f262..3a18fc59193b0288b825e1f0f10819e6cf6d2a11 100644 (file)
@@ -223,7 +223,8 @@ struct tvec_reg {
    */
 
   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 */
 };
 
@@ -239,8 +240,9 @@ struct tvec_regdef {
   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 } }
@@ -269,12 +271,16 @@ struct tvec_regty {
 
   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*/,
@@ -1879,6 +1885,42 @@ extern int tvec_claimeq_uint(struct tvec_state */*tv*/,
 #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
@@ -1919,7 +1961,7 @@ extern const struct tvec_floatinfo tvflt_finite, tvflt_nonneg;
  *             @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.
@@ -1946,8 +1988,11 @@ extern const struct tvec_floatinfo tvflt_finite, tvflt_nonneg;
  *                 %$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
@@ -1962,7 +2007,7 @@ extern int tvec_claimeqish_float(struct tvec_state */*tv*/,
                                 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@ --- *
@@ -1993,9 +2038,6 @@ extern int tvec_claimeq_float(struct tvec_state */*tv*/,
 /* 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;
@@ -2017,6 +2059,61 @@ 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