update /util

This commit is contained in:
Patrick Brosi 2019-06-28 15:10:15 +02:00
parent df1ba83a53
commit 79303f12f2
5 changed files with 1719 additions and 1354 deletions

View file

@ -31,7 +31,11 @@
#include <cmath>
#include <cstddef>
#define lest_VERSION "1.33.1"
#define lest_MAJOR 1
#define lest_MINOR 35
#define lest_PATCH 1
#define lest_VERSION lest_STRINGIFY(lest_MAJOR) "." lest_STRINGIFY(lest_MINOR) "." lest_STRINGIFY(lest_PATCH)
#ifndef lest_FEATURE_AUTO_REGISTER
# define lest_FEATURE_AUTO_REGISTER 0
@ -49,50 +53,55 @@
# define lest_FEATURE_REGEX_SEARCH 0
#endif
#ifndef lest_FEATURE_TIME_PRECISION
#define lest_FEATURE_TIME_PRECISION 0
#ifndef lest_FEATURE_TIME_PRECISION
# define lest_FEATURE_TIME_PRECISION 0
#endif
#ifndef lest_FEATURE_WSTRING
#define lest_FEATURE_WSTRING 1
#ifndef lest_FEATURE_WSTRING
# define lest_FEATURE_WSTRING 1
#endif
#ifdef lest_FEATURE_RTTI
# define lest__cpp_rtti lest_FEATURE_RTTI
#ifdef lest_FEATURE_RTTI
# define lest__cpp_rtti lest_FEATURE_RTTI
#elif defined(__cpp_rtti)
# define lest__cpp_rtti __cpp_rtti
# define lest__cpp_rtti __cpp_rtti
#elif defined(__GXX_RTTI) || defined (_CPPRTTI)
# define lest__cpp_rtti 1
# define lest__cpp_rtti 1
#else
# define lest__cpp_rtti 0
# define lest__cpp_rtti 0
#endif
#if lest_FEATURE_REGEX_SEARCH
# include <regex>
#endif
// Stringify:
#define lest_STRINGIFY( x ) lest_STRINGIFY_( x )
#define lest_STRINGIFY_( x ) #x
// Compiler warning suppression:
#ifdef __clang__
#if defined (__clang__)
# pragma clang diagnostic ignored "-Waggregate-return"
# pragma clang diagnostic ignored "-Woverloaded-shift-op-parentheses"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-comparison"
#elif defined __GNUC__
#elif defined (__GNUC__)
# pragma GCC diagnostic ignored "-Waggregate-return"
# pragma GCC diagnostic push
#endif
// Suppress shadow and unused-value warning for sections:
#if defined __clang__
#if defined (__clang__)
# define lest_SUPPRESS_WSHADOW _Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wshadow\"" )
# define lest_SUPPRESS_WUNUSED _Pragma( "clang diagnostic push" ) \
_Pragma( "clang diagnostic ignored \"-Wunused-value\"" )
# define lest_RESTORE_WARNINGS _Pragma( "clang diagnostic pop" )
#elif defined __GNUC__
#elif defined (__GNUC__)
# define lest_SUPPRESS_WSHADOW _Pragma( "GCC diagnostic push" ) \
_Pragma( "GCC diagnostic ignored \"-Wshadow\"" )
# define lest_SUPPRESS_WUNUSED _Pragma( "GCC diagnostic push" ) \
@ -104,12 +113,22 @@
# define lest_RESTORE_WARNINGS /*empty*/
#endif
#ifdef _MSVC_LANG
# define lest_CPP17_OR_GREATER_MS ( _MSVC_LANG >= 201703L )
#else
# define lest_CPP17_OR_GREATER_MS 0
// C++ language version detection (C++20 is speculative):
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
#ifndef lest_CPLUSPLUS
# if defined(_MSVC_LANG ) && !defined(__clang__)
# define lest_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
# else
# define lest_CPLUSPLUS __cplusplus
# endif
#endif
# define lest_CPP17_OR_GREATER ( __cplusplus >= 201703L || lest_CPP17_OR_GREATER_MS )
#define lest_CPP98_OR_GREATER ( lest_CPLUSPLUS >= 199711L )
#define lest_CPP11_OR_GREATER ( lest_CPLUSPLUS >= 201103L )
#define lest_CPP14_OR_GREATER ( lest_CPLUSPLUS >= 201402L )
#define lest_CPP17_OR_GREATER ( lest_CPLUSPLUS >= 201703L )
#define lest_CPP20_OR_GREATER ( lest_CPLUSPLUS >= 202000L )
#if ! defined( lest_NO_SHORT_MACRO_NAMES ) && ! defined( lest_NO_SHORT_ASSERTION_NAMES )
# define MODULE lest_MODULE
@ -186,7 +205,7 @@
if ( lest::result score = lest_DECOMPOSE( expr ) ) \
throw lest::failure{ lest_LOCATION, #expr, score.decomposition }; \
else if ( lest_env.pass() ) \
lest::report( lest_env.os, lest::passing{ lest_LOCATION, #expr, score.decomposition }, lest_env.context() ); \
lest::report( lest_env.os, lest::passing{ lest_LOCATION, #expr, score.decomposition, lest_env.zen() }, lest_env.context() ); \
} \
catch(...) \
{ \
@ -201,7 +220,7 @@
if ( lest::result score = lest_DECOMPOSE( expr ) ) \
{ \
if ( lest_env.pass() ) \
lest::report( lest_env.os, lest::passing{ lest_LOCATION, lest::not_expr( #expr ), lest::not_expr( score.decomposition ) }, lest_env.context() ); \
lest::report( lest_env.os, lest::passing{ lest_LOCATION, lest::not_expr( #expr ), lest::not_expr( score.decomposition ), lest_env.zen() }, lest_env.context() ); \
} \
else \
throw lest::failure{ lest_LOCATION, lest::not_expr( #expr ), lest::not_expr( score.decomposition ) }; \
@ -381,8 +400,8 @@ struct success : message
struct passing : success
{
passing( location where_, text expr_, text decomposition_ )
: success( "passed", where_, expr_ + " for " + decomposition_) {}
passing( location where_, text expr_, text decomposition_, bool zen )
: success( "passed", where_, expr_ + (zen ? "":" for " + decomposition_) ) {}
};
struct got_none : success
@ -524,14 +543,45 @@ inline char const * sfx( char const * txt ) { return txt; }
inline char const * sfx( char const * ) { return ""; }
#endif
inline std::string to_string( std::nullptr_t ) { return "nullptr"; }
inline std::string to_string( std::string const & txt ) { return "\"" + txt + "\"" ; }
inline std::string transformed( char chr )
{
struct Tr { char chr; char const * str; } table[] =
{
{'\\', "\\\\" },
{'\r', "\\r" }, {'\f', "\\f" },
{'\n', "\\n" }, {'\t', "\\t" },
};
for ( auto tr : table )
{
if ( chr == tr.chr )
return tr.str;
}
auto unprintable = [](char c){ return 0 <= c && c < ' '; };
auto to_hex_string = [](char c)
{
std::ostringstream os;
os << "\\x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>( static_cast<unsigned char>(c) );
return os.str();
};
return unprintable( chr ) ? to_hex_string( chr ) : std::string( 1, chr );
}
inline std::string make_tran_string( std::string const & txt ) { std::ostringstream os; for(auto c:txt) os << transformed(c); return os.str(); }
inline std::string make_strg_string( std::string const & txt ) { return "\"" + make_tran_string( txt ) + "\"" ; }
inline std::string make_char_string( char chr ) { return "\'" + make_tran_string( std::string( 1, chr ) ) + "\'" ; }
inline std::string to_string( std::nullptr_t ) { return "nullptr"; }
inline std::string to_string( std::string const & txt ) { return make_strg_string( txt ); }
#if lest_FEATURE_WSTRING
inline std::string to_string( std::wstring const & txt ) ;
#endif
inline std::string to_string( char const * const txt ) { return txt ? to_string( std::string ( txt ) ) : "{null string}"; }
inline std::string to_string( char * const txt ) { return txt ? to_string( std::string ( txt ) ) : "{null string}"; }
inline std::string to_string( char const * const txt ) { return txt ? make_strg_string( txt ) : "{null string}"; }
inline std::string to_string( char * const txt ) { return txt ? make_strg_string( txt ) : "{null string}"; }
#if lest_FEATURE_WSTRING
inline std::string to_string( wchar_t const * const txt ) { return txt ? to_string( std::wstring( txt ) ) : "{null string}"; }
inline std::string to_string( wchar_t * const txt ) { return txt ? to_string( std::wstring( txt ) ) : "{null string}"; }
@ -550,29 +600,9 @@ inline std::string to_string( unsigned long long value ) { return make_value_
inline std::string to_string( double value ) { return make_value_string( value ) ; }
inline std::string to_string( float value ) { return make_value_string( value ) + sfx("f" ); }
inline std::string to_string( signed char chr ) { return to_string( static_cast<char>( chr ) ); }
inline std::string to_string( unsigned char chr ) { return to_string( static_cast<char>( chr ) ); }
inline std::string to_string( char chr )
{
struct Tr { char chr; char const * str; } table[] =
{
{'\r', "'\\r'" }, {'\f', "'\\f'" },
{'\n', "'\\n'" }, {'\t', "'\\t'" },
};
for ( auto tr : table )
{
if ( chr == tr.chr )
return tr.str;
}
auto unprintable = [](char c){ return 0 <= c && c < ' '; };
return unprintable( chr )
? to_string( static_cast<unsigned int>( chr ) )
: "\'" + std::string( 1, chr ) + "\'" ;
}
inline std::string to_string( signed char chr ) { return make_char_string( static_cast<char>( chr ) ); }
inline std::string to_string( unsigned char chr ) { return make_char_string( static_cast<char>( chr ) ); }
inline std::string to_string( char chr ) { return make_char_string( chr ); }
template< typename T >
struct is_streamable
@ -968,7 +998,7 @@ inline bool select( text name, texts include )
inline int indefinite( int repeat ) { return repeat == -1; }
using seed_t = unsigned long;
using seed_t = std::mt19937::result_type;
struct options
{
@ -979,6 +1009,7 @@ struct options
bool tags = false;
bool time = false;
bool pass = false;
bool zen = false;
bool lexical = false;
bool random = false;
bool verbose = false;
@ -999,12 +1030,14 @@ struct env
env & operator()( text test )
{
testing = test; return *this;
clear(); testing = test; return *this;
}
bool abort() { return opt.abort; }
bool pass() { return opt.pass; }
bool zen() { return opt.zen; }
void clear() { ctx.clear(); }
void pop() { ctx.pop_back(); }
void push( text proposition ) { ctx.emplace_back( proposition ); }
@ -1311,6 +1344,7 @@ inline auto split_arguments( texts args ) -> std::tuple<options, texts>
else if ( opt == "-l" || "--list-tests" == opt ) { option.list = true; continue; }
else if ( opt == "-t" || "--time" == opt ) { option.time = true; continue; }
else if ( opt == "-p" || "--pass" == opt ) { option.pass = true; continue; }
else if ( opt == "-z" || "--pass-zen" == opt ) { option.zen = true; continue; }
else if ( opt == "-v" || "--verbose" == opt ) { option.verbose = true; continue; }
else if ( "--version" == opt ) { option.version = true; continue; }
else if ( opt == "--order" && "declared" == val ) { /* by definition */ ; continue; }
@ -1322,6 +1356,8 @@ inline auto split_arguments( texts args ) -> std::tuple<options, texts>
}
in.push_back( arg );
}
option.pass = option.pass || option.zen;
return std::make_tuple( option, in );
}
@ -1337,6 +1373,7 @@ inline int usage( std::ostream & os )
" -g, --list-tags list tags of selected tests\n"
" -l, --list-tests list selected tests\n"
" -p, --pass also report passing tests\n"
" -z, --pass-zen ... without expansion\n"
" -t, --time list duration of selected tests\n"
" -v, --verbose also report passing or failing sections\n"
" --order=declared use source code test order (default)\n"
@ -1437,9 +1474,9 @@ int run( test const (&specification)[N], int argc, char * argv[], std::ostream &
} // namespace lest
#ifdef __clang__
#if defined (__clang__)
# pragma clang diagnostic pop
#elif defined __GNUC__
#elif defined (__GNUC__)
# pragma GCC diagnostic pop
#endif