250 lines
8.1 KiB
C++
Executable File
250 lines
8.1 KiB
C++
Executable File
// (C) Copyright Gennadiy Rozental 2005-2007.
|
|
// 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: 43798 $
|
|
//
|
|
// 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
|