@@@ fltfmt mess
[mLib] / test / tvec-types.h
CommitLineData
b1a20bee
MW
1/* -*-c-*-
2 *
3 * Test-vector framework basic register types
4 *
5 * (c) 2024 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28#ifndef MLIB_TVEC_TYPES_H
29#define MLIB_TVEC_TYPES_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#ifndef MLIB_TVEC_H
38# include "tvec.h"
39#endif
40
41/*----- Integer types: signed and unsigned --------------------------------*/
42
43/* Integers may be input in decimal, hex, binary, or octal, following
44 * approximately usual conventions.
45 *
46 * * Signed integers may be preceded with a `+' or `-' sign.
47 *
48 * * Decimal integers are just a sequence of decimal digits `0' ... `9'.
49 *
50 * * Octal integers are a sequence of digits `0' ... `7', preceded by `0o'
51 * or `0O'.
52 *
53 * * Hexadecimal integers are a sequence of digits `0' ... `9', `a'
54 * ... `f', or `A' ... `F', preceded by `0x' or `0X'.
55 *
56 * * Radix-B integers are a sequence of digits `0' ... `9', `a' ... `f', or
57 * `A' ... `F', each with value less than B, preceded by `Br' or `BR',
58 * where 0 < B < 36 is expressed in decimal without any leading `0' or
59 * internal underscores `_'.
60 *
61 * * A digit sequence may contain internal underscore `_' separators, but
62 * not before or after all of the digits; and two consecutive `_'
63 * characters are not permitted.
64 */
65
66extern const struct tvec_regty tvty_int, tvty_uint;
67
68/* The @arg.p@ slot may be null or a pointer to @struct tvec_irange@ or
69 * @struct tvec_urange@ as appropriate. The bounds are inclusive; use, e.g.,
70 * @LONG_MAX@ explicitly if one or the other bound is logically inapplicable.
71 * If %$m$% is nonzero, then the value must additionally be congruent to
72 * %$a$% modulo %$m$%.
73 */
74struct tvec_irange { long min, max, m, a; };
75struct tvec_urange { unsigned long min, max, m, a; };
76
77/* Bounds corresponding to common integer types. */
78extern const struct tvec_irange
79 tvrange_schar, tvrange_short, tvrange_int, tvrange_long,
80 tvrange_sbyte, tvrange_i16, tvrange_i32;
81extern const struct tvec_urange
82 tvrange_uchar, tvrange_ushort, tvrange_uint, tvrange_ulong, tvrange_size,
83 tvrange_byte, tvrange_u16, tvrange_u32;
84
85/* --- @tvec_claimeq_int@, @TVEC_CLAIMEQ_INT@ --- *
86 *
87 * Arguments: @struct tvec_state *tv@ = test-vector state
88 * @long i0, i1@ = two signed integers
89 * @const char *file@, @unsigned @lno@ = calling file and line
90 * @const char *expr@ = the expression to quote on failure
91 *
92 * Returns: Nonzero if @i0@ and @i1@ are equal, otherwise zero.
93 *
94 * Use: Check that values of @i0@ and @i1@ are equal. As for
95 * @tvec_claim@ above, a test case is automatically begun and
96 * ended if none is already underway. If the values are
97 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
98 * mismatched values are dumped: @i0@ is printed as the output
99 * value and @i1@ is printed as the input reference.
100 *
101 * The @TVEC_CLAIM_INT@ macro is similar, only it (a) identifies
102 * the file and line number of the call site automatically, and
103 * (b) implicitly quotes the source text of the @i0@ and @i1@
104 * arguments in the failure message.
105 */
106
107extern int tvec_claimeq_int(struct tvec_state */*tv*/,
108 long /*i0*/, long /*i1*/,
109 const char */*file*/, unsigned /*lno*/,
110 const char */*expr*/);
111#define TVEC_CLAIMEQ_INT(tv, i0, i1) \
112 (tvec_claimeq_int(tv, i0, i1, __FILE__, __LINE__, #i0 " /= " #i1))
113
114/* --- @tvec_claimeq_uint@, @TVEC_CLAIMEQ_UINT@ --- *
115 *
116 * Arguments: @struct tvec_state *tv@ = test-vector state
117 * @unsigned long u0, u1@ = two unsigned integers
118 * @const char *file@, @unsigned @lno@ = calling file and line
119 * @const char *expr@ = the expression to quote on failure
120 *
121 * Returns: Nonzero if @u0@ and @u1@ are equal, otherwise zero.
122 *
123 * Use: Check that values of @u0@ and @u1@ are equal. As for
124 * @tvec_claim@ above, a test case is automatically begun and
125 * ended if none is already underway. If the values are
126 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
127 * mismatched values are dumped: @u0@ is printed as the output
128 * value and @u1@ is printed as the input reference.
129 *
130 * The @TVEC_CLAIM_UINT@ macro is similar, only it (a)
131 * identifies the file and line number of the call site
132 * automatically, and (b) implicitly quotes the source text of
133 * the @u0@ and @u1@ arguments in the failure message.
134 */
135
136extern int tvec_claimeq_uint(struct tvec_state */*tv*/,
137 unsigned long /*u0*/, unsigned long /*u1*/,
138 const char */*file*/, unsigned /*lno*/,
139 const char */*expr*/);
140#define TVEC_CLAIMEQ_UINT(tv, u0, u1) \
141 (tvec_claimeq_uint(tv, u0, u1, __FILE__, __LINE__, #u0 " /= " #u1))
142
143/*----- Size type ---------------------------------------------------------*/
144
145/* A size is an unsigned integer followed by an optional unit specifier
146 * consisting of an SI unit prefix and (optionally) the letter `B'.
147 */
148
149extern const struct tvec_regty tvty_size;
150
151/* --- @tvec_claimeq_size@ --- *
152 *
153 * Arguments: @struct tvec_state *tv@ = test-vector state
154 * @unsigned long sz0, sz1@ = two sizes
155 * @const char *file@, @unsigned @lno@ = calling file and line
156 * @const char *expr@ = the expression to quote on failure
157 *
158 * Returns: Nonzero if @sz0@ and @sz1@ are equal, otherwise zero.
159 *
160 * Use: Check that values of @u0@ and @u1@ are equal. As for
161 * @tvec_claim@ above, a test case is automatically begun and
162 * ended if none is already underway. If the values are
163 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
164 * mismatched values are dumped: @u0@ is printed as the output
165 * value and @u1@ is printed as the input reference.
166 *
167 * The @TVEC_CLAIM_SIZE@ macro is similar, only it (a)
168 * identifies the file and line number of the call site
169 * automatically, and (b) implicitly quotes the source text of
170 * the @u0@ and @u1@ arguments in the failure message.
171 */
172
173int tvec_claimeq_size(struct tvec_state *tv,
174 unsigned long sz0, unsigned long sz1,
175 const char *file, unsigned lno, const char *expr);
176#define TVEC_CLAIMEQ_UINT(tv, u0, u1) \
177 (tvec_claimeq_uint(tv, u0, u1, __FILE__, __LINE__, #u0 " /= " #u1))
178
179/*----- Floating-point type -----------------------------------------------*/
180
181/* Floating-point values are either NaN (%|#nan|%, if supported by the
182 * platform); positive or negative infinity (%|#inf|%, %|+#inf|%, or
183 * %|#+inf|% (preferring the last), and %|-#inf|% or %|#-inf|% (preferring
184 * the latter), if supported by the platform); or a number in strtod(3)
185 * syntax.
186 *
187 * The comparison rules for floating-point numbers are complex: see
188 * @tvec_claimeqish_float@ for details.
189 */
190
191extern const struct tvec_regty tvty_float;
192
193struct tvec_floatinfo {
194 /* Details about acceptable floating-point values. */
195
196 unsigned f; /* flags (@TVFF_...@ bits) */
197#define TVFF_NOMIN 0x0001 /* ignore @min@ (allow -∞) */
198#define TVFF_NOMAX 0x0002 /* ignore @max@ (allow +∞) */
199#define TVFF_NANOK 0x0004 /* permit NaN */
200#define TVFF_NEGINFOK 0x0008 /* permit -∞, check finite */
201#define TVFF_POSINFOK 0x0010 /* permit +∞, check finite */
202#define TVFF_INFOK (TVFF_NEGINFOK | TVFF_POSINFOK) /* permit ±∞ */
203#define TVFF_EQMASK 0x0f00 /* how to compare */
204#define TVFF_EXACT 0x0000 /* must equal exactly */
205#define TVFF_ABSDELTA 0x0100 /* must be within @delta@ */
206#define TVFF_RELDELTA 0x0200 /* diff < @delta@ fraction */
207 double min, max; /* smallest/largest value allowed */
208 double delta; /* maximum tolerable difference */
209};
210
211extern const struct tvec_floatinfo
212 tvflt_float, tvflt_double, tvflt_finite, tvflt_nonneg;
213
214/* --- @tvec_claimeqish_float@, @TVEC_CLAIMEQISH_FLOAT@ --- *
215 *
216 * Arguments: @struct tvec_state *tv@ = test-vector state
217 * @double f0, f1@ = two floating-point numbers
218 * @unsigned f@ = flags (@TVFF_...@)
219 * @double delta@ = maximum tolerable difference
220 * @const char *file@, @unsigned @lno@ = calling file and line
221 * @const char *expr@ = the expression to quote on failure
222 *
223 * Returns: Nonzero if @f0@ and @f1@ are sufficiently close, otherwise
224 * zero.
225 *
226 * Use: Check that values of @f0@ and @f1@ are sufficiently close.
227 * As for @tvec_claim@ above, a test case is automatically begun
228 * and ended if none is already underway. If the values are
229 * too far apart, then @tvec_fail@ is called, quoting @expr@,
230 * and the mismatched values are dumped: @f0@ is printed as the
231 * output value and @f1@ is printed as the input reference.
232 *
233 * The details for the comparison are as follows.
234 *
235 * * A NaN value matches any other NaN, and nothing else.
236 *
237 * * An infinity matches another infinity of the same sign,
238 * and nothing else.
239 *
240 * * If @f&TVFF_EQMASK@ is @TVFF_EXACT@, then any
241 * representable number matches only itself: in particular,
242 * positive and negative zero are considered distinct.
243 * (This allows tests to check that they land on the correct
244 * side of branch cuts, for example.)
245 *
246 * * If @f&TVFF_EQMASK@ is @TVFF_ABSDELTA@, then %$x$% matches
247 * %$y$% when %$|x - y| < \delta$%.
248 *
249 * * If @f&TVFF_EQMASK@ is @TVFF_RELDELTA@, then %$x$% matches
250 * %$y$% when %$|1 - x/y| < \delta$%. (Note that this
251 * criterion is asymmetric. Write %$x \approx_\delta y$%
252 * if and only if %$|1 - x/y < \delta$%. Then, for example,
253 * if %$y/(1 + \delta) < x < y (1 - \delta)$%, then
254 * %$x \approx_\delta y$%, but %$y \not\approx_\delta x$%.)
255 *
256 * The @TVEC_CLAIM_FLOAT@ macro is similar, only it (a)
257 * identifies the file and line number of the call site
258 * automatically, and (b) implicitly quotes the source text of
259 * the @f0@ and @f1@ arguments (and @delta@) in the failure
260 * message.
261 */
262
263extern int tvec_claimeqish_float(struct tvec_state */*tv*/,
264 double /*f0*/, double /*f1*/,
265 unsigned /*f*/, double /*delta*/,
266 const char */*file*/, unsigned /*lno*/,
267 const char */*expr*/);
268#define TVEC_CLAIMEQISH_FLOAT(tv, f0, f1, f, delta) \
269 (tvec_claimeqish_float(tv, f0, f1, f, delta, __FILE__, __LINE__, \
270 #f0 " /= " #f1 " (+/- " #delta ")"))
271
272/* --- @tvec_claimeq_float@, @TVEC_CLAIMEQ_FLOAT@ --- *
273 *
274 * Arguments: @struct tvec_state *tv@ = test-vector state
275 * @double f0, f1@ = two floating-point numbers
276 * @const char *file@, @unsigned @lno@ = calling file and line
277 * @const char *expr@ = the expression to quote on failure
278 *
279 * Returns: Nonzero if @f0@ and @u1@ are identical, otherwise zero.
280 *
281 * Use: Check that values of @f0@ and @f1@ are identical. The
282 * function is exactly equivalent to @tvec_claimeqish_float@
283 * with @f == TVFF_EXACT@; the macro is similarly like
284 * @TVEC_CLAIMEQISH_FLOAT@ with @f == TVFF_EXACT@, except that
285 * it doesn't bother to quote a delta.
286 */
287
288extern int tvec_claimeq_float(struct tvec_state */*tv*/,
289 double /*f0*/, double /*f1*/,
290 const char */*file*/, unsigned /*lno*/,
291 const char */*expr*/);
292#define TVEC_CLAIMEQ_FLOAT(tv, f0, f1) \
293 (tvec_claimeq_float(tv, f0, f1, __FILE__, __LINE__, #f0 " /= " #f1))
294
295/*----- Durations ---------------------------------------------------------*/
296
297/* A duration measures a time interval in seconds. The input format consists
298 * of a nonnegative decimal floating-point number in @strtod@ format followed
299 * by an optional unit specification.
300 */
301
302extern const struct tvec_regty tvty_duration;
303
304/* --- @tvec_parsedurunit@ --- *
305 *
306 * Arguments: @double *scale_out@ = where to leave the scale
307 * @const char **p_inout@ = input unit string, updated
308 *
309 * Returns: Zero on success, %$-1$% on error.
310 *
311 * Use: If @*p_inout@ begins with a unit string followed by the end
312 * of the string or some non-alphanumeric character, then store
313 * the corresponding scale factor in @*scale_out@, advance
314 * @*p_inout@ past the unit string, and return zero. Otherwise,
315 * return %$-1$%.
316 */
317
318extern int tvec_parsedurunit(double */*scale_out*/,
319 const char **/*p_inout*/);
320
321/* --- @tvec_claimeqish_duration@, @TVEC_CLAIMEQISH_DURATION@ --- *
322 *
323 * Arguments: @struct tvec_state *tv@ = test-vector state
324 * @double t0, t1@ = two durations
325 * @unsigned f@ = flags (@TVFF_...@)
326 * @double delta@ = maximum tolerable difference
327 * @const char *file@, @unsigned @lno@ = calling file and line
328 * @const char *expr@ = the expression to quote on failure
329 *
330 * Returns: Nonzero if @t0@ and @t1@ are sufficiently close, otherwise
331 * zero.
332 *
333 * Use: Check that values of @t0@ and @t1@ are sufficiently close.
334 * This is essentially the same as @tvec_claimeqish_float@, only
335 * it dumps the values as durations on a mismatch.
336 *
337 * The @TVEC_CLAIM_FLOAT@ macro is similar, only it (a)
338 * identifies the file and line number of the call site
339 * automatically, and (b) implicitly quotes the source text of
340 * the @t0@ and @t1@ arguments (and @delta@) in the failure
341 * message.
342 */
343
344extern int tvec_claimeqish_duration(struct tvec_state */*tv*/,
345 double /*t0*/, double /*t1*/,
346 unsigned /*f*/, double /*delta*/,
347 const char */*file*/, unsigned /*lno*/,
348 const char */*expr*/);
349#define TVEC_CLAIMEQISH_DURATION(tv, t0, t1, f, delta) \
350 (tvec_claimeqish_duration(tv, t0, t1, f, delta, __FILE__, __LINE__, \
351 #t0 " /= " #t1 " (+/- " #delta ")"))
352
353/* --- @tvec_claimeq_duration@, @TVEC_CLAIMEQ_DURATION@ --- *
354 *
355 * Arguments: @struct tvec_state *tv@ = test-vector state
356 * @double t0, t1@ = two durations
357 * @const char *file@, @unsigned @lno@ = calling file and line
358 * @const char *expr@ = the expression to quote on failure
359 *
360 * Returns: Nonzero if @t0@ and @t1@ are identical, otherwise zero.
361 *
362 * Use: Check that values of @t0@ and @t1@ are identical. The
363 * function is exactly equivalent to @tvec_claimeqish_duration@
364 * with @f == TVFF_EXACT@; the macro is similarly like
365 * @TVEC_CLAIMEQISH_DURATION@ with @f == TVFF_EXACT@, except
366 * that it doesn't bother to quote a delta.
367 */
368
369int tvec_claimeq_duration(struct tvec_state */*tv*/,
370 double /*t0*/, double /*t1*/,
371 const char */*file*/, unsigned /*lno*/,
372 const char */*expr*/);
373#define TVEC_CLAIMEQ_DURATION(tv, t0, t1) \
374 (tvec_claimeq_float(tv, t0, t1, __FILE__, __LINE__, #t0 " /= " #t1))
375
376/*----- Enumerated types --------------------------------------------------*/
377
378/* An enumeration describes a set of values of some underlying type, each of
379 * which has a symbolic name. Values outside of the defined set can occur --
380 * on output, because of bugs in the tested code, or on input to test
381 * handling of unexpected values.
382 *
383 * There is a distinct enumerated type for each of the branches of
384 * @tvec_misc@. In the following, we write @t@ for the type code, which is
385 * @i@ for signed integer, @u@ for unsigned integer, @f@ for floating-point,
386 * and @p@ for pointer.
387 *
388 * On input, an enumerated value may be given by name or as a literal value.
389 * For enumerations based on numeric types, the literal values can be written
390 * in the same syntax as the underlying values. For enumerations based on
391 * pointers, the only permitted literal is %|#nil|%, which denotes a null
392 * pointer. On output, names are preferred (with the underlying value given
393 * in a comment).
394 */
395
396#define DEFENUMTY(tag, ty, slot) \
397 extern const struct tvec_regty tvty_##slot##enum;
398TVEC_MISCSLOTS(DEFENUMTY)
399#undef DEFENUMTY
400
401/* A @struct tvec_tassoc@ associates a string tag with a value. */
402#define DEFASSOC(tag_, ty, slot) \
403 struct tvec_##slot##assoc { const char *tag; ty slot; };
404TVEC_MISCSLOTS(DEFASSOC)
405#undef DEFASSOC
406
407#define TVEC_ENDENUM { 0, 0 }
408
409/* Information about an enumerated type. */
410#define DEFINFO(tag, ty, slot) \
411 struct tvec_##slot##enuminfo { \
412 const char *name; /* type name for diagnostics */ \
413 const struct tvec_##slot##assoc *av; /* name/value mappings */ \
414 EXTRA_##tag##_INFOSLOTS /* type-specific extra info */ \
415 };
416
417#define EXTRA_INT_INFOSLOTS \
418 const struct tvec_irange *ir; /* allowed range of raw values */
419
420#define EXTRA_UINT_INFOSLOTS \
421 const struct tvec_urange *ur; /* allowed range of raw values */
422
423#define EXTRA_FLT_INFOSLOTS \
424 const struct tvec_floatinfo *fi; /* range and matching policy */
425
426#define EXTRA_PTR_INFOSLOTS /* (nothing) */
427
428TVEC_MISCSLOTS(DEFINFO)
429
430#undef EXTRA_INT_INFOSLOTS
431#undef EXTRA_UINT_INFOSLOTS
432#undef EXTRA_FLT_INFOSLOTS
433#undef EXTRA_PTR_INFOSLOTS
434
435#undef DEFINFO
436
437/* Standard enumerations. */
438extern const struct tvec_ienuminfo tvenum_bool;
439extern const struct tvec_ienuminfo tvenum_cmp;
440
441/* --- @tvec_claimeq_tenum@, @TVEC_CLAIMEQ_TENUM@ --- *
442 *
443 * Arguments: @struct tvec_state *tv@ = test-vector state
444 * @const struct tvec_typeenuminfo *ei@ = enumeration type info
445 * @ty t0, t1@ = two values
446 * @const char *file@, @unsigned @lno@ = calling file and line
447 * @const char *expr@ = the expression to quote on failure
448 *
449 * Returns: Nonzero if @t0@ and @t1@ are equal, otherwise zero.
450 *
451 * Use: Check that values of @t0@ and @t1@ are equal. As for
452 * @tvec_claim@ above, a test case is automatically begun and
453 * ended if none is already underway. If the values are
454 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
455 * mismatched values are dumped: @t0@ is printed as the output
456 * value and @t1@ is printed as the input reference.
457 *
458 * The @TVEC_CLAIM_TENUM@ macro is similar, only it (a)
459 * identifies the file and line number of the call site
460 * automatically, and (b) implicitly quotes the source text of
461 * the @t0@ and @t1@ arguments in the failure message.
462 */
463
464#define DECLCLAIM(tag, ty, slot) \
465 extern int tvec_claimeq_##slot##enum \
466 (struct tvec_state */*tv*/, \
467 const struct tvec_##slot##enuminfo */*ei*/, \
468 ty /*t0*/, ty /*t1*/, \
469 const char */*file*/, unsigned /*lno*/, const char */*expr*/);
470TVEC_MISCSLOTS(DECLCLAIM)
471#undef DECLCLAIM
472#define TVEC_CLAIMEQ_IENUM(tv, ei, i0, i1) \
473 (tvec_claimeq_ienum(tv, ei, i0, i1, \
474 __FILE__, __LINE__, #i0 " /= " #i1))
475#define TVEC_CLAIMEQ_UENUM(tv, ei, u0, u1) \
476 (tvec_claimeq_uenum(tv, ei, u0, u1, \
477 __FILE__, __LINE__, #u0 " /= " #u1))
478#define TVEC_CLAIMEQ_FENUM(tv, ei, f0, f1) \
479 (tvec_claimeq_fenum(tv, ei, f0, f1, \
480 __FILE__, __LINE__, #f0 " /= " #f1))
481#define TVEC_CLAIMEQ_PENUM(tv, ei, p0, p1) \
482 (tvec_claimeq_penum(tv, ei, p0, p1, \
483 __FILE__, __LINE__, #p0 " /= " #p1))
484
485/*----- Flags type --------------------------------------------------------*/
486
487/* A flags value packs a number of fields into a single nonnegative integer.
488 * Symbolic names are associated with the possible values of the various
489 * fields; more precisely, each name is associated with a value and a
490 * covering bitmask.
491 *
492 * The input syntax is a sequence of items separated by `%|||%' signs. Each
493 * item may be the symbolic name of a field value, or a literal unsigned
494 * integer. The masks associated with the given symbolic names must be
495 * disjoint. The resulting numerical value is simply the bitwise OR of the
496 * given values.
497 *
498 * On output, the table of symbolic names and their associated values and
499 * masks is repeatedly scanned, in order, to find disjoint matches -- i.e.,
500 * entries whose value matches the target value in the bit positions
501 * indicated by the mask, and whose mask doesn't overlap with any previously
502 * found matches; the names are then output, separated by `%|||%'. Any
503 * remaining nonzero bits not covered by any of the matching masks are output
504 * as a single literal integer, in hex.
505 */
506
507extern const struct tvec_regty tvty_flags;
508
509struct tvec_flag {
510 /* Definition of a single flag or bitfield value.
511 *
512 * Each named setting comes with a value @v@ and a mask @m@; the mask
513 * should cover all of the value bits, i.e., @(v&~m) == 0@.
514 */
515
516 const char *tag; /* name */
517 unsigned long m, v; /* mask and value */
518};
519
520#define TVEC_ENDFLAGS { 0, 0, 0 }
521
522struct tvec_flaginfo {
523 /* Information about a flags type. */
524
525 const char *name; /* type name for diagnostics */
526 const struct tvec_flag *fv; /* name/mask/value mappings */
527 const struct tvec_urange *range; /* permitted range for literals */
528};
529
530/* --- @tvec_claimeq_flags@, @TVEC_CLAIMEQ_FLAGS@ --- *
531 *
532 * Arguments: @struct tvec_state *tv@ = test-vector state
533 * @const struct tvec_flaginfo *fi@ = flags type info
534 * @unsigned long f0, f1@ = two values
535 * @const char *file@, @unsigned @lno@ = calling file and line
536 * @const char *expr@ = the expression to quote on failure
537 *
538 * Returns: Nonzero if @f0@ and @f1@ are equal, otherwise zero.
539 *
540 * Use: Check that values of @f0@ and @f1@ are equal. As for
541 * @tvec_claim@ above, a test case is automatically begun and
542 * ended if none is already underway. If the values are
543 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
544 * mismatched values are dumped: @f0@ is printed as the output
545 * value and @f1@ is printed as the input reference.
546 *
547 * The @TVEC_CLAIM_FLAGS@ macro is similar, only it (a)
548 * identifies the file and line number of the call site
549 * automatically, and (b) implicitly quotes the source text of
550 * the @f0@ and @f1@ arguments in the failure message.
551 */
552
553extern int tvec_claimeq_flags(struct tvec_state */*tv*/,
554 const struct tvec_flaginfo */*fi*/,
555 unsigned long /*f0*/, unsigned long /*f1*/,
556 const char */*file*/, unsigned /*lno*/,
557 const char */*expr*/);
558#define TVEC_CLAIMEQ_FLAGS(tv, fi, f0, f1) \
559 (tvec_claimeq_flags(tv, fi, f0, f1, \
560 __FILE__, __LINE__, #f0 " /= " #f1))
561
562/*----- Character type ----------------------------------------------------*/
563
564/* A character value holds a character, as read by @fgetc@. The special
565 * @EOF@ value can also be represented.
566 *
567 * On input, a character value can be given by symbolic name, with a leading
568 * `%|#|%'; or a character or `%|\|%'-escape sequence, optionally in single
569 * quotes.
570 *
571 * The following escape sequences and character names are recognized.
572 *
573 * * `%|#eof|%' is the special end-of-file marker.
574 *
575 * * `%|#nul|%' is the NUL character, sometimes used to terminate strings.
576 *
577 * * `%|bell|%', `%|bel|%', `%|ding|%', or `%|\a|%' is the BEL character
578 * used to ring the terminal bell (or do some other thing to attract the
579 * user's attention).
580 *
581 * * %|#backspace|%, %|#bs|%, or %|\b|% is the backspace character, used to
582 * move the cursor backwords by one cell.
583 *
584 * * %|#escape|% %|#esc|%, or%|\e|% is the escape character, used to
585 * introduce special terminal commands.
586 *
587 * * %|#formfeed|%, %|#ff|%, or %|\f|% is the formfeed character, used to
588 * separate pages of text.
589 *
590 * * %|#newline|%, %|#linefeed|%, %|#lf|%, %|#nl|%, or %|\n|% is the
591 * newline character, used to terminate lines of text or advance the
592 * cursor to the next line (perhaps without returning it to the start of
593 * the line).
594 *
595 * * %|#return|%, %|#carriage-return|%, %|#cr|%, or %|\r|% is the
596 * carriage-return character, used to return the cursor to the start of
597 * the line.
598 *
599 * * %|#tab|%, %|#horizontal-tab|%, %|#ht|%, or %|\t|% is the tab
600 * character, used to advance the cursor to the next tab stop on the
601 * current line.
602 *
603 * * %|#vertical-tab|%, %|#vt|%, %|\v|% is the vertical tab character.
604 *
605 * * %|#space|%, %|#spc|% is the space character.
606 *
607 * * %|#delete|%, %|#del|% is the delete character, used to erase the most
608 * recent character.
609 *
610 * * %|\'|% is the single-quote character.
611 *
612 * * %|\\|% is the backslash character.
613 *
614 * * %|\"|% is the double-quote character.
615 *
616 * * %|\NNN|% or %|\{NNN}|% is the character with code NNN in octal. The
617 * NNN may be up to three digits long.
618 *
619 * * %|\xNN|% or %|\x{NN}|% is the character with code NNN in hexadecimal.
620 */
621
622extern const struct tvec_regty tvty_char;
623
624/* --- @tvec_claimeq_char@, @TVEC_CLAIMEQ_CHAR@ --- *
625 *
626 * Arguments: @struct tvec_state *tv@ = test-vector state
627 * @int ch0, ch1@ = two character codes
628 * @const char *file@, @unsigned @lno@ = calling file and line
629 * @const char *expr@ = the expression to quote on failure
630 *
631 * Returns: Nonzero if @ch0@ and @ch1@ are equal, otherwise zero.
632 *
633 * Use: Check that values of @ch0@ and @ch1@ are equal. As for
634 * @tvec_claim@ above, a test case is automatically begun and
635 * ended if none is already underway. If the values are
636 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
637 * mismatched values are dumped: @ch0@ is printed as the output
638 * value and @ch1@ is printed as the input reference.
639 *
640 * The @TVEC_CLAIM_CHAR@ macro is similar, only it (a)
641 * identifies the file and line number of the call site
642 * automatically, and (b) implicitly quotes the source text of
643 * the @ch0@ and @ch1@ arguments in the failure message.
644 */
645
646extern int tvec_claimeq_char(struct tvec_state */*tv*/,
647 int /*ch0*/, int /*ch1*/,
648 const char */*file*/, unsigned /*lno*/,
649 const char */*expr*/);
650#define TVEC_CLAIMEQ_CHAR(tv, c0, c1) \
651 (tvec_claimeq_char(tv, c0, c1, __FILE__, __LINE__, #c0 " /= " #c1))
652
653/*----- Text and binary string types --------------------------------------*/
654
655/* A string is a sequence of octets. Text and binary strings differ
656 * primarily in presentation: text strings are shown as raw characters where
657 * possible; binary strings are shown as hex dumps with an auxiliary text
658 * display. Storage for strings always uses the standard C library
659 * allocator, though applications will probably need to call @malloc@ or
660 * @free@ only rarely.
661 *
662 * The input format for both kinds of strings is basically the same: a
663 * `compound string', consisting of
664 *
665 * * single-quoted strings, which are interpreted entirely literally, but
666 * can't contain single quotes or newlines;
667 *
668 * * double-quoted strings, in which `%|\|%'-escapes are interpreted as for
669 * characters;
670 *
671 * * character names, marked by an initial `%|#|%' sign;
672 *
673 * * special tokens marked by an initial `%|!|%' sign; or
674 *
675 * * barewords interpreted according to the current coding scheme.
676 *
677 * The special tokens are
678 *
679 * * `%|!bare|%', which causes subsequent sequences of barewords to be
680 * treated as plain text;
681 *
682 * * `%|!hex|%', `%|!base32|%', `%|!base64|%', which cause subsequent
683 * barewords to be decoded in the requested manner.
684 *
685 * * `%|!repeat|% %$n$% %|{|% %%\textit{string}%% %|}|%', which includes
686 * %$n$% copies of the (compound) string.
687 *
688 * The only difference between text and binary strings is that the initial
689 * coding scheme is %|bare|% for text strings and %|hex|% for binary strings.
690 *
691 * Either kind of string can contain internal nul characters. A trailing nul
692 * is appended -- beyond the stated input length -- to input strings as a
693 * convenience to test functions. Test functions may include such a nul
694 * character on output but this is not checked by the equality test.
695 *
696 * A @struct tvec_urange@ may be supplied as an argument: the length of the
697 * string (in bytes) will be checked against the permitted range.
698 */
699
700extern const struct tvec_regty tvty_text, tvty_bytes;
701
702/* --- @tvec_alloctext@, @tvec_allocbytes@ --- *
703 *
704 * Arguments: @union tvec_regval *rv@ = register value
705 * @size_t sz@ = required size
706 *
707 * Returns: ---
708 *
709 * Use: Allocated space in a text or binary string register. If the
710 * current register size is sufficient, its buffer is left
711 * alone; otherwise, the old buffer, if any, is freed and a
712 * fresh buffer allocated. These functions are not intended to
713 * be used to adjust a buffer repeatedly, e.g., while building
714 * output incrementally: (a) they will perform badly, and (b)
715 * the old buffer contents are simply discarded if reallocation
716 * is necessary. Instead, use a @dbuf@ or @dstr@.
717 *
718 * The @tvec_alloctext@ function sneakily allocates an extra
719 * byte for a terminating zero. The @tvec_allocbytes@ function
720 * doesn't do this.
721 */
722
723extern void tvec_alloctext(union tvec_regval */*rv*/, size_t /*sz*/);
724extern void tvec_allocbytes(union tvec_regval */*rv*/, size_t /*sz*/);
725
726/* --- @tvec_claimeq_text@, @TVEC_CLAIMEQ_TEXT@ --- *
727 *
728 * Arguments: @struct tvec_state *tv@ = test-vector state
729 * @const char *p0@, @size_t sz0@ = first string with length
730 * @const char *p1@, @size_t sz1@ = second string with length
731 * @const char *file@, @unsigned @lno@ = calling file and line
732 * @const char *expr@ = the expression to quote on failure
733 *
734 * Returns: Nonzero if the strings at @p0@ and @p1@ are equal, otherwise
735 * zero.
736 *
737 * Use: Check that strings at @p0@ and @p1@ are equal. As for
738 * @tvec_claim@ above, a test case is automatically begun and
739 * ended if none is already underway. If the values are
740 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
741 * mismatched values are dumped: @p0@ is printed as the output
742 * value and @p1@ is printed as the input reference.
743 *
744 * The @TVEC_CLAIM_TEXT@ macro is similar, only it (a)
745 * identifies the file and line number of the call site
746 * automatically, and (b) implicitly quotes the source text of
747 * the @ch0@ and @ch1@ arguments in the failure message.
748 */
749
750extern int tvec_claimeq_text(struct tvec_state */*tv*/,
751 const char */*p0*/, size_t /*sz0*/,
752 const char */*p1*/, size_t /*sz1*/,
753 const char */*file*/, unsigned /*lno*/,
754 const char */*expr*/);
755#define TVEC_CLAIMEQ_TEXT(tv, p0, sz0, p1, sz1) \
756 (tvec_claimeq_text(tv, p0, sz0, p1, sz1, __FILE__, __LINE__, \
757 #p0 "[" #sz0 "] /= " #p1 "[" #sz1 "]"))
758
759/* --- @tvec_claimeq_textz@, @TVEC_CLAIMEQ_TEXTZ@ --- *
760 *
761 * Arguments: @struct tvec_state *tv@ = test-vector state
762 * @const char *p0, *p1@ = two strings to compare
763 * @const char *file@, @unsigned @lno@ = calling file and line
764 * @const char *expr@ = the expression to quote on failure
765 *
766 * Returns: Nonzero if the strings at @p0@ and @p1@ are equal, otherwise
767 * zero.
768 *
769 * Use: Check that strings at @p0@ and @p1@ are equal, as for
770 * @tvec_claimeq_string@, except that the strings are assumed
771 * null-terminated, so their lengths don't need to be supplied
772 * explicitly. The macro is similarly like @TVEC_CLAIMEQ_TEXT@.
773 */
774
775extern int tvec_claimeq_textz(struct tvec_state */*tv*/,
776 const char */*p0*/, const char */*p1*/,
777 const char */*file*/, unsigned /*lno*/,
778 const char */*expr*/);
779#define TVEC_CLAIMEQ_TEXTZ(tv, p0, p1) \
780 (tvec_claimeq_textz(tv, p0, p1, __FILE__, __LINE__, #p0 " /= " #p1))
781
782/* --- @tvec_claimeq_bytes@, @TVEC_CLAIMEQ_BYTES@ --- *
783 *
784 * Arguments: @struct tvec_state *tv@ = test-vector state
785 * @const void *p0@, @size_t sz0@ = first string with length
786 * @const void *p1@, @size_t sz1@ = second string with length
787 * @const char *file@, @unsigned @lno@ = calling file and line
788 * @const char *expr@ = the expression to quote on failure
789 *
790 * Returns: Nonzero if the strings at @p0@ and @p1@ are equal, otherwise
791 * zero.
792 *
793 * Use: Check that binary strings at @p0@ and @p1@ are equal. As for
794 * @tvec_claim@ above, a test case is automatically begun and
795 * ended if none is already underway. If the values are
796 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
797 * mismatched values are dumped: @p0@ is printed as the output
798 * value and @p1@ is printed as the input reference.
799 *
800 * The @TVEC_CLAIM_STRING@ macro is similar, only it (a)
801 * identifies the file and line number of the call site
802 * automatically, and (b) implicitly quotes the source text of
803 * the @ch0@ and @ch1@ arguments in the failure message.
804 */
805
806extern int tvec_claimeq_bytes(struct tvec_state */*tv*/,
807 const void */*p0*/, size_t /*sz0*/,
808 const void */*p1*/, size_t /*sz1*/,
809 const char */*file*/, unsigned /*lno*/,
810 const char */*expr*/);
811#define TVEC_CLAIMEQ_BYTES(tv, p0, sz0, p1, sz1) \
812 (tvec_claimeq(tv, p0, sz0, p1, sz1, __FILE__, __LINE__, \
813 #p0 "[" #sz0 "] /= " #p1 "[" #sz1 "]"))
814
815/*----- Buffer type -------------------------------------------------------*/
816
817/* Buffer registers are primarily used for benchmarking. Only a buffer's
818 * allocation parameters are significant: its contents are ignored on
819 * comparison and output, and unspecified on input.
820 *
821 * The input format gives the buffer's size, and an optional alignment
822 * specification, in the form %|SZ [`@' M [`+' A]]|%. Each of %|SZ|%, %|M|%
823 * and %|A|% are sizes, as an integer, optionally suffixed with a unit `kB',
824 * `MB', `GB', `TB', `PB', `EB', `ZB', `YB' (with or without the `B')
825 * denoting a power of 1024. The %|SZ|% gives the (effective) buffer size.
826 * %|M|% is the `alignment quantum' and %|A|% is the `alignment offset'; both
827 * default to zero, but if %|M|% is nonzero then the start of the buffer is
828 * aligned such that it is %|A|% more than a multiple of %|M|% bytes. Note
829 * that %|M|% need not be a power of two, though this is common.
830 *
831 * Units other than `B' are used on output only when the size would be
832 * expressed exactly.
833 *
834 * Buffers are %%\emph{not}%% allocated by default. In benchmarks, this is
835 * best done in a @before@ function.
836 *
837 * No @claimeq@ functions or macros are provided for buffers because they
838 * don't seem very useful.
839 */
840
841extern const struct tvec_regty tvty_buffer;
842
843/* --- @tvec_initbuffer@ --- *
844 *
845 * Arguments: @union tvec_regval *rv@ = register value
846 * @const union tvec_regval *ref@ = reference buffer
847 * @size_t sz@ = size to allocate
848 *
849 * Returns: ---
850 *
851 * Use: Initialize the alignment parameters in @rv@ to match @ref@,
852 * and the size to @sz@.
853 */
854
855extern void tvec_initbuffer(union tvec_regval */*rv*/,
856 const union tvec_regval */*ref*/, size_t /*sz*/);
857
858/* --- @tvec_allocbuffer@ --- *
859 *
860 * Arguments: @union tvec_regval *rv@ = register value
861 *
862 * Returns: ---
863 *
864 * Use: Allocate @sz@ bytes to the buffer and fill the space with a
865 * distinctive pattern.
866 */
867
868extern void tvec_allocbuffer(union tvec_regval */*rv*/);
869
870/*----- That's all, folks -------------------------------------------------*/
871
872#ifdef __cplusplus
873 }
874#endif
875
876#endif