Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:00

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 //  File        : $RCSfile$
0009 //
0010 //  Version     : $Revision$
0011 //
0012 //  Description : implemets Unit Test Log
0013 // ***************************************************************************
0014 
0015 #ifndef BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
0016 #define BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
0017 
0018 // Boost.Test
0019 #include <boost/test/unit_test_log.hpp>
0020 #include <boost/test/unit_test_log_formatter.hpp>
0021 #include <boost/test/execution_monitor.hpp>
0022 #include <boost/test/framework.hpp>
0023 #include <boost/test/unit_test_parameters.hpp>
0024 
0025 #include <boost/test/utils/basic_cstring/compare.hpp>
0026 #include <boost/test/utils/foreach.hpp>
0027 
0028 #include <boost/test/output/compiler_log_formatter.hpp>
0029 #include <boost/test/output/xml_log_formatter.hpp>
0030 #include <boost/test/output/junit_log_formatter.hpp>
0031 
0032 // Boost
0033 #include <boost/shared_ptr.hpp>
0034 #include <boost/io/ios_state.hpp>
0035 typedef ::boost::io::ios_base_all_saver io_saver_type;
0036 
0037 #include <boost/test/detail/suppress_warnings.hpp>
0038 
0039 //____________________________________________________________________________//
0040 
0041 namespace boost {
0042 namespace unit_test {
0043 
0044 // ************************************************************************** //
0045 // **************             entry_value_collector            ************** //
0046 // ************************************************************************** //
0047 
0048 namespace ut_detail {
0049 
0050 entry_value_collector const&
0051 entry_value_collector::operator<<( lazy_ostream const& v ) const
0052 {
0053     unit_test_log << v;
0054 
0055     return *this;
0056 }
0057 
0058 //____________________________________________________________________________//
0059 
0060 entry_value_collector const&
0061 entry_value_collector::operator<<( const_string v ) const
0062 {
0063     unit_test_log << v;
0064 
0065     return *this;
0066 }
0067 
0068 //____________________________________________________________________________//
0069 
0070 entry_value_collector::~entry_value_collector()
0071 {
0072     if( m_last )
0073         unit_test_log << log::end();
0074 }
0075 
0076 //____________________________________________________________________________//
0077 
0078 } // namespace ut_detail
0079 
0080 // ************************************************************************** //
0081 // **************                 unit_test_log                ************** //
0082 // ************************************************************************** //
0083 
0084 namespace {
0085 
0086 // log data
0087 struct unit_test_log_data_helper_impl {
0088   typedef boost::shared_ptr<unit_test_log_formatter> formatter_ptr;
0089   typedef boost::shared_ptr<io_saver_type>           saver_ptr;
0090 
0091   bool                m_enabled;
0092   output_format       m_format;
0093   std::ostream*       m_stream;
0094   saver_ptr           m_stream_state_saver;
0095   formatter_ptr       m_log_formatter;
0096   bool                m_entry_in_progress;
0097 
0098   unit_test_log_data_helper_impl(unit_test_log_formatter* p_log_formatter, output_format format, bool enabled = false)
0099     : m_enabled( enabled )
0100     , m_format( format )
0101     , m_stream( &std::cout )
0102     , m_stream_state_saver( new io_saver_type( std::cout ) )
0103     , m_log_formatter()
0104     , m_entry_in_progress( false )
0105   {
0106     m_log_formatter.reset(p_log_formatter);
0107     m_log_formatter->set_log_level(log_all_errors);
0108   }
0109 
0110   // helper functions
0111   std::ostream&       stream()
0112   {
0113       return *m_stream;
0114   }
0115 
0116   log_level get_log_level() const
0117   {
0118       return m_log_formatter->get_log_level();
0119   }
0120 };
0121 
0122 struct unit_test_log_impl {
0123     // Constructor
0124     unit_test_log_impl()
0125     {
0126       m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::compiler_log_formatter, OF_CLF, true) ); // only this one is active by default,
0127       m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::xml_log_formatter, OF_XML, false) );
0128       m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::junit_log_formatter, OF_JUNIT, false) );
0129     }
0130 
0131     typedef std::vector<unit_test_log_data_helper_impl> v_formatter_data_t;
0132     v_formatter_data_t m_log_formatter_data;
0133 
0134     typedef std::vector<unit_test_log_data_helper_impl*> vp_formatter_data_t;
0135     vp_formatter_data_t m_active_log_formatter_data;
0136 
0137     // entry data
0138     log_entry_data      m_entry_data;
0139 
0140     bool has_entry_in_progress() const {
0141         for( vp_formatter_data_t::const_iterator it(m_active_log_formatter_data.begin()), ite(m_active_log_formatter_data.end()); 
0142              it < ite; 
0143              ++it)
0144         {
0145             unit_test_log_data_helper_impl& current_logger_data = **it;
0146             if( current_logger_data.m_entry_in_progress )
0147                 return true;
0148         }
0149         return false;
0150     }
0151 
0152     // check point data
0153     log_checkpoint_data m_checkpoint_data;
0154 
0155     void                set_checkpoint( const_string file, std::size_t line_num, const_string msg )
0156     {
0157         assign_op( m_checkpoint_data.m_message, msg, 0 );
0158         m_checkpoint_data.m_file_name   = file;
0159         m_checkpoint_data.m_line_num    = line_num;
0160     }
0161 };
0162 
0163 unit_test_log_impl& s_log_impl() { static unit_test_log_impl the_inst; return the_inst; }
0164 
0165 
0166 //____________________________________________________________________________//
0167 
0168 void
0169 log_entry_context( log_level l, unit_test_log_data_helper_impl& current_logger_data)
0170 {
0171     framework::context_generator const& context = framework::get_context();
0172     if( context.is_empty() )
0173         return;
0174 
0175     const_string frame;
0176     current_logger_data.m_log_formatter->entry_context_start( current_logger_data.stream(), l );
0177     while( !(frame=context.next()).is_empty() )
0178     {
0179         current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), l, frame );
0180     }
0181     current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream(), l );
0182 }
0183 
0184 //____________________________________________________________________________//
0185 
0186 void
0187 clear_entry_context()
0188 {
0189     framework::clear_context();
0190 }
0191 
0192 // convenience
0193 typedef unit_test_log_impl::vp_formatter_data_t vp_logger_t;
0194 typedef unit_test_log_impl::v_formatter_data_t v_logger_t;
0195 
0196 } // local namespace
0197 
0198 //____________________________________________________________________________//
0199 
0200 BOOST_TEST_SINGLETON_CONS_IMPL( unit_test_log_t )
0201 
0202 void
0203 unit_test_log_t::configure( )
0204 {
0205     // configure is not test_start:
0206     // test_start pushes the necessary log information when the test module is starting, and implies configure.
0207     // configure: should be called each time the set of loggers, stream or configuration is changed.
0208     s_log_impl().m_active_log_formatter_data.clear();
0209     for( unit_test_log_impl::v_formatter_data_t::iterator it(s_log_impl().m_log_formatter_data.begin()), 
0210                                                           ite(s_log_impl().m_log_formatter_data.end());
0211         it < ite;
0212         ++it)
0213     {
0214       if( !it->m_enabled || it->get_log_level() == log_nothing )
0215           continue;
0216 
0217       s_log_impl().m_active_log_formatter_data.push_back(&*it);
0218       it->m_entry_in_progress = false;
0219     }
0220 }
0221 
0222 //____________________________________________________________________________//
0223 
0224 void
0225 unit_test_log_t::test_start( counter_t test_cases_amount, test_unit_id )
0226 {
0227     configure();
0228     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0229     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0230     {
0231       unit_test_log_data_helper_impl& current_logger_data = **it;
0232 
0233       current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
0234       current_logger_data.m_log_formatter->log_build_info(
0235           current_logger_data.stream(),
0236           runtime_config::get<bool>( runtime_config::btrt_build_info ));
0237 
0238       //current_logger_data.stream().flush();
0239     }
0240 }
0241 
0242 //____________________________________________________________________________//
0243 
0244 void
0245 unit_test_log_t::test_finish()
0246 {
0247     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0248     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0249     {
0250       unit_test_log_data_helper_impl& current_logger_data = **it;
0251       current_logger_data.m_log_formatter->log_finish( current_logger_data.stream() );
0252       current_logger_data.stream().flush();
0253     }
0254 }
0255 
0256 //____________________________________________________________________________//
0257 
0258 void
0259 unit_test_log_t::test_aborted()
0260 {
0261     BOOST_TEST_LOG_ENTRY( log_messages ) << "Test is aborted";
0262 }
0263 
0264 //____________________________________________________________________________//
0265 
0266 void
0267 unit_test_log_t::test_unit_start( test_unit const& tu )
0268 {
0269     if( s_log_impl().has_entry_in_progress() )
0270         *this << log::end();
0271 
0272     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0273     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0274     {
0275         unit_test_log_data_helper_impl& current_logger_data = **it;
0276         if( current_logger_data.get_log_level() > log_test_units )
0277             continue;
0278         current_logger_data.m_log_formatter->test_unit_start( current_logger_data.stream(), tu );
0279     }
0280 }
0281 
0282 //____________________________________________________________________________//
0283 
0284 void
0285 unit_test_log_t::test_unit_finish( test_unit const& tu, unsigned long elapsed )
0286 {
0287     s_log_impl().m_checkpoint_data.clear();
0288 
0289     if( s_log_impl().has_entry_in_progress() )
0290         *this << log::end();
0291 
0292     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0293     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0294     {
0295         unit_test_log_data_helper_impl& current_logger_data = **it;
0296         if( current_logger_data.get_log_level() > log_test_units )
0297             continue;
0298 
0299         current_logger_data.m_log_formatter->test_unit_finish( current_logger_data.stream(), tu, elapsed );
0300     }
0301 }
0302 
0303 //____________________________________________________________________________//
0304 
0305 void
0306 unit_test_log_t::test_unit_skipped( test_unit const& tu, const_string reason )
0307 {
0308     if( s_log_impl().has_entry_in_progress() )
0309         *this << log::end();
0310 
0311     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0312     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0313     {
0314         unit_test_log_data_helper_impl& current_logger_data = **it;
0315         if( current_logger_data.get_log_level() > log_test_units )
0316             continue;
0317 
0318         current_logger_data.m_log_formatter->test_unit_skipped( current_logger_data.stream(), tu, reason );
0319     }
0320 }
0321 
0322 void
0323 unit_test_log_t::test_unit_aborted( test_unit const& tu )
0324 {
0325     if( s_log_impl().has_entry_in_progress() )
0326         *this << log::end();
0327 
0328     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0329     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0330     {
0331         unit_test_log_data_helper_impl& current_logger_data = **it;
0332         if( current_logger_data.get_log_level() > log_test_units )
0333             continue;
0334 
0335         current_logger_data.m_log_formatter->test_unit_aborted(current_logger_data.stream(), tu );
0336     }
0337 }
0338 
0339 void
0340 unit_test_log_t::test_unit_timed_out( test_unit const& tu )
0341 {
0342     if( s_log_impl().has_entry_in_progress() )
0343         *this << log::end();
0344 
0345     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0346     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0347     {
0348         unit_test_log_data_helper_impl& current_logger_data = **it;
0349         if( current_logger_data.get_log_level() > log_test_units )
0350             continue;
0351 
0352         current_logger_data.m_log_formatter->test_unit_timed_out(current_logger_data.stream(), tu );
0353     }
0354 }
0355 
0356 //____________________________________________________________________________//
0357 
0358 void
0359 unit_test_log_t::exception_caught( execution_exception const& ex )
0360 {
0361     log_level l =
0362         ex.code() <= execution_exception::cpp_exception_error   ? log_cpp_exception_errors :
0363         (ex.code() <= execution_exception::timeout_error        ? log_system_errors
0364                                                                 : log_fatal_errors );
0365 
0366     if( s_log_impl().has_entry_in_progress() )
0367         *this << log::end();
0368 
0369     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0370     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0371     {
0372       unit_test_log_data_helper_impl& current_logger_data = **it;
0373 
0374       if( l >= current_logger_data.get_log_level() ) {
0375 
0376           current_logger_data.m_log_formatter->log_exception_start( current_logger_data.stream(), s_log_impl().m_checkpoint_data, ex );
0377 
0378           log_entry_context( l, current_logger_data );
0379 
0380           current_logger_data.m_log_formatter->log_exception_finish( current_logger_data.stream() );
0381       }
0382     }
0383     clear_entry_context();
0384 }
0385 
0386 //____________________________________________________________________________//
0387 
0388 void
0389 unit_test_log_t::set_checkpoint( const_string file, std::size_t line_num, const_string msg )
0390 {
0391     s_log_impl().set_checkpoint( file, line_num, msg );
0392 }
0393 
0394 //____________________________________________________________________________//
0395 
0396 char
0397 set_unix_slash( char in )
0398 {
0399     return in == '\\' ? '/' : in;
0400 }
0401 
0402 unit_test_log_t&
0403 unit_test_log_t::operator<<( log::begin const& b )
0404 {
0405     if( s_log_impl().has_entry_in_progress() )
0406         *this << log::end();
0407 
0408     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0409     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0410     {
0411       unit_test_log_data_helper_impl& current_logger_data = **it;
0412       current_logger_data.m_stream_state_saver->restore();
0413     }
0414 
0415     s_log_impl().m_entry_data.clear();
0416 
0417     assign_op( s_log_impl().m_entry_data.m_file_name, b.m_file_name, 0 );
0418 
0419     // normalize file name
0420     std::transform( s_log_impl().m_entry_data.m_file_name.begin(), s_log_impl().m_entry_data.m_file_name.end(),
0421                     s_log_impl().m_entry_data.m_file_name.begin(),
0422                     &set_unix_slash );
0423 
0424     s_log_impl().m_entry_data.m_line_num = b.m_line_num;
0425 
0426     return *this;
0427 }
0428 
0429 //____________________________________________________________________________//
0430 
0431 unit_test_log_t&
0432 unit_test_log_t::operator<<( log::end const& )
0433 {
0434     if( s_log_impl().has_entry_in_progress() ) {
0435         vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0436         log_level l = s_log_impl().m_entry_data.m_level;
0437         for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0438         {
0439             unit_test_log_data_helper_impl& current_logger_data = **it;
0440             if( current_logger_data.m_entry_in_progress ) {
0441                 if( l >= current_logger_data.get_log_level() ) {
0442                     log_entry_context( l, current_logger_data );
0443                 }
0444                 current_logger_data.m_log_formatter->log_entry_finish( current_logger_data.stream() );
0445             }
0446             current_logger_data.m_entry_in_progress = false;
0447         }
0448     }
0449 
0450     clear_entry_context();
0451 
0452     return *this;
0453 }
0454 
0455 //____________________________________________________________________________//
0456 
0457 unit_test_log_t&
0458 unit_test_log_t::operator<<( log_level l )
0459 {
0460     s_log_impl().m_entry_data.m_level = l;
0461 
0462     return *this;
0463 }
0464 
0465 //____________________________________________________________________________//
0466 
0467 ut_detail::entry_value_collector
0468 unit_test_log_t::operator()( log_level l )
0469 {
0470     *this << l;
0471 
0472     return ut_detail::entry_value_collector();
0473 }
0474 
0475 //____________________________________________________________________________//
0476 
0477 bool
0478 log_entry_start(unit_test_log_data_helper_impl &current_logger_data)
0479 {
0480     if( current_logger_data.m_entry_in_progress )
0481         return true;
0482 
0483     switch( s_log_impl().m_entry_data.m_level ) {
0484     case log_successful_tests:
0485         current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
0486                                               unit_test_log_formatter::BOOST_UTL_ET_INFO );
0487         break;
0488     case log_messages:
0489         current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
0490                                               unit_test_log_formatter::BOOST_UTL_ET_MESSAGE );
0491         break;
0492     case log_warnings:
0493         current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
0494                                               unit_test_log_formatter::BOOST_UTL_ET_WARNING );
0495         break;
0496     case log_all_errors:
0497     case log_cpp_exception_errors:
0498     case log_system_errors:
0499         current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
0500                                               unit_test_log_formatter::BOOST_UTL_ET_ERROR );
0501         break;
0502     case log_fatal_errors:
0503         current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
0504                                               unit_test_log_formatter::BOOST_UTL_ET_FATAL_ERROR );
0505         break;
0506     case log_nothing:
0507     case log_test_units:
0508     case invalid_log_level:
0509         return false;
0510     }
0511 
0512     current_logger_data.m_entry_in_progress = true;
0513     return true;
0514 }
0515 
0516 //____________________________________________________________________________//
0517 
0518 unit_test_log_t&
0519 unit_test_log_t::operator<<( const_string value )
0520 {
0521     if(value.empty()) {
0522         return *this;
0523     }
0524 
0525     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0526     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0527     {
0528         unit_test_log_data_helper_impl& current_logger_data = **it;
0529         if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() )
0530             if( log_entry_start(current_logger_data) ) {
0531                 current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
0532             }
0533     }
0534     return *this;
0535 }
0536 
0537 //____________________________________________________________________________//
0538 
0539 unit_test_log_t&
0540 unit_test_log_t::operator<<( lazy_ostream const& value )
0541 {
0542     if(value.empty()) {
0543         return *this;
0544     }
0545 
0546     vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
0547     for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0548     {
0549         unit_test_log_data_helper_impl& current_logger_data = **it;
0550         if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() ) {
0551             if( log_entry_start(current_logger_data) ) {
0552                 current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
0553             }
0554         }
0555     }
0556     return *this;
0557 }
0558 
0559 //____________________________________________________________________________//
0560 
0561 void
0562 unit_test_log_t::set_stream( std::ostream& str )
0563 {
0564     if( s_log_impl().has_entry_in_progress() )
0565         return;
0566 
0567     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0568     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0569     {
0570         unit_test_log_data_helper_impl& current_logger_data = *it;
0571 
0572         current_logger_data.m_stream = &str;
0573         current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
0574     }
0575 }
0576 
0577 //____________________________________________________________________________//
0578 
0579 void
0580 unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
0581 {
0582     if( s_log_impl().has_entry_in_progress() )
0583         return;
0584 
0585     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0586     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0587     {
0588         unit_test_log_data_helper_impl& current_logger_data = *it;
0589         if( current_logger_data.m_format == log_format) {
0590             current_logger_data.m_stream = &str;
0591             current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
0592             break;
0593         }
0594     }
0595 }
0596 
0597 std::ostream*
0598 unit_test_log_t::get_stream( output_format log_format ) const
0599 {
0600     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0601     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0602     {
0603         unit_test_log_data_helper_impl& current_logger_data = *it;
0604         if( current_logger_data.m_format == log_format) {
0605             return current_logger_data.m_stream;
0606         }
0607     }
0608     return 0;
0609 }
0610 
0611 //____________________________________________________________________________//
0612 
0613 log_level
0614 unit_test_log_t::set_threshold_level( log_level lev )
0615 {
0616     if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
0617         return invalid_log_level;
0618 
0619     log_level ret = log_nothing;
0620     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0621     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0622     {
0623         unit_test_log_data_helper_impl& current_logger_data = *it;
0624         ret = (std::min)(ret, current_logger_data.m_log_formatter->get_log_level());
0625         current_logger_data.m_log_formatter->set_log_level( lev );
0626     }
0627     return ret;
0628 }
0629 
0630 //____________________________________________________________________________//
0631 
0632 log_level
0633 unit_test_log_t::set_threshold_level( output_format log_format, log_level lev )
0634 {
0635     if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
0636         return invalid_log_level;
0637 
0638     log_level ret = log_nothing;
0639     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0640     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0641     {
0642         unit_test_log_data_helper_impl& current_logger_data = *it;
0643         if( current_logger_data.m_format == log_format) {
0644             ret = current_logger_data.m_log_formatter->get_log_level(); 
0645             current_logger_data.m_log_formatter->set_log_level( lev );
0646             break;
0647         }
0648     }
0649     return ret;
0650 }
0651 
0652 //____________________________________________________________________________//
0653 
0654 void
0655 unit_test_log_t::set_format( output_format log_format )
0656 {
0657     if( s_log_impl().has_entry_in_progress() )
0658         return;
0659 
0660     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0661     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0662     {
0663         unit_test_log_data_helper_impl& current_logger_data = *it;
0664         current_logger_data.m_enabled = current_logger_data.m_format == log_format;
0665     }
0666 }
0667 
0668 //____________________________________________________________________________//
0669 
0670 void
0671 unit_test_log_t::add_format( output_format log_format )
0672 {
0673     if( s_log_impl().has_entry_in_progress() )
0674         return;
0675 
0676     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0677     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0678     {
0679         unit_test_log_data_helper_impl& current_logger_data = *it;
0680         if( current_logger_data.m_format == log_format) {
0681             current_logger_data.m_enabled = true;
0682             break;
0683         }
0684     }
0685 }
0686 
0687 //____________________________________________________________________________//
0688 
0689 unit_test_log_formatter*
0690 unit_test_log_t::get_formatter( output_format log_format ) {
0691     
0692     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0693     for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0694     {
0695         unit_test_log_data_helper_impl& current_logger_data = *it;
0696         if( current_logger_data.m_format == log_format) {
0697             return current_logger_data.m_log_formatter.get();
0698         }
0699     }
0700     return 0;
0701 }
0702 
0703 
0704 void
0705 unit_test_log_t::add_formatter( unit_test_log_formatter* the_formatter )
0706 {
0707     // remove only user defined logger
0708     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0709     for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0710     {
0711         if( it->m_format == OF_CUSTOM_LOGGER) {
0712             s_log_impl().m_log_formatter_data.erase(it);
0713             break;
0714         }
0715     }
0716 
0717     if( the_formatter ) {
0718         s_log_impl().m_active_log_formatter_data.clear(); // otherwise dandling references
0719         vloggers.push_back( unit_test_log_data_helper_impl(the_formatter, OF_CUSTOM_LOGGER, true) );
0720     }
0721 }
0722 
0723 void
0724 unit_test_log_t::set_formatter( unit_test_log_formatter* the_formatter )
0725 {
0726     if( s_log_impl().has_entry_in_progress() )
0727         return;
0728 
0729     // remove only user defined logger
0730     log_level current_level = invalid_log_level;
0731     std::ostream *current_stream = 0;
0732     output_format previous_format = OF_INVALID;
0733     v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
0734     for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
0735     {
0736         if( it->m_enabled ) {
0737             if( current_level == invalid_log_level || it->m_format < previous_format || it->m_format == OF_CUSTOM_LOGGER) {
0738                 current_level = it->get_log_level();
0739                 current_stream = &(it->stream());
0740                 previous_format = it->m_format;
0741             }
0742         }
0743     }
0744 
0745     if( the_formatter ) {
0746         add_formatter(the_formatter);
0747         set_format(OF_CUSTOM_LOGGER);
0748         set_threshold_level(OF_CUSTOM_LOGGER, current_level);
0749         set_stream(OF_CUSTOM_LOGGER, *current_stream);
0750     }
0751 
0752     configure();
0753 }
0754 
0755 //____________________________________________________________________________//
0756 
0757 // ************************************************************************** //
0758 // **************            unit_test_log_formatter           ************** //
0759 // ************************************************************************** //
0760 
0761 void
0762 unit_test_log_formatter::log_entry_value( std::ostream& ostr, lazy_ostream const& value )
0763 {
0764     log_entry_value( ostr, (wrap_stringstream().ref() << value).str() );
0765 }
0766 
0767 void
0768 unit_test_log_formatter::set_log_level(log_level new_log_level)
0769 {
0770     m_log_level = new_log_level;
0771 }
0772 
0773 log_level
0774 unit_test_log_formatter::get_log_level() const
0775 {
0776     return m_log_level;
0777 }
0778 
0779 //____________________________________________________________________________//
0780 
0781 } // namespace unit_test
0782 } // namespace boost
0783 
0784 #include <boost/test/detail/enable_warnings.hpp>
0785 
0786 #endif // BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
0787