@@@ fltfmt mess
[mLib] / test / tvec-adhoc.h
CommitLineData
b1a20bee
MW
1/* -*-c-*-
2 *
3 * Test-vector framework ad-hoc testing interface
4 *
5 * (c) 2024 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28#ifndef MLIB_TVEC_ADHOC_H
29#define MLIB_TVEC_ADHOC_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#include <stdarg.h>
38
39#ifndef MLIB_TVEC_H
40# include "tvec.h"
41#endif
42
43/*----- Data structures ---------------------------------------------------*/
44
45extern const struct tvec_config tvec_adhocconfig;
46 /* A special @struct tvec_config@ to use for programs which perform ad-hoc
47 * testing.
48 */
49
50/*----- Functions provided ------------------------------------------------*/
51
52/* --- @tvec_adhoc@ --- *
53 *
54 * Arguments: @struct tvec_state *tv@ = test-vector state
55 *
56 * Returns: ---
57 *
58 * Use: Begin ad-hoc testing, i.e., without reading a file of
59 * test-vector data.
60 *
61 * The other functions in this section assume that @tvec_adhoc@
62 * has been called.
63 */
64
65extern void tvec_adhoc(struct tvec_state */*tv*/);
66
67/* --- @tvec_begingroup@, @TVEC_BEGINGROUP@ --- *
68 *
69 * Arguments: @struct tvec_state *tv@ = test-vector state
70 * @const char *name@ = name for this test group
71 * @const char *file@, @unsigned @lno@ = calling file and line
72 *
73 * Returns: ---
74 *
75 * Use: Begin an ad-hoc test group with the given name. The @file@
76 * and @lno@ can be anything, but it's usually best if they
77 * refer to the source code performing the test: the macro
78 * @TVEC_BEGINGROUP@ does this automatically.
79 */
80
81extern void tvec_begingroup(struct tvec_state */*tv*/, const char */*name*/,
82 const char */*file*/, unsigned /*lno*/);
83#define TVEC_BEGINGROUP(tv, name) \
84 do tvec_begingroup(tv, name, __FILE__, __LINE__); while (0)
85
86/* --- @tvec_endgroup@ --- *
87 *
88 * Arguments: @struct tvec_state *tv@ = test-vector state
89 *
90 * Returns: ---
91 *
92 * Use: End an ad-hoc test group. The statistics are updated and the
93 * outcome is reported to the output formatter.
94 */
95
96extern void tvec_endgroup(struct tvec_state */*tv*/);
97
98/* --- @TVEC_TESTGROUP@, @TVEC_TESTGROUP_TAG@ --- *
99 *
100 * Arguments: @tag@ = label-disambiguation tag
101 * @const struct tvec_state *tv = test-vector state
102 * @const char *name@ = test-group name
103 *
104 * Returns: ---
105 *
106 * Use: Control-structure macro: @TVEC_TESTGROUP(tv, name) stmt@
107 * establishes a test group with the given @name@ (attributing
108 * it to the source file and lie number), executes @stmt@, and
109 * ends the test group. If @stmt@ invokes @break@ then the test
110 * group is skipped. @TVEC_TESTGROUP_TAG@ is the same, with an
111 * additional @tag@ argument for use in higher-level macros.
112 */
113
114#define TVEC_TESTGROUP_TAG(tag, tv, name) \
115 MC_WRAP(tag##__around, \
116 { TVEC_BEGINGROUP(tv, name); }, \
117 { tvec_endgroup(tv); }, \
118 { if (!((tv)->f&TVSF_SKIP)) tvec_skipgroup(tv, 0); \
119 tvec_endgroup(tv); })
120#define TVEC_TESTGROUP(tv, name) TVEC_TESTGROUP_TAG(grp, tv, name)
121
122/* --- @tvec_begintest@, @TVEC_BEGINTEST@ --- *
123 *
124 * Arguments: @struct tvec_state *tv@ = test-vector state
125 * @const char *file@, @unsigned @lno@ = calling file and line
126 *
127 * Returns: ---
128 *
129 * Use: Begin an ad-hoc test case. The @file@ and @lno@ can be
130 * anything, but it's usually best if they refer to the source
131 * code performing the test: the macro @TVEC_BEGINGROUP@ does
132 * this automatically.
133 */
134
135extern void tvec_begintest(struct tvec_state */*tv*/,
136 const char */*file*/, unsigned /*lno*/);
137#define TVEC_BEGINTEST(tv) \
138 do tvec_begintest(tv, __FILE__, __LINE__); while (0)
139
140/* --- @tvec_endtest@ --- *
141 *
142 * Arguments: @struct tvec_state *tv@ = test-vector state
143 *
144 * Returns: ---
145 *
146 * Use: End an ad-hoc test case, The statistics are updated and the
147 * outcome is reported to the output formatter.
148 */
149
150extern void tvec_endtest(struct tvec_state */*tv*/);
151
152/* --- @TVEC_TEST@, @TVEC_TEST_TAG@ --- *
153 *
154 * Arguments: @tag@ = label-disambiguation tag
155 * @struct tvec_test *t@ = space for a test definition
156 *
157 * Returns: ---
158 *
159 * Use: Control-structure macro: @TVEC_TEST(tv) stmt@ begins a test
160 * case, executes @stmt@, and ends the test case. If @stmt@
161 * invokes @break@ then the test case is skipped.
162 * @TVEC_TEST_TAG@ is the same, with an additional @tag@ argumet
163 * for use in higher-level macros.
164 */
165
166#define TVEC_TEST_TAG(tag, tv) \
167 MC_WRAP(tag##__around, \
168 { TVEC_BEGINTEST(tv); }, \
169 { tvec_endtest(tv); }, \
170 { if ((tv)->f&TVSF_ACTIVE) tvec_skip((tv), 0); \
171 tvec_endtest(tv); })
172#define TVEC_TEST(tv) TVEC_TEST_TAG(test, tv)
173
174/* --- @tvec_claim@, @tvec_claim_v@, @TVEC_CLAIM@ --- *
175 *
176 * Arguments: @struct tvec_state *tv@ = test-vector state
177 * @int ok@ = a flag
178 * @const char *file@, @unsigned @lno@ = calling file and line
179 * @const char *msg@, @va_list *ap@ = message to report on
180 * failure
181 *
182 * Returns: The value @ok@.
183 *
184 * Use: Check that a claimed condition holds, as (part of) a test.
185 * If no test case is underway (i.e., if @TVSF_OPEN@ is reset in
186 * @tv->f@), then a new test case is begun and ended. The
187 * @file@ and @lno@ are passed to the output formatter to be
188 * reported in case of a failure. If @ok@ is nonzero, then
189 * nothing else happens; so, in particular, if @tvec_claim@
190 * established a new test case, then the test case succeeds. If
191 * @ok@ is zero, then a failure is reported, quoting @msg@.
192 *
193 * The @TVEC_CLAIM@ macro is similar, only it (a) identifies the
194 * file and line number of the call site automatically, and (b)
195 * implicitly quotes the source text of the @ok@ condition in
196 * the failure message.
197 */
198
199extern PRINTF_LIKE(5, 6)
200 int tvec_claim(struct tvec_state */*tv*/, int /*ok*/,
201 const char */*file*/, unsigned /*lno*/,
202 const char */*msg*/, ...);
203extern int tvec_claim_v(struct tvec_state */*tv*/, int /*ok*/,
204 const char */*file*/, unsigned /*lno*/,
205 const char */*msg*/, va_list */*ap*/);
206#define TVEC_CLAIM(tv, cond) \
207 (tvec_claim(tv, !!(cond), __FILE__, __LINE__, "%s untrue", #cond))
208
209/* --- @tvec_claimeq@ --- *
210 *
211 * Arguments: @struct tvec_state *tv@ = test-vector state
212 * @const struct tvec_regty *ty@ = register type
213 * @const union tvec_misc *arg@ = register type argument
214 * @const char *file@, @unsigned @lno@ = calling file and line
215 * @const char *expr@ = the expression to quote on failure
216 *
217 * Returns: Nonzero if the input and output values of register 0 are
218 * equal, zero if they differ.
219 *
220 * Use: Check that the input and output values of register 0 are
221 * equal (according to the register type @ty@). As for
222 * @tvec_claim@ above, a test case is automatically begun and
223 * ended if none is already underway. If the values are
224 * unequal, then @tvec_fail@ is called, quoting @expr@, and the
225 * mismatched values are dumped.
226 *
227 * This function is not expected to be called directly, but
228 * through type-specific wrapper functions or macros such as
229 * @TVEC_CLAIMEQ_INT@.
230 */
231
232extern int tvec_claimeq(struct tvec_state */*tv*/,
233 const struct tvec_regty */*ty*/,
234 const union tvec_misc */*arg*/,
235 const char */*file*/, unsigned /*lno*/,
236 const char */*expr*/);
237
238/*----- That's all, folks -------------------------------------------------*/
239
240#ifdef __cplusplus
241 }
242#endif
243
244#endif