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