config_file.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // (C) Copyright Gennadiy Rozental 2005-2008.
  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. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision: 49312 $
  10. //
  11. // Description : implements models configuration file, it's parameter and parameter namespaces
  12. // ***************************************************************************
  13. // Boost.Runtime.Parameter
  14. #include <boost/test/utils/runtime/config.hpp>
  15. #include <boost/test/utils/runtime/file/config_file.hpp>
  16. #include <boost/test/utils/runtime/validation.hpp>
  17. // Boost.Test
  18. #include <boost/test/utils/foreach.hpp>
  19. #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
  20. #include <boost/test/utils/basic_cstring/io.hpp>
  21. #include <boost/test/utils/iterator/token_iterator.hpp>
  22. namespace boost {
  23. namespace BOOST_RT_PARAM_NAMESPACE {
  24. namespace file {
  25. // ************************************************************************** //
  26. // ************** runtime::file::parameter ************** //
  27. // ************************************************************************** //
  28. parameter::parameter( cstring name, cstring value, param_namespace const& parent )
  29. : m_parent( parent )
  30. {
  31. assign_op( p_name.value, name, 0 );
  32. assign_op( p_value.value, value, 0 );
  33. }
  34. //____________________________________________________________________________//
  35. std::ostream&
  36. operator<<( std::ostream& os, parameter const& p )
  37. {
  38. p.m_parent.print_full_name( os );
  39. return os << p.p_name << " = \"" << p.p_value << "\"";
  40. }
  41. //____________________________________________________________________________//
  42. // ************************************************************************** //
  43. // ************** runtime::file::param_namespace ************** //
  44. // ************************************************************************** //
  45. param_namespace::param_namespace( cstring name, param_namespace const* parent )
  46. : p_parent( parent )
  47. {
  48. assign_op( p_name.value, name );
  49. }
  50. //____________________________________________________________________________//
  51. void
  52. param_namespace::insert_param( cstring param_name, cstring param_value )
  53. {
  54. BOOST_TEST_FOREACH( parameter const&, p, m_parameters )
  55. BOOST_RT_PARAM_VALIDATE_LOGIC( p.p_name != param_name,
  56. BOOST_RT_PARAM_LITERAL( "Duplicate parameter " ) << param_name );
  57. m_parameters.push_back( parameter( param_name, param_value, *this ) );
  58. }
  59. //____________________________________________________________________________//
  60. param_namespace&
  61. param_namespace::subnamespace( cstring namespace_name )
  62. {
  63. BOOST_TEST_FOREACH( param_namespace&, subns, m_subnamespaces )
  64. if( subns.p_name == namespace_name )
  65. return subns;
  66. m_subnamespaces.push_back( param_namespace( namespace_name, this ) );
  67. return m_subnamespaces.back();
  68. }
  69. //____________________________________________________________________________//
  70. void
  71. param_namespace::clear()
  72. {
  73. m_parameters.clear();
  74. m_subnamespaces.clear();
  75. }
  76. //____________________________________________________________________________//
  77. void
  78. param_namespace::print_full_name( std::ostream& os ) const
  79. {
  80. if( !p_parent )
  81. return;
  82. p_parent.get()->print_full_name( os );
  83. os << p_name << "::";
  84. }
  85. //____________________________________________________________________________//
  86. boost::optional<cstring>
  87. get_param_value( param_namespace const& where_from,
  88. cstring name_part1,
  89. cstring name_part2,
  90. cstring name_part3,
  91. cstring name_part4,
  92. cstring name_part5 )
  93. {
  94. if( name_part2.is_empty() ) {
  95. boost::optional<cstring> res;
  96. BOOST_TEST_FOREACH( parameter const&, p, where_from ) {
  97. if( p.p_name == name_part1 ) {
  98. res = cstring( p.p_value );
  99. break;
  100. }
  101. }
  102. return res;
  103. }
  104. param_namespace const* sns = get_param_subns( where_from, name_part1 );
  105. return sns ? get_param_value( *sns, name_part2, name_part3, name_part4, name_part5 )
  106. : boost::optional<cstring>();
  107. }
  108. //____________________________________________________________________________//
  109. cstring
  110. get_requ_param_value( param_namespace const& where_from,
  111. cstring name_part1,
  112. cstring name_part2,
  113. cstring name_part3,
  114. cstring name_part4,
  115. cstring name_part5 )
  116. {
  117. boost::optional<cstring> v = get_param_value( where_from, name_part1, name_part2, name_part3, name_part4, name_part5 );
  118. #define APPEND_PART( part ) (part.is_empty() ? "" : "::") << (part.is_empty() ? cstring() : part)
  119. BOOST_RT_PARAM_VALIDATE_LOGIC( !!v, BOOST_RT_PARAM_LITERAL( "Required parameter " )
  120. << name_part1
  121. << APPEND_PART( name_part2 )
  122. << APPEND_PART( name_part3 )
  123. << APPEND_PART( name_part4 )
  124. << APPEND_PART( name_part5 )
  125. << BOOST_RT_PARAM_LITERAL( " value is missing" ) );
  126. #undef APPEND_PART
  127. return *v;
  128. }
  129. //____________________________________________________________________________//
  130. param_namespace const*
  131. get_param_subns( param_namespace const& where_from, cstring namespace_name )
  132. {
  133. param_namespace::sub_ns_const_iterator it = where_from.sub_ns_begin();
  134. param_namespace::sub_ns_const_iterator end = where_from.sub_ns_end();
  135. while( it != end ) {
  136. if( it->p_name == namespace_name )
  137. return &*it;
  138. ++it;
  139. }
  140. return 0;
  141. }
  142. //____________________________________________________________________________//
  143. void
  144. param_namespace::load_impl( config_file_iterator cf_it,
  145. cstring value_marker, cstring value_delimeter, cstring namespace_delimeter )
  146. {
  147. using namespace unit_test;
  148. while( cf_it != config_file_iterator() ) {
  149. string_token_iterator ti( *cf_it, (max_tokens = 2,kept_delimeters = dt_none, dropped_delimeters = value_delimeter) );
  150. cstring param_name = *ti;
  151. cstring param_value = *(++ti);
  152. param_value.trim( value_marker );
  153. param_namespace* targ_ns = this;
  154. while( !param_name.is_empty() ) {
  155. cstring::size_type pos = param_name.find( namespace_delimeter );
  156. cstring subname( param_name.begin(), pos == cstring::npos ? param_name.size() : pos );
  157. if( subname.size() == param_name.size() ) {
  158. targ_ns->insert_param( param_name, param_value );
  159. break;
  160. }
  161. else {
  162. targ_ns = &targ_ns->subnamespace( subname );
  163. param_name.trim_left( subname.size() + namespace_delimeter.size() );
  164. }
  165. }
  166. ++cf_it;
  167. }
  168. }
  169. //____________________________________________________________________________//
  170. // ************************************************************************** //
  171. // ************** runtime::file::config_file ************** //
  172. // ************************************************************************** //
  173. config_file::config_file()
  174. : param_namespace( cstring() )
  175. {
  176. }
  177. //____________________________________________________________________________//
  178. config_file::config_file( cstring file_name )
  179. : param_namespace( cstring() )
  180. {
  181. load( file_name );
  182. }
  183. //____________________________________________________________________________//
  184. } // namespace file
  185. } // namespace BOOST_RT_PARAM_NAMESPACE
  186. } // namespace boost
  187. // EOF