// (C) Copyright Gennadiy Rozental 2005-2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/test for the library home page. // Boost.Test #ifndef BOOST_TEST_DYN_LINK #define BOOST_TEST_DYN_LINK #endif #include // Boost.Runtime.Param //#include #include #include namespace rt = boost::runtime; namespace cla = boost::runtime::cla; // STL #include //_________________________________________________________________// // System API namespace dyn_lib { #if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) // WIN32 API #include typedef HINSTANCE handle; inline handle open( std::string const& file_name ) { return LoadLibrary( file_name.c_str() ); } //_________________________________________________________________// template inline TargType locate_symbol( handle h, std::string const& symbol ) { return reinterpret_cast( GetProcAddress( h, symbol.c_str() ) ); } //_________________________________________________________________// inline void close( handle h ) { if( h ) FreeLibrary( h ); } //_________________________________________________________________// inline std::string error() { LPTSTR msg = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&msg, 0, NULL ); std::string res( msg ); if( msg ) LocalFree( msg ); return res; } //_________________________________________________________________// #elif defined(BOOST_HAS_UNISTD_H) // POSIX API #include #include #include #include typedef void* handle; inline handle open( std::string const& file_name ) { return dlopen( file_name.c_str(), RTLD_LOCAL | RTLD_LAZY ); } //_________________________________________________________________// template inline TargType locate_symbol( handle h, std::string const& symbol ) { return reinterpret_cast( dlsym( h, symbol.c_str() ) ); } //_________________________________________________________________// inline void close( handle h ) { if( h ) dlclose( h ); } //_________________________________________________________________// inline std::string error() { return dlerror(); } //_________________________________________________________________// #else #error "Dynamic library API is unknown" #endif } // namespace dyn_lib //____________________________________________________________________________// static std::string test_lib_name; static std::string init_func_name( "init_unit_test" ); dyn_lib::handle test_lib_handle; bool load_test_lib() { typedef bool (*init_func_ptr)(); init_func_ptr init_func; test_lib_handle = dyn_lib::open( test_lib_name ); if( !test_lib_handle ) throw std::logic_error( std::string("Fail to load test library: ") .append( dyn_lib::error() ) ); init_func = dyn_lib::locate_symbol( test_lib_handle, init_func_name ); if( !init_func ) throw std::logic_error( std::string("Can't locate test initilization function ") .append( init_func_name ) .append( ": " ) .append( dyn_lib::error() ) ); return (*init_func)(); } //____________________________________________________________________________// int main( int argc, char* argv[] ) { try { rt::parameters_store store; rt::parameter p_test( "test" ); p_test.add_cla_id( "--", "test", " " ); store.add( p_test ); rt::parameter p_init( "init" ); p_init.add_cla_id( "--", "init", " " ); store.add( p_init ); rt::cla::parser P( store ); rt::arguments_store args_store; P.parse( argc, argv, args_store ); test_lib_name = args_store.get( "test" ); if( args_store.has("init") ) init_func_name = args_store.get( "init" ); int res = ::boost::unit_test::unit_test_main( &load_test_lib, argc, argv ); ::boost::unit_test::framework::clear(); dyn_lib::close( test_lib_handle ); return res; } catch( rt::param_error const& ex ) { std::cout << "Fail to parse command line arguments: " << ex.msg << std::endl; return -1; } } //____________________________________________________________________________// // EOF