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