X-Git-Url: https://git.distorted.org.uk/~mdw/mLib/blobdiff_plain/814e42ff7421d66c0a2e33af5765afa2078bc18f..c4ccbbf992e1587ae316f66af6a28006780688d8:/test/tvec.h diff --git a/test/tvec.h b/test/tvec.h index 1e1e154..3a18fc5 100644 --- a/test/tvec.h +++ b/test/tvec.h @@ -192,8 +192,13 @@ union tvec_regval { unsigned long u; /* unsigned integer */ void *p; /* pointer */ double f; /* floating point */ - struct { unsigned char *p; size_t sz; } bytes; /* binary string of bytes */ struct { char *p; size_t sz; } text; /* text string */ + struct { unsigned char *p; size_t sz; } bytes; /* binary string of bytes */ + struct { /* buffer */ + unsigned char *p; size_t sz; /* binary string */ + size_t a, m; /* residue and modulus */ + size_t off; /* offset into full buffer */ + } buf; #ifdef TVEC_REGSLOTS TVEC_REGSLOTS #endif @@ -218,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 */ }; @@ -231,11 +237,12 @@ struct tvec_regdef { */ const char *name; /* register name (for input files) */ - unsigned i; /* register index */ 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 } } @@ -264,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*/, @@ -316,6 +327,8 @@ struct tvec_regty { /*----- Test descriptions -------------------------------------------------*/ +struct tvec_env; + typedef void tvec_testfn(const struct tvec_reg */*in*/, struct tvec_reg */*out*/, void */*ctx*/); @@ -335,8 +348,6 @@ typedef void tvec_testfn(const struct tvec_reg */*in*/, * anything to do with the test function's context. */ -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 @@ -430,17 +441,6 @@ struct tvec_test { }; #define TVEC_ENDTESTS { 0, 0, 0, 0 } -enum { - /* Register output dispositions. */ - - TVRD_INPUT, /* input-only register */ - TVRD_OUTPUT, /* output-only (input is dead) */ - TVRD_MATCH, /* matching (equal) registers */ - TVRD_FOUND, /* mismatching output register */ - TVRD_EXPECT, /* mismatching input register */ - TVRD_LIMIT /* (number of dispositions) */ -}; - /*----- Test state --------------------------------------------------------*/ enum { @@ -453,9 +453,18 @@ enum { TVOUT_LIMIT /* (number of possible outcomes) */ }; +struct tvec_config { + /* An overall test configuration. */ + + const struct tvec_test *tests; /* the tests to be performed */ + unsigned nrout, nreg; /* number of output/total regs */ + size_t regsz; /* size of a register */ +}; + struct tvec_state { /* The primary state structure for the test vector machinery. */ + /* Flags. Read-only for all callers. */ unsigned f; /* flags */ #define TVSF_SKIP 0x0001u /* skip this test group */ #define TVSF_OPEN 0x0002u /* test is open */ @@ -466,13 +475,17 @@ struct tvec_state { #define TVSF_XFAIL 0x0100u /* test expected to fail */ #define TVSF_MUFFLE 0x0200u /* muffle errors */ - /* Registers. Available to execution environments. */ - unsigned nrout, nreg; /* number of output/total registers */ - size_t regsz; /* size of register entry */ + /* Test configuration. Read-only for all callers. */ + struct tvec_config cfg; /* test configuration */ + + /* Registers. Available to execution environments, which may modify the + * contents of the active registers, as defined by the current test group, + * but not the vector pointers themselves or inactive registers. + */ struct tvec_reg *in, *out; /* register vectors */ - /* Test groups state. Available to output formatters. */ - const struct tvec_test *tests, *test; /* all tests and current test */ + /* Test group state. Read-only for all callers. */ + const struct tvec_test *test; /* current test */ /* Test scoreboard. Available to output formatters. */ unsigned curr[TVOUT_LIMIT], all[TVOUT_LIMIT], grps[TVOUT_LIMIT]; @@ -491,15 +504,7 @@ struct tvec_state { * @out@, and @i@ is an integer, then this evaluates to the address of the * @i@th register in the selected vector. */ -#define TVEC_REG(tv, vec, i) TVEC_GREG((tv)->vec, (i), (tv)->regsz) - -struct tvec_config { - /* An overall test configuration. */ - - const struct tvec_test *tests; /* the tests to be performed */ - unsigned nrout, nreg; /* number of output/total regs */ - size_t regsz; /* size of a register */ -}; +#define TVEC_REG(tv, vec, i) TVEC_GREG((tv)->vec, (i), (tv)->cfg.regsz) /*----- Output formatting -------------------------------------------------*/ @@ -508,13 +513,34 @@ struct tvec_output { const struct tvec_outops *ops; /* pointer to operations */ }; +enum { + /* Register output dispositions. */ + + TVRD_INPUT, /* input-only register */ + TVRD_OUTPUT, /* output-only (input is dead) */ + TVRD_MATCH, /* matching (equal) registers */ + TVRD_FOUND, /* mismatching output register */ + TVRD_EXPECT, /* mismatching input register */ + TVRD_LIMIT /* (number of dispositions) */ +}; + +#define TVEC_LEVELS(_) \ + _(NOTE, "notice", 4) \ + _(ERR, "ERROR", 8) +enum { +#define TVEC_DEFLEVEL(tag, name, val) TVLEV_##tag = val, + TVEC_LEVELS(TVEC_DEFLEVEL) +#undef TVEC_DEFLEVEL + TVLEV_LIMIT +}; + /* Benchmarking details. */ enum { TVBU_OP, /* counting operations of some kind */ TVBU_BYTE, /* counting bytes (@rbuf >= 0@) */ TVBU_LIMIT /* (number of units) */ }; -struct bench_timing; /* forward declaration */ +struct bench_timing; /* include for the real definition */ struct tvec_outops { /* Output operations. */ @@ -615,17 +641,6 @@ struct tvec_outops { /* Release any resources acquired by the driver. */ }; -#define TVEC_LEVELS(_) \ - _(NOTE, "notice", 4) \ - _(ERR, "ERROR", 8) - -enum { -#define TVEC_DEFLEVEL(tag, name, val) TVLEV_##tag = val, - TVEC_LEVELS(TVEC_DEFLEVEL) -#undef TVEC_DEFLEVEL - TVLEV_LIMIT -}; - /*----- Session lifecycle -------------------------------------------------*/ /* --- @tvec_begin@ --- * @@ -1199,6 +1214,8 @@ extern void tvec_benchreport /*----- Remote execution --------------------------------------------------*/ +struct tvec_remoteenv; + struct tvec_remotecomms { int infd, outfd; /* input and output descriptors */ dbuf bout; /* output buffer */ @@ -1392,7 +1409,7 @@ extern tvec_connectfn tvec_fork, tvec_exec; struct tvec_timeoutenv { struct tvec_env _env; - int timer; /* the timer (@ITIMER_...@) */ + int timer; /* the timer (@ITIMER_...@) */ double t; /* time to wait (in seconds) */ const struct tvec_env *env; /* subsidiary environment */ }; @@ -1437,7 +1454,7 @@ extern tvec_envteardownfn tvec_timeoutteardown; * message. */ -extern const char *tvec_strlevel(unsigned /*level*/); +extern const char *tvec_strlevel(unsigned /*level*/); /* --- @tvec_report@, @tvec_report_v@ --- * * @@ -1476,6 +1493,32 @@ extern PRINTF_LIKE(2, 3) extern PRINTF_LIKE(2, 3) void tvec_notice(struct tvec_state */*tv*/, const char */*msg*/, ...); +/* --- @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 + * @const char *name@ = register or pseudoregister name + * + * Returns: %$-1$%. + * + * Use: Reports an error that the register or pseudoregister has been + * assigned already in the current test. + */ + +extern int tvec_dupreg(struct tvec_state */*tv*/, const char */*name*/); + /* --- @tvec_humanoutput@ --- * * * Arguments: @FILE *fp@ = output file to write on @@ -1638,32 +1681,6 @@ extern PRINTF_LIKE(3, 4) 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 - * @const char *name@ = register or pseudoregister name - * - * Returns: %$-1$%. - * - * Use: Reports an error that the register or pseudoregister has been - * assigned already in the current test. - */ - -extern int tvec_dupreg(struct tvec_state */*tv*/, const char */*name*/); - /* --- @tvec_skipspc@ --- * * * Arguments: @struct tvec_state *tv@ = test-vector state @@ -1727,6 +1744,7 @@ extern int tvec_nexttoken(struct tvec_state */*tv*/); * * Arguments: @struct tvec_state *tv@ = test-vector state * @dstr *d@ = string to append the word to + * @const char **p_inout@ = pointer into string, updated * @const char *delims@ = additional delimiters to stop at * @const char *expect@, @va_list ap@ = what was expected * @@ -1749,14 +1767,23 @@ extern int tvec_nexttoken(struct tvec_state */*tv*/); * word constituents, a null terminator is written to @d@, and * it is safe to treat the string in @d@ as being null- * terminated. + * + * If @p_inout@ is not null, then @*p_inout@ must be a pointer + * into @d->buf@, which will be adjusted so that it will + * continue to point at the same position even if the buffer is + * reallocated. As a subtle tweak, if @*p_inout@ initially + * points at the end of the buffer, then it will be adjusted to + * point at the beginning of the next word, rather than at the + * additional intervening space. */ -extern PRINTF_LIKE(4, 5) +extern PRINTF_LIKE(5, 6) int tvec_readword(struct tvec_state */*tv*/, dstr */*d*/, - const char */*delims*/, const char */*expect*/, ...); + const char **/*p_inout*/, const char */*delims*/, + const char */*expect*/, ...); extern int tvec_readword_v(struct tvec_state */*tv*/, dstr */*d*/, - const char */*delims*/, const char */*expect*/, - va_list */*ap*/); + const char **/*p_inout*/, const char */*delims*/, + const char */*expect*/, va_list */*ap*/); /*----- Integer types: signed and unsigned --------------------------------*/ @@ -1858,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 @@ -1887,6 +1950,8 @@ struct tvec_floatinfo { double delta; /* maximum tolerable difference */ }; +extern const struct tvec_floatinfo tvflt_finite, tvflt_nonneg; + /* --- @tvec_claimeqish_float@, @TVEC_CLAIMEQISH_FLOAT@ --- * * * Arguments: @struct tvec_state *tv@ = test-vector state @@ -1896,7 +1961,7 @@ struct tvec_floatinfo { * @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. @@ -1923,8 +1988,11 @@ struct tvec_floatinfo { * %$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 @@ -1939,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@ --- * @@ -1965,20 +2033,87 @@ extern int tvec_claimeq_float(struct tvec_state */*tv*/, #define TVEC_CLAIMEQ_FLOAT(tv, f0, f1) \ (tvec_claimeq_float(tv, f0, f1, __FILE__, __LINE__, #f0 " /= " #f1)) -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; +/* --- @tvec_parsedurunit@ --- * + * + * Arguments: @double *scale_out@ = where to leave the scale + * @const char **p_inout@ = input unit string, updated + * + * Returns: Zero on success, %$-1$% on error. + * + * Use: If @*p_inout@ begins with a unit string followed by the end + * of the string or some non-alphanumeric character, then store + * the corresponding scale factor in @*scale_out@, advance + * @*p_inout@ past the unit string, and return zero. Otherwise, + * return %$-1$%. + */ + +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 @@ -2303,6 +2438,30 @@ extern int tvec_claimeq_char(struct tvec_state */*tv*/, extern const struct tvec_regty tvty_text, tvty_bytes; +/* --- @tvec_alloctext@, @tvec_allocbytes@ --- * + * + * Arguments: @union tvec_regval *rv@ = register value + * @size_t sz@ = required size + * + * Returns: --- + * + * Use: Allocated space in a text or binary string register. If the + * current register size is sufficient, its buffer is left + * alone; otherwise, the old buffer, if any, is freed and a + * fresh buffer allocated. These functions are not intended to + * be used to adjust a buffer repeatedly, e.g., while building + * output incrementally: (a) they will perform badly, and (b) + * the old buffer contents are simply discarded if reallocation + * is necessary. Instead, use a @dbuf@ or @dstr@. + * + * The @tvec_alloctext@ function sneakily allocates an extra + * byte for a terminating zero. The @tvec_allocbytes@ function + * doesn't do this. + */ + +extern void tvec_alloctext(union tvec_regval */*rv*/, size_t /*sz*/); +extern void tvec_allocbytes(union tvec_regval */*rv*/, size_t /*sz*/); + /* --- @tvec_claimeq_text@, @TVEC_CLAIMEQ_TEXT@ --- * * * Arguments: @struct tvec_state *tv@ = test-vector state @@ -2392,46 +2551,60 @@ extern int tvec_claimeq_bytes(struct tvec_state */*tv*/, (tvec_claimeq(tv, p0, sz0, p1, sz1, __FILE__, __LINE__, \ #p0 "[" #sz0 "] /= " #p1 "[" #sz1 "]")) -/* --- @tvec_alloctext@, @tvec_allocbytes@ --- * +/*----- Buffer type -------------------------------------------------------*/ + +/* Buffer registers are primarily used for benchmarking. Only a buffer's + * allocation parameters are significant: its contents are ignored on + * comparison and output, and unspecified on input. * - * Arguments: @union tvec_regval *rv@ = register value - * @size_t sz@ = required size + * The input format gives the buffer's size, and an optional alignment + * specification, in the form %|SZ [`@' M [`+' A]]|%. Each of %|SZ|%, %|M|% + * and %|A|% are sizes, as an integer, optionally suffixed with a unit `kB', + * `MB', `GB', `TB', `PB', `EB', `ZB', `YB' (with or without the `B') + * denoting a power of 1024. The %|SZ|% gives the (effective) buffer size. + * %|M|% is the `alignment quantum' and %|A|% is the `alignment offset'; both + * default to zero, but if %|M|% is nonzero then the start of the buffer is + * aligned such that it is %|A|% more than a multiple of %|M|% bytes. Note + * that %|M|% need not be a power of two, though this is common. * - * Returns: --- + * Units other than `B' are used on output only when the size would be + * expressed exactly. * - * Use: Allocated space in a text or binary string register. If the - * current register size is sufficient, its buffer is left - * alone; otherwise, the old buffer, if any, is freed and a - * fresh buffer allocated. These functions are not intended to - * be used to adjust a buffer repeatedly, e.g., while building - * output incrementally: (a) they will perform badly, and (b) - * the old buffer contents are simply discarded if reallocation - * is necessary. Instead, use a @dbuf@ or @dstr@. + * Buffers are %%\emph{not}%% allocated by default. In benchmarks, this is + * best done in a @before@ function. * - * The @tvec_alloctext@ function sneakily allocates an extra - * byte for a terminating zero. The @tvec_allocbytes@ function - * doesn't do this. + * No @claimeq@ functions or macros are provided for buffers because they + * don't seem very useful. */ -extern void tvec_alloctext(union tvec_regval */*rv*/, size_t /*sz*/); -extern void tvec_allocbytes(union tvec_regval */*rv*/, size_t /*sz*/); +extern const struct tvec_regty tvty_buffer; -/*----- Buffer type -------------------------------------------------------*/ +/* --- @tvec_initbuffer@ --- * + * + * Arguments: @union tvec_regval *rv@ = register value + * @const union tvec_regval *ref@ = reference buffer + * @size_t sz@ = size to allocate + * + * Returns: --- + * + * Use: Initialize the alignment parameters in @rv@ to match @ref@, + * and the size to @sz@. + */ -/* Buffer registers are primarily used for benchmarking. Only a buffer's - * size is significant: its contents are ignored on comparison and output, - * and unspecified on input. +extern void tvec_initbuffer(union tvec_regval */*rv*/, + const union tvec_regval */*ref*/, size_t /*sz*/); + +/* --- @tvec_allocbuffer@ --- * * - * The input is simply the buffer size, as an integer, optionally suffixed - * with a unit `kB', `MB', `GB', `TB', `PB', `EB', `ZB', `YB' (with or - * without the `B') denoting a power of 1024. Units are used on output only - * when the size would be expressed exactly. + * Arguments: @union tvec_regval *rv@ = register value * - * No @claimeq@ functions or macros are provided for buffers because they - * don't seem very useful. + * Returns: --- + * + * Use: Allocate @sz@ bytes to the buffer and fill the space with a + * distinctive pattern. */ -extern const struct tvec_regty tvty_buffer; +extern void tvec_allocbuffer(union tvec_regval */*rv*/); /*----- That's all, folks -------------------------------------------------*/