stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/driver.cpp
changeset 31 ce057bb09d0b
child 34 5fae379060a7
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 /************************************************************************
       
     2  *
       
     3  * driver.cpp - definitions of the test driver
       
     4  *
       
     5  * $Id: driver.cpp 290009 2005-09-18 23:28:26Z sebor $
       
     6  *
       
     7  ************************************************************************
       
     8  *
       
     9  * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
       
    10  * Software division. Licensed under the Apache License, Version 2.0 (the
       
    11  * "License");  you may  not use this file except  in compliance with the
       
    12  * License.    You    may   obtain   a   copy   of    the   License    at
       
    13  * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
       
    14  * applicable law  or agreed to  in writing,  software  distributed under
       
    15  * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
       
    16  * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
       
    17  * for the specific language governing permissions  and limitations under
       
    18  * the License.
       
    19  *
       
    20  **************************************************************************/
       
    21 
       
    22 // expand _TEST_EXPORT macros
       
    23 #define _RWSTD_TEST_SRC
       
    24 
       
    25 #include "opt_diags.h"
       
    26 #include "opt_lines.h"
       
    27 #include "opt_trace.h"
       
    28 #include "opt_types.h"
       
    29 
       
    30 #include <cmdopt.h>    // for rw_setopts()
       
    31 #include <printf.h>    // for rw_snprintfa()
       
    32 
       
    33 #include <assert.h>    // for assert
       
    34 #include <setjmp.h>    // for longjmp, setjmp, ...
       
    35 #include <stdarg.h>    // for va_list
       
    36 #include <stdio.h>     // for fileno, fprintf
       
    37 #include <stdlib.h>    // for free
       
    38 #include <string.h>    // for strchr, strcpy
       
    39 #include"std_log_result.h"
       
    40 #define LOG_FILENAME_LINE __FILE__, __LINE__
       
    41 #if !defined (_WIN32) && !defined (_WIN64)
       
    42 #  include <unistd.h>    // for isatty
       
    43 
       
    44 // declare fileno in case it's not declared (for strict ANSI conformance)
       
    45 extern "C" {
       
    46 
       
    47 IMPORT_C int (fileno)(FILE*) _LIBC_THROWS ();
       
    48 
       
    49 }   // extern "C"
       
    50 
       
    51 #else
       
    52    // no isatty on Windoze
       
    53 #  define _RWSTD_NO_ISATTY
       
    54 #endif   // _WIN{32,64}
       
    55 
       
    56 // expand _TEST_EXPORT macros
       
    57 #define _RWSTD_TEST_SRC
       
    58 #include <driver.h>
       
    59 
       
    60 /************************************************************************/
       
    61 
       
    62 #define RW_TEST_STRSTR(x)   #x
       
    63 #define RW_TEST_STR(x)      RW_TEST_STRSTR(x)
       
    64 
       
    65 #ifndef RW_TEST_COMPILER
       
    66 #  if defined (__DECCXX__)
       
    67 #    define RW_TEST_COMPILER "Compaq C++, __DECCXX__ = " \
       
    68             RW_TEST_STR (__DECCXX__)
       
    69 #  elif defined (__INTEL_COMPILER)
       
    70 #    if defined (__EDG_VERSION__)
       
    71 #      define RW_TEST_ICC_EDG_VER \
       
    72               ", __EDG_VERSION__ = "  RW_TEST_STR (__EDG_VERSION__)
       
    73 #    else
       
    74 #      define RW_TEST_ICC_EDG_VER ""
       
    75 #    endif
       
    76 #    if defined (_MSC_VER)
       
    77 #      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
       
    78               RW_TEST_STR (__INTEL_COMPILER) ", _MSC_VER = " \
       
    79               RW_TEST_STR (_MSC_VER) \
       
    80               RW_TEST_ICC_EDG_VER
       
    81 #    elif defined (__INTEL_COMPILER_BUILD_DATE)
       
    82 #      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
       
    83               RW_TEST_STR (__INTEL_COMPILER) \
       
    84               ", __INTEL_COMPILER_BUILD_DATE = " \
       
    85               RW_TEST_STR (__INTEL_COMPILER_BUILD_DATE) \
       
    86               RW_TEST_ICC_EDG_VER
       
    87 #    else
       
    88 #      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
       
    89               RW_TEST_STR (__INTEL_COMPILER) \
       
    90               RW_TEST_ICC_EDG_VER
       
    91 #    endif
       
    92 #  elif defined (__GNUC__)
       
    93 #    if defined (__VERSION__)
       
    94 #      define RW_TEST_GCC_VER ", __VERSION__ = \"" __VERSION__ "\""
       
    95 #    else
       
    96 #      define RW_TEST_GCC_VER ""
       
    97 #    endif
       
    98 #    if defined (__GNUC_PATCHLEVEL__)
       
    99 #      define RW_TEST_COMPILER "gcc "            \
       
   100               RW_TEST_STR (__GNUC__) "."         \
       
   101               RW_TEST_STR (__GNUC_MINOR__) "."   \
       
   102               RW_TEST_STR (__GNUC_PATCHLEVEL__)  \
       
   103               RW_TEST_GCC_VER
       
   104 #    else
       
   105 #      define RW_TEST_COMPILER "gcc " \
       
   106               RW_TEST_STR (__GNUC__) "." RW_TEST_STR (__GNUC_MINOR__) 
       
   107               RW_TEST_GCC_VER
       
   108 #    endif
       
   109 #  elif defined (_COMPILER_VERSION) && defined (__sgi)
       
   110 #    define RW_TEST_COMPILER "SGI MIPSpro, _COMPILER_VERSION = " \
       
   111             RW_TEST_STR (_COMPILER_VERSION)
       
   112 #  elif defined (__INTEL_COMPILER)
       
   113 #    if defined (_MSC_VER)
       
   114 #      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
       
   115               RW_TEST_STR (__INTEL_COMPILER) ", _MSC_VER = " \
       
   116               RW_TEST_STR (_MSC_VER)
       
   117 #    else
       
   118 #      define RW_TEST_COMPILER "Intel C++, __INTEL_COMPILER = " \
       
   119               RW_TEST_STR (__INTEL_COMPILER)
       
   120 #    endif
       
   121 #  elif defined (__EDG__)
       
   122 #    define RW_TEST_COMPILER "EDG eccp, __EDG_VERSION__ = " \
       
   123             RW_TEST_STR (__EDG_VERSION__)
       
   124 #  elif defined (__HP_aCC)
       
   125 #    define RW_TEST_COMPILER "HP aCC, __HP_aCC = " \
       
   126             RW_TEST_STR (__HP_aCC)
       
   127 #  elif defined (__IBMCPP__)
       
   128 #    define RW_TEST_COMPILER "IBM VisualAge C++, __IBMCPP__ = " \
       
   129             RW_TEST_STR (__IBMCPP__)
       
   130 #  elif defined (_MSC_VER)
       
   131 #    define RW_TEST_COMPILER "MSVC, _MSC_VER = " \
       
   132             RW_TEST_STR (_MSC_VER)
       
   133 #  elif defined (__SUNPRO_CC)
       
   134 #    define RW_TEST_COMPILER "SunPro, __SUNPRO_CC = " \
       
   135             RW_TEST_STR (__SUNPRO_CC)
       
   136 #  else
       
   137 #    define RW_TEST_COMPILER "unknown"
       
   138 #  endif
       
   139 #endif
       
   140 
       
   141 #ifndef RW_TEST_LIBSTD
       
   142 #  ifdef _RWSTD_VER
       
   143 #    define RW_TEST_LIBSTD "Rogue Wave C++ Standard Library, " \
       
   144             "_RWSTD_VER = " RW_TEST_STR (_RWSTD_VER)
       
   145 #  elif defined (__GLIBCXX__)
       
   146 #    define RW_TEST_LIBSTD "GNU C++ Standard Library, " \
       
   147             "__GLIBCXX__ = " \
       
   148             RW_TEST_STR (__GLIBCXX__)
       
   149 #  elif defined (_STLPORT_VERSION)
       
   150      // check for STLport before SGI STL since STLport,
       
   151      // being derived from SGI STL, #defines both macros
       
   152 #    define RW_TEST_LIBSTD "STLport, " \
       
   153             "_STLPORT_VERSION = " \
       
   154             RW_TEST_STR (_STLPORT_VERSION)
       
   155 #  elif defined (__SGI_STL)
       
   156 #    define RW_TEST_LIBSTD "SGI STL, " \
       
   157             "__SGI_STL = " \
       
   158             RW_TEST_STR (__SGI_STL)
       
   159 #  elif defined (_YVALS)
       
   160      // is there a better way to identify the Dinkumware
       
   161      // implementation? does it have a version macro?
       
   162 #    define RW_TEST_LIBSTD "Dinkum C++ Standard Library"
       
   163 #  endif
       
   164 #endif   // RW_TEST_LIBSTD
       
   165 
       
   166 #ifndef RW_TEST_HARDWARE
       
   167 #  if defined (__alpha__) || defined (__alpha)
       
   168 #    define RW_TEST_ARCH "alpha"
       
   169 #  elif defined (__amd64__) || defined (__amd64)
       
   170 #    if defined (__LP64__) || defined (_LP64)
       
   171 #      define RW_TEST_ARCH "amd64/LP64"
       
   172 #    else
       
   173 #      define RW_TEST_ARCH "amd64/ILP32"
       
   174 #    endif
       
   175 #  elif defined (_PA_RISC2_0)
       
   176 #    define RW_TEST_ARCH "pa-risc 2.0"
       
   177 #  elif defined (_PA_RISC1_0)
       
   178 #    define RW_TEST_ARCH "pa-risc 1.0"
       
   179 #  elif defined (__hppa)
       
   180 #    define RW_TEST_ARCH "pa-risc"
       
   181 #  elif defined (__pentiumpro__) || defined (__pentiumpro)
       
   182 #    define RW_TEST_ARCH "pentiumpro"
       
   183 #  elif defined (__pentium__) || defined (__pentium)
       
   184 #    define RW_TEST_ARCH "pentium"
       
   185 #  elif defined (__i486__) || defined (__i486)
       
   186 #    define RW_TEST_ARCH "i486"
       
   187 #  elif defined (__i386__) || defined (__i386)
       
   188 #    define RW_TEST_ARCH "i386"
       
   189 #  elif defined (__i586__) || defined (__i586)
       
   190 #    define RW_TEST_ARCH "i586"
       
   191 #  elif defined (__ia64)
       
   192 #    define RW_TEST_ARCH "ia64"
       
   193 #  elif defined (__mips)
       
   194 #    define RW_TEST_ARCH "mips"
       
   195 #  elif defined (__sparcv9)
       
   196 #    define RW_TEST_ARCH "sparc-v9"
       
   197 #  elif defined (__sparcv8)
       
   198 #    define RW_TEST_ARCH "sparc-v8"
       
   199 #  elif defined (__sparc)
       
   200 #    define RW_TEST_ARCH "sparc"
       
   201 #  elif defined (_POWER)
       
   202 #    if defined (_ARCH_PWR5)
       
   203 #      define RW_TEST_ARCH "power-5"
       
   204 #    elif defined (_ARCH_PWR4)
       
   205 #      define RW_TEST_ARCH "power-4"
       
   206 #    elif defined (_ARCH_PWR3)
       
   207 #      define RW_TEST_ARCH "power-3"
       
   208 #    elif defined (_ARCH_604)
       
   209 #      define RW_TEST_ARCH "powerpc-604"
       
   210 #    elif defined (_ARCH_603)
       
   211 #      define RW_TEST_ARCH "powerpc-603"
       
   212 #    elif defined (_ARCH_602)
       
   213 #      define RW_TEST_ARCH "powerpc-602"
       
   214 #    elif defined (_ARCH_601)
       
   215 #      define RW_TEST_ARCH "powerpc-601"
       
   216 #    elif defined (_ARCH_403)
       
   217 #      define RW_TEST_ARCH "powerpc-403"
       
   218 #    elif defined (_ARCH_PPC64)
       
   219 #      define RW_TEST_ARCH "powerpc/LP64"
       
   220 #    else
       
   221 #      define RW_TEST_ARCH "powerpc"
       
   222 #    endif
       
   223 #  elif defined (_WIN64)
       
   224 #    define RW_TEST_ARCH "ia64"
       
   225 #  elif defined (_WIN32)
       
   226 #    define RW_TEST_ARCH "i86"
       
   227 #  elif defined (__x86_64__) || defined (__x86_64)
       
   228 #    if defined (__LP64__) || defined (_LP64)
       
   229 #      define RW_TEST_ARCH "x86_64/LP64"
       
   230 #    else
       
   231 #      define RW_TEST_ARCH "x86_64/ILP32"
       
   232 #    endif
       
   233 #  else
       
   234 #    define RW_TEST_ARCH "unknown"
       
   235 #  endif
       
   236 
       
   237 
       
   238 #  if defined (_AIX54)
       
   239 #    define RW_TEST_OS "aix-5.4 (or better)"
       
   240 #  elif defined (_AIX53)
       
   241 #    define RW_TEST_OS "aix-5.3"
       
   242 #  elif defined (_AIX52)
       
   243 #    define RW_TEST_OS "aix-5.2"
       
   244 #  elif defined (_AIX51)
       
   245 #    define RW_TEST_OS "aix-5.1"
       
   246 #  elif defined (_AIX50)
       
   247 #    define RW_TEST_OS "aix-5.0"
       
   248 #  elif defined (_AIX43)
       
   249 #    define RW_TEST_OS "aix-4.3"
       
   250 #  elif defined (_AIX41)
       
   251 #    define RW_TEST_OS "aix-4.1"
       
   252 #  elif defined (_AIX32)
       
   253 #    define RW_TEST_OS "aix-3.2"
       
   254 #  elif defined (_AIX)
       
   255 #    define RW_TEST_OS "aix"
       
   256 #  elif defined (__hpux)
       
   257 #    define RW_TEST_OS "hp-ux"
       
   258 #  elif defined (__osf__)
       
   259 #    define RW_TEST_OS "tru64-unix"
       
   260 #  elif defined (__sgi) && defined (__mips)
       
   261 #    define RW_TEST_OS "irix"
       
   262 #  elif defined (__linux__) || defined (__linux)
       
   263 
       
   264      // get Linux release string (UTS_RELEASE)
       
   265 #    include <linux/version.h>
       
   266 
       
   267 #    ifndef UTS_RELEASE
       
   268 #      define UTS_RELEASE "(unknown release)"
       
   269 #    endif   // UTS_RELEASE
       
   270 
       
   271 #    if defined (__ELF__)
       
   272 #      define LINUX_TYPE "linux-elf"
       
   273 #    else
       
   274 #      define LINUX_TYPE "linux"
       
   275 #    endif
       
   276 
       
   277 #    define RW_TEST_OS LINUX_TYPE " "     \
       
   278             UTS_RELEASE " with glibc "    \
       
   279             RW_TEST_STR (__GLIBC__) "."   \
       
   280             RW_TEST_STR (__GLIBC_MINOR__)
       
   281 
       
   282 #  elif defined (__SunOS_5_10)
       
   283 #    define RW_TEST_OS "sunos-5.10"
       
   284 #  elif defined (__SunOS_5_9)
       
   285 #    define RW_TEST_OS "sunos-5.9"
       
   286 #  elif defined (__SunOS_5_8)
       
   287 #    define RW_TEST_OS "sunos-5.8"
       
   288 #  elif defined (__SunOS_5_7)
       
   289 #    define RW_TEST_OS "sunos-5.7"
       
   290 #  elif defined (__SunOS_5_6)
       
   291 #    define RW_TEST_OS "sunos-5.6"
       
   292 #  elif defined (__sun__)
       
   293 #    define RW_TEST_OS "sunos"
       
   294 #  elif defined (_WIN64)
       
   295 #    define RW_TEST_OS "win64"
       
   296 #  elif defined (_WIN32)
       
   297 #    define RW_TEST_OS "win32"
       
   298 #  else
       
   299 #    define RW_TEST_OS "unknown"
       
   300 #  endif
       
   301 
       
   302 #  define RW_TEST_HARDWARE RW_TEST_ARCH " running " RW_TEST_OS
       
   303 #else
       
   304 #  define RW_TEST_HARDWARE "unknown"
       
   305 #endif
       
   306 
       
   307 /************************************************************************/
       
   308 
       
   309 // defined in printf.cpp but not declared in printf.h
       
   310 _TEST_EXPORT int
       
   311 rw_vasnprintf (char**, size_t*, const char*, va_list);
       
   312 
       
   313 /************************************************************************/
       
   314 
       
   315 // array to store the number of each type of diagnostic
       
   316 static int
       
   317 ndiags [N_DIAG_TYPES][2] /* = { { total, active }, ... }*/;
       
   318 
       
   319 static FILE *ftestout;
       
   320 
       
   321 static jmp_buf test_env;
       
   322 
       
   323 // set to 1 after the driver has been initialized
       
   324 static int driver_initialized = 0;
       
   325 
       
   326 // set to 1 after the driver has finished running
       
   327 static int driver_finished = 0;
       
   328 
       
   329 #if 0   // disabled
       
   330 // %S: severity
       
   331 // %M: diagnostic
       
   332 // %m: diagnostic if not empty
       
   333 // %F: file name
       
   334 // %f: file name if not empty
       
   335 // %C: clause
       
   336 // %c: clause if not empty
       
   337 // %L: line number
       
   338 // %l: line number if valid
       
   339 // %T: text
       
   340 // %t: text if not empty
       
   341 static char diag_pattern [80];
       
   342 #endif
       
   343 
       
   344 // option: use CSV format (comma separated values)
       
   345 static int _rw_opt_csv = 0;
       
   346 
       
   347 static char clause_id [80];
       
   348 
       
   349 /************************************************************************/
       
   350 
       
   351 #define CHECK_INIT(init, func)   _rw_check_init (init, __LINE__, func)
       
   352 
       
   353 static inline void
       
   354 _rw_check_init (bool init, int line, const char *func)
       
   355 {
       
   356     if (init && !driver_initialized) {
       
   357         fprintf (stderr, "%s:%d: %s: test driver already initialized\n",
       
   358                  __FILE__, line, func);
       
   359      std_log(LOG_FILENAME_LINE,"%s:%d: %s: test driver already initialized\n",
       
   360                  __FILE__, line, func);                 
       
   361         abort ();
       
   362     }
       
   363 
       
   364     if (!init && driver_initialized) {
       
   365         fprintf (stderr, "%s:%d: %s: test driver not initialized yet\n",
       
   366                  __FILE__, line, func);
       
   367       std_log(LOG_FILENAME_LINE,"%s:%d: %s: test driver not initialized yet\n",
       
   368                  __FILE__, line, func);                  
       
   369         abort ();
       
   370     }
       
   371 
       
   372     if (driver_finished) {
       
   373         fprintf (stderr, "%s:%d: %s: test finished, cannot call\n",
       
   374                  __FILE__, line, func);
       
   375      std_log(LOG_FILENAME_LINE,"%s:%d: %s: test finished, cannot call\n",
       
   376                  __FILE__, line, func);                 
       
   377     }
       
   378 }
       
   379 
       
   380 /************************************************************************/
       
   381 
       
   382 static int
       
   383 _rw_opt_brief (int argc, char *argv[])
       
   384 {
       
   385     static int opt_brief;
       
   386 
       
   387     if (0 == argc) {
       
   388         // query mode: return the value of the option
       
   389         return opt_brief;
       
   390     }
       
   391 
       
   392     if (1 == argc && argv && 0 == argv [0]) {
       
   393         // help mode: set argv[0] to the text of the help message
       
   394 
       
   395         static const char helpstr[] = {
       
   396             "Enables brief mode.\n"
       
   397         };
       
   398 
       
   399         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   400 
       
   401         return 0;
       
   402     }
       
   403 
       
   404     // set mode: enable the option
       
   405     opt_brief = 1;
       
   406 
       
   407     return 0;
       
   408 }
       
   409 
       
   410 /************************************************************************/
       
   411 
       
   412 static int
       
   413 _rw_opt_quiet (int argc, char *argv[])
       
   414 {
       
   415     static int opt_quiet;
       
   416 
       
   417     if (0 == argc) {
       
   418         // query mode: return the value of the option
       
   419         return opt_quiet;
       
   420     }
       
   421 
       
   422     if (1 == argc && argv && 0 == argv [0]) {
       
   423         // help mode: set argv[0] to the text of the help message
       
   424 
       
   425         static const char helpstr[] = {
       
   426             "Enables quiet mode.\n"
       
   427             "In quiet mode only diagnostics with severity 7 and above are "
       
   428             "issued."
       
   429         };
       
   430 
       
   431         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   432 
       
   433         return 0;
       
   434     }
       
   435 
       
   436     // set mode: enable the option
       
   437     _rw_diag_mask = ~((1 << 7) | (1 << 8) | (1 << 9));
       
   438     opt_quiet     = 1;
       
   439 
       
   440     return 0;
       
   441 }
       
   442 
       
   443 /************************************************************************/
       
   444 
       
   445 static int
       
   446 _rw_opt_verbose (int argc, char *argv[])
       
   447 {
       
   448     static int opt_verbose;
       
   449 
       
   450     if (0 == argc) {
       
   451         // query mode: return the value of the option
       
   452         return opt_verbose;
       
   453     }
       
   454 
       
   455     if (1 == argc && argv && 0 == argv [0]) {
       
   456         // help mode: set argv[0] to the text of the help message
       
   457 
       
   458         static const char helpstr[] = {
       
   459             "Enables verbose mode.\n"
       
   460         };
       
   461 
       
   462         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   463 
       
   464         return 0;
       
   465     }
       
   466 
       
   467     // set mode: enable the option
       
   468     opt_verbose = 1;
       
   469 
       
   470     return 0;
       
   471 }
       
   472 
       
   473 /************************************************************************/
       
   474 
       
   475 static int
       
   476 _rw_setopt_csv (int argc, char *argv[])
       
   477 {
       
   478     if (1 == argc && argv && 0 == argv [0]) {
       
   479         static const char helpstr[] = {
       
   480             "Enables CSV (comma separated values) mode.\n"
       
   481         };
       
   482 
       
   483         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   484 
       
   485         return 0;
       
   486     }
       
   487 
       
   488     _rw_opt_csv = 1;
       
   489     return 0;
       
   490 }
       
   491 
       
   492 /************************************************************************/
       
   493 
       
   494 static int
       
   495 _rw_opt_compat (int argc, char *argv[])
       
   496 {
       
   497     static int opt_compat;
       
   498 
       
   499     if (0 == argc) {
       
   500         // query mode: return the value of the option
       
   501         return opt_compat;
       
   502     }
       
   503 
       
   504     if (1 == argc && argv && 0 == argv [0]) {
       
   505         // help mode: set argv[0] to the text of the help message
       
   506 
       
   507         static const char helpstr[] = {
       
   508             "Enables RWTest-format compatibility mode.\n"
       
   509         };
       
   510 
       
   511         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   512 
       
   513         return 0;
       
   514     }
       
   515 
       
   516     // set mode: enable the option
       
   517     opt_compat = 1;
       
   518 
       
   519     return 0;
       
   520 }
       
   521 
       
   522 /************************************************************************/
       
   523 
       
   524 static int
       
   525 _rw_opt_no_stdout (int argc, char *argv[])
       
   526 {
       
   527     static int opt_no_stdout;
       
   528 
       
   529     if (0 == argc) {
       
   530         // query mode: return the value of the option
       
   531         return opt_no_stdout;
       
   532     }
       
   533 
       
   534     if (1 == argc && argv && 0 == argv [0]) {
       
   535         // help mode: set argv[0] to the text of the help message
       
   536 
       
   537         static const char helpstr[] = {
       
   538             "Prevents the program from using stdandard output for diagnostic\n"
       
   539             "messages. Instead, the driver will create a log file with a name\n"
       
   540             "obtained from the from the basename of the program source file,\n"
       
   541             "usually obtained by passing the value of the __FILE__ macro to\n"
       
   542             "the driver, with the .out extension. If successful, the driver\n"
       
   543             "will write all diagnostic messages issued by the program to this\n"
       
   544             "file. Otherwise, the driver exits with an error.\n"
       
   545         };
       
   546 
       
   547         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   548 
       
   549         return 0;
       
   550     }
       
   551     
       
   552     // set mode: enable the option
       
   553     opt_no_stdout = 1;
       
   554 
       
   555     return 0;
       
   556 }
       
   557 
       
   558 /************************************************************************/
       
   559 
       
   560 static int
       
   561 _rw_setopt_output_file (int argc, char *argv[])
       
   562 {
       
   563     if (1 == argc && argv && 0 == argv [0]) {
       
   564         static const char helpstr[] = {
       
   565             "Specifies the name of the output file to be used by the program\n"
       
   566             "for diagnostic messages. Unless this option is specified, the\n"
       
   567             "program will issue all diagnostic messages to the standard output."
       
   568             "\nDriver diagnostics are always directed to stderr.\n"
       
   569         };
       
   570 
       
   571         argv [0] = _RWSTD_CONST_CAST (char*, helpstr);
       
   572 
       
   573         return 0;
       
   574     }
       
   575 
       
   576     const char *file_name = 0;
       
   577 
       
   578     if ('-' == argv [0][0] && 'O' == argv [0][1] || 'o' == argv [0][1]) {
       
   579         file_name = argv [0] + 2;
       
   580     }
       
   581     else if (1 < argc && '-' != argv [1][0]) {
       
   582         file_name = argv [1];
       
   583     }
       
   584 
       
   585     if (file_name) {
       
   586 
       
   587         FILE* const f = fopen (file_name, "w");
       
   588 
       
   589         if (f) {
       
   590             if (ftestout && ftestout != stderr)
       
   591                 fclose (ftestout);
       
   592 
       
   593             ftestout = f;
       
   594         }
       
   595     }
       
   596 
       
   597     // return 0 on success, any non-zero value on failure
       
   598     return !(ftestout != 0);
       
   599 }
       
   600 
       
   601 /************************************************************************/
       
   602 
       
   603 _TEST_EXPORT int
       
   604 rw_vsetopts (const char *opts, va_list va);
       
   605 
       
   606 /************************************************************************/
       
   607 
       
   608 static int
       
   609 _rw_use_color ()
       
   610 {
       
   611 #ifndef _RWSTD_NO_ISATTY
       
   612 
       
   613     // is output sent to a terminal?
       
   614     // if so, assume a vt100 compatible terminal for now
       
   615     static const int tty = isatty (fileno (ftestout));
       
   616 
       
   617 #else   // if defined (_RWSTD_NO_ISATTY)
       
   618 
       
   619     // FIXME: deal with a missing isatty() and Windows
       
   620     static const int tty = 0;
       
   621 
       
   622 #endif   // _RWSTD_NO_ISATTY
       
   623 
       
   624     return 0 != tty;
       
   625 }
       
   626 
       
   627 /************************************************************************/
       
   628 
       
   629 _TEST_EXPORT int
       
   630 rw_vtest (int argc, char **argv,
       
   631           const char *file_name,
       
   632           const char *clause,
       
   633           const char *comment,
       
   634           int (*fun)(int, char**),
       
   635           const char *optstr,
       
   636           va_list     va)
       
   637 {
       
   638     CHECK_INIT (false, "rw_vtest()");
       
   639 
       
   640     driver_initialized = 1;
       
   641 
       
   642     if (optstr && 0 > rw_vsetopts (optstr, va)) {
       
   643         fprintf (stderr, "%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
       
   644         std_log(LOG_FILENAME_LINE,"%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
       
   645         return 1;
       
   646     }
       
   647 
       
   648     const int nopts =
       
   649         rw_setopts ("|-no-stdout "
       
   650                     "|-diags= "      // argument required
       
   651                     "|-trace "
       
   652                     "|-severity= "   // argument required
       
   653                     "|-csv "
       
   654                     "|-compat "
       
   655                     "o|-output:"     // argument optional
       
   656                     "b|-brief "
       
   657                     "q|-quiet "
       
   658                     "v|-verbose",
       
   659                     _rw_opt_no_stdout,
       
   660                     _rw_setopt_diags,
       
   661                     _rw_setopt_trace,
       
   662                     _rw_setopt_trace_mask,
       
   663                     _rw_setopt_csv,
       
   664                     _rw_opt_compat,
       
   665                     _rw_setopt_output_file,
       
   666                     _rw_opt_brief,
       
   667                     _rw_opt_quiet,
       
   668                     _rw_opt_verbose,
       
   669                     0);
       
   670 
       
   671     if (3 > nopts) {
       
   672         fprintf (stderr, "%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
       
   673         std_log(LOG_FILENAME_LINE,"%s:%d: rw_setopts() failed\n", __FILE__, __LINE__);
       
   674         abort ();
       
   675         return 1;
       
   676     }
       
   677 
       
   678 #ifndef _RWSTD_USE_CONFIG
       
   679 
       
   680     // enable RWTest-format compatibility mode
       
   681     _rw_opt_compat (1, 0);
       
   682 
       
   683     // disable output to stdout
       
   684     _rw_opt_no_stdout (1, 0);
       
   685 
       
   686 #endif   // _RWSTD_USE_CONFIG
       
   687 
       
   688     _rw_setopts_types ();
       
   689 
       
   690     _rw_setopts_lines ();
       
   691 
       
   692     int status = rw_runopts (argc, argv);
       
   693 
       
   694     if (status)
       
   695         return status;
       
   696 
       
   697     if (0 == ftestout) {
       
   698 
       
   699         if (_rw_opt_no_stdout (0, 0) && file_name) {
       
   700             char fname [256] = "C:\\";
       
   701 
       
   702             const char* const slash = strrchr (file_name, _RWSTD_PATH_SEP);
       
   703             strcat (fname, slash ? slash + 1 : file_name);
       
   704 
       
   705             char* const dot = strchr (fname, '.');
       
   706             if (dot)
       
   707                 strcpy (dot, ".out");
       
   708             else
       
   709                 strcat (fname, ".out");
       
   710 
       
   711             ftestout = fopen (fname, "w");
       
   712         }
       
   713         else
       
   714             ftestout = stdout;
       
   715     }
       
   716 
       
   717     if (clause)
       
   718         strcpy (clause_id, clause);
       
   719 
       
   720     const char begin_fmt[] = {
       
   721         "\n"
       
   722         "# COMPILER: %s\n"
       
   723         "# ENVIRONMENT: %s\n"
       
   724         "# FILE: %s\n"
       
   725         "# COMPILED: %s, %s\n"
       
   726         "# COMMENT: %s\n"
       
   727         "######################################################"
       
   728     };
       
   729 
       
   730     const char* const fname = strrchr (file_name, _RWSTD_PATH_SEP);
       
   731 
       
   732     rw_info (0, 0, 0,
       
   733              begin_fmt,
       
   734              RW_TEST_COMPILER, RW_TEST_HARDWARE,
       
   735              fname ? fname + 1 : file_name,
       
   736              __DATE__, __TIME__,
       
   737              comment ? comment : "");
       
   738 
       
   739     status = setjmp (test_env);
       
   740 
       
   741     if (0 == status) {
       
   742         // environment set, execute the callback function
       
   743         status = fun (argc, argv);
       
   744     }
       
   745     else {
       
   746         // fatal test error (via a call to rw_fatal())
       
   747     }
       
   748 
       
   749     driver_finished = 1;
       
   750 
       
   751     static const char tblrow[] =
       
   752         "+-----------------------+--------+--------+--------+";
       
   753 
       
   754     fprintf (ftestout,
       
   755              "# %s\n"
       
   756              "# | DIAGNOSTIC            | ACTIVE |  TOTAL |INACTIVE|\n"
       
   757              "# %s\n",
       
   758              tblrow, tblrow);
       
   759 
       
   760     int nlines = 0;
       
   761 
       
   762     for (int i = 0; i != N_DIAG_TYPES; ++i) {
       
   763         if (ndiags [i][0] || !(_rw_diag_mask & (1 << diag_trace))) {
       
   764 
       
   765             // print out details for any non-zero totals
       
   766             // or for all totals when debugging or tracing
       
   767             // is enabled
       
   768 
       
   769             ++nlines;
       
   770 
       
   771             const long num = (ndiags [i][0] - ndiags [i][1]) * 100L;
       
   772             const long den = ndiags [i][0];
       
   773 
       
   774             const long pct = den ? num / den : 0;
       
   775 
       
   776             const char* pfx = "";
       
   777             const char* sfx = "";
       
   778 
       
   779             static int use_color = _rw_use_color ();
       
   780 
       
   781             if (use_color) {
       
   782                 pfx = ndiags [i][1] ? diag_msgs [i].esc_pfx : "";
       
   783                 sfx = ndiags [i][1] ? diag_msgs [i].esc_sfx : "";
       
   784             }
       
   785 
       
   786             fprintf (ftestout,
       
   787                      "# | (S%d) %-*s |%s %6d %s| %6d | %5ld%% |\n",
       
   788                      i, int (sizeof diag_msgs [i].code), diag_msgs [i].code,
       
   789                      pfx, ndiags [i][1], sfx, ndiags [i][0], pct);
       
   790         }
       
   791     }
       
   792 
       
   793     if (0 == nlines)
       
   794         fprintf (ftestout, "# no diagnostics\n");
       
   795 
       
   796     fprintf (ftestout, "# %s\n", tblrow);
       
   797 
       
   798     if (_rw_opt_compat (0, 0)) {
       
   799 
       
   800         // TO DO: get rid of this
       
   801 
       
   802         // RWTest compatibility format
       
   803 
       
   804         fprintf (ftestout,
       
   805                  "######################################################\n"
       
   806                  "## Warnings = %d\n"
       
   807                  "## Assertions = %d\n"
       
   808                  "## FailedAssertions = %d\n",
       
   809                  ndiags [diag_warn][1] + ndiags [diag_xwarn][1],
       
   810                  ndiags [diag_assert][0],
       
   811                  ndiags [diag_assert][1] + ndiags [diag_xassert][1]);
       
   812     }
       
   813 
       
   814     fclose (ftestout);
       
   815     ftestout = 0;
       
   816 
       
   817     return status;
       
   818 }
       
   819 
       
   820 /************************************************************************/
       
   821 
       
   822 _TEST_EXPORT int
       
   823 rw_test (int argc, char **argv,
       
   824          const char *fname,
       
   825          const char *clause,
       
   826          const char *comment,
       
   827          int (*testfun)(int, char**),
       
   828          const char *optstr,
       
   829          ...)
       
   830 {
       
   831     CHECK_INIT (false, "rw_test()");
       
   832 
       
   833     va_list va;
       
   834     va_start (va, optstr);
       
   835 
       
   836     const int status =
       
   837         rw_vtest (argc, argv, fname, clause, comment, testfun, optstr, va);
       
   838 
       
   839     va_end (va);
       
   840 
       
   841     return status;
       
   842 }
       
   843 
       
   844 /************************************************************************/
       
   845 
       
   846 // escape every occurrence of the double quote character in the string
       
   847 // pointed to by buf by prepending to it the escape character specified
       
   848 // by the last acrgument
       
   849 // returns the new buffer if the size of the existing buffer isn't
       
   850 // sufficient and sets *pbufsize to the size of the newly allocated
       
   851 // buffer, otherwise the original value of buf and leaves *pbufsize
       
   852 // unchanged
       
   853 static char*
       
   854 _rw_escape (char *buf, size_t bufsize, char esc)
       
   855 {
       
   856     // handle null buffer
       
   857     if (0 == buf)
       
   858         return buf;
       
   859 
       
   860     // count the number of embedded quotes
       
   861     char *quote = buf;
       
   862     size_t nquotes = 0;
       
   863     
       
   864     #ifdef __ARMCC__
       
   865     #pragma diag_suppress 1293
       
   866     #endif
       
   867     while ((quote = strchr (quote, '"'))) {
       
   868         ++nquotes;
       
   869         ++quote;
       
   870     }
       
   871     
       
   872 
       
   873     // no quotes found, return the original buffer
       
   874     if (0 == nquotes)
       
   875         return buf;
       
   876 
       
   877     // conpute the size of the buffer that will be needed to escape
       
   878     // all the double quotes
       
   879     size_t newbufsize = strlen (buf) + nquotes + 1;
       
   880 
       
   881     char *newbuf = 0;
       
   882 
       
   883     if (0 /* newbufsize <= bufsize */) {
       
   884         // FIXME: escape embedded quotes in place w/o reallocation
       
   885         _RWSTD_UNUSED (bufsize);
       
   886     }
       
   887     else {
       
   888         newbuf = (char*)malloc (newbufsize);
       
   889         if (0 == newbuf) {
       
   890             return 0;
       
   891         }
       
   892 
       
   893         // set the next pointer to the beginning of the new buffer
       
   894         // as the destination where to copy the string argument
       
   895         char *next = newbuf;
       
   896 
       
   897         // set quote to initially point to the beginning of
       
   898         // the source buffer and then just past the last quote
       
   899         quote = buf;
       
   900 
       
   901         for (char *q = buf; ; ++q) {
       
   902 
       
   903             // look for the next (or first) quote
       
   904             q = strchr (q, '"');
       
   905 
       
   906             // compute the number of characters, excluding the quote
       
   907             // to copy to the destination buffer
       
   908             const size_t nchars = q ? size_t (q - quote) : strlen (quote);
       
   909 
       
   910             memcpy (next, quote, nchars);
       
   911 
       
   912             if (q) {
       
   913                 // append the escape character to the destination buffer
       
   914                 next [nchars] = esc;
       
   915 
       
   916                 // append the quote from the source string
       
   917                 next [nchars + 1] = '"';
       
   918 
       
   919                 // advance the destination pointer past the quote
       
   920                 next += nchars + 2;
       
   921 
       
   922                 // advance the source pointer past the embedded quote
       
   923                 quote = q + 1;
       
   924             }
       
   925             else {
       
   926                 // NUL-terminate the destination buffer
       
   927                 *next = '\0';
       
   928                 break;
       
   929             }
       
   930         }
       
   931     }
       
   932 
       
   933     return newbuf;
       
   934 }
       
   935 
       
   936 /************************************************************************/
       
   937 
       
   938 static void
       
   939 _rw_vissue_diag (diag_t diag, int severity, const char *file, int line,
       
   940                  const char *fmt, va_list va)
       
   941 {
       
   942     CHECK_INIT (true, "_rw_vissue_diag()");
       
   943 
       
   944     if (0 == fmt)
       
   945         fmt = "";
       
   946 
       
   947     static char fmterr[] = "*** formatting error ***";
       
   948 
       
   949     char *usrbuf = 0;
       
   950     const int nchars = rw_vasnprintf (&usrbuf, 0, fmt, va);
       
   951 
       
   952     if (nchars < 0 || 0 == usrbuf)
       
   953         usrbuf = fmterr;
       
   954 
       
   955     // compute the number of newline characters in the text
       
   956     int nlines = 0;
       
   957     
       
   958     #ifdef __ARMCC__
       
   959     #pragma diag_suppress 1293
       
   960     #endif
       
   961     for (const char *nl = usrbuf; (nl = strchr (nl, '\n')); ++nl)
       
   962         ++nlines;
       
   963     
       
   964 
       
   965     static const int use_color = _rw_use_color ();
       
   966 
       
   967     const char* const diagstr[] = {
       
   968         use_color ? diag_msgs [severity].esc_pfx : "",
       
   969         *diag_msgs [severity].code ? diag_msgs [severity].code : "UNKNOWN",
       
   970         use_color  ? diag_msgs [severity].esc_sfx : "",
       
   971         _rw_opt_verbose (0, 0) && *diag_msgs [severity].desc ?
       
   972         diag_msgs [severity].desc : 0
       
   973     };
       
   974 
       
   975     const char* const traced_diag =
       
   976         0 == severity && diag_msgs [diag].code ? diag_msgs [diag].code : 0;
       
   977 
       
   978     const char* const slash = file ? strrchr (file, _RWSTD_PATH_SEP) : 0;
       
   979     if (slash)
       
   980         file = slash + 1;
       
   981 
       
   982     char *mybuf = 0;
       
   983 
       
   984     if (_rw_opt_csv) {
       
   985 
       
   986         // format all fields as comma separated values (CSV):
       
   987         // -- a field containing the quote character, the comma,
       
   988         //    or the newline or linefeed character must be enclosed
       
   989         //    in a pair of double quotes
       
   990         // -- every occurrence of the double quote character in a field
       
   991         //    must be escaped by prepening another double quote character
       
   992         //    to it
       
   993 
       
   994         // escape all double quotes by prepending the double
       
   995         // quote character to each according to the CSV format
       
   996         char* const newbuf = _rw_escape (usrbuf, 0, '"');
       
   997         if (newbuf != usrbuf) {
       
   998             free (usrbuf);
       
   999             usrbuf = newbuf;
       
  1000         }
       
  1001 
       
  1002         mybuf =
       
  1003             rw_sprintfa ("%d, "                      // severity
       
  1004                          "\"%s%s"                    // diagnostic
       
  1005                          "%{?}_%s%{;}%s\", "         // traced diagnostic
       
  1006                          "\"%s\", "                  // clause
       
  1007                          "\"%s\", "                  // file
       
  1008                          "%d, "                      // line
       
  1009                          "\"%s\"",                   // user text
       
  1010                          severity,
       
  1011                          diagstr [0], diagstr [1],
       
  1012                          0 != traced_diag, traced_diag, diagstr [2],
       
  1013                          clause_id,
       
  1014                          0 != file ? file : "",
       
  1015                          line,
       
  1016                          usrbuf);
       
  1017     }
       
  1018     else {
       
  1019 
       
  1020         nlines += 2 + ('\0' != *clause_id) + (0 != file) + (0 < line);
       
  1021 
       
  1022         mybuf =
       
  1023             rw_sprintfa ("# %s"                      // escape prefix
       
  1024                          "%s"                        // diagnostic
       
  1025                          "%{?}_%s%{;}"               // traced diagnostic
       
  1026                          "%s "                       // escape suffix
       
  1027                          "(S%d)"                     // severity
       
  1028                          "%{?}, %s%{;} "             // description
       
  1029                          "(%d lines):\n"             // number of lines
       
  1030                          "# TEXT: %s\n"              // user text
       
  1031                          "%{?}# CLAUSE: %s\n%{;}"    // clause if not empty
       
  1032                          "%{?}# FILE: %s\n%{;}"      // file if not null
       
  1033                          "%{?}# LINE: %d\n%{;}",     // line if positive
       
  1034                          diagstr [0],
       
  1035                          diagstr [1],
       
  1036                          0 != traced_diag, traced_diag,
       
  1037                          diagstr [2],
       
  1038                          severity,
       
  1039                          0 != diagstr [3], diagstr [3],
       
  1040                          nlines,
       
  1041                          usrbuf,
       
  1042                          '\0' != *clause_id, clause_id,
       
  1043                          0 != file, file,
       
  1044                          0 < line, line);
       
  1045     }
       
  1046 #if 0   // disabled
       
  1047     else {
       
  1048 
       
  1049         mybuf =
       
  1050             rw_sprintfa ("# %s%s"                 // diagnostic
       
  1051                          "%{?}_%s%{;}%s "         // traced diagnostic
       
  1052                          "(S%d): "                // severity
       
  1053                          "%{?}[%s] %{;}"          // clause if not empty
       
  1054                          "%{?}(%d lines): %{;}"   // number of lines if > 1
       
  1055                          "%{?}%s:"                // if (file) then file
       
  1056                          "%{?}%d:%{;} "           //   if (0 < line) line
       
  1057                          "%{:}"                   // else
       
  1058                          "%{?}line %d: %{;}"      //   if (0 < line) line
       
  1059                          "%{;}"                   // endif
       
  1060                          "%s",                    // user text
       
  1061                          diagstr [0], diagstr [1],
       
  1062                          0 != traced_diag, traced_diag, diagstr [2],
       
  1063                          severity,
       
  1064                          '\0' != *clause_id, clause_id,
       
  1065                          1 < nlines, nlines,
       
  1066                          0 != file, file,
       
  1067                          0 < line, line,
       
  1068                          0 < line, line,
       
  1069                          usrbuf);
       
  1070     }
       
  1071 #endif   // 0/1
       
  1072 
       
  1073     fprintf (ftestout, "%s\n", mybuf);
       
  1074 
       
  1075     if (mybuf != fmterr)
       
  1076         free (mybuf);
       
  1077 
       
  1078     if (usrbuf != fmterr)
       
  1079         free (usrbuf);
       
  1080 }
       
  1081 
       
  1082 /************************************************************************/
       
  1083 
       
  1084 static void
       
  1085 _rw_vdiag (diag_t diag, int severity, const char *file, int line,
       
  1086            const char *fmt, va_list va)
       
  1087 {
       
  1088     CHECK_INIT (true, "_rw_vdiag()");
       
  1089 
       
  1090     // check if the diagnostic is expected
       
  1091     const int expected = 0 != _rw_expected (line);
       
  1092 
       
  1093     if (expected) {
       
  1094         if (severity) {
       
  1095             // if the diagnostic is expected to be active,
       
  1096             // adjust its type and severity
       
  1097             if (diag_assert == diag)
       
  1098                 diag = diag_xassert;
       
  1099             else if (diag_warn == diag)
       
  1100                 diag = diag_xwarn;
       
  1101 
       
  1102             severity = diag * severity;
       
  1103         }
       
  1104         else {
       
  1105             // if the diagnostic is expected to be active but isn't,
       
  1106             // adjust its type to an unexpectdly inactive one
       
  1107             if (diag_assert == diag || diag_warn == diag)
       
  1108                 diag = diag_expect;
       
  1109 
       
  1110             severity = diag;
       
  1111         }
       
  1112     }
       
  1113     else if (diag) {
       
  1114         // normalize the severity
       
  1115         severity = diag * severity;
       
  1116     }
       
  1117 
       
  1118     if (severity < 0)
       
  1119         severity = 0;
       
  1120     else if (N_DIAG_TYPES <= severity)
       
  1121         severity = N_DIAG_TYPES - 1;
       
  1122 
       
  1123     // increment the diagnostic counter
       
  1124     ++ndiags [diag][0];
       
  1125 
       
  1126     if (severity) {
       
  1127 
       
  1128         ++ndiags [diag][1];
       
  1129     }
       
  1130 
       
  1131     const int sevbit = (1 << severity);
       
  1132 
       
  1133     if (0 == (sevbit & _rw_diag_mask)) {
       
  1134         // issue the diagnostic
       
  1135         _rw_vissue_diag (diag, severity, file, line, fmt, va);
       
  1136     }
       
  1137 
       
  1138     if (diag_fatal == diag && severity) {
       
  1139         // fatal error, terminate test
       
  1140         longjmp (test_env, severity);
       
  1141     }
       
  1142 }
       
  1143 
       
  1144 /************************************************************************/
       
  1145 
       
  1146 _TEST_EXPORT int
       
  1147 rw_fatal (int success, const char *file, int line, const char *fmt, ...)
       
  1148 {
       
  1149     CHECK_INIT (true, "rw_fatal()");
       
  1150 
       
  1151     va_list va;
       
  1152     va_start (va, fmt);
       
  1153 
       
  1154     _rw_vdiag (diag_fatal, 0 == success, file, line, fmt, va);
       
  1155 
       
  1156     va_end (va);
       
  1157 
       
  1158     return success;
       
  1159 }
       
  1160 
       
  1161 /************************************************************************/
       
  1162 
       
  1163 _TEST_EXPORT int
       
  1164 rw_error (int success, const char *file, int line, const char *fmt, ...)
       
  1165 {
       
  1166     CHECK_INIT (true, "rw_error()");
       
  1167 
       
  1168     va_list va;
       
  1169     va_start (va, fmt);
       
  1170 
       
  1171     _rw_vdiag (diag_error, 0 == success, file, line, fmt, va);
       
  1172 
       
  1173     va_end (va);
       
  1174 
       
  1175     return success;
       
  1176 }
       
  1177 
       
  1178 /************************************************************************/
       
  1179 
       
  1180 _TEST_EXPORT int
       
  1181 rw_assert (int success, const char *file, int line, const char *fmt, ...)
       
  1182 {
       
  1183     CHECK_INIT (true, "rw_assert()");
       
  1184 
       
  1185     va_list va;
       
  1186     va_start (va, fmt);
       
  1187 
       
  1188     _rw_vdiag (diag_assert, 0 == success, file, line, fmt, va);
       
  1189 
       
  1190     va_end (va);
       
  1191 
       
  1192     return success;
       
  1193 }
       
  1194 
       
  1195 /************************************************************************/
       
  1196 
       
  1197 _TEST_EXPORT int
       
  1198 rw_warn (int success, const char *file, int line, const char *fmt, ...)
       
  1199 {
       
  1200     CHECK_INIT (true, "rw_warn()");
       
  1201 
       
  1202     va_list va;
       
  1203     va_start (va, fmt);
       
  1204 
       
  1205     _rw_vdiag (diag_warn, 0 == success, file, line, fmt, va);
       
  1206 
       
  1207     va_end (va);
       
  1208 
       
  1209     return success;
       
  1210 }
       
  1211 
       
  1212 /************************************************************************/
       
  1213 
       
  1214 _TEST_EXPORT int
       
  1215 rw_note (int success, const char *file, int line, const char *fmt, ...)
       
  1216 {
       
  1217     CHECK_INIT (true, "rw_note()");
       
  1218 
       
  1219     va_list va;
       
  1220     va_start (va, fmt);
       
  1221 
       
  1222     _rw_vdiag (diag_note, 0 == success, file, line, fmt, va);
       
  1223 
       
  1224     va_end (va);
       
  1225 
       
  1226     return success;
       
  1227 }
       
  1228 
       
  1229 /************************************************************************/
       
  1230 
       
  1231 _TEST_EXPORT int
       
  1232 rw_info (int success, const char *file, int line, const char *fmt, ...)
       
  1233 {
       
  1234     CHECK_INIT (true, "rw_info()");
       
  1235 
       
  1236     va_list va;
       
  1237     va_start (va, fmt);
       
  1238 
       
  1239     _rw_vdiag (diag_info, 0 == success, file, line, fmt, va);
       
  1240 
       
  1241     va_end (va);
       
  1242 
       
  1243     return success;
       
  1244 }