Fix typo in reference manual
[dejagnu.git] / dejagnu.h
blob96b080593a135e076dae9421d92060fe2b833ba1
1 /* DejaGnu unit testing header.
2 Copyright (C) 2000-2016, 2022 Free Software Foundation, Inc.
4 This file is part of DejaGnu.
6 DejaGnu is free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 DejaGnu is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DejaGnu. If not, see <http://www.gnu.org/licenses/>. */
19 #ifndef __DEJAGNU_H__
20 #define __DEJAGNU_H__
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
27 /* If you have problems with DejaGnu dropping failed, untested, or
28 * unresolved messages generated by a unit testcase, then see the section
29 * "Priority of Expect Patterns" in *note (dejagnu)Writing a test case. or
30 * use the DejaGnu built-in unit testing support in your testsuite, which
31 * has been improved to resolve this issue in DejaGnu 1.6.3. */
33 static struct {
34 int pass;
35 int fail;
36 int xpass;
37 int xfail;
38 int untested;
39 int unresolved;
40 int unsupported;
41 /**/
42 int endmsg_registered;
43 int TestState_count; /* number of live TestState objects in C++ */
44 } DG__status = { 0 };
46 static inline void
47 DG__endmsg (void)
48 { puts ("\tEND: done"); }
50 static inline void
51 DG__init (void)
53 if (DG__status.endmsg_registered) return;
55 if (atexit (DG__endmsg) == 0)
56 DG__status.endmsg_registered = 1;
59 static inline void
60 pass (const char* fmt, ...)
62 va_list ap;
64 DG__status.pass++;
65 DG__init ();
67 flockfile (stdout);
68 fputs ("\tPASSED: ", stdout);
69 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
70 fputc ('\n', stdout);
71 funlockfile (stdout);
74 static inline void
75 xpass (const char* fmt, ...)
77 va_list ap;
79 DG__status.xpass++;
80 DG__init ();
82 flockfile (stdout);
83 fputs ("\tXPASSED: ", stdout);
84 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
85 fputc ('\n', stdout);
86 funlockfile (stdout);
89 static inline void
90 fail (const char* fmt, ...)
92 va_list ap;
94 DG__status.fail++;
95 DG__init ();
97 flockfile (stdout);
98 fputs ("\tFAILED: ", stdout);
99 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
100 fputc ('\n', stdout);
101 funlockfile (stdout);
104 static inline void
105 xfail (const char* fmt, ...)
107 va_list ap;
109 DG__status.xfail++;
110 DG__init ();
112 flockfile (stdout);
113 fputs ("\tXFAILED: ", stdout);
114 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
115 fputc ('\n', stdout);
116 funlockfile (stdout);
119 static inline void
120 untested (const char* fmt, ...)
122 va_list ap;
124 DG__status.untested++;
125 DG__init ();
127 flockfile (stdout);
128 fputs ("\tUNTESTED: ", stdout);
129 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
130 fputc ('\n', stdout);
131 funlockfile (stdout);
134 static inline void
135 unresolved (const char* fmt, ...)
137 va_list ap;
139 DG__status.unresolved++;
140 DG__init ();
142 flockfile (stdout);
143 fputs ("\tUNRESOLVED: ", stdout);
144 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
145 fputc ('\n', stdout);
146 funlockfile (stdout);
149 static inline void
150 unsupported (const char* fmt, ...)
152 va_list ap;
154 DG__status.unsupported++;
155 DG__init ();
157 flockfile (stdout);
158 fputs ("\tUNSUPPORTED: ", stdout);
159 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
160 fputc ('\n', stdout);
161 funlockfile (stdout);
164 static inline void
165 note (const char* fmt, ...)
167 va_list ap;
169 DG__init ();
171 flockfile (stdout);
172 fputs ("\tNOTE: ", stdout);
173 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
174 fputc ('\n', stdout);
175 funlockfile (stdout);
178 static inline void
179 DG_error (const char* fmt, ...)
181 va_list ap;
183 DG__init ();
185 flockfile (stdout);
186 fputs ("\tERROR: ", stdout);
187 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
188 fputc ('\n', stdout);
189 funlockfile (stdout);
192 static inline void
193 DG_warning (const char* fmt, ...)
195 va_list ap;
197 DG__init ();
199 flockfile (stdout);
200 fputs ("\tWARNING: ", stdout);
201 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
202 fputc ('\n', stdout);
203 funlockfile (stdout);
206 static inline void
207 totals (void)
209 printf ("\nTotals:\n");
210 printf ("\t#passed:\t\t%d\n", DG__status.pass);
211 printf ("\t#failed:\t\t%d\n", DG__status.fail);
212 if (DG__status.xfail)
213 printf ("\t#expected failures:\t\t%d\n", DG__status.xfail);
214 if (DG__status.xpass)
215 printf ("\t#unexpected passes:\t\t%d\n", DG__status.xpass);
216 if (DG__status.untested)
217 printf ("\t#untested:\t\t%d\n", DG__status.untested);
218 if (DG__status.unresolved)
219 printf ("\t#unresolved:\t\t%d\n", DG__status.unresolved);
220 if (DG__status.unsupported)
221 printf ("\t#unsupported:\t\t%d\n", DG__status.unsupported);
224 #ifdef __cplusplus
226 #include <iostream>
227 #include <iomanip>
228 #include <fstream>
229 #include <string>
231 const char * DG__outstate_list[] = {
232 "\tFAILED: ", "\tPASSED: ",
233 "\tUNTESTED: ", "\tUNRESOLVED: ", "\tUNSUPPORTED: ",
234 "\tXFAILED: ", "\tXPASSED: "
237 enum DG_teststate { FAILED, PASSED,
238 UNTESTED, UNRESOLVED, UNSUPPORTED,
239 XFAILED, XPASSED };
241 class TestState {
242 private:
243 DG_teststate laststate;
244 std::string lastmsg;
245 public:
246 TestState (void)
248 DG__status.TestState_count++;
250 if (DG__status.TestState_count > 1)
251 return; /* Do not clear the counters if additional TestState
252 objects are constructed. */
254 DG__status.pass = 0;
255 DG__status.fail = 0;
256 DG__status.xpass = 0;
257 DG__status.xfail = 0;
258 DG__status.untested = 0;
259 DG__status.unresolved = 0;
260 DG__status.unsupported = 0;
262 /* C++ object destruction will substitute for atexit(). */
263 DG__status.endmsg_registered = 1;
266 ~TestState (void)
268 DG__status.TestState_count--;
270 if (DG__status.TestState_count > 0) return;
272 /* The last TestState object is being destroyed. */
273 totals ();
274 std::cout << "\tEND: done" << std::endl;
277 void testrun (bool b, std::string s)
279 if (b)
280 pass (s);
281 else
282 fail (s);
285 void pass (std::string s)
287 DG__status.pass++;
288 laststate = PASSED;
289 lastmsg = s;
290 std::cout << DG__outstate_list[PASSED] << s << std::endl;
293 void xpass (std::string s)
295 DG__status.xpass++;
296 laststate = PASSED;
297 lastmsg = s;
298 std::cout << DG__outstate_list[XPASSED] << s << std::endl;
301 void fail (std::string s)
303 DG__status.fail++;
304 laststate = FAILED;
305 lastmsg = s;
306 std::cout << DG__outstate_list[FAILED] << s << std::endl;
309 void xfail (std::string s)
311 DG__status.xfail++;
312 laststate = XFAILED;
313 lastmsg = s;
314 std::cout << DG__outstate_list[XFAILED] << s << std::endl;
317 void untested (std::string s)
319 DG__status.untested++;
320 laststate = UNTESTED;
321 lastmsg = s;
322 std::cout << DG__outstate_list[UNTESTED] << s << std::endl;
325 void unresolved (std::string s)
327 DG__status.unresolved++;
328 laststate = UNRESOLVED;
329 lastmsg = s;
330 std::cout << DG__outstate_list[UNRESOLVED] << s << std::endl;
333 void unsupported (std::string s)
335 DG__status.unsupported++;
336 laststate = UNSUPPORTED;
337 lastmsg = s;
338 std::cout << DG__outstate_list[UNSUPPORTED] << s << std::endl;
341 void note (std::string s)
343 std::cout << "\t" << "NOTE: " << s << std::endl;
346 void error (std::string s)
348 std::cout << "\t" << "ERROR: " << s << std::endl;
351 void warning (std::string s)
353 std::cout << "\t" << "WARNING: " << s << std::endl;
356 void totals (void)
358 std::cout << std::endl << "Totals:" << std::endl;
360 std::cout << "\t#passed:\t\t"
361 << DG__status.pass << std::endl;
362 std::cout << "\t#failed:\t\t"
363 << DG__status.fail << std::endl;
365 if (DG__status.xfail)
366 std::cout << "\t#expected failures:\t\t"
367 << DG__status.xfail << std::endl;
368 if (DG__status.xpass)
369 std::cout << "\t#unexpected passes:\t\t"
370 << DG__status.xpass << std::endl;
371 if (DG__status.untested)
372 std::cout << "\t#untested:\t\t"
373 << DG__status.untested << std::endl;
374 if (DG__status.unresolved)
375 std::cout << "\t#unresolved:\t\t"
376 << DG__status.unresolved << std::endl;
377 if (DG__status.unsupported)
378 std::cout << "\t#unsupported:\t\t"
379 << DG__status.unsupported << std::endl;
382 // This is so this class can be printed in an ostream.
383 friend std::ostream & operator << (std::ostream &os, TestState& t)
385 return os << DG__outstate_list[t.laststate] << t.lastmsg ;
388 int GetState (void) { return laststate; }
389 std::string GetMsg (void) { return lastmsg; }
392 TestState DG;
394 #endif /* __cplusplus */
395 #endif /* _DEJAGNU_H_ */