// (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 #include #include // Boost.Test #include #include #include #include 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 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 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 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 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