1// (C) Copyright Gennadiy Rozental 2001. 2// (C) Copyright Beman Dawes 1995-2001. 3// Distributed under the Boost Software License, Version 1.0. 4// (See accompanying file LICENSE_1_0.txt or copy at 5// http://www.boost.org/LICENSE_1_0.txt) 6 7// See http://www.boost.org/libs/test for the library home page. 8// 9// File : $RCSfile$ 10// 11// Version : $Revision$ 12// 13// Description : main function implementation for Program Executon Monitor 14// *************************************************************************** 15 16#ifndef BOOST_TEST_CPP_MAIN_IPP_012205GER 17#define BOOST_TEST_CPP_MAIN_IPP_012205GER 18 19// Boost.Test 20#include <boost/test/execution_monitor.hpp> 21#include <boost/test/detail/config.hpp> 22#include <boost/test/utils/basic_cstring/io.hpp> 23 24// Boost 25#include <boost/cstdlib.hpp> // for exit codes 26#include <boost/config.hpp> // for workarounds 27 28// STL 29#include <iostream> 30#include <cstdlib> // std::getenv 31#include <cstring> // std::strerror 32 33#include <boost/test/detail/suppress_warnings.hpp> 34 35//____________________________________________________________________________// 36 37#ifdef BOOST_NO_STDC_NAMESPACE 38namespace std { using ::getenv; using ::strerror; } 39#endif 40 41namespace { 42 43struct cpp_main_caller { 44 cpp_main_caller( int (*cpp_main_func)( int argc, char* argv[] ), int argc, char** argv ) 45 : m_cpp_main_func( cpp_main_func ) 46 , m_argc( argc ) 47 , m_argv( argv ) {} 48 49 int operator()() { return (*m_cpp_main_func)( m_argc, m_argv ); } 50 51private: 52 // Data members 53 int (*m_cpp_main_func)( int argc, char* argv[] ); 54 int m_argc; 55 char** m_argv; 56}; 57 58} // local namespace 59 60// ************************************************************************** // 61// ************** prg_exec_monitor_main ************** // 62// ************************************************************************** // 63 64namespace boost { 65 66int BOOST_TEST_DECL 67prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char* argv[] ) 68{ 69 int result = 0; 70 71 BOOST_TEST_I_TRY { 72 boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) ); 73 ::boost::execution_monitor ex_mon; 74 75 ex_mon.p_catch_system_errors.value = p != "no"; 76 77 result = ex_mon.execute( cpp_main_caller( cpp_main, argc, argv ) ); 78 79 if( result == 0 ) 80 result = ::boost::exit_success; 81 else if( result != ::boost::exit_success ) { 82 std::cout << "\n**** error return code: " << result << std::endl; 83 result = ::boost::exit_failure; 84 } 85 } 86 BOOST_TEST_I_CATCH( ::boost::execution_exception, exex ) { 87 std::cout << "\n**** exception(" << exex.code() << "): " << exex.what() << std::endl; 88 result = ::boost::exit_exception_failure; 89 } 90 BOOST_TEST_I_CATCH( ::boost::system_error, ex ) { 91 std::cout << "\n**** failed to initialize execution monitor." 92 << "\n**** expression at fault: " << ex.p_failed_exp 93 << "\n**** error(" << ex.p_errno << "): " << std::strerror( ex.p_errno ) << std::endl; 94 result = ::boost::exit_exception_failure; 95 } 96 97 if( result != ::boost::exit_success ) { 98 std::cerr << "******** errors detected; see standard output for details ********" << std::endl; 99 } 100 else { 101 // Some prefer a confirming message when all is well, while others don't 102 // like the clutter. Use an environment variable to avoid command 103 // line argument modifications; for use in production programs 104 // that's a no-no in some organizations. 105 ::boost::unit_test::const_string p( std::getenv( "BOOST_PRG_MON_CONFIRM" ) ); 106 if( p != "no" ) { 107 std::cerr << std::flush << "no errors detected" << std::endl; 108 } 109 } 110 111 return result; 112} 113 114} // namespace boost 115 116#if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN) 117 118// ************************************************************************** // 119// ************** main function for tests using lib ************** // 120// ************************************************************************** // 121 122int cpp_main( int argc, char* argv[] ); // prototype for user's cpp_main() 123 124int BOOST_TEST_CALL_DECL 125main( int argc, char* argv[] ) 126{ 127 return ::boost::prg_exec_monitor_main( &cpp_main, argc, argv ); 128} 129 130//____________________________________________________________________________// 131 132#endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN 133 134#include <boost/test/detail/enable_warnings.hpp> 135 136#endif // BOOST_TEST_CPP_MAIN_IPP_012205GER 137