aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Bachmeyer <jcb@gnu.org>2022-11-30 22:52:25 -0600
committerJacob Bachmeyer <jcb@gnu.org>2022-11-30 22:52:25 -0600
commitcc2dcde3edb178434be6ce74fdd12322a35fcfb5 (patch)
tree008fb21128bf7c744327772e772065cf7b3a0f58
parent25c50aa4235fd396b740f19c5641dea5adaebc27 (diff)
downloaddejagnu-cc2dcde3edb178434be6ce74fdd12322a35fcfb5.zip
dejagnu-cc2dcde3edb178434be6ce74fdd12322a35fcfb5.tar.gz
dejagnu-cc2dcde3edb178434be6ce74fdd12322a35fcfb5.tar.bz2
Revise generation of "END" messages in dejagnu.h
The "END" message is now produced upon normal exit, without requiring that the totals() function or method be called. The C++ API now emits totals only when the last TestState object in the program is destroyed, instead of every time a TestState object is destroyed. This required adding code to track the number of live TestState objects.
-rw-r--r--ChangeLog13
-rw-r--r--dejagnu.h44
2 files changed, 53 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 128bf52..27d1b57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2022-11-30 Jacob Bachmeyer <jcb@gnu.org>
+ * dejagnu.h (DG__endmsg): New function, called using atexit().
+ (endmsg_registered, TestState_count): Add fields to DG__status.
+ (DG__init): New function, to register DG__endmsg.
+ (pass, xpass, fail, xfail, untested, unresolved, unsupported)
+ (note): Call DG__init to ensure libdejagnu initialization.
+ (totals): Move "END" message to DG__endmsg.
+ (TestState::TestState): Consider DG__endmsg registered when a
+ TestState object is constructed.
+ (TestState::TestState, TestState::~TestState): Track number of
+ live TestState objects in global status structure.
+ (TestState::~TestState): Call totals() and emit "END" message only
+ when the last TestState object is destroyed.
+
* dejagnu.h (outstate): Remove.
(TestState::pass, TestState::xpass, TestState::fail)
(TestState::xfail, TestState::untested, TestState::unresolved)
diff --git a/dejagnu.h b/dejagnu.h
index 2541464..920ff69 100644
--- a/dejagnu.h
+++ b/dejagnu.h
@@ -22,6 +22,7 @@ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#include <stdio.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <string.h>
/* If you have problems with DejaGnu dropping failed, untested, or
@@ -38,14 +39,31 @@ static struct {
int untested;
int unresolved;
int unsupported;
+ /**/
+ int endmsg_registered;
+ int TestState_count; /* number of live TestState objects in C++ */
} DG__status = { 0 };
static inline void
+DG__endmsg (void)
+{ puts ("\tEND: done"); }
+
+static inline void
+DG__init (void)
+{
+ if (DG__status.endmsg_registered) return;
+
+ if (atexit (DG__endmsg) == 0)
+ DG__status.endmsg_registered = 1;
+}
+
+static inline void
pass (const char* fmt, ...)
{
va_list ap;
DG__status.pass++;
+ DG__init ();
flockfile (stdout);
fputs ("\tPASSED: ", stdout);
@@ -60,6 +78,7 @@ xpass (const char* fmt, ...)
va_list ap;
DG__status.xpass++;
+ DG__init ();
flockfile (stdout);
fputs ("\tXPASSED: ", stdout);
@@ -74,6 +93,7 @@ fail (const char* fmt, ...)
va_list ap;
DG__status.fail++;
+ DG__init ();
flockfile (stdout);
fputs ("\tFAILED: ", stdout);
@@ -88,6 +108,7 @@ xfail (const char* fmt, ...)
va_list ap;
DG__status.xfail++;
+ DG__init ();
flockfile (stdout);
fputs ("\tXFAILED: ", stdout);
@@ -102,6 +123,7 @@ untested (const char* fmt, ...)
va_list ap;
DG__status.untested++;
+ DG__init ();
flockfile (stdout);
fputs ("\tUNTESTED: ", stdout);
@@ -116,6 +138,7 @@ unresolved (const char* fmt, ...)
va_list ap;
DG__status.unresolved++;
+ DG__init ();
flockfile (stdout);
fputs ("\tUNRESOLVED: ", stdout);
@@ -130,6 +153,7 @@ unsupported (const char* fmt, ...)
va_list ap;
DG__status.unsupported++;
+ DG__init ();
flockfile (stdout);
fputs ("\tUNSUPPORTED: ", stdout);
@@ -143,6 +167,8 @@ note (const char* fmt, ...)
{
va_list ap;
+ DG__init ();
+
flockfile (stdout);
fputs ("\tNOTE: ", stdout);
va_start (ap, fmt); vfprintf (stdout, fmt, ap); va_end (ap);
@@ -166,7 +192,6 @@ totals (void)
printf ("\t#unresolved:\t\t%d\n", DG__status.unresolved);
if (DG__status.unsupported)
printf ("\t#unsupported:\t\t%d\n", DG__status.unsupported);
- printf ("\tEND: done\n");
}
#ifdef __cplusplus
@@ -200,9 +225,22 @@ class TestState {
DG__status.untested = 0;
DG__status.unresolved = 0;
DG__status.unsupported = 0;
+
+ /* C++ object destruction will substitute for atexit(). */
+ DG__status.endmsg_registered = 1;
+ DG__status.TestState_count++;
}
- ~TestState (void) { totals(); }
+ ~TestState (void)
+ {
+ DG__status.TestState_count--;
+
+ if (DG__status.TestState_count > 0) return;
+
+ /* The last TestState object is being destroyed. */
+ totals ();
+ std::cout << "\tEND: done" << std::endl;
+ }
void testrun (bool b, std::string s)
{
@@ -297,8 +335,6 @@ class TestState {
if (DG__status.unsupported)
std::cout << "\t#unsupported:\t\t"
<< DG__status.unsupported << std::endl;
-
- std::cout << "\tEND: done" << std::endl;
}
// This is so this class can be printed in an ostream.