stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/driver.cpp
changeset 0 e4d67989cc36
child 22 ddc455616bd6
child 56 acd3cd4aaceb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/driver.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,1234 @@
+/************************************************************************
+ *
+ * driver.cpp - definitions of the test driver
+ *
+ * $Id: driver.cpp 290009 2005-09-18 23:28:26Z sebor $
+ *
+ ************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
+ * Software division. Licensed under the Apache License, Version 2.0 (the
+ * "License");  you may  not use this file except  in compliance with the
+ * License.    You    may   obtain   a   copy   of    the   License    at
+ * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
+ * applicable law  or agreed to  in writing,  software  distributed under
+ * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
+ * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
+ * for the specific language governing permissions  and limitations under
+ * the License.
+ *
+ **************************************************************************/
+
+// expand _TEST_EXPORT macros
+#define _RWSTD_TEST_SRC
+
+#include "opt_diags.h"
+#include "opt_lines.h"
+#include "opt_trace.h"
+#include "opt_types.h"
+
+#include <cmdopt.h>    // for rw_setopts()
+#include <printf.h>    // for rw_snprintfa()
+
+#include <assert.h>    // for assert
+#include <setjmp.h>    // for longjmp, setjmp, ...
+#include <stdarg.h>    // for va_list
+#include <stdio.h>     // for fileno, fprintf
+#include <stdlib.h>    // for free
+#include <string.h>    // for strchr, strcpy
+#include"std_log_result.h"
+#define LOG_FILENAME_LINE __FILE__, __LINE__
+#if !defined (_WIN32) && !defined (_WIN64)
+#  include <unistd.h>    // for isatty
+
+// declare fileno in case it's not declared (for strict ANSI conformance)
+extern "C" {
+
+_RWSTD_DLLIMPORT int (fileno)(FILE*) _LIBC_THROWS ();
+
+}   // extern "C"
+
+#else
+   // no isatty on Windoze
+#  define _RWSTD_NO_ISATTY
+#endif   // _WIN{32,64}
+
+// expand _TEST_EXPORT macros
+#define _RWSTD_TEST_SRC
+#include <driver.h>
+
+/************************************************************************/
+
+#define RW_TEST_STRSTR(x)   #x
+#define RW_TEST_STR(x)      RW_TEST_STRSTR(x)
+
+#ifndef RW_TEST_COMPILER
+#  if defined (__DECCXX__)
+#    define RW_TEST_COMPILER "Compaq C++, __DECCXX__ = " \
+            RW_TEST_STR (__DECCXX__)
+#  elif defined (__INTEL_COMPILER)
+#    if defined (__EDG_VERSION__)
+#      define RW_TEST_ICC_EDG_VER \
+              ", __EDG_VERSION__ = "  RW_TEST_STR (__EDG_VERSION__)
+#    else
+#      define RW_TEST_ICC_EDG_VER ""
+#    endif
+#    if defined (_MSC_VER)
+#      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
+              RW_TEST_STR (__INTEL_COMPILER) ", _MSC_VER = " \
+              RW_TEST_STR (_MSC_VER) \
+              RW_TEST_ICC_EDG_VER
+#    elif defined (__INTEL_COMPILER_BUILD_DATE)
+#      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
+              RW_TEST_STR (__INTEL_COMPILER) \
+              ", __INTEL_COMPILER_BUILD_DATE = " \
+              RW_TEST_STR (__INTEL_COMPILER_BUILD_DATE) \
+              RW_TEST_ICC_EDG_VER
+#    else
+#      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
+              RW_TEST_STR (__INTEL_COMPILER) \
+              RW_TEST_ICC_EDG_VER
+#    endif
+#  elif defined (__GNUC__)
+#    if defined (__VERSION__)
+#      define RW_TEST_GCC_VER ", __VERSION__ = \"" __VERSION__ "\""
+#    else
+#      define RW_TEST_GCC_VER ""
+#    endif
+#    if defined (__GNUC_PATCHLEVEL__)
+#      define RW_TEST_COMPILER "gcc "            \
+              RW_TEST_STR (__GNUC__) "."         \
+              RW_TEST_STR (__GNUC_MINOR__) "."   \
+              RW_TEST_STR (__GNUC_PATCHLEVEL__)  \
+              RW_TEST_GCC_VER
+#    else
+#      define RW_TEST_COMPILER "gcc " \
+              RW_TEST_STR (__GNUC__) "." RW_TEST_STR (__GNUC_MINOR__) 
+              RW_TEST_GCC_VER
+#    endif
+#  elif defined (_COMPILER_VERSION) && defined (__sgi)
+#    define RW_TEST_COMPILER "SGI MIPSpro, _COMPILER_VERSION = " \
+            RW_TEST_STR (_COMPILER_VERSION)
+#  elif defined (__INTEL_COMPILER)
+#    if defined (_MSC_VER)
+#      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
+              RW_TEST_STR (__INTEL_COMPILER) ", _MSC_VER = " \
+              RW_TEST_STR (_MSC_VER)
+#    else
+#      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
+              RW_TEST_STR (__INTEL_COMPILER)
+#    endif
+#  elif defined (__EDG__)
+#    define RW_TEST_COMPILER "EDG eccp, __EDG_VERSION__ = " \
+            RW_TEST_STR (__EDG_VERSION__)
+#  elif defined (__HP_aCC)
+#    define RW_TEST_COMPILER "HP aCC, __HP_aCC = " \
+            RW_TEST_STR (__HP_aCC)
+#  elif defined (__IBMCPP__)
+#    define RW_TEST_COMPILER "IBM VisualAge C++, __IBMCPP__ = " \
+            RW_TEST_STR (__IBMCPP__)
+#  elif defined (_MSC_VER)
+#    define RW_TEST_COMPILER "MSVC, _MSC_VER = " \
+            RW_TEST_STR (_MSC_VER)
+#  elif defined (__SUNPRO_CC)
+#    define RW_TEST_COMPILER "SunPro, __SUNPRO_CC = " \
+            RW_TEST_STR (__SUNPRO_CC)
+#  else
+#    define RW_TEST_COMPILER "unknown"
+#  endif
+#endif
+
+#ifndef RW_TEST_LIBSTD
+#  ifdef _RWSTD_VER
+#    define RW_TEST_LIBSTD "Rogue Wave C++ Standard Library, " \
+            "_RWSTD_VER = " RW_TEST_STR (_RWSTD_VER)
+#  elif defined (__GLIBCXX__)
+#    define RW_TEST_LIBSTD "GNU C++ Standard Library, " \
+            "__GLIBCXX__ = " \
+            RW_TEST_STR (__GLIBCXX__)
+#  elif defined (_STLPORT_VERSION)
+     // check for STLport before SGI STL since STLport,
+     // being derived from SGI STL, #defines both macros
+#    define RW_TEST_LIBSTD "STLport, " \
+            "_STLPORT_VERSION = " \
+            RW_TEST_STR (_STLPORT_VERSION)
+#  elif defined (__SGI_STL)
+#    define RW_TEST_LIBSTD "SGI STL, " \
+            "__SGI_STL = " \
+            RW_TEST_STR (__SGI_STL)
+#  elif defined (_YVALS)
+     // is there a better way to identify the Dinkumware
+     // implementation? does it have a version macro?
+#    define RW_TEST_LIBSTD "Dinkum C++ Standard Library"
+#  endif
+#endif   // RW_TEST_LIBSTD
+
+#ifndef RW_TEST_HARDWARE
+#  if defined (__alpha__) || defined (__alpha)
+#    define RW_TEST_ARCH "alpha"
+#  elif defined (__amd64__) || defined (__amd64)
+#    if defined (__LP64__) || defined (_LP64)
+#      define RW_TEST_ARCH "amd64/LP64"
+#    else
+#      define RW_TEST_ARCH "amd64/ILP32"
+#    endif
+#  elif defined (_PA_RISC2_0)
+#    define RW_TEST_ARCH "pa-risc 2.0"
+#  elif defined (_PA_RISC1_0)
+#    define RW_TEST_ARCH "pa-risc 1.0"
+#  elif defined (__hppa)
+#    define RW_TEST_ARCH "pa-risc"
+#  elif defined (__pentiumpro__) || defined (__pentiumpro)
+#    define RW_TEST_ARCH "pentiumpro"
+#  elif defined (__pentium__) || defined (__pentium)
+#    define RW_TEST_ARCH "pentium"
+#  elif defined (__i486__) || defined (__i486)
+#    define RW_TEST_ARCH "i486"
+#  elif defined (__i386__) || defined (__i386)
+#    define RW_TEST_ARCH "i386"
+#  elif defined (__i586__) || defined (__i586)
+#    define RW_TEST_ARCH "i586"
+#  elif defined (__ia64)
+#    define RW_TEST_ARCH "ia64"
+#  elif defined (__mips)
+#    define RW_TEST_ARCH "mips"
+#  elif defined (__sparcv9)
+#    define RW_TEST_ARCH "sparc-v9"
+#  elif defined (__sparcv8)
+#    define RW_TEST_ARCH "sparc-v8"
+#  elif defined (__sparc)
+#    define RW_TEST_ARCH "sparc"
+#  elif defined (_POWER)
+#    if defined (_ARCH_PWR5)
+#      define RW_TEST_ARCH "power-5"
+#    elif defined (_ARCH_PWR4)
+#      define RW_TEST_ARCH "power-4"
+#    elif defined (_ARCH_PWR3)
+#      define RW_TEST_ARCH "power-3"
+#    elif defined (_ARCH_604)
+#      define RW_TEST_ARCH "powerpc-604"
+#    elif defined (_ARCH_603)
+#      define RW_TEST_ARCH "powerpc-603"
+#    elif defined (_ARCH_602)
+#      define RW_TEST_ARCH "powerpc-602"
+#    elif defined (_ARCH_601)
+#      define RW_TEST_ARCH "powerpc-601"
+#    elif defined (_ARCH_403)
+#      define RW_TEST_ARCH "powerpc-403"
+#    elif defined (_ARCH_PPC64)
+#      define RW_TEST_ARCH "powerpc/LP64"
+#    else
+#      define RW_TEST_ARCH "powerpc"
+#    endif
+#  elif defined (_WIN64)
+#    define RW_TEST_ARCH "ia64"
+#  elif defined (_WIN32)
+#    define RW_TEST_ARCH "i86"
+#  elif defined (__x86_64__) || defined (__x86_64)
+#    if defined (__LP64__) || defined (_LP64)
+#      define RW_TEST_ARCH "x86_64/LP64"
+#    else
+#      define RW_TEST_ARCH "x86_64/ILP32"
+#    endif
+#  else
+#    define RW_TEST_ARCH "unknown"
+#  endif
+
+
+#  if defined (_AIX54)
+#    define RW_TEST_OS "aix-5.4 (or better)"
+#  elif defined (_AIX53)
+#    define RW_TEST_OS "aix-5.3"
+#  elif defined (_AIX52)
+#    define RW_TEST_OS "aix-5.2"
+#  elif defined (_AIX51)
+#    define RW_TEST_OS "aix-5.1"
+#  elif defined (_AIX50)
+#    define RW_TEST_OS "aix-5.0"
+#  elif defined (_AIX43)
+#    define RW_TEST_OS "aix-4.3"
+#  elif defined (_AIX41)
+#    define RW_TEST_OS "aix-4.1"
+#  elif defined (_AIX32)
+#    define RW_TEST_OS "aix-3.2"
+#  elif defined (_AIX)
+#    define RW_TEST_OS "aix"
+#  elif defined (__hpux)
+#    define RW_TEST_OS "hp-ux"
+#  elif defined (__osf__)
+#    define RW_TEST_OS "tru64-unix"
+#  elif defined (__sgi) && defined (__mips)
+#    define RW_TEST_OS "irix"
+#  elif defined (__linux__) || defined (__linux)
+
+     // get Linux release string (UTS_RELEASE)
+#    include <linux/version.h>
+
+#    ifndef UTS_RELEASE
+#      define UTS_RELEASE "(unknown release)"
+#    endif   // UTS_RELEASE
+
+#    if defined (__ELF__)
+#      define LINUX_TYPE "linux-elf"
+#    else
+#      define LINUX_TYPE "linux"
+#    endif
+
+#    define RW_TEST_OS LINUX_TYPE " "     \
+            UTS_RELEASE " with glibc "    \
+            RW_TEST_STR (__GLIBC__) "."   \
+            RW_TEST_STR (__GLIBC_MINOR__)
+
+#  elif defined (__SunOS_5_10)
+#    define RW_TEST_OS "sunos-5.10"
+#  elif defined (__SunOS_5_9)
+#    define RW_TEST_OS "sunos-5.9"
+#  elif defined (__SunOS_5_8)
+#    define RW_TEST_OS "sunos-5.8"
+#  elif defined (__SunOS_5_7)
+#    define RW_TEST_OS "sunos-5.7"
+#  elif defined (__SunOS_5_6)
+#    define RW_TEST_OS "sunos-5.6"
+#  elif defined (__sun__)
+#    define RW_TEST_OS "sunos"
+#  elif defined (_WIN64)
+#    define RW_TEST_OS "win64"
+#  elif defined (_WIN32)
+#    define RW_TEST_OS "win32"
+#  else
+#    define RW_TEST_OS "unknown"
+#  endif
+
+#  define RW_TEST_HARDWARE RW_TEST_ARCH " running " RW_TEST_OS
+#else
+#  define RW_TEST_HARDWARE "unknown"
+#endif
+
+/************************************************************************/
+
+// defined in printf.cpp but not declared in printf.h
+_TEST_EXPORT int
+rw_vasnprintf (char**, size_t*, const char*, va_list);
+
+/************************************************************************/
+
+// array to store the number of each type of diagnostic
+static int
+ndiags [N_DIAG_TYPES][2] /* = { { total, active }, ... }*/;
+
+static FILE *ftestout;
+
+static jmp_buf test_env;
+
+// set to 1 after the driver has been initialized
+static int driver_initialized = 0;
+
+// set to 1 after the driver has finished running
+static int driver_finished = 0;
+
+#if 0   // disabled
+// %S: severity
+// %M: diagnostic
+// %m: diagnostic if not empty
+// %F: file name
+// %f: file name if not empty
+// %C: clause
+// %c: clause if not empty
+// %L: line number
+// %l: line number if valid
+// %T: text
+// %t: text if not empty
+static char diag_pattern [80];
+#endif
+
+// option: use CSV format (comma separated values)
+static int _rw_opt_csv = 0;
+
+static char clause_id [80];
+
+/************************************************************************/
+
+#define CHECK_INIT(init, func)   _rw_check_init (init, __LINE__, func)
+
+static inline void
+_rw_check_init (bool init, int line, const char *func)
+{
+    if (init && !driver_initialized) {
+        fprintf (stderr, "%s:%d: %s: test driver already initialized\n",
+                 __FILE__, line, func);
+     std_log(LOG_FILENAME_LINE,"%s:%d: %s: test driver already initialized\n",
+                 __FILE__, line, func);                 
+        abort ();
+    }
+
+    if (!init && driver_initialized) {
+        fprintf (stderr, "%s:%d: %s: test driver not initialized yet\n",
+                 __FILE__, line, func);
+      std_log(LOG_FILENAME_LINE,"%s:%d: %s: test driver not initialized yet\n",
+                 __FILE__, line, func);                  
+        abort ();
+    }
+
+    if (driver_finished) {
+        fprintf (stderr, "%s:%d: %s: test finished, cannot call\n",
+                 __FILE__, line, func);
+     std_log(LOG_FILENAME_LINE,"%s:%d: %s: test finished, cannot call\n",
+                 __FILE__, line, func);                 
+    }
+}
+
+/************************************************************************/
+
+static int
+_rw_opt_brief (int argc, char *argv[])
+{
+    static int opt_brief;
+
+    if (0 == argc) {
+        // query mode: return the value of the option
+        return opt_brief;
+    }
+
+    if (1 == argc && argv && 0 == argv [0]) {
+        // help mode: set argv[0] to the text of the help message
+
+        static const char helpstr[] = {
+            "Enables brief mode.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    // set mode: enable the option
+    opt_brief = 1;
+
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_opt_quiet (int argc, char *argv[])
+{
+    static int opt_quiet;
+
+    if (0 == argc) {
+        // query mode: return the value of the option
+        return opt_quiet;
+    }
+
+    if (1 == argc && argv && 0 == argv [0]) {
+        // help mode: set argv[0] to the text of the help message
+
+        static const char helpstr[] = {
+            "Enables quiet mode.\n"
+            "In quiet mode only diagnostics with severity 7 and above are "
+            "issued."
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    // set mode: enable the option
+    _rw_diag_mask = ~((1 << 7) | (1 << 8) | (1 << 9));
+    opt_quiet     = 1;
+
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_opt_verbose (int argc, char *argv[])
+{
+    static int opt_verbose;
+
+    if (0 == argc) {
+        // query mode: return the value of the option
+        return opt_verbose;
+    }
+
+    if (1 == argc && argv && 0 == argv [0]) {
+        // help mode: set argv[0] to the text of the help message
+
+        static const char helpstr[] = {
+            "Enables verbose mode.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    // set mode: enable the option
+    opt_verbose = 1;
+
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_setopt_csv (int argc, char *argv[])
+{
+    if (1 == argc && argv && 0 == argv [0]) {
+        static const char helpstr[] = {
+            "Enables CSV (comma separated values) mode.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    _rw_opt_csv = 1;
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_opt_compat (int argc, char *argv[])
+{
+    static int opt_compat;
+
+    if (0 == argc) {
+        // query mode: return the value of the option
+        return opt_compat;
+    }
+
+    if (1 == argc && argv && 0 == argv [0]) {
+        // help mode: set argv[0] to the text of the help message
+
+        static const char helpstr[] = {
+            "Enables RWTest-format compatibility mode.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    // set mode: enable the option
+    opt_compat = 1;
+
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_opt_no_stdout (int argc, char *argv[])
+{
+    static int opt_no_stdout;
+
+    if (0 == argc) {
+        // query mode: return the value of the option
+        return opt_no_stdout;
+    }
+
+    if (1 == argc && argv && 0 == argv [0]) {
+        // help mode: set argv[0] to the text of the help message
+
+        static const char helpstr[] = {
+            "Prevents the program from using stdandard output for diagnostic\n"
+            "messages. Instead, the driver will create a log file with a name\n"
+            "obtained from the from the basename of the program source file,\n"
+            "usually obtained by passing the value of the __FILE__ macro to\n"
+            "the driver, with the .out extension. If successful, the driver\n"
+            "will write all diagnostic messages issued by the program to this\n"
+            "file. Otherwise, the driver exits with an error.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+    
+    // set mode: enable the option
+    opt_no_stdout = 1;
+
+    return 0;
+}
+
+/************************************************************************/
+
+static int
+_rw_setopt_output_file (int argc, char *argv[])
+{
+    if (1 == argc && argv && 0 == argv [0]) {
+        static const char helpstr[] = {
+            "Specifies the name of the output file to be used by the program\n"
+            "for diagnostic messages. Unless this option is specified, the\n"
+            "program will issue all diagnostic messages to the standard output."
+            "\nDriver diagnostics are always directed to stderr.\n"
+        };
+
+        argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
+
+        return 0;
+    }
+
+    const char *file_name = 0;
+
+    if ('-' == argv [0][0] && 'O' == argv [0][1] || 'o' == argv [0][1]) {
+        file_name = argv [0] + 2;
+    }
+    else if (1 < argc && '-' != argv [1][0]) {
+        file_name = argv [1];
+    }
+
+    if (file_name) {
+
+        FILE* const f = fopen (file_name, "w");
+
+        if (f) {
+            if (ftestout && ftestout != stderr)
+                fclose (ftestout);
+
+            ftestout = f;
+        }
+    }
+
+    // return 0 on success, any non-zero value on failure
+    return !(ftestout != 0);
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_vsetopts (const char *opts, va_list va);
+
+/************************************************************************/
+
+static int
+_rw_use_color ()
+{
+#ifndef _RWSTD_NO_ISATTY
+
+    // is output sent to a terminal?
+    // if so, assume a vt100 compatible terminal for now
+    static const int tty = isatty (fileno (ftestout));
+
+#else   // if defined (_RWSTD_NO_ISATTY)
+
+    // FIXME: deal with a missing isatty() and Windows
+    static const int tty = 0;
+
+#endif   // _RWSTD_NO_ISATTY
+
+    return 0 != tty;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_vtest (int argc, char **argv,
+          const char *file_name,
+          const char *clause,
+          const char *comment,
+          int (*fun)(int, char**),
+          const char *optstr,
+          va_list     va)
+{
+    CHECK_INIT (false, "rw_vtest()");
+
+    driver_initialized = 1;
+
+    if (optstr && 0 > rw_vsetopts (optstr, va)) {
+        fprintf (stderr, "%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
+        std_log(LOG_FILENAME_LINE,"%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
+        return 1;
+    }
+
+    const int nopts =
+        rw_setopts ("|-no-stdout "
+                    "|-diags= "      // argument required
+                    "|-trace "
+                    "|-severity= "   // argument required
+                    "|-csv "
+                    "|-compat "
+                    "o|-output:"     // argument optional
+                    "b|-brief "
+                    "q|-quiet "
+                    "v|-verbose",
+                    _rw_opt_no_stdout,
+                    _rw_setopt_diags,
+                    _rw_setopt_trace,
+                    _rw_setopt_trace_mask,
+                    _rw_setopt_csv,
+                    _rw_opt_compat,
+                    _rw_setopt_output_file,
+                    _rw_opt_brief,
+                    _rw_opt_quiet,
+                    _rw_opt_verbose,
+                    0);
+
+    if (3 > nopts) {
+        fprintf (stderr, "%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
+        std_log(LOG_FILENAME_LINE,"%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
+        abort ();
+        return 1;
+    }
+
+#ifndef _RWSTD_USE_CONFIG
+
+    // enable RWTest-format compatibility mode
+    _rw_opt_compat (1, 0);
+
+    // disable output to stdout
+    _rw_opt_no_stdout (1, 0);
+
+#endif   // _RWSTD_USE_CONFIG
+
+    _rw_setopts_types ();
+
+    _rw_setopts_lines ();
+
+    int status = rw_runopts (argc, argv);
+
+    if (status)
+        return status;
+
+    if (0 == ftestout) {
+
+        if (_rw_opt_no_stdout (0, 0) && file_name) {
+            char fname [256] = "C:\\";
+
+            const char* const slash = strrchr (file_name, _RWSTD_PATH_SEP);
+            strcat (fname, slash ? slash + 1 : file_name);
+
+            char* const dot = strchr (fname, '.');
+            if (dot)
+                strcpy (dot, ".out");
+            else
+                strcat (fname, ".out");
+
+            ftestout = fopen (fname, "w");
+        }
+        else
+            ftestout = stdout;
+    }
+
+    if (clause)
+        strcpy (clause_id, clause);
+
+    const char begin_fmt[] = {
+        "\n"
+        "# COMPILER: %s\n"
+        "# ENVIRONMENT: %s\n"
+        "# FILE: %s\n"
+        "# COMPILED: %s, %s\n"
+        "# COMMENT: %s\n"
+        "######################################################"
+    };
+
+    const char* const fname = strrchr (file_name, _RWSTD_PATH_SEP);
+
+    rw_info (0, 0, 0,
+             begin_fmt,
+             RW_TEST_COMPILER, RW_TEST_HARDWARE,
+             fname ? fname + 1 : file_name,
+             __DATE__, __TIME__,
+             comment ? comment : "");
+
+    status = setjmp (test_env);
+
+    if (0 == status) {
+        // environment set, execute the callback function
+        status = fun (argc, argv);
+    }
+    else {
+        // fatal test error (via a call to rw_fatal())
+    }
+
+    driver_finished = 1;
+
+    static const char tblrow[] =
+        "+-----------------------+--------+--------+--------+";
+
+    fprintf (ftestout,
+             "# %s\n"
+             "# | DIAGNOSTIC            | ACTIVE |  TOTAL |INACTIVE|\n"
+             "# %s\n",
+             tblrow, tblrow);
+
+    int nlines = 0;
+
+    for (int i = 0; i != N_DIAG_TYPES; ++i) {
+        if (ndiags [i][0] || !(_rw_diag_mask & (1 << diag_trace))) {
+
+            // print out details for any non-zero totals
+            // or for all totals when debugging or tracing
+            // is enabled
+
+            ++nlines;
+
+            const long num = (ndiags [i][0] - ndiags [i][1]) * 100L;
+            const long den = ndiags [i][0];
+
+            const long pct = den ? num / den : 0;
+
+            const char* pfx = "";
+            const char* sfx = "";
+
+            static int use_color = _rw_use_color ();
+
+            if (use_color) {
+                pfx = ndiags [i][1] ? diag_msgs [i].esc_pfx : "";
+                sfx = ndiags [i][1] ? diag_msgs [i].esc_sfx : "";
+            }
+
+            fprintf (ftestout,
+                     "# | (S%d) %-*s |%s %6d %s| %6d | %5ld%% |\n",
+                     i, int (sizeof diag_msgs [i].code), diag_msgs [i].code,
+                     pfx, ndiags [i][1], sfx, ndiags [i][0], pct);
+        }
+    }
+
+    if (0 == nlines)
+        fprintf (ftestout, "# no diagnostics\n");
+
+    fprintf (ftestout, "# %s\n", tblrow);
+
+    if (_rw_opt_compat (0, 0)) {
+
+        // TO DO: get rid of this
+
+        // RWTest compatibility format
+
+        fprintf (ftestout,
+                 "######################################################\n"
+                 "## Warnings = %d\n"
+                 "## Assertions = %d\n"
+                 "## FailedAssertions = %d\n",
+                 ndiags [diag_warn][1] + ndiags [diag_xwarn][1],
+                 ndiags [diag_assert][0],
+                 ndiags [diag_assert][1] + ndiags [diag_xassert][1]);
+    }
+
+    fclose (ftestout);
+    ftestout = 0;
+
+    return status;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_test (int argc, char **argv,
+         const char *fname,
+         const char *clause,
+         const char *comment,
+         int (*testfun)(int, char**),
+         const char *optstr,
+         ...)
+{
+    CHECK_INIT (false, "rw_test()");
+
+    va_list va;
+    va_start (va, optstr);
+
+    const int status =
+        rw_vtest (argc, argv, fname, clause, comment, testfun, optstr, va);
+
+    va_end (va);
+
+    return status;
+}
+
+/************************************************************************/
+
+// escape every occurrence of the double quote character in the string
+// pointed to by buf by prepending to it the escape character specified
+// by the last acrgument
+// returns the new buffer if the size of the existing buffer isn't
+// sufficient and sets *pbufsize to the size of the newly allocated
+// buffer, otherwise the original value of buf and leaves *pbufsize
+// unchanged
+static char*
+_rw_escape (char *buf, size_t bufsize, char esc)
+{
+    // handle null buffer
+    if (0 == buf)
+        return buf;
+
+    // count the number of embedded quotes
+    char *quote = buf;
+    size_t nquotes = 0;
+    while ((quote = strchr (quote, '"'))) {
+        ++nquotes;
+        ++quote;
+    }
+
+    // no quotes found, return the original buffer
+    if (0 == nquotes)
+        return buf;
+
+    // conpute the size of the buffer that will be needed to escape
+    // all the double quotes
+    size_t newbufsize = strlen (buf) + nquotes + 1;
+
+    char *newbuf = 0;
+
+    if (0 /* newbufsize <= bufsize */) {
+        // FIXME: escape embedded quotes in place w/o reallocation
+        _RWSTD_UNUSED (bufsize);
+    }
+    else {
+        newbuf = (char*)malloc (newbufsize);
+        if (0 == newbuf) {
+            return 0;
+        }
+
+        // set the next pointer to the beginning of the new buffer
+        // as the destination where to copy the string argument
+        char *next = newbuf;
+
+        // set quote to initially point to the beginning of
+        // the source buffer and then just past the last quote
+        quote = buf;
+
+        for (char *q = buf; ; ++q) {
+
+            // look for the next (or first) quote
+            q = strchr (q, '"');
+
+            // compute the number of characters, excluding the quote
+            // to copy to the destination buffer
+            const size_t nchars = q ? size_t (q - quote) : strlen (quote);
+
+            memcpy (next, quote, nchars);
+
+            if (q) {
+                // append the escape character to the destination buffer
+                next [nchars] = esc;
+
+                // append the quote from the source string
+                next [nchars + 1] = '"';
+
+                // advance the destination pointer past the quote
+                next += nchars + 2;
+
+                // advance the source pointer past the embedded quote
+                quote = q + 1;
+            }
+            else {
+                // NUL-terminate the destination buffer
+                *next = '\0';
+                break;
+            }
+        }
+    }
+
+    return newbuf;
+}
+
+/************************************************************************/
+
+static void
+_rw_vissue_diag (diag_t diag, int severity, const char *file, int line,
+                 const char *fmt, va_list va)
+{
+    CHECK_INIT (true, "_rw_vissue_diag()");
+
+    if (0 == fmt)
+        fmt = "";
+
+    static char fmterr[] = "*** formatting error ***";
+
+    char *usrbuf = 0;
+    const int nchars = rw_vasnprintf (&usrbuf, 0, fmt, va);
+
+    if (nchars < 0 || 0 == usrbuf)
+        usrbuf = fmterr;
+
+    // compute the number of newline characters in the text
+    int nlines = 0;
+    for (const char *nl = usrbuf; (nl = strchr (nl, '\n')); ++nl)
+        ++nlines;
+
+    static const int use_color = _rw_use_color ();
+
+    const char* const diagstr[] = {
+        use_color ? diag_msgs [severity].esc_pfx : "",
+        *diag_msgs [severity].code ? diag_msgs [severity].code : "UNKNOWN",
+        use_color  ? diag_msgs [severity].esc_sfx : "",
+        _rw_opt_verbose (0, 0) && *diag_msgs [severity].desc ?
+        diag_msgs [severity].desc : 0
+    };
+
+    const char* const traced_diag =
+        0 == severity && diag_msgs [diag].code ? diag_msgs [diag].code : 0;
+
+    const char* const slash = file ? strrchr (file, _RWSTD_PATH_SEP) : 0;
+    if (slash)
+        file = slash + 1;
+
+    char *mybuf = 0;
+
+    if (_rw_opt_csv) {
+
+        // format all fields as comma separated values (CSV):
+        // -- a field containing the quote character, the comma,
+        //    or the newline or linefeed character must be enclosed
+        //    in a pair of double quotes
+        // -- every occurrence of the double quote character in a field
+        //    must be escaped by prepening another double quote character
+        //    to it
+
+        // escape all double quotes by prepending the double
+        // quote character to each according to the CSV format
+        char* const newbuf = _rw_escape (usrbuf, 0, '"');
+        if (newbuf != usrbuf) {
+            free (usrbuf);
+            usrbuf = newbuf;
+        }
+
+        mybuf =
+            rw_sprintfa ("%d, "                      // severity
+                         "\"%s%s"                    // diagnostic
+                         "%{?}_%s%{;}%s\", "         // traced diagnostic
+                         "\"%s\", "                  // clause
+                         "\"%s\", "                  // file
+                         "%d, "                      // line
+                         "\"%s\"",                   // user text
+                         severity,
+                         diagstr [0], diagstr [1],
+                         0 != traced_diag, traced_diag, diagstr [2],
+                         clause_id,
+                         0 != file ? file : "",
+                         line,
+                         usrbuf);
+    }
+    else {
+
+        nlines += 2 + ('\0' != *clause_id) + (0 != file) + (0 < line);
+
+        mybuf =
+            rw_sprintfa ("# %s"                      // escape prefix
+                         "%s"                        // diagnostic
+                         "%{?}_%s%{;}"               // traced diagnostic
+                         "%s "                       // escape suffix
+                         "(S%d)"                     // severity
+                         "%{?}, %s%{;} "             // description
+                         "(%d lines):\n"             // number of lines
+                         "# TEXT: %s\n"              // user text
+                         "%{?}# CLAUSE: %s\n%{;}"    // clause if not empty
+                         "%{?}# FILE: %s\n%{;}"      // file if not null
+                         "%{?}# LINE: %d\n%{;}",     // line if positive
+                         diagstr [0],
+                         diagstr [1],
+                         0 != traced_diag, traced_diag,
+                         diagstr [2],
+                         severity,
+                         0 != diagstr [3], diagstr [3],
+                         nlines,
+                         usrbuf,
+                         '\0' != *clause_id, clause_id,
+                         0 != file, file,
+                         0 < line, line);
+    }
+#if 0   // disabled
+    else {
+
+        mybuf =
+            rw_sprintfa ("# %s%s"                 // diagnostic
+                         "%{?}_%s%{;}%s "         // traced diagnostic
+                         "(S%d): "                // severity
+                         "%{?}[%s] %{;}"          // clause if not empty
+                         "%{?}(%d lines): %{;}"   // number of lines if > 1
+                         "%{?}%s:"                // if (file) then file
+                         "%{?}%d:%{;} "           //   if (0 < line) line
+                         "%{:}"                   // else
+                         "%{?}line %d: %{;}"      //   if (0 < line) line
+                         "%{;}"                   // endif
+                         "%s",                    // user text
+                         diagstr [0], diagstr [1],
+                         0 != traced_diag, traced_diag, diagstr [2],
+                         severity,
+                         '\0' != *clause_id, clause_id,
+                         1 < nlines, nlines,
+                         0 != file, file,
+                         0 < line, line,
+                         0 < line, line,
+                         usrbuf);
+    }
+#endif   // 0/1
+
+    fprintf (ftestout, "%s\n", mybuf);
+
+    if (mybuf != fmterr)
+        free (mybuf);
+
+    if (usrbuf != fmterr)
+        free (usrbuf);
+}
+
+/************************************************************************/
+
+static void
+_rw_vdiag (diag_t diag, int severity, const char *file, int line,
+           const char *fmt, va_list va)
+{
+    CHECK_INIT (true, "_rw_vdiag()");
+
+    // check if the diagnostic is expected
+    const int expected = 0 != _rw_expected (line);
+
+    if (expected) {
+        if (severity) {
+            // if the diagnostic is expected to be active,
+            // adjust its type and severity
+            if (diag_assert == diag)
+                diag = diag_xassert;
+            else if (diag_warn == diag)
+                diag = diag_xwarn;
+
+            severity = diag * severity;
+        }
+        else {
+            // if the diagnostic is expected to be active but isn't,
+            // adjust its type to an unexpectdly inactive one
+            if (diag_assert == diag || diag_warn == diag)
+                diag = diag_expect;
+
+            severity = diag;
+        }
+    }
+    else if (diag) {
+        // normalize the severity
+        severity = diag * severity;
+    }
+
+    if (severity < 0)
+        severity = 0;
+    else if (N_DIAG_TYPES <= severity)
+        severity = N_DIAG_TYPES - 1;
+
+    // increment the diagnostic counter
+    ++ndiags [diag][0];
+
+    if (severity) {
+
+        ++ndiags [diag][1];
+    }
+
+    const int sevbit = (1 << severity);
+
+    if (0 == (sevbit & _rw_diag_mask)) {
+        // issue the diagnostic
+        _rw_vissue_diag (diag, severity, file, line, fmt, va);
+    }
+
+    if (diag_fatal == diag && severity) {
+        // fatal error, terminate test
+        longjmp (test_env, severity);
+    }
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_fatal (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_fatal()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_fatal, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_error (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_error()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_error, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_assert (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_assert()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_assert, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_warn (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_warn()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_warn, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_note (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_note()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_note, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}
+
+/************************************************************************/
+
+_TEST_EXPORT int
+rw_info (int success, const char *file, int line, const char *fmt, ...)
+{
+    CHECK_INIT (true, "rw_info()");
+
+    va_list va;
+    va_start (va, fmt);
+
+    _rw_vdiag (diag_info, 0 == success, file, line, fmt, va);
+
+    va_end (va);
+
+    return success;
+}