source: NonGTP/Boost/boost/test/utils/runtime/file/config_file.cpp @ 857

Revision 857, 8.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Gennadiy Rozental 2005.
2//  Use, modification, and distribution are subject to the
3//  Boost Software License, Version 1.0. (See accompanying file
4//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6//  See http://www.boost.org/libs/test for the library home page.
7//
8//  File        : $RCSfile: config_file.cpp,v $
9//
10//  Version     : $Revision: 1.1 $
11//
12//  Description : implements models configuration file, it's parameter and parameter namespaces
13// ***************************************************************************
14
15// Boost.Runtime.Parameter
16#include <boost/test/utils/runtime/config.hpp>
17
18#include <boost/test/utils/runtime/file/config_file.hpp>
19#include <boost/test/utils/runtime/validation.hpp>
20
21// Boost.Test
22#include <boost/test/utils/foreach.hpp>
23#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
24#include <boost/test/utils/basic_cstring/io.hpp>
25#include <boost/test/utils/iterator/token_iterator.hpp>
26
27namespace boost {
28
29namespace BOOST_RT_PARAM_NAMESPACE {
30
31namespace file {
32
33// ************************************************************************** //
34// **************           runtime::file::parameter           ************** //
35// ************************************************************************** //
36
37parameter::parameter( cstring name, cstring value, param_namespace const& parent )
38: m_parent( parent )
39{
40    assign_op( p_name.value, name, 0 );
41    assign_op( p_value.value, value, 0 );
42}
43
44//____________________________________________________________________________//
45
46std::ostream&
47operator<<( std::ostream& os, parameter const& p )
48{
49    p.m_parent.print_full_name( os );
50
51    return os << p.p_name << " = \"" << p.p_value << "\"";
52}
53
54//____________________________________________________________________________//
55
56// ************************************************************************** //
57// **************        runtime::file::param_namespace        ************** //
58// ************************************************************************** //
59
60param_namespace::param_namespace( cstring name, param_namespace const* parent )
61: p_parent( parent )
62{
63    assign_op( p_name.value, name );
64}
65
66//____________________________________________________________________________//
67
68void
69param_namespace::insert_param( cstring param_name, cstring param_value )
70{
71    BOOST_TEST_FOREACH( parameter const&, p, m_parameters )
72        BOOST_RT_PARAM_VALIDATE_LOGIC( p.p_name != param_name,
73                                       BOOST_RT_PARAM_LITERAL( "Duplicate parameter " ) << param_name );
74
75    m_parameters.push_back( parameter( param_name, param_value, *this ) );
76}
77
78//____________________________________________________________________________//
79
80param_namespace&
81param_namespace::subnamespace( cstring namespace_name )
82{
83    BOOST_TEST_FOREACH( param_namespace&, subns, m_subnamespaces )
84        if( subns.p_name == namespace_name )
85            return subns;
86
87    m_subnamespaces.push_back( param_namespace( namespace_name, this ) );
88
89    return m_subnamespaces.back();
90}
91
92//____________________________________________________________________________//
93
94void
95param_namespace::clear()
96{
97    m_parameters.clear();
98    m_subnamespaces.clear();
99}
100
101//____________________________________________________________________________//
102
103void
104param_namespace::print_full_name( std::ostream& os ) const
105{
106    if( !p_parent )
107        return;
108
109    p_parent.get()->print_full_name( os );
110
111    os << p_name << "::";
112}
113
114//____________________________________________________________________________//
115
116boost::optional<cstring>
117get_param_value( param_namespace const& where_from,
118                 cstring                name_part1,
119                 cstring                name_part2,
120                 cstring                name_part3,
121                 cstring                name_part4,
122                 cstring                name_part5 )
123{
124    if( name_part2.is_empty() ) {
125        boost::optional<cstring> res;
126
127        BOOST_TEST_FOREACH( parameter const&, p, where_from ) {
128            if( p.p_name == name_part1 ) {
129                res = cstring( p.p_value );
130                break;
131            }
132        }
133
134        return res;
135    }
136   
137    param_namespace const* sns = get_param_subns( where_from, name_part1 );
138
139    return sns ? get_param_value( *sns, name_part2, name_part3, name_part4, name_part5 )
140               : boost::optional<cstring>();
141}
142
143//____________________________________________________________________________//
144
145cstring
146get_requ_param_value( param_namespace const& where_from,
147                      cstring                name_part1,
148                      cstring                name_part2,
149                      cstring                name_part3,
150                      cstring                name_part4,
151                      cstring                name_part5 )
152{
153    boost::optional<cstring> v = get_param_value( where_from, name_part1, name_part2, name_part3, name_part4, name_part5 );
154
155#define APPEND_PART( part ) (part.is_empty() ? "" : "::") << (part.is_empty() ? cstring() : part)
156    BOOST_RT_PARAM_VALIDATE_LOGIC( !!v, BOOST_RT_PARAM_LITERAL( "Required parameter " )
157                                        << name_part1
158                                        << APPEND_PART( name_part2 )
159                                        << APPEND_PART( name_part3 )
160                                        << APPEND_PART( name_part4 )
161                                        << APPEND_PART( name_part5 )
162                                        << BOOST_RT_PARAM_LITERAL( " value is missing" ) );
163#undef APPEND_PART
164
165    return *v;
166}
167
168//____________________________________________________________________________//
169
170param_namespace const*
171get_param_subns( param_namespace const& where_from, cstring namespace_name )
172{
173    param_namespace::sub_ns_const_iterator it   = where_from.sub_ns_begin();
174    param_namespace::sub_ns_const_iterator end  = where_from.sub_ns_end();
175
176    while( it != end ) {
177        if( it->p_name == namespace_name )
178            return &*it;
179
180        ++it;
181    }
182
183    return 0;
184}
185
186//____________________________________________________________________________//
187
188void
189param_namespace::load_impl( config_file_iterator cf_it,
190                            cstring value_marker, cstring value_delimeter, cstring namespace_delimeter )
191{
192    using namespace unit_test;
193
194    while( cf_it != config_file_iterator() ) {
195        string_token_iterator ti( *cf_it, (max_tokens = 2,kept_delimeters = dt_none, dropped_delimeters = value_delimeter) );
196
197        cstring param_name  = *ti;
198        cstring param_value = *(++ti);
199
200        param_value.trim( value_marker );
201
202        param_namespace* targ_ns = this;
203
204        while( !param_name.is_empty() ) {
205            cstring::size_type pos = param_name.find( namespace_delimeter );
206            cstring            subname( param_name.begin(), pos == cstring::npos ? param_name.size() : pos );
207
208            if( subname.size() == param_name.size() ) {
209                targ_ns->insert_param( param_name, param_value );
210                break;
211            }
212            else {
213                targ_ns = &targ_ns->subnamespace( subname );
214
215                param_name.trim_left( subname.size() + namespace_delimeter.size() );
216            }
217        }
218        ++cf_it;
219    }
220}
221
222//____________________________________________________________________________//
223
224// ************************************************************************** //
225// **************          runtime::file::config_file          ************** //
226// ************************************************************************** //
227
228config_file::config_file()
229: param_namespace( cstring() )
230{
231}
232
233//____________________________________________________________________________//
234
235config_file::config_file( cstring file_name )
236: param_namespace( cstring() )
237{
238    load( file_name );
239}
240
241//____________________________________________________________________________//
242
243} // namespace file
244
245} // namespace BOOST_RT_PARAM_NAMESPACE
246
247} // namespace boost
248
249// ************************************************************************** //
250//   Revision History:
251//
252//   $Log: config_file.cpp,v $
253//   Revision 1.1  2005/04/12 06:42:43  rogeeff
254//   Runtime.Param library initial commit
255//
256// ************************************************************************** //
Note: See TracBrowser for help on using the repository browser.