// (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 |