stdcpp/tsrc/Stdcpp_test/stdcxx/testengine/src/driver.cpp
changeset 0 e4d67989cc36
child 22 ddc455616bd6
child 56 acd3cd4aaceb
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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 _RWSTD_DLLIMPORT 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     while ((quote = strchr (quote, '"'))) {
       
   864         ++nquotes;
       
   865         ++quote;
       
   866     }
       
   867 
       
   868     // no quotes found, return the original buffer
       
   869     if (0 == nquotes)
       
   870         return buf;
       
   871 
       
   872     // conpute the size of the buffer that will be needed to escape
       
   873     // all the double quotes
       
   874     size_t newbufsize = strlen (buf) + nquotes + 1;
       
   875 
       
   876     char *newbuf = 0;
       
   877 
       
   878     if (0 /* newbufsize <= bufsize */) {
       
   879         // FIXME: escape embedded quotes in place w/o reallocation
       
   880         _RWSTD_UNUSED (bufsize);
       
   881     }
       
   882     else {
       
   883         newbuf = (char*)malloc (newbufsize);
       
   884         if (0 == newbuf) {
       
   885             return 0;
       
   886         }
       
   887 
       
   888         // set the next pointer to the beginning of the new buffer
       
   889         // as the destination where to copy the string argument
       
   890         char *next = newbuf;
       
   891 
       
   892         // set quote to initially point to the beginning of
       
   893         // the source buffer and then just past the last quote
       
   894         quote = buf;
       
   895 
       
   896         for (char *q = buf; ; ++q) {
       
   897 
       
   898             // look for the next (or first) quote
       
   899             q = strchr (q, '"');
       
   900 
       
   901             // compute the number of characters, excluding the quote
       
   902             // to copy to the destination buffer
       
   903             const size_t nchars = q ? size_t (q - quote) : strlen (quote);
       
   904 
       
   905             memcpy (next, quote, nchars);
       
   906 
       
   907             if (q) {
       
   908                 // append the escape character to the destination buffer
       
   909                 next [nchars] = esc;
       
   910 
       
   911                 // append the quote from the source string
       
   912                 next [nchars + 1] = '"';
       
   913 
       
   914                 // advance the destination pointer past the quote
       
   915                 next += nchars + 2;
       
   916 
       
   917                 // advance the source pointer past the embedded quote
       
   918                 quote = q + 1;
       
   919             }
       
   920             else {
       
   921                 // NUL-terminate the destination buffer
       
   922                 *next = '\0';
       
   923                 break;
       
   924             }
       
   925         }
       
   926     }
       
   927 
       
   928     return newbuf;
       
   929 }
       
   930 
       
   931 /************************************************************************/
       
   932 
       
   933 static void
       
   934 _rw_vissue_diag (diag_t diag, int severity, const char *file, int line,
       
   935                  const char *fmt, va_list va)
       
   936 {
       
   937     CHECK_INIT (true, "_rw_vissue_diag()");
       
   938 
       
   939     if (0 == fmt)
       
   940         fmt = "";
       
   941 
       
   942     static char fmterr[] = "*** formatting error ***";
       
   943 
       
   944     char *usrbuf = 0;
       
   945     const int nchars = rw_vasnprintf (&usrbuf, 0, fmt, va);
       
   946 
       
   947     if (nchars < 0 || 0 == usrbuf)
       
   948         usrbuf = fmterr;
       
   949 
       
   950     // compute the number of newline characters in the text
       
   951     int nlines = 0;
       
   952     for (const char *nl = usrbuf; (nl = strchr (nl, '\n')); ++nl)
       
   953         ++nlines;
       
   954 
       
   955     static const int use_color = _rw_use_color ();
       
   956 
       
   957     const char* const diagstr[] = {
       
   958         use_color ? diag_msgs [severity].esc_pfx : "",
       
   959         *diag_msgs [severity].code ? diag_msgs [severity].code : "UNKNOWN",
       
   960         use_color  ? diag_msgs [severity].esc_sfx : "",
       
   961         _rw_opt_verbose (0, 0) && *diag_msgs [severity].desc ?
       
   962         diag_msgs [severity].desc : 0
       
   963     };
       
   964 
       
   965     const char* const traced_diag =
       
   966         0 == severity && diag_msgs [diag].code ? diag_msgs [diag].code : 0;
       
   967 
       
   968     const char* const slash = file ? strrchr (file, _RWSTD_PATH_SEP) : 0;
       
   969     if (slash)
       
   970         file = slash + 1;
       
   971 
       
   972     char *mybuf = 0;
       
   973 
       
   974     if (_rw_opt_csv) {
       
   975 
       
   976         // format all fields as comma separated values (CSV):
       
   977         // -- a field containing the quote character, the comma,
       
   978         //    or the newline or linefeed character must be enclosed
       
   979         //    in a pair of double quotes
       
   980         // -- every occurrence of the double quote character in a field
       
   981         //    must be escaped by prepening another double quote character
       
   982         //    to it
       
   983 
       
   984         // escape all double quotes by prepending the double
       
   985         // quote character to each according to the CSV format
       
   986         char* const newbuf = _rw_escape (usrbuf, 0, '"');
       
   987         if (newbuf != usrbuf) {
       
   988             free (usrbuf);
       
   989             usrbuf = newbuf;
       
   990         }
       
   991 
       
   992         mybuf =
       
   993             rw_sprintfa ("%d, "                      // severity
       
   994                          "\"%s%s"                    // diagnostic
       
   995                          "%{?}_%s%{;}%s\", "         // traced diagnostic
       
   996                          "\"%s\", "                  // clause
       
   997                          "\"%s\", "                  // file
       
   998                          "%d, "                      // line
       
   999                          "\"%s\"",                   // user text
       
  1000                          severity,
       
  1001                          diagstr [0], diagstr [1],
       
  1002                          0 != traced_diag, traced_diag, diagstr [2],
       
  1003                          clause_id,
       
  1004                          0 != file ? file : "",
       
  1005                          line,
       
  1006                          usrbuf);
       
  1007     }
       
  1008     else {
       
  1009 
       
  1010         nlines += 2 + ('\0' != *clause_id) + (0 != file) + (0 < line);
       
  1011 
       
  1012         mybuf =
       
  1013             rw_sprintfa ("# %s"                      // escape prefix
       
  1014                          "%s"                        // diagnostic
       
  1015                          "%{?}_%s%{;}"               // traced diagnostic
       
  1016                          "%s "                       // escape suffix
       
  1017                          "(S%d)"                     // severity
       
  1018                          "%{?}, %s%{;} "             // description
       
  1019                          "(%d lines):\n"             // number of lines
       
  1020                          "# TEXT: %s\n"              // user text
       
  1021                          "%{?}# CLAUSE: %s\n%{;}"    // clause if not empty
       
  1022                          "%{?}# FILE: %s\n%{;}"      // file if not null
       
  1023                          "%{?}# LINE: %d\n%{;}",     // line if positive
       
  1024                          diagstr [0],
       
  1025                          diagstr [1],
       
  1026                          0 != traced_diag, traced_diag,
       
  1027                          diagstr [2],
       
  1028                          severity,
       
  1029                          0 != diagstr [3], diagstr [3],
       
  1030                          nlines,
       
  1031                          usrbuf,
       
  1032                          '\0' != *clause_id, clause_id,
       
  1033                          0 != file, file,
       
  1034                          0 < line, line);
       
  1035     }
       
  1036 #if 0   // disabled
       
  1037     else {
       
  1038 
       
  1039         mybuf =
       
  1040             rw_sprintfa ("# %s%s"                 // diagnostic
       
  1041                          "%{?}_%s%{;}%s "         // traced diagnostic
       
  1042                          "(S%d): "                // severity
       
  1043                          "%{?}[%s] %{;}"          // clause if not empty
       
  1044                          "%{?}(%d lines): %{;}"   // number of lines if > 1
       
  1045                          "%{?}%s:"                // if (file) then file
       
  1046                          "%{?}%d:%{;} "           //   if (0 < line) line
       
  1047                          "%{:}"                   // else
       
  1048                          "%{?}line %d: %{;}"      //   if (0 < line) line
       
  1049                          "%{;}"                   // endif
       
  1050                          "%s",                    // user text
       
  1051                          diagstr [0], diagstr [1],
       
  1052                          0 != traced_diag, traced_diag, diagstr [2],
       
  1053                          severity,
       
  1054                          '\0' != *clause_id, clause_id,
       
  1055                          1 < nlines, nlines,
       
  1056                          0 != file, file,
       
  1057                          0 < line, line,
       
  1058                          0 < line, line,
       
  1059                          usrbuf);
       
  1060     }
       
  1061 #endif   // 0/1
       
  1062 
       
  1063     fprintf (ftestout, "%s\n", mybuf);
       
  1064 
       
  1065     if (mybuf != fmterr)
       
  1066         free (mybuf);
       
  1067 
       
  1068     if (usrbuf != fmterr)
       
  1069         free (usrbuf);
       
  1070 }
       
  1071 
       
  1072 /************************************************************************/
       
  1073 
       
  1074 static void
       
  1075 _rw_vdiag (diag_t diag, int severity, const char *file, int line,
       
  1076            const char *fmt, va_list va)
       
  1077 {
       
  1078     CHECK_INIT (true, "_rw_vdiag()");
       
  1079 
       
  1080     // check if the diagnostic is expected
       
  1081     const int expected = 0 != _rw_expected (line);
       
  1082 
       
  1083     if (expected) {
       
  1084         if (severity) {
       
  1085             // if the diagnostic is expected to be active,
       
  1086             // adjust its type and severity
       
  1087             if (diag_assert == diag)
       
  1088                 diag = diag_xassert;
       
  1089             else if (diag_warn == diag)
       
  1090                 diag = diag_xwarn;
       
  1091 
       
  1092             severity = diag * severity;
       
  1093         }
       
  1094         else {
       
  1095             // if the diagnostic is expected to be active but isn't,
       
  1096             // adjust its type to an unexpectdly inactive one
       
  1097             if (diag_assert == diag || diag_warn == diag)
       
  1098                 diag = diag_expect;
       
  1099 
       
  1100             severity = diag;
       
  1101         }
       
  1102     }
       
  1103     else if (diag) {
       
  1104         // normalize the severity
       
  1105         severity = diag * severity;
       
  1106     }
       
  1107 
       
  1108     if (severity < 0)
       
  1109         severity = 0;
       
  1110     else if (N_DIAG_TYPES <= severity)
       
  1111         severity = N_DIAG_TYPES - 1;
       
  1112 
       
  1113     // increment the diagnostic counter
       
  1114     ++ndiags [diag][0];
       
  1115 
       
  1116     if (severity) {
       
  1117 
       
  1118         ++ndiags [diag][1];
       
  1119     }
       
  1120 
       
  1121     const int sevbit = (1 << severity);
       
  1122 
       
  1123     if (0 == (sevbit & _rw_diag_mask)) {
       
  1124         // issue the diagnostic
       
  1125         _rw_vissue_diag (diag, severity, file, line, fmt, va);
       
  1126     }
       
  1127 
       
  1128     if (diag_fatal == diag && severity) {
       
  1129         // fatal error, terminate test
       
  1130         longjmp (test_env, severity);
       
  1131     }
       
  1132 }
       
  1133 
       
  1134 /************************************************************************/
       
  1135 
       
  1136 _TEST_EXPORT int
       
  1137 rw_fatal (int success, const char *file, int line, const char *fmt, ...)
       
  1138 {
       
  1139     CHECK_INIT (true, "rw_fatal()");
       
  1140 
       
  1141     va_list va;
       
  1142     va_start (va, fmt);
       
  1143 
       
  1144     _rw_vdiag (diag_fatal, 0 == success, file, line, fmt, va);
       
  1145 
       
  1146     va_end (va);
       
  1147 
       
  1148     return success;
       
  1149 }
       
  1150 
       
  1151 /************************************************************************/
       
  1152 
       
  1153 _TEST_EXPORT int
       
  1154 rw_error (int success, const char *file, int line, const char *fmt, ...)
       
  1155 {
       
  1156     CHECK_INIT (true, "rw_error()");
       
  1157 
       
  1158     va_list va;
       
  1159     va_start (va, fmt);
       
  1160 
       
  1161     _rw_vdiag (diag_error, 0 == success, file, line, fmt, va);
       
  1162 
       
  1163     va_end (va);
       
  1164 
       
  1165     return success;
       
  1166 }
       
  1167 
       
  1168 /************************************************************************/
       
  1169 
       
  1170 _TEST_EXPORT int
       
  1171 rw_assert (int success, const char *file, int line, const char *fmt, ...)
       
  1172 {
       
  1173     CHECK_INIT (true, "rw_assert()");
       
  1174 
       
  1175     va_list va;
       
  1176     va_start (va, fmt);
       
  1177 
       
  1178     _rw_vdiag (diag_assert, 0 == success, file, line, fmt, va);
       
  1179 
       
  1180     va_end (va);
       
  1181 
       
  1182     return success;
       
  1183 }
       
  1184 
       
  1185 /************************************************************************/
       
  1186 
       
  1187 _TEST_EXPORT int
       
  1188 rw_warn (int success, const char *file, int line, const char *fmt, ...)
       
  1189 {
       
  1190     CHECK_INIT (true, "rw_warn()");
       
  1191 
       
  1192     va_list va;
       
  1193     va_start (va, fmt);
       
  1194 
       
  1195     _rw_vdiag (diag_warn, 0 == success, file, line, fmt, va);
       
  1196 
       
  1197     va_end (va);
       
  1198 
       
  1199     return success;
       
  1200 }
       
  1201 
       
  1202 /************************************************************************/
       
  1203 
       
  1204 _TEST_EXPORT int
       
  1205 rw_note (int success, const char *file, int line, const char *fmt, ...)
       
  1206 {
       
  1207     CHECK_INIT (true, "rw_note()");
       
  1208 
       
  1209     va_list va;
       
  1210     va_start (va, fmt);
       
  1211 
       
  1212     _rw_vdiag (diag_note, 0 == success, file, line, fmt, va);
       
  1213 
       
  1214     va_end (va);
       
  1215 
       
  1216     return success;
       
  1217 }
       
  1218 
       
  1219 /************************************************************************/
       
  1220 
       
  1221 _TEST_EXPORT int
       
  1222 rw_info (int success, const char *file, int line, const char *fmt, ...)
       
  1223 {
       
  1224     CHECK_INIT (true, "rw_info()");
       
  1225 
       
  1226     va_list va;
       
  1227     va_start (va, fmt);
       
  1228 
       
  1229     _rw_vdiag (diag_info, 0 == success, file, line, fmt, va);
       
  1230 
       
  1231     va_end (va);
       
  1232 
       
  1233     return success;
       
  1234 }