| // (C) Copyright Gennadiy Rozental 2005-2008. |
| // Use, modification, and distribution are subject to 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. |
| // |
| // File : $RCSfile$ |
| // |
| // Version : $Revision: 49312 $ |
| // |
| // Description : implements models configuration file, it's parameter and parameter namespaces |
| // *************************************************************************** |
| |
| // Boost.Runtime.Parameter |
| #include <boost/test/utils/runtime/config.hpp> |
| |
| #include <boost/test/utils/runtime/file/config_file.hpp> |
| #include <boost/test/utils/runtime/validation.hpp> |
| |
| // Boost.Test |
| #include <boost/test/utils/foreach.hpp> |
| #include <boost/test/utils/basic_cstring/basic_cstring.hpp> |
| #include <boost/test/utils/basic_cstring/io.hpp> |
| #include <boost/test/utils/iterator/token_iterator.hpp> |
| |
| namespace boost { |
| |
| namespace BOOST_RT_PARAM_NAMESPACE { |
| |
| namespace file { |
| |
| // ************************************************************************** // |
| // ************** runtime::file::parameter ************** // |
| // ************************************************************************** // |
| |
| parameter::parameter( cstring name, cstring value, param_namespace const& parent ) |
| : m_parent( parent ) |
| { |
| assign_op( p_name.value, name, 0 ); |
| assign_op( p_value.value, value, 0 ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| std::ostream& |
| operator<<( std::ostream& os, parameter const& p ) |
| { |
| p.m_parent.print_full_name( os ); |
| |
| return os << p.p_name << " = \"" << p.p_value << "\""; |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** runtime::file::param_namespace ************** // |
| // ************************************************************************** // |
| |
| param_namespace::param_namespace( cstring name, param_namespace const* parent ) |
| : p_parent( parent ) |
| { |
| assign_op( p_name.value, name ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| void |
| param_namespace::insert_param( cstring param_name, cstring param_value ) |
| { |
| BOOST_TEST_FOREACH( parameter const&, p, m_parameters ) |
| BOOST_RT_PARAM_VALIDATE_LOGIC( p.p_name != param_name, |
| BOOST_RT_PARAM_LITERAL( "Duplicate parameter " ) << param_name ); |
| |
| m_parameters.push_back( parameter( param_name, param_value, *this ) ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| param_namespace& |
| param_namespace::subnamespace( cstring namespace_name ) |
| { |
| BOOST_TEST_FOREACH( param_namespace&, subns, m_subnamespaces ) |
| if( subns.p_name == namespace_name ) |
| return subns; |
| |
| m_subnamespaces.push_back( param_namespace( namespace_name, this ) ); |
| |
| return m_subnamespaces.back(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| void |
| param_namespace::clear() |
| { |
| m_parameters.clear(); |
| m_subnamespaces.clear(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| void |
| param_namespace::print_full_name( std::ostream& os ) const |
| { |
| if( !p_parent ) |
| return; |
| |
| p_parent.get()->print_full_name( os ); |
| |
| os << p_name << "::"; |
| } |
| |
| //____________________________________________________________________________// |
| |
| boost::optional<cstring> |
| get_param_value( param_namespace const& where_from, |
| cstring name_part1, |
| cstring name_part2, |
| cstring name_part3, |
| cstring name_part4, |
| cstring name_part5 ) |
| { |
| if( name_part2.is_empty() ) { |
| boost::optional<cstring> res; |
| |
| BOOST_TEST_FOREACH( parameter const&, p, where_from ) { |
| if( p.p_name == name_part1 ) { |
| res = cstring( p.p_value ); |
| break; |
| } |
| } |
| |
| return res; |
| } |
| |
| param_namespace const* sns = get_param_subns( where_from, name_part1 ); |
| |
| return sns ? get_param_value( *sns, name_part2, name_part3, name_part4, name_part5 ) |
| : boost::optional<cstring>(); |
| } |
| |
| //____________________________________________________________________________// |
| |
| cstring |
| get_requ_param_value( param_namespace const& where_from, |
| cstring name_part1, |
| cstring name_part2, |
| cstring name_part3, |
| cstring name_part4, |
| cstring name_part5 ) |
| { |
| boost::optional<cstring> v = get_param_value( where_from, name_part1, name_part2, name_part3, name_part4, name_part5 ); |
| |
| #define APPEND_PART( part ) (part.is_empty() ? "" : "::") << (part.is_empty() ? cstring() : part) |
| BOOST_RT_PARAM_VALIDATE_LOGIC( !!v, BOOST_RT_PARAM_LITERAL( "Required parameter " ) |
| << name_part1 |
| << APPEND_PART( name_part2 ) |
| << APPEND_PART( name_part3 ) |
| << APPEND_PART( name_part4 ) |
| << APPEND_PART( name_part5 ) |
| << BOOST_RT_PARAM_LITERAL( " value is missing" ) ); |
| #undef APPEND_PART |
| |
| return *v; |
| } |
| |
| //____________________________________________________________________________// |
| |
| param_namespace const* |
| get_param_subns( param_namespace const& where_from, cstring namespace_name ) |
| { |
| param_namespace::sub_ns_const_iterator it = where_from.sub_ns_begin(); |
| param_namespace::sub_ns_const_iterator end = where_from.sub_ns_end(); |
| |
| while( it != end ) { |
| if( it->p_name == namespace_name ) |
| return &*it; |
| |
| ++it; |
| } |
| |
| return 0; |
| } |
| |
| //____________________________________________________________________________// |
| |
| void |
| param_namespace::load_impl( config_file_iterator cf_it, |
| cstring value_marker, cstring value_delimeter, cstring namespace_delimeter ) |
| { |
| using namespace unit_test; |
| |
| while( cf_it != config_file_iterator() ) { |
| string_token_iterator ti( *cf_it, (max_tokens = 2,kept_delimeters = dt_none, dropped_delimeters = value_delimeter) ); |
| |
| cstring param_name = *ti; |
| cstring param_value = *(++ti); |
| |
| param_value.trim( value_marker ); |
| |
| param_namespace* targ_ns = this; |
| |
| while( !param_name.is_empty() ) { |
| cstring::size_type pos = param_name.find( namespace_delimeter ); |
| cstring subname( param_name.begin(), pos == cstring::npos ? param_name.size() : pos ); |
| |
| if( subname.size() == param_name.size() ) { |
| targ_ns->insert_param( param_name, param_value ); |
| break; |
| } |
| else { |
| targ_ns = &targ_ns->subnamespace( subname ); |
| |
| param_name.trim_left( subname.size() + namespace_delimeter.size() ); |
| } |
| } |
| ++cf_it; |
| } |
| } |
| |
| //____________________________________________________________________________// |
| |
| // ************************************************************************** // |
| // ************** runtime::file::config_file ************** // |
| // ************************************************************************** // |
| |
| config_file::config_file() |
| : param_namespace( cstring() ) |
| { |
| } |
| |
| //____________________________________________________________________________// |
| |
| config_file::config_file( cstring file_name ) |
| : param_namespace( cstring() ) |
| { |
| load( file_name ); |
| } |
| |
| //____________________________________________________________________________// |
| |
| } // namespace file |
| |
| } // namespace BOOST_RT_PARAM_NAMESPACE |
| |
| } // namespace boost |
| |
| // EOF |