Update web site addresses in manual
[dejagnu.git] / dejagnu.h
blobfc6aaca1722ab3fb968cbd9cb317256ce8b0cfdd
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, write to the Free Software Foundation,
18 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20 #ifndef __DEJAGNU_H__
21 #define __DEJAGNU_H__
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
28 /* If you have problems with DejaGnu dropping failed, untested, or
29 * unresolved messages generated by a unit testcase, then see the section
30 * "Priority of Expect Patterns" in *note (dejagnu)Writing a test case. or
31 * use the DejaGnu built-in unit testing support in your testsuite, which
32 * has been improved to resolve this issue in DejaGnu 1.6.3. */
34 static struct {
35 int pass;
36 int fail;
37 int xpass;
38 int xfail;
39 int untested;
40 int unresolved;
41 int unsupported;
42 /**/
43 int endmsg_registered;
44 int TestState_count; /* number of live TestState objects in C++ */
45 } DG__status = { 0 };
47 static inline void
48 DG__endmsg (void)
49 { puts ("\tEND: done"); }
51 static inline void
52 DG__init (void)
54 if (DG__status.endmsg_registered) return;
56 if (atexit (DG__endmsg) == 0)
57 DG__status.endmsg_registered = 1;
60 static inline void
61 pass (const char* fmt, ...)
63 va_list ap;
65 DG__status.pass++;
66 DG__init ();
68 flockfile (stdout);
69 fputs ("\tPASSED: ", stdout);
70 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
71 fputc ('\n', stdout);
72 funlockfile (stdout);
75 static inline void
76 xpass (const char* fmt, ...)
78 va_list ap;
80 DG__status.xpass++;
81 DG__init ();
83 flockfile (stdout);
84 fputs ("\tXPASSED: ", stdout);
85 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
86 fputc ('\n', stdout);
87 funlockfile (stdout);
90 static inline void
91 fail (const char* fmt, ...)
93 va_list ap;
95 DG__status.fail++;
96 DG__init ();
98 flockfile (stdout);
99 fputs ("\tFAILED: ", stdout);
100 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
101 fputc ('\n', stdout);
102 funlockfile (stdout);
105 static inline void
106 xfail (const char* fmt, ...)
108 va_list ap;
110 DG__status.xfail++;
111 DG__init ();
113 flockfile (stdout);
114 fputs ("\tXFAILED: ", stdout);
115 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
116 fputc ('\n', stdout);
117 funlockfile (stdout);
120 static inline void
121 untested (const char* fmt, ...)
123 va_list ap;
125 DG__status.untested++;
126 DG__init ();
128 flockfile (stdout);
129 fputs ("\tUNTESTED: ", stdout);
130 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
131 fputc ('\n', stdout);
132 funlockfile (stdout);
135 static inline void
136 unresolved (const char* fmt, ...)
138 va_list ap;
140 DG__status.unresolved++;
141 DG__init ();
143 flockfile (stdout);
144 fputs ("\tUNRESOLVED: ", stdout);
145 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
146 fputc ('\n', stdout);
147 funlockfile (stdout);
150 static inline void
151 unsupported (const char* fmt, ...)
153 va_list ap;
155 DG__status.unsupported++;
156 DG__init ();
158 flockfile (stdout);
159 fputs ("\tUNSUPPORTED: ", stdout);
160 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
161 fputc ('\n', stdout);
162 funlockfile (stdout);
165 static inline void
166 note (const char* fmt, ...)
168 va_list ap;
170 DG__init ();
172 flockfile (stdout);
173 fputs ("\tNOTE: ", stdout);
174 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
175 fputc ('\n', stdout);
176 funlockfile (stdout);
179 static inline void
180 DG_error (const char* fmt, ...)
182 va_list ap;
184 DG__init ();
186 flockfile (stdout);
187 fputs ("\tERROR: ", stdout);
188 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
189 fputc ('\n', stdout);
190 funlockfile (stdout);
193 static inline void
194 DG_warning (const char* fmt, ...)
196 va_list ap;
198 DG__init ();
200 flockfile (stdout);
201 fputs ("\tWARNING: ", stdout);
202 va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
203 fputc ('\n', stdout);
204 funlockfile (stdout);
207 static inline void
208 totals (void)
210 printf ("\nTotals:\n");
211 printf ("\t#passed:\t\t%d\n", DG__status.pass);
212 printf ("\t#failed:\t\t%d\n", DG__status.fail);
213 if (DG__status.xfail)
214 printf ("\t#expected failures:\t\t%d\n", DG__status.xfail);
215 if (DG__status.xpass)
216 printf ("\t#unexpected passes:\t\t%d\n", DG__status.xpass);
217 if (DG__status.untested)
218 printf ("\t#untested:\t\t%d\n", DG__status.untested);
219 if (DG__status.unresolved)
220 printf ("\t#unresolved:\t\t%d\n", DG__status.unresolved);
221 if (DG__status.unsupported)
222 printf ("\t#unsupported:\t\t%d\n", DG__status.unsupported);
225 #ifdef __cplusplus
227 #include <iostream>
228 #include <iomanip>
229 #include <fstream>
230 #include <string>
232 const char * DG__outstate_list[] = {
233 "\tFAILED: ", "\tPASSED: ",
234 "\tUNTESTED: ", "\tUNRESOLVED: ", "\tUNSUPPORTED: ",
235 "\tXFAILED: ", "\tXPASSED: "
238 enum DG_teststate { FAILED, PASSED,
239 UNTESTED, UNRESOLVED, UNSUPPORTED,
240 XFAILED, XPASSED };
242 class TestState {
243 private:
244 DG_teststate laststate;
245 std::string lastmsg;
246 public:
247 TestState (void)
249 DG__status.TestState_count++;
251 if (DG__status.TestState_count > 1)
252 return; /* Do not clear the counters if additional TestState
253 objects are constructed. */
255 DG__status.pass = 0;
256 DG__status.fail = 0;
257 DG__status.xpass = 0;
258 DG__status.xfail = 0;
259 DG__status.untested = 0;
260 DG__status.unresolved = 0;
261 DG__status.unsupported = 0;
263 /* C++ object destruction will substitute for atexit(). */
264 DG__status.endmsg_registered = 1;
267 ~TestState (void)
269 DG__status.TestState_count--;
271 if (DG__status.TestState_count > 0) return;
273 /* The last TestState object is being destroyed. */
274 totals ();
275 std::cout << "\tEND: done" << std::endl;
278 void testrun (bool b, std::string s)
280 if (b)
281 pass (s);
282 else
283 fail (s);
286 void pass (std::string s)
288 DG__status.pass++;
289 laststate = PASSED;
290 lastmsg = s;
291 std::cout << DG__outstate_list[PASSED] << s << std::endl;
294 void xpass (std::string s)
296 DG__status.xpass++;
297 laststate = PASSED;
298 lastmsg = s;
299 std::cout << DG__outstate_list[XPASSED] << s << std::endl;
302 void fail (std::string s)
304 DG__status.fail++;
305 laststate = FAILED;
306 lastmsg = s;
307 std::cout << DG__outstate_list[FAILED] << s << std::endl;
310 void xfail (std::string s)
312 DG__status.xfail++;
313 laststate = XFAILED;
314 lastmsg = s;
315 std::cout << DG__outstate_list[XFAILED] << s << std::endl;
318 void untested (std::string s)
320 DG__status.untested++;
321 laststate = UNTESTED;
322 lastmsg = s;
323 std::cout << DG__outstate_list[UNTESTED] << s << std::endl;
326 void unresolved (std::string s)
328 DG__status.unresolved++;
329 laststate = UNRESOLVED;
330 lastmsg = s;
331 std::cout << DG__outstate_list[UNRESOLVED] << s << std::endl;
334 void unsupported (std::string s)
336 DG__status.unsupported++;
337 laststate = UNSUPPORTED;
338 lastmsg = s;
339 std::cout << DG__outstate_list[UNSUPPORTED] << s << std::endl;
342 void note (std::string s)
344 std::cout << "\t" << "NOTE: " << s << std::endl;
347 void error (std::string s)
349 std::cout << "\t" << "ERROR: " << s << std::endl;
352 void warning (std::string s)
354 std::cout << "\t" << "WARNING: " << s << std::endl;
357 void totals (void)
359 std::cout << std::endl << "Totals:" << std::endl;
361 std::cout << "\t#passed:\t\t"
362 << DG__status.pass << std::endl;
363 std::cout << "\t#failed:\t\t"
364 << DG__status.fail << std::endl;
366 if (DG__status.xfail)
367 std::cout << "\t#expected failures:\t\t"
368 << DG__status.xfail << std::endl;
369 if (DG__status.xpass)
370 std::cout << "\t#unexpected passes:\t\t"
371 << DG__status.xpass << std::endl;
372 if (DG__status.untested)
373 std::cout << "\t#untested:\t\t"
374 << DG__status.untested << std::endl;
375 if (DG__status.unresolved)
376 std::cout << "\t#unresolved:\t\t"
377 << DG__status.unresolved << std::endl;
378 if (DG__status.unsupported)
379 std::cout << "\t#unsupported:\t\t"
380 << DG__status.unsupported << std::endl;
383 // This is so this class can be printed in an ostream.
384 friend std::ostream & operator << (std::ostream &os, TestState& t)
386 return os << DG__outstate_list[t.laststate] << t.lastmsg ;
389 int GetState (void) { return laststate; }
390 std::string GetMsg (void) { return lastmsg; }
393 TestState DG;
395 #endif /* __cplusplus */
396 #endif /* _DEJAGNU_H_ */