Chris@16: // (C) Copyright Gennadiy Rozental 2001-2008. Chris@16: // (C) Copyright Beman Dawes 1995-2001. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/libs/test for the library home page. Chris@16: // Chris@16: // File : $RCSfile$ Chris@16: // Chris@101: // Version : $Revision$ Chris@16: // Chris@16: // Description : main function implementation for Program Executon Monitor Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_TEST_CPP_MAIN_IPP_012205GER Chris@16: #define BOOST_TEST_CPP_MAIN_IPP_012205GER Chris@16: Chris@16: // Boost.Test Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Boost Chris@16: #include // for exit codes Chris@16: #include // for workarounds Chris@16: Chris@16: // STL Chris@16: #include Chris@16: #include // std::getenv Chris@16: #include // std::strerror Chris@16: Chris@16: #include Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #ifdef BOOST_NO_STDC_NAMESPACE Chris@16: namespace std { using ::getenv; using ::strerror; } Chris@16: #endif Chris@16: Chris@16: namespace { Chris@16: Chris@16: struct cpp_main_caller { Chris@16: cpp_main_caller( int (*cpp_main_func)( int argc, char* argv[] ), int argc, char** argv ) Chris@16: : m_cpp_main_func( cpp_main_func ) Chris@16: , m_argc( argc ) Chris@16: , m_argv( argv ) {} Chris@16: Chris@16: int operator()() { return (*m_cpp_main_func)( m_argc, m_argv ); } Chris@16: Chris@16: private: Chris@16: // Data members Chris@16: int (*m_cpp_main_func)( int argc, char* argv[] ); Chris@16: int m_argc; Chris@16: char** m_argv; Chris@16: }; Chris@16: Chris@16: } // local namespace Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** prg_exec_monitor_main ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: int BOOST_TEST_DECL Chris@16: prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char* argv[] ) Chris@16: { Chris@16: int result = 0; Chris@16: Chris@16: try { Chris@16: boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) ); Chris@16: ::boost::execution_monitor ex_mon; Chris@16: Chris@16: ex_mon.p_catch_system_errors.value = p != "no"; Chris@16: Chris@16: result = ex_mon.execute( Chris@16: ::boost::unit_test::callback0( cpp_main_caller( cpp_main, argc, argv ) ) ); Chris@16: Chris@16: if( result == 0 ) Chris@16: result = ::boost::exit_success; Chris@16: else if( result != ::boost::exit_success ) { Chris@16: std::cout << "\n**** error return code: " << result << std::endl; Chris@16: result = ::boost::exit_failure; Chris@16: } Chris@16: } Chris@16: catch( ::boost::execution_exception const& exex ) { Chris@16: std::cout << "\n**** exception(" << exex.code() << "): " << exex.what() << std::endl; Chris@16: result = ::boost::exit_exception_failure; Chris@16: } Chris@16: catch( ::boost::system_error const& ex ) { Chris@16: std::cout << "\n**** failed to initialize execution monitor." Chris@16: << "\n**** expression at fault: " << ex.p_failed_exp Chris@16: << "\n**** error(" << ex.p_errno << "): " << std::strerror( ex.p_errno ) << std::endl; Chris@16: result = ::boost::exit_exception_failure; Chris@16: } Chris@16: Chris@16: if( result != ::boost::exit_success ) { Chris@16: std::cerr << "******** errors detected; see standard output for details ********" << std::endl; Chris@16: } Chris@16: else { Chris@16: // Some prefer a confirming message when all is well, while others don't Chris@16: // like the clutter. Use an environment variable to avoid command Chris@16: // line argument modifications; for use in production programs Chris@16: // that's a no-no in some organizations. Chris@16: ::boost::unit_test::const_string p( std::getenv( "BOOST_PRG_MON_CONFIRM" ) ); Chris@16: if( p != "no" ) { Chris@16: std::cerr << std::flush << "no errors detected" << std::endl; Chris@16: } Chris@16: } Chris@16: Chris@16: return result; Chris@16: } Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN) Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** main function for tests using lib ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: int cpp_main( int argc, char* argv[] ); // prototype for user's cpp_main() Chris@16: Chris@16: int BOOST_TEST_CALL_DECL Chris@16: main( int argc, char* argv[] ) Chris@16: { Chris@16: return ::boost::prg_exec_monitor_main( &cpp_main, argc, argv ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TEST_CPP_MAIN_IPP_012205GER