chiark / gitweb /
@@@ more mess
[mLib] / test / tvec.h
1 /* -*-c-*-
2  *
3  * Test vector processing framework
4  *
5  * (c) 2023 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_H
29 #define MLIB_TVEC_H
30
31 #ifdef __cplusplus
32   extern "C" {
33 #endif
34
35 /* Here's the overall flow for a testing session.
36  *
37  * @tvec_begin@
38  *                      -> output @bsession@
39  * @tvec_read@
40  *                      -> output @bgroup@
41  *                      -> env @setup@
42  *   one or more tests
43  *                      -> type @init@ (input and output)
44  *                      -> type @parse@ (input)
45  *                      -> output @btest@
46  *                      -> env @before@
47  *                              -> @tvec_skipgroup@
48  *                                      -> output @skipgroup@
49  *                      -> env @run@
50  *                              -> @tvec_skip@
51  *                                      -> output @skip@
52  *                              -> test @fn@
53  *                              -> @tvec_checkregs@
54  *                                      -> type @eq@
55  *                              -> @tvec_fail@
56  *                                      -> output @fail@
57  *                              -> @tvec_mismatch@
58  *                                      -> output @dumpreg@
59  *                                              -> type @dump@
60  *                      -> output @etest@
61  *                      -> env @after@
62  *   finally
63  *                      -> output @egroup@
64  *                      -> env @teardown@
65  *
66  * Ad-hoc testing
67  *   @tvec_begingroup@
68  *                      -> output @bgroup@
69  *                      -> env @setup@
70  *     @tvec_begintest@
71  *                      -> output @btest@
72  *     @tvec_skip@
73  *                      -> output @skip@
74  *     @tvec_claimeq@
75  *                      -> @tvec_fail@
76  *                              -> output @fail@
77  *                      -> @tvec_mismatch@
78  *                              -> output @dumpreg@
79  *                              -> type @dump@
80  *     @tvec_endtest@
81  *                      -> output @etest@
82  *     or @tvec_skipgroup@
83  *                      -> output @skipgroup@
84  * @tvec_endgroup@
85  *                      -> output @egroup@
86  *
87  * @tvec_end@
88  *                      -> output @esession@
89  *                      -> output @destroy@
90  *
91  * @tvec_benchrun@
92  *                      -> type @dump@ (compact style)
93  *                      -> output @bbench@
94  *                      -> subenv @run@
95  *                              -> test @fn@
96  *                      -> output @ebench@
97  *                              -> @tvec_benchreport@
98  *
99  * The output functions @error@ and @notice@ can be called at arbitrary
100  * times.
101  */
102
103 /*----- Header files ------------------------------------------------------*/
104
105 #include <stdarg.h>
106 #include <stddef.h>
107 #include <stdio.h>
108 #include <string.h>
109
110 #ifndef MLIB_ARENA_H
111 #  include "arena.h"
112 #endif
113
114 #ifndef MLIB_BUF_H
115 #  include "buf.h"
116 #endif
117
118 #ifndef MLIB_DSTR_H
119 #  include "dstr.h"
120 #endif
121
122 #ifndef MLIB_GPRINTF_H
123 #  include "gprintf.h"
124 #endif
125
126 #ifndef MLIB_MACROS_H
127 #  include "macros.h"
128 #endif
129
130 /*----- Miscellaneous values ----------------------------------------------*/
131
132 /* These are attached to structures which represent extension points, as a
133  * way to pass an opaque parameter to whatever things are hooked onto them.
134  */
135
136 #define TVEC_MISCSLOTS(_)                                               \
137         _(PTR, const void *, p)         /* arbitrary pointer */         \
138         _(INT, long, i)                 /* signed integer */            \
139         _(UINT, unsigned long, u)       /* signed integer */            \
140         _(FLT, double, f)               /* floating point */
141
142 union tvec_misc {
143 #define TVEC_DEFSLOT(tag, ty, slot) ty slot;
144   TVEC_MISCSLOTS(TVEC_DEFSLOT)
145 #undef TVEC_DEFSLOT
146 };
147 enum {
148 #define TVEC_DEFCONST(tag, ty, slot) TVMISC_##tag,
149   TVEC_MISCSLOTS(TVEC_DEFCONST)
150   TVMISC_LIMIT
151 };
152
153 /*----- Register values ---------------------------------------------------*/
154
155 /* The framework doesn't have a preconceived idea about what's in a register
156  * value: it just allocates them and accesses them through the register type
157  * functions.  It doesn't even have a baked-in idea of how big a register
158  * value is: instead, it gets that via the `regsz' slot in `struct
159  * tvec_testinfo'.  So, as far as the framework is concerned, it's safe to
160  * add new slots to this union, even if they make the overall union larger.
161  * This can be done by defining the preprocessor macro `TVEC_REGSLOTS' to be
162  * a `union' fragment defining any additional union members.
163  *
164  * This creates a distinction between code which does and doesn't know the
165  * size of a register value.  Code which does, which typically means the test
166  * functions, benchmarking setup and teardown functions, and tightly-bound
167  * runner functions, is free to index the register vectors directly.  Code
168  * which doesn't, which means the framework core itself and output formatting
169  * machinery, must use the `TVEC_REG' macro (or its more general `TVEC_GREG'
170  * companion) for indexing register vectors.  (In principle, register type
171  * handlers also fit into this category, but they have no business peering
172  * into register values other than the one's they're given.)
173  */
174
175 union tvec_regval {
176   /* The actual register value.  This is what the type handler sees.
177    * Additional members can be added by setting `TVEC_REGSLOTS' before
178    * including this file.
179    *
180    * A register value can be /initialized/, which simply means that its
181    * contents represent a valid value according to its type -- the register
182    * can be compared, dumped, serialized, parsed into, etc.  You can't do
183    * anything safely to an uninitialized register value other than initialize
184    * it.
185    */
186
187   long i;                               /* signed integer */
188   unsigned long u;                      /* unsigned integer */
189   void *p;                              /* pointer */
190   double f;                             /* floating point */
191   struct { char *p; size_t sz; } text;  /* text string */
192   struct { unsigned char *p; size_t sz; } bytes; /* binary string of bytes */
193   struct {                              /* buffer */
194     unsigned char *p; size_t sz;        /* binary string */
195     size_t a, m;                        /* residue and modulus */
196     size_t off;                         /* offset into full buffer */
197   } buf;
198 #ifdef TVEC_REGSLOTS
199   TVEC_REGSLOTS
200 #endif
201 };
202
203 struct tvec_reg {
204   /* A register.
205    *
206    * Note that all of the registers listed as being used by a particular test
207    * group are initialized at all times[1] while that test group is being
208    * processed.  (The other register slots don't even have types associated
209    * with them, so there's nothing useful we could do with them.)
210    *
211    * The `TVRF_LIVE' flag indicates that the register was assigned a value by
212    * the test vector file: it's the right thing to use to check whether an
213    * optional register is actually present.  Even `dead' registers are still
214    * initialized, though.
215    *
216    * [1] This isn't quite true.  Between individual tests, the registers are
217    *     released and reinitialized in order to reset them to known values
218    *     ready for the next test.  But you won't see them at this point.
219    */
220
221   unsigned f;                           /* flags */
222 #define TVRF_SEEN 1u                    /*   assignment seen in file  */
223 #define TVRF_LIVE 2u                    /*   used in current test  */
224   union tvec_regval v;                  /* register value */
225 };
226
227 struct tvec_regdef {
228   /* A register definition.  Register definitions list the registers which
229    * are used by a particular test group (see `struct tvec_test' below).
230    *
231    * A vector of register definitions is terminated by a definition whose
232    * `name' slot is null.
233    */
234
235   const char *name;                     /* register name (for input files) */
236   const struct tvec_regty *ty;          /* register type descriptor */
237   unsigned i;                           /* register index */
238   unsigned f;                           /* flags */
239 #define TVRF_UNSET 1u                   /*   register may be marked unset */
240 #define TVRF_OPT 2u                     /*   register need not be assigned */
241 #define TVRF_SYNTH 4u                   /*   register must not be assigned */
242 #define TVRF_ID 8u                      /*   part of test identity  */
243   union tvec_misc arg;                  /* extra detail for the type */
244 };
245 #define TVEC_ENDREGS { 0, 0, 0, 0, { 0 } }
246
247 /* @TVEC_GREG(vec, i, regsz)@
248  *
249  * If @vec@ is a data pointer which happens to contain the address of a
250  * vector of @struct tvec_reg@ objects, @i@ is an integer, and @regsz@ is the
251  * size of a @struct tvec_reg@, then this evaluates to the address of the
252  * @i@th element of the vector.
253  *
254  * This is the general tool you need for accessing register vectors when you
255  * don't have absolute knowledge of the size of a @union tvec_regval@.
256  * Usually you want to access one of the register vectors in a @struct
257  * tvec_state@, and @TVEC_REG@ will be more convenient.
258  */
259 #define TVEC_GREG(vec, i, regsz)                                        \
260         ((struct tvec_reg *)((unsigned char *)(vec) + (i)*(regsz)))
261
262 /*----- Register types ----------------------------------------------------*/
263
264 struct tvec_state;                      /* forward declaration */
265
266 struct tvec_regty {
267   /* A register type. */
268
269   void (*init)(union tvec_regval */*rv*/, const struct tvec_regdef */*rd*/);
270     /* Initialize the value in @*rv@.  This will be called before any other
271      * function acting on the value, including @release@.  Following @init@,
272      * the register value must be valid to use for all other type entry
273      * points.
274      */
275
276   void (*release)(union tvec_regval */*rv*/,
277                   const struct tvec_regdef */*rd*/);
278     /* Release any resources associated with the value in @*rv@.  The
279      * register value may be left in an invalid state.
280      */
281
282   int (*eq)(const union tvec_regval */*rv0*/,
283             const union tvec_regval */*rv1*/,
284             const struct tvec_regdef */*rd*/);
285     /* Return nonzero if @*rv0@ and @*rv1@ are equal values.  Asymmetric
286      * criteria are permitted: @tvec_checkregs@ calls @eq@ with the input
287      * register as @rv0@ and the output as @rv1@.
288      */
289
290   void (*copy)(union tvec_regval */*rvd*/,
291                const union tvec_regval */*rvs*/,
292                const struct tvec_regdef */*rd*/);
293     /* Copy the value from @rvs@ to @rvd@. */
294
295   int (*tobuf)(buf */*b*/, const union tvec_regval */*rv*/,
296                const struct tvec_regdef */*rd*/);
297     /* Serialize the value @*rv@, writing the result to @b@.  Return zero on
298      * success, or %$-1$% on error.
299      */
300
301   int (*frombuf)(buf */*b*/, union tvec_regval */*rv*/,
302                  const struct tvec_regdef */*rd*/);
303     /* Deserialize a value from @b@, storing it in @*rv@.  Return zero on
304      * success, or %$-1$% on error.
305      */
306
307   int (*parse)(union tvec_regval */*rv*/, const struct tvec_regdef */*rd*/,
308                struct tvec_state */*tv*/);
309     /* Parse a value from @tv->fp@, storing it in @*rv@.  Return zero on
310      * success, or %$-1$% on error, having reported one or more errors via
311      * @tvec_error@ or @tvec_syntax@.  If @TVSF_NEXT@ is not set on exit,
312      * then the caller will advance to the start of the next non-continuation
313      * line, reporting an error it any non-whitespace non-comment material
314      * found following a successful return.
315      */
316
317   void (*dump)(const union tvec_regval */*rv*/,
318                const struct tvec_regdef */*rd*/,
319                unsigned /*style*/,
320                const struct gprintf_ops */*gops*/, void */*go*/);
321 #define TVSF_COMPACT 1u
322 #define TVSF_RAW 2u
323     /* Write a human-readable representation of the value @*rv@ using
324      * @gprintf@ on @gops@ and @go@.  The @style@ is a collection of flags:
325      * if @TVSF_COMPACT@ is set, then output should be minimal, and must fit
326      * on a single line; otherwise, output may consist of multiple lines and
327      * may contain redundant information if that is likely to be useful to a
328      * human reader.  If @TVSF_RAW@ is set, then output should prefer
329      * machine-readability over human-readability.
330      */
331 };
332
333 /*----- Test descriptions -------------------------------------------------*/
334
335 struct tvec_env;
336
337 typedef void tvec_testfn(const struct tvec_reg */*in*/,
338                          struct tvec_reg */*out*/,
339                          void */*ctx*/);
340   /* A test function.  It should read inputs from @in@ and write outputs to
341    * @out@.  The @TVRF_LIVE@ is set on inputs which are actually present, and
342    * on outputs which are wanted to test.  A test function can set additional
343    * `gratuitous outputs' by setting @TVRF_LIVE@ on them; clearing
344    * @TVRF_LIVE@ on a wanted output causes a mismatch.
345    *
346    * A test function may be called zero or more times by the environment.  In
347    * particular, it may be called multiple times, though usually by prior
348    * arrangement with the environment.
349    *
350    * The @ctx@ is supplied by the environment's @run@ function (see below).
351    * The default environment calls the test function once, with a null
352    * @ctx@.  There is no expectation that the environment's context has
353    * anything to do with the test function's context.
354    */
355
356 typedef int tvec_setvarfn(struct tvec_state */*tv*/, const char */*var*/,
357                           const union tvec_regval */*rv*/, void */*ctx*/);
358   /* Called after a variable is read.  Return zero on success or %$-1$% on
359    * error.  This function is never called if the test group is skipped.
360    */
361
362 struct tvec_vardef {
363   size_t regsz;                         /* (minimum) register size */
364   tvec_setvarfn *setvar;                /* function to set variable */
365   struct tvec_regdef def;               /* register definition */
366 };
367
368 typedef void tvec_envsetupfn(struct tvec_state */*tv*/,
369                              const struct tvec_env */*env*/,
370                              void */*pctx*/, void */*ctx*/);
371   /* Initialize the context; called at the start of a test group; @pctx@ is
372    * null for environments called by the core, but may be non-null for
373    * subordinate environments.  If setup fails, the function should call
374    * @tvec_skipgroup@ with a suitable excuse.  The @set@, @after@, and
375    * @teardown@ entry points will still be called, but @before@ and @run@
376    * will not.
377    */
378
379 typedef const struct tvec_vardef *tvec_envfindvarfn
380   (struct tvec_state */*tv*/, const char */*name*/,
381    void **/*ctx_out*/, void */*ctx*/);
382   /* Called when the parser finds a %|@var|%' special variable.  If a
383    * suitable variable was found, set @*ctx_out@ to a suitable context and
384    * return the variable definition; the context will be passed to the
385    * variable definition's @setvar@ function.  If no suitable variable was
386    * found, then return null.
387    */
388
389 typedef void tvec_envbeforefn(struct tvec_state */*tv*/, void */*ctx*/);
390   /* Called prior to running a test.  This is the right place to act on any
391    * `%|@var|%' settings.  If preparation fails, the function should call
392    * @tvec_skip@ with a suitable excuse.  This function is never called if
393    * the test group is skipped.  It %%\emph{is}%% called if the test will be
394    * skipped due to erroneous test data.  It should check the @TVSF_ACTIVE@
395    * flag if necessary.
396    */
397
398 typedef void tvec_envrunfn(struct tvec_state */*tv*/,
399                            tvec_testfn */*fn*/, void */*ctx*/);
400   /* Run the test.  It should either call @tvec_skip@, or run @fn@ one or
401    * more times.  In the latter case, it is responsible for checking the
402    * outputs, and calling @tvec_fail@ as necessary; @tvec_checkregs@ will
403    * check the register values against the supplied test vector, while
404    * @tvec_check@ does pretty much everything necessary.  This function is
405    * never called if the test group is skipped.
406    */
407
408 typedef void tvec_envafterfn(struct tvec_state */*tv*/, void */*ctx*/);
409   /* Called after running or skipping a test.  Typical actions involve
410    * resetting whatever things were established by @set@.  This function
411    * %%\emph{is}%% called if the test group is skipped or the test data is
412    * erroneous, so that the test environment can reset variables set by the
413    * @set@ entry point.  It should check the @TVSF_SKIP@ flag if necessary.
414    */
415
416 typedef void tvec_envteardownfn(struct tvec_state */*tv*/, void */*ctx*/);
417   /* Tear down the environment: called at the end of a test group. */
418
419 struct tvec_env {
420   /* A test environment sets things up for and arranges to run the test.
421    *
422    * The caller is responsible for allocating storage for the environment's
423    * context, based on the @ctxsz@ slot, and freeing it later; this space is
424    * passed in as the @ctx@ parameter to the remaining functions; if @ctxsz@
425    * is zero then @ctx@ is null.
426    */
427
428   size_t ctxsz;                         /* environment context size */
429
430   tvec_envsetupfn *setup;               /* setup for group */
431   tvec_envfindvarfn *findvar;           /* find variable */
432   tvec_envbeforefn *before;             /* prepare for test */
433   tvec_envrunfn *run;                   /* run test function */
434   tvec_envafterfn *after;               /* clean up after test */
435   tvec_envteardownfn *teardown;         /* tear down after group */
436 };
437
438 struct tvec_test {
439   /* A test description. */
440
441   const char *name;                     /* name of the test */
442   const struct tvec_regdef *regs;       /* descriptions of the registers */
443   const struct tvec_env *env;           /* environment to run test in */
444   tvec_testfn *fn;                      /* test function */
445 };
446
447 struct tvec_config {
448   /* An overall test configuration. */
449
450   const struct tvec_test *const *tests; /* the tests to be performed */
451   unsigned nrout, nreg;                 /* number of output/total regs */
452   size_t regsz;                         /* size of a register */
453 };
454
455 /*----- Test state --------------------------------------------------------*/
456
457 struct tvec_output;
458
459 enum {
460   /* Possible test outcomes. */
461
462   TVOUT_LOSE,                           /* test failed */
463   TVOUT_SKIP,                           /* test skipped */
464   TVOUT_XFAIL,                          /* test passed, but shouldn't have */
465   TVOUT_WIN,                            /* test passed */
466   TVOUT_LIMIT                           /* (number of possible outcomes) */
467 };
468
469 struct tvec_state {
470   /* The primary state structure for the test vector machinery. */
471
472   /* Flags.  Read-only for all callers. */
473   unsigned f;                           /* flags */
474 #define TVSF_SKIP 0x0001u               /*   skip this test group */
475 #define TVSF_OPEN 0x0002u               /*   test is open */
476 #define TVSF_ACTIVE 0x0004u             /*   test is active */
477 #define TVSF_ERROR 0x0008u              /*   an error occurred */
478 #define TVSF_OUTMASK 0x00f0u            /*   test outcome (@TVOUT_...@) */
479 #define TVSF_OUTSHIFT 4                 /*   shift applied to outcome */
480 #define TVSF_XFAIL 0x0100u              /*   test expected to fail */
481 #define TVSF_MUFFLE 0x0200u             /*   muffle errors */
482 #define TVSF_NEXT 0x0400u               /*   input at next definition */
483
484   /* Memory allocation.  Read-only for all callers. */
485   arena *a;
486
487   /* Test configuration.  Read-only for all callers. */
488   struct tvec_config cfg;               /* test configuration */
489
490   /* Registers.  Available to execution environments, which may modify the
491    * contents of the active registers, as defined by the current test group,
492    * but not the vector pointers themselves or inactive registers.
493    */
494   struct tvec_reg *in, *out;            /* register vectors */
495
496   /* Test group state.  Read-only for all callers. */
497   const struct tvec_test *test;         /* current test */
498
499   /* Test scoreboard.  Available to output formatters. */
500   unsigned curr[TVOUT_LIMIT], all[TVOUT_LIMIT], grps[TVOUT_LIMIT];
501
502   /* Output machinery.  Read-only for environments. */
503   struct tvec_output *output;           /* output formatter */
504
505   /* Input machinery.  Available to type parsers. */
506   const char *infile; unsigned lno, test_lno; /* input file name, line */
507   FILE *fp;                             /* input file stream */
508
509   /* Adhoc testing state.  Private. */
510   struct tvec_test adhoc_test;
511   const struct tvec_test *adhoc_tests[];
512 };
513
514 /* @TVEC_REG(tv, vec, i)@
515  *
516  * If @tv@ is a pointer to a @struct tvec_state@, @vec@ is either @in@ or
517  * @out@, and @i@ is an integer, then this evaluates to the address of the
518  * @i@th register in the selected vector.
519  */
520 #define TVEC_REG(tv, vec, i) TVEC_GREG((tv)->vec, (i), (tv)->cfg.regsz)
521
522 /*----- Session lifecycle -------------------------------------------------*/
523
524 /* --- @tvec_begin@ --- *
525  *
526  * Arguments:   @struct tvec_state *tv_out@ = state structure to fill in
527  *              @const struct tvec_config *config@ = test configuration
528  *              @struct tvec_output *o@ = output driver
529  *
530  * Returns:     ---
531  *
532  * Use:         Initialize a state structure ready to do some testing.  The
533  *              test state takes ownership of the output driver: @tvec_end@
534  *              will destroy it.
535  */
536
537 extern void tvec_begin(struct tvec_state */*tv_out*/,
538                        const struct tvec_config */*config*/,
539                        struct tvec_output */*o*/);
540
541 /* --- @tvec_end@ --- *
542  *
543  * Arguments:   @struct tvec_state *tv@ = test-vector state
544  *
545  * Returns:     A proposed exit code.
546  *
547  * Use:         Conclude testing and suggests an exit code to be returned to
548  *              the calling program.  (The exit code comes from the output
549  *              driver's @esession@ method.)  The output driver, originally
550  *              passed to @tvec_begin@ is destroyed.
551  */
552
553 extern int tvec_end(struct tvec_state */*tv*/);
554
555 /* --- @tvec_read@ --- *
556  *
557  * Arguments:   @struct tvec_state *tv@ = test-vector state
558  *              @const char *infile@ = the name of the input file
559  *              @FILE *fp@ = stream to read from
560  *
561  * Returns:     Zero on success, %$-1$% on error.
562  *
563  * Use:         Read test vector data from @fp@ and exercise test functions.
564  *              THe return code doesn't indicate test failures: it's only
565  *              concerned with whether there were problems with the input
566  *              file or with actually running the tests.
567  */
568
569 extern int tvec_read(struct tvec_state */*tv*/,
570                      const char */*infile*/, FILE */*fp*/);
571
572 /*----- Command-line interface --------------------------------------------*/
573
574 /* --- @tvec_parseargs@ --- *
575  *
576  * Arguments:   @int argc@ = number of command-line arguments
577  *              @char *argv[]@ = vector of argument strings
578  *              @struct tvec_state *tv_out@ = test vector state to initialize
579  *              @int *argpos_out@ = where to leave unread argument index
580  *              @const struct tvec_config *config@ = test vector
581  *                      configuration
582  *
583  * Returns:     ---
584  *
585  * Use:         Parse arguments and set up the test vector state @*tv_out@.
586  *              If errors occur, print messages to standard error and exit
587  *              with status 2.
588  */
589
590 extern void tvec_parseargs(int /*argc*/, char */*argv*/[],
591                            struct tvec_state */*tv_out*/,
592                            int */*argpos_out*/,
593                            const struct tvec_config */*config*/);
594
595 /* --- @tvec_readstdin@, @tvec_readfile@, @tvec_readarg@ --- *
596  *
597  * Arguments:   @struct tvec_state *tv@ = test vector state
598  *              @const char *file@ = pathname of file to read
599  *              @const char *arg@ = argument to interpret
600  *
601  * Returns:     Zero on success, %$-1$% on error.
602  *
603  * Use:         Read test vector data from stdin or a named file.  The
604  *              @tvec_readarg@ function reads from stdin if @arg@ is `%|-|%',
605  *              and from the named file otherwise.
606  */
607
608 extern int tvec_readstdin(struct tvec_state */*tv*/);
609 extern int tvec_readfile(struct tvec_state */*tv*/, const char */*file*/);
610 extern int tvec_readarg(struct tvec_state */*tv*/, const char */*arg*/);
611
612 /* --- @tvec_readdflt@ --- *
613  *
614  * Arguments:   @struct tvec_state *tv@ = test vector state
615  *              @const char *dflt@ = defsault filename or null
616  *
617  * Returns:     Zero on success, %$-1$% on error.
618  *
619  * Use:         Reads from the default test vector data.  If @file@ is null,
620  *              then read from standard input, unless that's a terminal; if
621  *              @file@ is not null, then read the named file, looking in the
622  *              directory named by the `%|srcdir|%' environment variable if
623  *              that's set, or otherwise in the current directory.
624  */
625
626 extern int tvec_readdflt(struct tvec_state */*tv*/, const char */*file*/);
627
628 /* --- @tvec_readargs@ --- *
629  *
630  * Arguments:   @int argc@ = number of command-line arguments
631  *              @char *argv[]@ = vector of argument strings
632  *              @struct tvec_state *tv@ = test vector state
633  *              @int *argpos_inout@ = current argument position (updated)
634  *              @const char *dflt@ = default filename or null
635  *
636  * Returns:     Zero on success, %$-1$% on error.
637  *
638  * Use:         Reads from the sources indicated by the command-line
639  *              arguments, in order, interpreting each as for @tvec_readarg@;
640  *              if no arguments are given then read from @dflt@ as for
641  *              @tvec_readdflt@.
642  */
643
644 extern int tvec_readargs(int /*argc*/, char */*argv*/[],
645                          struct tvec_state */*tv*/,
646                          int */*argpos_inout*/, const char */*dflt*/);
647
648 /* --- @tvec_main@ --- *
649  *
650  * Arguments:   @int argc@ = number of command-line arguments
651  *              @char *argv[]@ = vector of argument strings
652  *              @const struct tvec_config *config@ = test vector
653  *                      configuration
654  *              @const char *dflt@ = default filename or null
655  *
656  * Returns:     Exit code.
657  *
658  * Use:         All-in-one test vector front-end.  Parse options from the
659  *              command-line as for @tvec_parseargs@, and then process the
660  *              remaining positional arguments as for @tvec_readargs@.  The
661  *              function constructs and disposes of a test vector state.
662  */
663
664 extern int tvec_main(int /*argc*/, char */*argv*/[],
665                      const struct tvec_config */*config*/,
666                      const char */*dflt*/);
667
668 /*----- Test processing ---------------------------------------------------*/
669
670 /* --- @tvec_skipgroup@, @tvec_skipgroup_v@ --- *
671  *
672  * Arguments:   @struct tvec_state *tv@ = test-vector state
673  *              @const char *excuse@, @va_list *ap@ = reason why skipped
674  *
675  * Returns:     ---
676  *
677  * Use:         Skip the current group.  This should only be called from a
678  *              test environment @setup@ function; a similar effect occurs if
679  *              the @setup@ function fails.
680  */
681
682 extern PRINTF_LIKE(2, 3)
683   void tvec_skipgroup(struct tvec_state */*tv*/,
684                       const char */*excuse*/, ...);
685 extern void tvec_skipgroup_v(struct tvec_state */*tv*/,
686                              const char */*excuse*/, va_list */*ap*/);
687
688 /* --- @tvec_skip@, @tvec_skip_v@ --- *
689  *
690  * Arguments:   @struct tvec_state *tv@ = test-vector state
691  *              @const char *excuse@, @va_list *ap@ = reason why test skipped
692  *
693  * Returns:     ---
694  *
695  * Use:         Skip the current test.  This should only be called from a
696  *              test environment @run@ function; a similar effect occurs if
697  *              the @before@ function fails.
698  */
699
700 extern PRINTF_LIKE(2, 3)
701   void tvec_skip(struct tvec_state */*tv*/, const char */*excuse*/, ...);
702 extern void tvec_skip_v(struct tvec_state */*tv*/,
703                         const char */*excuse*/, va_list */*ap*/);
704
705 /* --- @tvec_fail@, @tvec_fail_v@ --- *
706  *
707  * Arguments:   @struct tvec_state *tv@ = test-vector state
708  *              @const char *detail@, @va_list *ap@ = description of test
709  *
710  * Returns:     ---
711  *
712  * Use:         Report the current test as a failure.  This function can be
713  *              called multiple times for a single test, e.g., if the test
714  *              environment's @run@ function invokes the test function
715  *              repeatedly; but a single test that fails repeatedly still
716  *              only counts as a single failure in the statistics.  The
717  *              @detail@ string and its format parameters can be used to
718  *              distinguish which of several invocations failed; it can
719  *              safely be left null if the test function is run only once.
720  */
721
722 extern PRINTF_LIKE(2, 3)
723   void tvec_fail(struct tvec_state */*tv*/, const char */*detail*/, ...);
724 extern void tvec_fail_v(struct tvec_state */*tv*/,
725                         const char */*detail*/, va_list */*ap*/);
726
727 /* --- @tvec_dumpreg@ --- *
728  *
729  * Arguments:   @struct tvec_state *tv@ = test-vector state
730  *              @unsigned disp@ = the register disposition (@TVRD_...@)
731  *              @const union tvec_regval *tv@ = register value, or null
732  *              @const struct tvec_regdef *rd@ = register definition
733  *
734  * Returns:     ---
735  *
736  * Use:         Dump a register value to the output.  This is the lowest-
737  *              level function for dumping registers, and calls the output
738  *              formatter directly.
739  *
740  *              Usually @tvec_mismatch@ is much more convenient.  Low-level
741  *              access is required for reporting `virtual' registers
742  *              corresponding to test environment settings.
743  */
744
745 extern void tvec_dumpreg(struct tvec_state */*tv*/,
746                          unsigned /*disp*/, const union tvec_regval */*rv*/,
747                          const struct tvec_regdef */*rd*/);
748
749 /* --- @tvec_initregs@, @tvec_releaseregs@ --- *
750  *
751  * Arguments:   @struct tvec_state *tv@ = test-vector state
752  *
753  * Returns:     ---
754  *
755  * Use:         Initialize or release, respectively, the registers required
756  *              by the current test.  All of the registers, both input and
757  *              output, are effected.  Initialized registers are not marked
758  *              live.
759  */
760
761 extern void tvec_initregs(struct tvec_state */*tv*/);
762 extern void tvec_releaseregs(struct tvec_state */*tv*/);
763
764 /* --- @tvec_resetoutputs@ --- *
765  *
766  * Arguments:   @struct tvec_state *tv@ = test-vector state
767  *
768  * Returns:     ---
769  *
770  * Use:         Reset (releases and reinitializes) the output registers in
771  *              the test state.  This is mostly of use to test environment
772  *              @run@ functions, between invocations of the test function.
773  *              Output registers are marked live if and only if the
774  *              corresponding input register is live.
775  */
776
777 extern void tvec_resetoutputs(struct tvec_state */*tv*/);
778
779 /* --- @tvec_checkregs@ --- *
780  *
781  * Arguments:   @struct tvec_state *tv@ = test-vector state
782  *
783  * Returns:     Zero on success, %$-1$% on mismatch.
784  *
785  * Use:         Compare the active output registers (according to the current
786  *              test group definition) with the corresponding input register
787  *              values.  A mismatch occurs if the two values differ
788  *              (according to the register type's @eq@ method), or if the
789  *              input is live but the output is dead.
790  *
791  *              This function only checks for a mismatch and returns the
792  *              result; it takes no other action.  In particular, it doesn't
793  *              report a failure, or dump register values.
794  */
795
796 extern int tvec_checkregs(struct tvec_state */*tv*/);
797
798 /* --- @tvec_mismatch@ --- *
799  *
800  * Arguments:   @struct tvec_state *tv@ = test-vector state
801  *              @unsigned f@ = flags (@TVMF_...@)
802  *
803  * Returns:     ---
804  *
805  * Use:         Dumps registers suitably to report a mismatch.  The flag bits
806  *              @TVMF_IN@ and @TVF_OUT@ select input-only and output
807  *              registers.  If both are reset then nothing happens.
808  *              Suppressing the output registers may be useful, e.g., if the
809  *              test function crashed rather than returning outputs.
810  */
811
812 #define TVMF_IN 1u
813 #define TVMF_OUT 2u
814 extern void tvec_mismatch(struct tvec_state */*tv*/, unsigned /*f*/);
815
816 /* --- @tvec_check@, @tvec_check_v@ --- *
817  *
818  * Arguments:   @struct tvec_state *tv@ = test-vector state
819  *              @const char *detail@, @va_list *ap@ = description of test
820  *
821  * Returns:     ---
822  *
823  * Use:         Check the register values, reporting a failure and dumping
824  *              the registers in the event of a mismatch.  This just wraps up
825  *              @tvec_checkregs@, @tvec_fail@ and @tvec_mismatch@ in the
826  *              obvious way.
827  */
828
829 extern PRINTF_LIKE(2, 3)
830   void tvec_check(struct tvec_state */*tv*/, const char */*detail*/, ...);
831 extern void tvec_check_v(struct tvec_state */*tv*/,
832                          const char */*detail*/, va_list */*ap*/);
833
834 /*----- Output functions --------------------------------------------------*/
835
836 /* --- @tvec_strlevel@ --- *
837  *
838  * Arguments:   @unsigned level@ = level code
839  *
840  * Returns:     A human-readable description.
841  *
842  * Use:         Converts a level code into something that you can print in a
843  *              message.
844  */
845
846 extern const char *tvec_strlevel(unsigned /*level*/);
847
848 /* --- @tvec_report@, @tvec_report_v@ --- *
849  *
850  * Arguments:   @struct tvec_state *tv@ = test-vector state
851  *              @const char *msg@, @va_list *ap@ = error message
852  *
853  * Returns:     ---
854  *
855  * Use:         Report an message with a given severity.  Messages with level
856  *              @TVLEV_ERR@ or higher force a nonzero exit code.
857  */
858
859 #define TVEC_LEVELS(_)                                                  \
860         _(INFO, "info", 3)                                              \
861         _(NOTE, "notice", 4)                                            \
862         _(ERR, "ERROR", 7)
863 enum {
864 #define TVEC_DEFLEVEL(tag, name, val) TVLEV_##tag = val,
865   TVEC_LEVELS(TVEC_DEFLEVEL)
866 #undef TVEC_DEFLEVEL
867   TVLEV_LIMIT
868 };
869
870 extern PRINTF_LIKE(3, 4)
871   void tvec_report(struct tvec_state */*tv*/, unsigned /*level*/,
872                    const char */*msg*/, ...);
873 extern void tvec_report_v(struct tvec_state */*tv*/, unsigned /*level*/,
874                           const char */*msg*/, va_list */*ap*/);
875
876 /* --- @tvec_error@, @tvec_notice@, @tvec_info@ --- *
877  *
878  * Arguments:   @struct tvec_state *tv@ = test-vector state
879  *              @const char *msg@, @va_list *ap@ = error message
880  *
881  * Returns:     The @tvec_error@ function returns %$-1$% as a trivial
882  *              convenience; @tvec_notice@ does not return a value.
883  *
884  * Use:         Report a message.  Errors are distinct from test
885  *              failures, and indicate that a problem was encountered which
886  *              compromised the activity of testing.  Notices are important
887  *              information which doesn't fit into any other obvious
888  *              category.  Information is anything else, and is a reasonable
889  *              fallback for writing unstructured information in the absence
890  *              of dedicated support in an output driver.
891  *
892  *              These functions are simple convenience wrappers around
893  *              @tvec_report@.  Use @tvec_report_v@ directly if you have a
894  *              captured @va_list@ of arguments to format.
895  */
896
897 extern PRINTF_LIKE(2, 3)
898   int tvec_error(struct tvec_state */*tv*/, const char */*msg*/, ...);
899 extern PRINTF_LIKE(2, 3)
900   void tvec_notice(struct tvec_state */*tv*/, const char */*msg*/, ...);
901 extern PRINTF_LIKE(2, 3)
902   void tvec_info(struct tvec_state */*tv*/, const char */*msg*/, ...);
903
904 /* --- @tvec_unkregerr@, @tvec_dupregerr@, @tvec_synthregerr@ --- *
905  *
906  * Arguments:   @struct tvec_state *tv@ = test-vector state
907  *              @const char *name@ = register or pseudoregister name
908  *
909  * Returns:     %$-1$%.
910  *
911  * Use:         Reports an error about a misused register: @tvec_unkregerr@
912  *              reports that the register is unknown, @tvec_dupregerr@ that
913  *              it is already assigned, and @tvec_synthregerr@ that it is
914  *              synthetic.
915  */
916
917 extern int tvec_unkregerr(struct tvec_state */*tv*/, const char */*name*/);
918 extern int tvec_dupregerr(struct tvec_state */*tv*/, const char */*name*/);
919 extern int tvec_synthregerr(struct tvec_state */*tv*/, const char */*name*/);
920
921 /*----- Built-in output drivers -------------------------------------------*/
922
923 /* --- @tvec_humanoutput@ --- *
924  *
925  * Arguments:   @FILE *fp@ = output file to write on
926  *              @unsigned f, m@ = flags and mask
927  *
928  * Returns:     An output formatter.
929  *
930  * Use:         Return an output formatter which writes on @fp@ with the
931  *              expectation that a human will interpret the output.
932  *
933  *              The flags @f@ and mask @m@ operate together.  Flag bits not
934  *              covered by the mask must be left clear, i.e., @f&~m$ must be
935  *              zero; the semantics are that a set mask bit indicates that
936  *              the corresponding bit of @f@ should control the indicated
937  *              behaviour; a clear mask bit indicates that a suitable default
938  *              should be chosen based on environmental conditions.
939  *
940  *              If @TVHF_TTY@ is set, then the output shows a `scoreboard'
941  *              indicating the outcome of each test case attempted, providing
942  *              a visual indication of progress.  If @TVHF_COLOUR@ is set,
943  *              then the output uses control codes for colour and other
944  *              highlighting.  It is unusual to set @TVHF_COLOUR@ without
945  *              @TVHF_TTY@, this is permitted anyway.
946  *
947  *              The environment variables %|TVEC_TTY|% and %|TVEC_COLOUR|%
948  *              provide default values for these settings.  If they are not
949  *              set, then @TVHF_TTY@ is set if @fp@ refers to a terminal, and
950  *              @TVHF_COLOUR@ is set if @TVHF_TTY@ is set and, additionally,
951  *              the %|TERM|% environment variable is set to a value other
952  *              than %|dumb|%.
953  */
954
955 #define TVHF_TTY 1u                     /*   output to terminal */
956 #define TVHF_COLOUR 2u                  /*   output in colour */
957 extern struct tvec_output *tvec_humanoutput(FILE */*fp*/,
958                                             unsigned /*f*/, unsigned /*m*/);
959
960 /* --- @tvec_machineoutput@ --- *
961  *
962  * Arguments:   @FILE *fp@ = output file to write on
963  *
964  * Returns:     An output formatter.
965  *
966  * Use:         Return an output formatter which writes on @fp@ in a
967  *              moderately simple machine-readable format.
968  */
969
970 struct tvec_output *tvec_machineoutput(FILE *fp);
971
972 /* --- @tvec_tapoutput@ --- *
973  *
974  * Arguments:   @FILE *fp@ = output file to write on
975  *              @unsigned style@ = output style (@TVSF_...@)
976  *
977  * Returns:     An output formatter.
978  *
979  * Use:         Return an output formatter which writes on @fp@ in `TAP'
980  *              (`Test Anything Protocol') format.
981  *
982  *              TAP comes from the Perl community, but has spread rather
983  *              further.  This driver currently produces TAP version 14, but
984  *              pretends to be version 13.  The driver produces a TAP `test
985  *              point' -- i.e., a result reported as `ok' or `not ok' -- for
986  *              each input test group.  Failure reports and register dumps
987  *              are produced as diagnostic messages before the final group
988  *              result.  (TAP permits structuerd YAML data after the
989  *              test-point result, which could be used to report details, but
990  *              (a) postponing the details until after the report is
991  *              inconvenient, and (b) there is no standardization for the
992  *              YAML anyway, so in practice it's no more useful than the
993  *              unstructured diagnostics.
994  */
995
996 extern struct tvec_output *tvec_tapoutput(FILE */*fp*/);
997
998 /* --- @tvec_dfltoutput@ --- *
999  *
1000  * Arguments:   @FILE *fp@ = output file to write on
1001  *
1002  * Returns:     An output formatter.
1003  *
1004  * Use:         Selects and instantiates an output formatter suitable for
1005  *              writing on @fp@.  The policy is subject to change, but
1006  *              currently the `human' output format is selected if @fp@ is
1007  *              interactive (i.e., if @isatty(fileno(fp))@ is true), and
1008  *              otherwise the `machine' format is used.
1009  */
1010
1011 extern struct tvec_output *tvec_dfltoutput(FILE */*fp*/);
1012
1013 /* --- @tvec_amoutput@ --- *
1014  *
1015  * Arguments:   @const struct tvec_amargs *a@ = arguments from Automake
1016  *                      command-line protocol
1017  *
1018  * Returns:     An output formatter.
1019  *
1020  * Use:         Returns an output formatter which writes on standard output
1021  *              in human format, pretending that the output is to a terminal
1022  *              (in order to cope with %%\manpage{make}{1}%%'s output-
1023  *              buffering behaviour, writes to the log file @a->log@ in
1024  *              machine-readable format, and writes an Automake rST-format
1025  *              test result file to @a->trs@.  The `test name' is currently
1026  *              ignored, because the framework has its own means of
1027  *              determining test names.
1028  */
1029
1030 struct tvec_amargs {
1031   unsigned f;                           /* flags */
1032 #define TVAF_COLOUR 1u                  /*   produce colour output */
1033   const char *name;                     /* test name */
1034   FILE *log;                            /* `log' output file */
1035   FILE *trs;                            /* `trs' summary file */
1036 };
1037
1038 extern struct tvec_output *tvec_amoutput(const struct tvec_amargs */*a*/);
1039
1040 /*------ Serialization utilities ------------------------------------------*/
1041
1042 /* Serialization format.
1043  *
1044  * The `candidate register definitions' are those entries @r@ in the @regs@
1045  * vector whose index @r.i@ is strictly less than @nr@ and where
1046  * @r.f&mask == want@* .  The `selected register definitions' are those
1047  * candidate register definitions @r@ for which the indicated register
1048  * @rv[r.i]@ has the @TVRF_LIVE@ flag set.  The serialized output begins with
1049  * a header bitmap: if there are %$n$% candidate register definitions then
1050  * the header bitmap consists of %$\lceil n/8 \rceil$% bytes.  Bits are
1051  * ordered starting from the least significant bit of the first byte, end
1052  * ending at the most significant bit of the final byte.  The bit
1053  * corresponding to a candidate register definition is set if and only if
1054  * that register defintion is selected.  The header bitmap is then followed
1055  * by the serializations of the selected registers -- i.e., for each selected
1056  * register definition @r@, the serialized value of register @rv[r.i]@ --
1057  * simply concatenated together, with no padding or alignment.
1058  */
1059
1060 /* --- @tvec_serialize@ --- *
1061  *
1062  * Arguments:   @const struct tvec_reg *rv@ = vector of registers
1063  *              @buf *b@ = buffer to write on
1064  *              @const struct tvec_regdef *regs@ = vector of register
1065  *                      descriptions, terminated by an entry with a null
1066  *                      @name@ slot
1067  *              @unsigned mask, want@ = flag-based selection
1068  *              @unsigned nr@ = number of entries in the @rv@ vector
1069  *              @size_t regsz@ = true size of each element of @rv@
1070  *
1071  * Returns:     Zero on success, %$-1$% on failure.
1072  *
1073  * Use:         Serialize a collection of register values.
1074  *
1075  *              The serialized output is written to the buffer @b@.  Failure
1076  *              can be caused by running out of buffer space, or a failing
1077  *              type handler.
1078  */
1079
1080 extern int tvec_serialize(const struct tvec_reg */*rv*/, buf */*b*/,
1081                           const struct tvec_regdef */*regs*/,
1082                           unsigned /*mask*/, unsigned /*want*/,
1083                           unsigned /*nr*/, size_t /*regsz*/);
1084
1085 /* --- @tvec_deserialize@ --- *
1086  *
1087  * Arguments:   @struct tvec_reg *rv@ = vector of registers
1088  *              @buf *b@ = buffer to write on
1089  *              @const struct tvec_regdef *regs@ = vector of register
1090  *                      descriptions, terminated by an entry with a null
1091  *                      @name@ slot
1092  *              @unsigned mask, want@ = flag-based selection
1093  *              @unsigned nr@ = number of entries in the @rv@ vector
1094  *              @size_t regsz@ = true size of each element of @rv@
1095  *
1096  * Returns:     Zero on success, %$-1$% on failure.
1097  *
1098  * Use:         Deserialize a collection of register values.
1099  *
1100  *              The size of the register vector @nr@ and the register
1101  *              definitions @regs@ must match those used when producing the
1102  *              serialization.  For each serialized register value,
1103  *              deserialize and store the value into the appropriate register
1104  *              slot, and set the @TVRF_LIVE@ flag on the register.  See
1105  *              @tvec_serialize@ for a description of the format.
1106  *
1107  *              Failure results only from an input too small for the initial
1108  *              bitmap or a failing register type handler.
1109  */
1110
1111 extern int tvec_deserialize(struct tvec_reg */*rv*/, buf */*b*/,
1112                             const struct tvec_regdef */*regs*/,
1113                             unsigned /*mask*/, unsigned /*want*/,
1114                             unsigned /*nr*/, size_t /*regsz*/);
1115
1116 /*----- Input utilities ---------------------------------------------------*/
1117
1118 /* These are provided by the core for the benefit of type @parse@ methods,
1119  * and test-environment @set@ functions, which get to read from the test
1120  * input file.  The latter are usually best implemented by calling on the
1121  * former.
1122  *
1123  * The two main rules are as follows.
1124  *
1125  *   * Leave the file position at the beginning of the line following
1126  *     whatever it was that you read.
1127  *
1128  *   * When you read and consume a newline (which you do at least once, by
1129  *     the previous rule), then increment @tv->lno@ to keep track of the
1130  *     current line number.
1131  */
1132
1133 /* --- @tvec_syntax@, @tvec_syntax_v@ --- *
1134  *
1135  * Arguments:   @struct tvec_state *tv@ = test-vector state
1136  *              @int ch@ = the character found (in @fgetc@ format)
1137  *              @const char *expect@, @va_list *ap@ = what was expected
1138  *
1139  * Returns:     %$-1$%.
1140  *
1141  * Use:         Report a syntax error quoting @ch@ and @expect@.
1142  *
1143  *              If @ch@ is a newline, or if @TVSF_NEXT@ is set, then unread
1144  *              it so that it can be read again (e.g., by @tvec_nexttoken@).
1145  *              The intent here is that you can safely read a character,
1146  *              inspect it, and then complain about it with @tvec_syntax@
1147  *              without having to worry too much about backing up.  The
1148  *              flipside of this is that you %%\emph{must}%% read a
1149  *              character, even if you don't have one ready, e,g, if you
1150  *              called @tvec_nexttoken@ and it said there wasn't one
1151  *              available.
1152  */
1153
1154 extern PRINTF_LIKE(3, 4)
1155   int tvec_syntax(struct tvec_state */*tv*/, int /*ch*/,
1156                   const char */*expect*/, ...);
1157 extern int tvec_syntax_v(struct tvec_state */*tv*/, int /*ch*/,
1158                          const char */*expect*/, va_list */*ap*/);
1159
1160 /* --- @tvec_skipspc@ --- *
1161  *
1162  * Arguments:   @struct tvec_state *tv@ = test-vector state
1163  *
1164  * Returns:     ---
1165  *
1166  * Use:         Advance over any whitespace characters other than newlines.
1167  *              This will stop at `;', end-of-file, or any other kind of
1168  *              non-whitespace; and it won't consume a newline.
1169  */
1170
1171 extern void tvec_skipspc(struct tvec_state */*tv*/);
1172
1173 /* --- @tvec_nexttoken@ --- *
1174  *
1175  * Arguments:   @struct tvec_state *tv@ = test-vector state
1176  *
1177  * Returns:     Zero if there is a next token which can be read; %$-1$% if no
1178  *              token is available.
1179  *
1180  * Use:         Advance to the next whitespace-separated token, which may be
1181  *              on the next line.
1182  *
1183  *              Tokens are separated by non-newline whitespace, comments, and
1184  *              newlines followed by whitespace; a newline /not/ followed by
1185  *              whitespace instead begins the next assignment, and two
1186  *              newlines separated only by whitespace terminate the data for
1187  *              a test.
1188  *
1189  *              If this function returns zero, then the next character in the
1190  *              file begins a suitable token which can be read and processed.
1191  *              If it returns %$-1$% then there is no such token, @TVSF_NEXT@
1192  *              is set, and the file position is left correctly.  The line
1193  *              number count is updated appropriately.
1194  */
1195
1196 extern int tvec_nexttoken(struct tvec_state */*tv*/);
1197
1198 /* --- @tvec_readword@, @tvec_readword_v@ --- *
1199  *
1200  * Arguments:   @struct tvec_state *tv@ = test-vector state
1201  *              @dstr *d@ = string to append the word to
1202  *              @const char **p_inout@ = pointer into string, updated
1203  *              @const char *delims@ = additional delimiters to stop at
1204  *              @const char *expect@, @va_list *ap@ = what was expected
1205  *
1206  * Returns:     Zero on success, %$-1$% on failure.
1207  *
1208  * Use:         A `word' consists of characters other than whitespace, null
1209  *              characters, and other than those listed in @delims@;
1210  *              furthermore, a word does not begin with a `;'.  (If you want
1211  *              reading to stop at comments not preceded by whitespace, then
1212  *              include `;' in @delims@.  This is a common behaviour.)
1213  *
1214  *              The function advances past whitespace and comments, as for
1215  *              @tvec_nexttoken@.  If there is no word beginning after the
1216  *              current file position, but before the start of the next
1217  *              non-continuation line, then return %$-1$%; furthermore, if
1218  *              @expect@ is not null, then report an appropriate error via
1219  *              @tvec_syntax@.
1220  *
1221  *              Otherwise, the word is accumulated in @d@ and zero is
1222  *              returned; if @d@ was not empty at the start of the call, the
1223  *              newly read word is separated from the existing material by a
1224  *              single space character.  Since null bytes are never valid
1225  *              word constituents, a null terminator is written to @d@, and
1226  *              it is safe to treat the string in @d@ as being null-
1227  *              terminated.
1228  *
1229  *              If @p_inout@ is not null, then @*p_inout@ must be a pointer
1230  *              into @d->buf@, which will be adjusted so that it will
1231  *              continue to point at the same position even if the buffer is
1232  *              reallocated.  As a subtle tweak, if @*p_inout@ initially
1233  *              points at the end of the buffer, then it will be adjusted to
1234  *              point at the beginning of the next word, rather than at the
1235  *              additional intervening space.
1236  */
1237
1238 extern PRINTF_LIKE(5, 6)
1239   int tvec_readword(struct tvec_state */*tv*/, dstr */*d*/,
1240                     const char **/*p_inout*/, const char */*delims*/,
1241                     const char */*expect*/, ...);
1242 extern int tvec_readword_v(struct tvec_state */*tv*/, dstr */*d*/,
1243                            const char **/*p_inout*/, const char */*delims*/,
1244                            const char */*expect*/, va_list */*ap*/);
1245
1246 /*----- That's all, folks -------------------------------------------------*/
1247
1248 #ifdef __cplusplus
1249   }
1250 #endif
1251
1252 #endif