3 * Test-vector framework output machinery
5 * (c) 2024 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the mLib utilities library.
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.
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.
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,
28 #ifndef MLIB_TVEC_OUTPUT_H
29 #define MLIB_TVEC_OUTPUT_H
35 /*----- Header files ------------------------------------------------------*/
41 /*----- Data structures ---------------------------------------------------*/
46 /* An output formatter. */
48 const struct tvec_outops *ops; /* pointer to operations */
52 /* Register output dispositions. */
54 TVRD_INPUT, /* input-only register */
55 TVRD_OUTPUT, /* output-only (input is dead) */
56 TVRD_MATCH, /* matching (equal) registers */
57 TVRD_FOUND, /* mismatching output register */
58 TVRD_EXPECT, /* mismatching input register */
59 TVRD_LIMIT /* (number of dispositions) */
62 struct tvec_fallbackoutput {
63 /* Dummy fallback output driver. This may be useful for fallback output
64 * driver implementations.
67 struct tvec_output _o;
68 struct tvec_state *tv;
72 /* Output operations. */
74 void (*bsession)(struct tvec_output */*o*/, struct tvec_state */*tv*/);
75 /* Begin a test session. The output driver will probably want to
76 * save @tv@, because this isn't provided to any other methods.
79 int (*esession)(struct tvec_output */*o*/);
80 /* End a session, and return the suggested exit code. */
82 void (*bgroup)(struct tvec_output */*o*/);
83 /* Begin a test group. The test group description is @tv->test@. */
85 void (*skipgroup)(struct tvec_output */*o*/,
86 const char */*excuse*/, va_list */*ap*/);
87 /* The group is being skipped; @excuse@ may be null or a format
88 * string explaining why. The @egroup@ method will not be called
92 void (*egroup)(struct tvec_output */*o*/);
93 /* End a test group. At least one test was attempted or @skipgroup@
94 * would have been called instead. If @tv->curr[TVOUT_LOSE]@ is nonzero
95 * then the test group as a whole failed; otherwise it passed.
98 void (*btest)(struct tvec_output */*o*/);
99 /* Begin a test case. */
101 void (*skip)(struct tvec_output */*o*/,
102 const char */*excuse*/, va_list */*ap*/);
103 /* The test case is being skipped; @excuse@ may be null or a format
104 * string explaining why. The @etest@ function will still be called (so
105 * this works differently from @skipgroup@ and @egroup@). A test case
106 * can be skipped at most once, and, if skipped, it cannot fail.
109 void (*fail)(struct tvec_output */*o*/,
110 const char */*detail*/, va_list */*ap*/);
111 /* The test case failed.
113 * The output driver should preferably report the filename (@infile@) and
114 * line number (@test_lno@, not @lno@) for the failing test.
116 * The @detail@ may be null or a format string describing detail about
117 * how the failing test was run which can't be determined from the
118 * registers; a @detail@ is usually provided when (and only when) the
119 * test environment potentially invokes the test function more than once.
121 * A single test case can fail multiple times!
124 void (*dumpreg)(struct tvec_output */*o*/,
125 unsigned /*disp*/, const union tvec_regval */*rv*/,
126 const struct tvec_regdef */*rd*/);
127 /* Dump a register. The `disposition' @disp@ explains what condition the
128 * register is in; see @tvec_dumpreg@ and the @TVRD_...@ codes. The
129 * register value is at @rv@, and its definition, including its type, at
130 * @rd@. Note that this function may be called on virtual registers
131 * which aren't in either of the register vectors or mentioned by the
132 * test description. It may also be called with @rv@ null, indicating
133 * that the register is not live.
136 void (*etest)(struct tvec_output */*o*/, unsigned /*outcome*/);
137 /* The test case concluded with the given @outcome@ (one of the
141 void (*report)(struct tvec_output */*o*/, unsigned /*level*/,
142 const char */*msg*/, va_list */*ap*/);
143 /* Report a message. The driver should ideally report the filename
144 * (@infile@) and line number (@lno@) prompting the error.
147 const void *(*extend)(struct tvec_output */*o*/, const char */*name*/);
148 /* Return a pointer to the output driver's implementation of the
149 * extension @name@, or null. Typically, the implementation will be a
150 * structure of function pointers, though the details are necessarily
151 * extension-specific.
154 void (*destroy)(struct tvec_output */*o*/);
155 /* Release any resources acquired by the driver. */
158 /*----- Functions provided ------------------------------------------------*/
160 /* --- @tvec_outputext@ --- *
162 * Arguments: @struct tvec_state *tv@ = test-vector state
163 * @struct tvec_output **o_out@ = output object
164 * @struct tvec_fallbackoutput *fo@ = fallback output
166 * @const char *ext@ = extension name
167 * @const void *fops@ = fallback operations
169 * Returns: An output extension operations table.
171 * Use: Calls the output driver's @extend@ function, passing @ext@ as
172 * the extension name. If the output driver recognizes the
173 * extension, then @*o_out@ is set to the output driver object
174 * and the driver's extension-operations table is returned.
175 * Otherwise, a fallback output object is constructed in @*fo@,
176 * @*o_out@ is set to @&fo->_o@, and @fops@ is returned. In
177 * this way, a call to an extension function, passing @*o_out@
178 * as the output object, will either call the output driver's
179 * extension implementation or the fallback implementation as
183 extern const void *tvec_outputext(struct tvec_state */*tv*/,
184 struct tvec_output **/*o_out*/,
185 struct tvec_fallbackoutput */*fo*/,
186 const char */*ext*/, const void */*fops*/);
188 /*----- That's all, folks -------------------------------------------------*/