From 7cfe7537ea7af825c41047fc70024fd0ae4eec4e Mon Sep 17 00:00:00 2001 From: Gennadiy Rozental Date: Tue, 12 Apr 2005 06:42:44 +0000 Subject: [PATCH] Runtime.Param library initial commit [SVN r28158] --- include/boost/test/utils/runtime/argument.hpp | 108 +++ .../utils/runtime/cla/argument_factory.hpp | 227 ++++++ .../test/utils/runtime/cla/argv_traverser.cpp | 25 + .../test/utils/runtime/cla/argv_traverser.hpp | 107 +++ .../test/utils/runtime/cla/argv_traverser.ipp | 213 ++++++ .../utils/runtime/cla/basic_parameter.hpp | 93 +++ .../test/utils/runtime/cla/char_parameter.cpp | 25 + .../test/utils/runtime/cla/char_parameter.hpp | 107 +++ .../test/utils/runtime/cla/char_parameter.ipp | 66 ++ .../cla/detail/argument_value_usage.hpp | 91 +++ .../utils/runtime/cla/dual_name_parameter.cpp | 25 + .../utils/runtime/cla/dual_name_parameter.hpp | 97 +++ .../utils/runtime/cla/dual_name_parameter.ipp | 99 +++ include/boost/test/utils/runtime/cla/fwd.hpp | 64 ++ .../test/utils/runtime/cla/id_policy.cpp | 25 + .../test/utils/runtime/cla/id_policy.hpp | 146 ++++ .../test/utils/runtime/cla/id_policy.ipp | 121 +++ .../runtime/cla/iface/argument_factory.hpp | 58 ++ .../utils/runtime/cla/iface/id_policy.hpp | 72 ++ .../boost/test/utils/runtime/cla/modifier.hpp | 78 ++ .../utils/runtime/cla/named_parameter.cpp | 25 + .../utils/runtime/cla/named_parameter.hpp | 102 +++ .../utils/runtime/cla/named_parameter.ipp | 125 ++++ .../test/utils/runtime/cla/parameter.hpp | 159 ++++ .../boost/test/utils/runtime/cla/parser.cpp | 27 + .../boost/test/utils/runtime/cla/parser.hpp | 162 +++++ .../boost/test/utils/runtime/cla/parser.ipp | 270 +++++++ .../runtime/cla/positional_parameter.hpp | 100 +++ .../utils/runtime/cla/typed_parameter.hpp | 77 ++ .../test/utils/runtime/cla/validation.cpp | 25 + .../test/utils/runtime/cla/validation.hpp | 64 ++ .../test/utils/runtime/cla/validation.ipp | 73 ++ .../utils/runtime/cla/value_generator.hpp | 90 +++ .../test/utils/runtime/cla/value_handler.hpp | 66 ++ include/boost/test/utils/runtime/config.hpp | 110 +++ .../test/utils/runtime/configuration.hpp | 70 ++ .../test/utils/runtime/env/environment.cpp | 32 + .../test/utils/runtime/env/environment.hpp | 175 +++++ .../test/utils/runtime/env/environment.ipp | 136 ++++ include/boost/test/utils/runtime/env/fwd.hpp | 57 ++ .../boost/test/utils/runtime/env/modifier.hpp | 56 ++ .../boost/test/utils/runtime/env/variable.hpp | 222 ++++++ .../test/utils/runtime/file/config_file.cpp | 256 +++++++ .../test/utils/runtime/file/config_file.hpp | 191 +++++ .../runtime/file/config_file_iterator.cpp | 687 ++++++++++++++++++ .../runtime/file/config_file_iterator.hpp | 175 +++++ include/boost/test/utils/runtime/fwd.hpp | 50 ++ .../runtime/interpret_argument_value.hpp | 172 +++++ .../boost/test/utils/runtime/parameter.hpp | 47 ++ include/boost/test/utils/runtime/trace.hpp | 39 + .../boost/test/utils/runtime/validation.hpp | 91 +++ 51 files changed, 5778 insertions(+) create mode 100755 include/boost/test/utils/runtime/argument.hpp create mode 100755 include/boost/test/utils/runtime/cla/argument_factory.hpp create mode 100755 include/boost/test/utils/runtime/cla/argv_traverser.cpp create mode 100755 include/boost/test/utils/runtime/cla/argv_traverser.hpp create mode 100755 include/boost/test/utils/runtime/cla/argv_traverser.ipp create mode 100755 include/boost/test/utils/runtime/cla/basic_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/char_parameter.cpp create mode 100755 include/boost/test/utils/runtime/cla/char_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/char_parameter.ipp create mode 100755 include/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp create mode 100755 include/boost/test/utils/runtime/cla/dual_name_parameter.cpp create mode 100755 include/boost/test/utils/runtime/cla/dual_name_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/dual_name_parameter.ipp create mode 100755 include/boost/test/utils/runtime/cla/fwd.hpp create mode 100755 include/boost/test/utils/runtime/cla/id_policy.cpp create mode 100755 include/boost/test/utils/runtime/cla/id_policy.hpp create mode 100755 include/boost/test/utils/runtime/cla/id_policy.ipp create mode 100755 include/boost/test/utils/runtime/cla/iface/argument_factory.hpp create mode 100755 include/boost/test/utils/runtime/cla/iface/id_policy.hpp create mode 100755 include/boost/test/utils/runtime/cla/modifier.hpp create mode 100755 include/boost/test/utils/runtime/cla/named_parameter.cpp create mode 100755 include/boost/test/utils/runtime/cla/named_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/named_parameter.ipp create mode 100755 include/boost/test/utils/runtime/cla/parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/parser.cpp create mode 100755 include/boost/test/utils/runtime/cla/parser.hpp create mode 100755 include/boost/test/utils/runtime/cla/parser.ipp create mode 100755 include/boost/test/utils/runtime/cla/positional_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/typed_parameter.hpp create mode 100755 include/boost/test/utils/runtime/cla/validation.cpp create mode 100755 include/boost/test/utils/runtime/cla/validation.hpp create mode 100755 include/boost/test/utils/runtime/cla/validation.ipp create mode 100755 include/boost/test/utils/runtime/cla/value_generator.hpp create mode 100755 include/boost/test/utils/runtime/cla/value_handler.hpp create mode 100755 include/boost/test/utils/runtime/config.hpp create mode 100755 include/boost/test/utils/runtime/configuration.hpp create mode 100755 include/boost/test/utils/runtime/env/environment.cpp create mode 100755 include/boost/test/utils/runtime/env/environment.hpp create mode 100755 include/boost/test/utils/runtime/env/environment.ipp create mode 100755 include/boost/test/utils/runtime/env/fwd.hpp create mode 100755 include/boost/test/utils/runtime/env/modifier.hpp create mode 100755 include/boost/test/utils/runtime/env/variable.hpp create mode 100755 include/boost/test/utils/runtime/file/config_file.cpp create mode 100755 include/boost/test/utils/runtime/file/config_file.hpp create mode 100755 include/boost/test/utils/runtime/file/config_file_iterator.cpp create mode 100755 include/boost/test/utils/runtime/file/config_file_iterator.hpp create mode 100755 include/boost/test/utils/runtime/fwd.hpp create mode 100755 include/boost/test/utils/runtime/interpret_argument_value.hpp create mode 100755 include/boost/test/utils/runtime/parameter.hpp create mode 100755 include/boost/test/utils/runtime/trace.hpp create mode 100755 include/boost/test/utils/runtime/validation.hpp diff --git a/include/boost/test/utils/runtime/argument.hpp b/include/boost/test/utils/runtime/argument.hpp new file mode 100755 index 00000000..ab2321d3 --- /dev/null +++ b/include/boost/test/utils/runtime/argument.hpp @@ -0,0 +1,108 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : model of actual argument (both typed and abstract interface) +// *************************************************************************** + +#ifndef BOOST_RT_ARGUMENT_HPP_062604GER +#define BOOST_RT_ARGUMENT_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include +#include + +// Boost.Test +#include +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::argument ************** // +// ************************************************************************** // + +class argument { +public: + // Constructor + argument( parameter const& p, rtti::id_t value_type ) + : p_formal_parameter( p ) + , p_value_type( value_type ) + {} + + // Destructor + virtual ~argument() {} + + // Public properties + unit_test::readonly_property p_formal_parameter; + unit_test::readonly_property p_value_type; +}; + +// ************************************************************************** // +// ************** runtime::typed_argument ************** // +// ************************************************************************** // + +template +class typed_argument : public argument { +public: + // Constructor + explicit typed_argument( parameter const& p ) + : argument( p, rtti::type_id() ) + {} + typed_argument( parameter const& p, T const& t ) + : argument( p, rtti::type_id() ) + , p_value( t ) + {} + + unit_test::readwrite_property p_value; +}; + +// ************************************************************************** // +// ************** runtime::arg_value ************** // +// ************************************************************************** // + +template +inline T const& +arg_value( argument const& arg ) +{ + return polymorphic_downcast const&>( arg ).p_value.value; +} + +//____________________________________________________________________________// + +template +inline T& +arg_value( argument& arg ) +{ + return polymorphic_downcast&>( arg ).p_value.value; +} + +//____________________________________________________________________________// + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ARGUMENT_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/argument_factory.hpp b/include/boost/test/utils/runtime/cla/argument_factory.hpp new file mode 100755 index 00000000..11d147a5 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/argument_factory.hpp @@ -0,0 +1,227 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : generic typed_argument_factory implementation +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER +#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +// Boost.Test +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** default_value_interpreter ************** // +// ************************************************************************** // + +namespace rt_cla_detail { + +struct default_value_interpreter { + template + void operator()( argv_traverser& tr, boost::optional& value ) + { + if( interpret_argument_value( tr.token(), value, 0 ) ) + tr.next_token(); + } +}; + +} // namespace rt_cla_detail + +// ************************************************************************** // +// ************** typed_argument_factory ************** // +// ************************************************************************** // + +template +struct typed_argument_factory : public argument_factory { + // Constructor + typed_argument_factory() + : m_value_interpreter( rt_cla_detail::default_value_interpreter() ) + {} + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {} + + // properties modification + template + void accept_modifier( Modifier const& m ) + { + optionally_assign( m_value_handler, m, handler ); + optionally_assign( m_value_interpreter, m, interpreter ); + + if( m.has( default_value ) ) { + BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator, + BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) ); + + T const& dv_ref = m[default_value]; + m_value_generator = rt_cla_detail::const_generator( dv_ref ); + } + + if( m.has( default_refer_to ) ) { + BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator, + BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) ); + + cstring ref_id = m[default_refer_to]; + m_value_generator = rt_cla_detail::ref_generator( ref_id ); + } + + if( m.has( assign_to ) ) { + BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_handler, + BOOST_RT_PARAM_LITERAL( "multiple value handlers for parameter" ) ); + + m_value_handler = rt_cla_detail::assigner( m[assign_to] ); + } + } + + // Argument factory implementation + virtual argument_ptr produce_using( parameter& p, argv_traverser& tr ); + virtual argument_ptr produce_using( parameter& p, parser const& ); + virtual void argument_usage_info( format_stream& fs ); + +// !! private? + // Data members + unit_test::callback2 m_value_handler; + unit_test::callback2&> m_value_generator; + unit_test::callback2&> m_value_interpreter; +}; + +//____________________________________________________________________________// + +template +inline argument_ptr +typed_argument_factory::produce_using( parameter& p, argv_traverser& tr ) +{ + boost::optional value; + + try { + m_value_interpreter( tr, value ); + } + catch( ... ) { // !! should we do that? + BOOST_RT_PARAM_TRACE( "Fail to parse argument value" ); + + if( !p.p_optional_value ) + throw; + } + + argument_ptr arg = p.actual_argument(); + + BOOST_RT_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr, + BOOST_RT_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() ); + + BOOST_RT_CLA_VALIDATE_INPUT( !arg || p.p_multiplicable, tr, + BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() ); + + if( !!value && !!m_value_handler ) + m_value_handler( p, *value ); + + if( !p.p_multiplicable ) + arg.reset( p.p_optional_value + ? (argument*)new typed_argument >( p, value ) + : (argument*)new typed_argument( p, *value ) ); + else { + typedef std::list > optional_list; + + if( !arg ) + arg.reset( p.p_optional_value + ? (argument*)new typed_argument( p ) + : (argument*)new typed_argument >( p ) ); + + if( p.p_optional_value ) { + optional_list& values = arg_value( *arg ); + + values.push_back( value ); + } + else { + std::list& values = arg_value >( *arg ); + + values.push_back( *value ); + } + } + + return arg; +} + +//____________________________________________________________________________// + +template +inline argument_ptr +typed_argument_factory::produce_using( parameter& p, parser const& pa ) +{ + argument_ptr arg; + + if( !m_value_generator ) + return arg; + + boost::optional value; + m_value_generator( pa, value ); + + if( !value ) + return arg; + + if( !!m_value_handler ) + m_value_handler( p, *value ); + + arg.reset( new typed_argument( p, *value ) ); + + return arg; +} + +//____________________________________________________________________________// + +template +inline void +typed_argument_factory::argument_usage_info( format_stream& fs ) +{ + rt_cla_detail::argument_value_usage( fs, 0, (T*)0 ); +} + +//____________________________________________________________________________// + +} // namespace boost + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace cla + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/argv_traverser.cpp b/include/boost/test/utils/runtime/cla/argv_traverser.cpp new file mode 100755 index 00000000..17d9954b --- /dev/null +++ b/include/boost/test/utils/runtime/cla/argv_traverser.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : offline implementation for argc/argv traverser +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/argv_traverser.hpp b/include/boost/test/utils/runtime/cla/argv_traverser.hpp new file mode 100755 index 00000000..dad33150 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/argv_traverser.hpp @@ -0,0 +1,107 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines facility to hide input traversing details +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER +#define BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost.Test +#include + +// Boost +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::argv_traverser ************** // +// ************************************************************************** // + +class argv_traverser : noncopyable { + class parser; +public: + // Constructor + argv_traverser(); + + // public_properties + unit_test::readwrite_property p_ignore_mismatch; + unit_test::readwrite_property p_separator; + + // argc+argv <-> internal buffer exchange + void init( int argc, char_type** argv ); + void remainder( int& argc, char_type** argv ); + + // token based parsing + cstring token() const; + void next_token(); + + // whole input parsing + cstring input() const; + void trim( std::size_t size ); + bool match_front( cstring ); + bool match_front( char_type c ); + bool eoi() const; + + // transaction logic support + void commit(); + void rollback(); + + // current position access; used to save some reference points in input + std::size_t input_pos() const; + + // returns true if mismatch detected during input parsing handled successfully + bool handle_mismatch(); + +private: + // Data members + dstring m_buffer; + cstring m_work_buffer; + + cstring m_token; + cstring::iterator m_commited_end; + + shared_array m_remainder; + std::size_t m_remainder_size; +}; + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/argv_traverser.ipp b/include/boost/test/utils/runtime/cla/argv_traverser.ipp new file mode 100755 index 00000000..b06d4321 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/argv_traverser.ipp @@ -0,0 +1,213 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : implements facility to hide input traversing details +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER +#define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER + +// Boost.Runtime.Parameter +#include + +#include + +// STL +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::argv_traverser ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE +argv_traverser::argv_traverser() +: p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) ) +{ +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::init( int argc, char_type** argv ) +{ + for( int index = 1; index < argc; ++index ) { + m_buffer += argv[index]; + if( index != argc-1 ) + m_buffer += BOOST_RT_PARAM_LITERAL( ' ' ); + } + + m_remainder.reset( new char_type[m_buffer.size()+1] ); + m_remainder_size = 0; + m_work_buffer = m_buffer; + m_commited_end = m_work_buffer.begin(); + + BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer ); + + next_token(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::remainder( int& argc, char_type** argv ) +{ + argc = 1; + std::size_t pos = 0; + while(pos < m_remainder_size ) { + argv[argc++] = m_remainder.get() + pos; + + pos = std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size, + BOOST_RT_PARAM_LITERAL( ' ' ) ) - m_remainder.get(); + m_remainder[pos++] = BOOST_RT_PARAM_LITERAL( '\0' ); + } +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE cstring +argv_traverser::token() const +{ + return m_token; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::next_token() +{ + if( m_work_buffer.is_empty() ) + return; + + m_work_buffer.trim_left( m_token.size() ); // skip remainder of current token + + if( m_work_buffer.size() != m_buffer.size() ) // !! is there a better way to identify first token + m_work_buffer.trim_left( 1 ); // skip separator if not first token; + + m_token.assign( m_work_buffer.begin(), + std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE cstring +argv_traverser::input() const +{ + return m_work_buffer; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::trim( std::size_t size ) +{ + m_work_buffer.trim_left( size ); + + if( size <= m_token.size() ) + m_token.trim_left( size ); + else { + m_token.assign( m_work_buffer.begin(), + std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); + } +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +argv_traverser::match_front( cstring str ) +{ + return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +argv_traverser::match_front( char_type c ) +{ + return first_char( m_work_buffer ) == c; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +argv_traverser::eoi() const +{ + return m_work_buffer.is_empty(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::commit() +{ + m_commited_end = m_work_buffer.begin(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +argv_traverser::rollback() +{ + m_work_buffer.assign( m_commited_end, m_work_buffer.end() ); + m_token.assign( m_work_buffer.begin(), + std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); + +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE std::size_t +argv_traverser::input_pos() const +{ + return m_work_buffer.begin() - m_commited_end; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +argv_traverser::handle_mismatch() +{ + if( !p_ignore_mismatch ) + return false; + + std::memcpy( m_remainder.get() + m_remainder_size, token().begin(), token().size() ); + m_remainder_size += token().size(); + m_remainder[m_remainder_size++] = p_separator; + + next_token(); + commit(); + + return true; +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER diff --git a/include/boost/test/utils/runtime/cla/basic_parameter.hpp b/include/boost/test/utils/runtime/cla/basic_parameter.hpp new file mode 100755 index 00000000..315cebe5 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/basic_parameter.hpp @@ -0,0 +1,93 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : generic custom parameter generator +// *************************************************************************** + +#ifndef BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::basic_parameter ************** // +// ************************************************************************** // + +template +class basic_parameter : public typed_parameter { +public: + // Constructors + explicit basic_parameter( cstring n ) + : typed_parameter( m_id_policy ) + { + this->accept_modifier( name = n ); + } + + // parameter properties modification + template + void accept_modifier( Modifier const& m ) + { + typed_parameter::accept_modifier( m ); + + m_id_policy.accept_modifier( m ); + } + +private: + IdPolicy m_id_policy; +}; + +//____________________________________________________________________________// + +#define BOOST_RT_CLA_NAMED_PARAM_GENERATORS( param_type ) \ +template \ +inline shared_ptr > \ +param_type( cstring name = cstring() ) \ +{ \ + return shared_ptr >( new param_type ## _t( name ) ); \ +} \ + \ +inline shared_ptr > \ +param_type( cstring name = cstring() ) \ +{ \ + return shared_ptr >( new param_type ## _t( name ) ); \ +} \ +/**/ + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/char_parameter.cpp b/include/boost/test/utils/runtime/cla/char_parameter.cpp new file mode 100755 index 00000000..939c90a0 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/char_parameter.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : offline implementation of char parameter +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/char_parameter.hpp b/include/boost/test/utils/runtime/cla/char_parameter.hpp new file mode 100755 index 00000000..b8f035e9 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/char_parameter.hpp @@ -0,0 +1,107 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines model of parameter with single char name +// *************************************************************************** + +#ifndef BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include + +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** char_name_policy ************** // +// ************************************************************************** // + +class char_name_policy : public basic_naming_policy { +public: + // Constructor + char_name_policy(); + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~char_name_policy() {} + + // policy interface + virtual bool conflict_with( identification_policy const& ) const; + + // Accept modifier + template + void accept_modifier( Modifier const& m ) + { + basic_naming_policy::accept_modifier( m ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( m_name.size() <= 1, "Invalid parameter name " << m_name ); + } +}; + +// ************************************************************************** // +// ************** runtime::cla::char_parameter ************** // +// ************************************************************************** // + +template +class char_parameter_t : public basic_parameter { + typedef basic_parameter base; +public: + // Constructors + explicit char_parameter_t( char_type name ) : base( cstring( &name, 1 ) ) {} +}; + +//____________________________________________________________________________// + +template +inline shared_ptr > +char_parameter( char_type name ) +{ + return shared_ptr >( new char_parameter_t( name ) ); +} + +//____________________________________________________________________________// + +inline shared_ptr > +char_parameter( char_type name ) +{ + return shared_ptr >( new char_parameter_t( name ) ); +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/char_parameter.ipp b/include/boost/test/utils/runtime/cla/char_parameter.ipp new file mode 100755 index 00000000..e4f16a25 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/char_parameter.ipp @@ -0,0 +1,66 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : implements model of parameter with single char name +// *************************************************************************** + +#ifndef BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER +#define BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER + +// Boost.Runtime.Parameter +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** char_name_policy ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE +char_name_policy::char_name_policy() +: basic_naming_policy( rtti::type_id() ) +{ + assign_op( m_prefix, BOOST_RT_PARAM_CSTRING_LITERAL( "-" ), 0 ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +char_name_policy::conflict_with( identification_policy const& id ) const +{ + return id.p_type_id == p_type_id && + m_name == polymorphic_downcast( id ).m_name; +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER diff --git a/include/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp b/include/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp new file mode 100755 index 00000000..825dde7e --- /dev/null +++ b/include/boost/test/utils/runtime/cla/detail/argument_value_usage.hpp @@ -0,0 +1,91 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. +// +// File : $RCSfile$ +// +// Version : $Revision$ +// +// Description : argument usage printing helpers +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER +#define BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include + +// Boost.Test +#include +#include + +#include + +// STL +// !! could we eliminate these includes? +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +namespace rt_cla_detail { + +// ************************************************************************** // +// ************** argument_value_usage ************** // +// ************************************************************************** // + +// generic case +template +inline void +argument_value_usage( format_stream& fs, long, T* = 0 ) +{ + fs << BOOST_RT_PARAM_CSTRING_LITERAL( "" ); +} + +//____________________________________________________________________________// + +// specialization for list of values +template +inline void +argument_value_usage( format_stream& fs, int, std::list* = 0 ) +{ + fs << BOOST_RT_PARAM_CSTRING_LITERAL( "(, ..., )" ); +} + +//____________________________________________________________________________// + +// specialization for type bool +inline void +argument_value_usage( format_stream& fs, int, bool* = 0 ) +{ + fs << BOOST_RT_PARAM_CSTRING_LITERAL( "[yes|y|no|n]" ); +} + +//____________________________________________________________________________// + +} // namespace rt_cla_detail + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/dual_name_parameter.cpp b/include/boost/test/utils/runtime/cla/dual_name_parameter.cpp new file mode 100755 index 00000000..7d5c869e --- /dev/null +++ b/include/boost/test/utils/runtime/cla/dual_name_parameter.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : offline implementation of generic parameter with dual naming +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/dual_name_parameter.hpp b/include/boost/test/utils/runtime/cla/dual_name_parameter.hpp new file mode 100755 index 00000000..d522d4e7 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/dual_name_parameter.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines model of generic parameter with dual naming +// *************************************************************************** + +#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** dual_name_policy ************** // +// ************************************************************************** // + +class dual_name_policy : public dual_id_policy { +public: + dual_name_policy(); + + // Accept modifer + template + void accept_modifier( Modifier const& m ) + { + if( m.has( prefix ) ) + set_prefix( m[prefix] ); + + if( m.has( name ) ) + set_name( m[name] ); + + if( m.has( separator ) ) + set_separator( m[separator] ); + } +private: + void set_prefix( cstring ); + void set_name( cstring ); + void set_separator( cstring ); +}; + +// ************************************************************************** // +// ************** runtime::cla::dual_name_parameter ************** // +// ************************************************************************** // + +template +class dual_name_parameter_t : public basic_parameter { + typedef basic_parameter base; +public: + // Constructors + explicit dual_name_parameter_t( cstring name ) : base( name ) {} +}; + +//____________________________________________________________________________// + +BOOST_RT_CLA_NAMED_PARAM_GENERATORS( dual_name_parameter ) + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/dual_name_parameter.ipp b/include/boost/test/utils/runtime/cla/dual_name_parameter.ipp new file mode 100755 index 00000000..2e20515d --- /dev/null +++ b/include/boost/test/utils/runtime/cla/dual_name_parameter.ipp @@ -0,0 +1,99 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : implements model of generic parameter with dual naming +// *************************************************************************** + +#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER +#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER + +// Boost.Runtime.Parameter +#include +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** dual_name_policy ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE +dual_name_policy::dual_name_policy() +{ + m_primary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "--" ) ); + m_secondary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "-" ) ); +} + +//____________________________________________________________________________// + +namespace { + +template +inline void +split( string_name_policy& snp, char_name_policy& cnp, cstring src, K const& k ) +{ + cstring::iterator sep = std::find( src.begin(), src.end(), BOOST_RT_PARAM_LITERAL( '|' ) ); + + if( sep != src.begin() ) + snp.accept_modifier( k = cstring( src.begin(), sep ) ); + + if( sep != src.end() ) + cnp.accept_modifier( k = cstring( sep+1, src.end() ) ); +} + +} // local namespace + +BOOST_RT_PARAM_INLINE void +dual_name_policy::set_prefix( cstring src ) +{ + split( m_primary, m_secondary, src, prefix ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +dual_name_policy::set_name( cstring src ) +{ + split( m_primary, m_secondary, src, name ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +dual_name_policy::set_separator( cstring src ) +{ + split( m_primary, m_secondary, src, separator ); +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER diff --git a/include/boost/test/utils/runtime/cla/fwd.hpp b/include/boost/test/utils/runtime/cla/fwd.hpp new file mode 100755 index 00000000..83e2d8e7 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/fwd.hpp @@ -0,0 +1,64 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : cla subsystem forward declarations +// *************************************************************************** + +#ifndef BOOST_RT_CLA_FWD_HPP_062604GER +#define BOOST_RT_CLA_FWD_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +class parser; +class parameter; +typedef shared_ptr parameter_ptr; +class naming_policy; +typedef shared_ptr naming_policy_ptr; +class argv_traverser; + +namespace rt_cla_detail { + +template class const_generator; +template class ref_generator; + +template class assigner; + +class named_parameter_base; +class positional_parameter_base; + +} // namespace rt_cla_detail + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_FWD_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/id_policy.cpp b/include/boost/test/utils/runtime/cla/id_policy.cpp new file mode 100755 index 00000000..d5779bb5 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/id_policy.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : some generic identification policies offline implementation +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/id_policy.hpp b/include/boost/test/utils/runtime/cla/id_policy.hpp new file mode 100755 index 00000000..8aae5532 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/id_policy.hpp @@ -0,0 +1,146 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : some generic identification policies definition +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ID_POLICY_HPP_062604GER +#define BOOST_RT_CLA_ID_POLICY_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include +#include + +#include + +// Boost.Test +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** naming_policy_base ************** // +// ************************************************************************** // +// model: + +class basic_naming_policy : public identification_policy { +public: + // Policy interface + virtual bool responds_to( cstring name ) const { return m_name == name; } + virtual cstring id_2_report() const { return m_name; } + virtual void usage_info( format_stream& fs ) const; + virtual bool matching( parameter const& p, argv_traverser& tr, bool primary ) const; + + // Accept modifer + template + void accept_modifier( Modifier const& m ) + { + nfp::optionally_assign( m_prefix, m, prefix ); + nfp::optionally_assign( m_name, m, name ); + nfp::optionally_assign( m_separator, m, separator ); + } + +protected: + explicit basic_naming_policy( rtti::id_t const& dyn_type ) + : identification_policy( dyn_type ) + {} + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~basic_naming_policy() {} + + // Naming policy interface + virtual bool match_prefix( argv_traverser& tr ) const; + virtual bool match_name( argv_traverser& tr ) const; + virtual bool match_separator( argv_traverser& tr ) const; + + // Data members + dstring m_prefix; + dstring m_name; + dstring m_separator; +}; + +// ************************************************************************** // +// ************** dual_id_policy ************** // +// ************************************************************************** // + +template +class dual_id_policy : public identification_policy { +public: + // Constructor + dual_id_policy() + : identification_policy( rtti::type_id() ) + , m_primary() + , m_secondary() + {} + + // Policy interface + virtual bool responds_to( cstring name ) const + { + return m_primary.responds_to( name ) || m_secondary.responds_to( name ); + } + virtual bool conflict_with( identification_policy const& id_p ) const + { + return m_primary.conflict_with( id_p ) || m_secondary.conflict_with( id_p ); + } + virtual cstring id_2_report() const + { + return m_primary.id_2_report(); + } + virtual void usage_info( format_stream& fs ) const + { + fs << BOOST_RT_PARAM_LITERAL( '{' ); + m_primary.usage_info( fs ); + fs << BOOST_RT_PARAM_LITERAL( '|' ); + m_secondary.usage_info( fs ); + fs << BOOST_RT_PARAM_LITERAL( '}' ); + } + virtual bool matching( parameter const& p, argv_traverser& tr, bool primary ) const + { + return m_primary.matching( p, tr, primary ) || m_secondary.matching( p, tr, primary ); + } + +protected: + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~dual_id_policy() {} + + // Data members + PrimaryId m_primary; + SecondId m_secondary; +}; + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ID_POLICY_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/id_policy.ipp b/include/boost/test/utils/runtime/cla/id_policy.ipp new file mode 100755 index 00000000..476135dc --- /dev/null +++ b/include/boost/test/utils/runtime/cla/id_policy.ipp @@ -0,0 +1,121 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : some generic identification policies implementation +// *************************************************************************** + +#ifndef BOOST_RT_CLA_ID_POLICY_IPP_062904GER +#define BOOST_RT_CLA_ID_POLICY_IPP_062904GER + +// Boost.Runtime.Parameter +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** basic_naming_policy ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE void +basic_naming_policy::usage_info( format_stream& fs ) const +{ + fs << m_prefix << m_name << m_separator; + + if( m_separator.empty() ) + fs << BOOST_RT_PARAM_LITERAL( ' ' ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +basic_naming_policy::match_prefix( argv_traverser& tr ) const +{ + if( !tr.match_front( m_prefix ) ) + return false; + + tr.trim( m_prefix.size() ); + return true; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +basic_naming_policy::match_name( argv_traverser& tr ) const +{ + if( !tr.match_front( m_name ) ) + return false; + + tr.trim( m_name.size() ); + return true; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +basic_naming_policy::match_separator( argv_traverser& tr ) const +{ + if( m_separator.empty() ) { + if( !tr.token().is_empty() ) + return false; + + tr.trim( 1 ); + } + else { + if( !tr.match_front( m_separator ) ) + return false; + + tr.trim( m_separator.size() ); + } + + return true; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +basic_naming_policy::matching( parameter const&, argv_traverser& tr, bool ) const +{ + if( !match_prefix( tr ) ) + return false; + + if( !match_name( tr ) ) + return false; + + if( !match_separator( tr ) ) + return false; + + return true; +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_ID_POLICY_IPP_062904GER diff --git a/include/boost/test/utils/runtime/cla/iface/argument_factory.hpp b/include/boost/test/utils/runtime/cla/iface/argument_factory.hpp new file mode 100755 index 00000000..0f9ff27c --- /dev/null +++ b/include/boost/test/utils/runtime/cla/iface/argument_factory.hpp @@ -0,0 +1,58 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines interface for argument_factory +// *************************************************************************** + +#ifndef BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER +#define BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** argument_factory ************** // +// ************************************************************************** // +// another name could be argument production policy + +class argument_factory { +public: + // Argument factory interface + virtual argument_ptr produce_using( parameter& p, argv_traverser& tr ) = 0; /// produce argument based on input + virtual argument_ptr produce_using( parameter& p, parser const& ) = 0; /// produce argument based on internal generator and/or values of other parameters + virtual void argument_usage_info( format_stream& fs ) = 0; /// argument value format information +}; + +} // namespace boost + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace cla + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_IFACE_ARGUMENT_FACTORY_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/iface/id_policy.hpp b/include/boost/test/utils/runtime/cla/iface/id_policy.hpp new file mode 100755 index 00000000..1f1d2e3a --- /dev/null +++ b/include/boost/test/utils/runtime/cla/iface/id_policy.hpp @@ -0,0 +1,72 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines interface for identification_policy +// *************************************************************************** + +#ifndef BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER +#define BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +// Boost.Test +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** identification_policy ************** // +// ************************************************************************** // + +class identification_policy { +public: + // Public properties + unit_test::readwrite_property p_type_id; + + // Policy interface + virtual bool responds_to( cstring name ) const = 0; + virtual cstring id_2_report() const = 0; + virtual void usage_info( format_stream& fs ) const = 0; + virtual bool matching( parameter const& p, argv_traverser& tr, bool primary ) const = 0; + + virtual bool conflict_with( identification_policy const& ) const = 0; + +protected: + // Constructor + explicit identification_policy( rtti::id_t const& dyn_type ) + : p_type_id( dyn_type ) + {} +}; + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_IFACE_ID_POLICY_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/modifier.hpp b/include/boost/test/utils/runtime/cla/modifier.hpp new file mode 100755 index 00000000..cb42fb46 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/modifier.hpp @@ -0,0 +1,78 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : parameter modifiers +// *************************************************************************** + +#ifndef BOOST_RT_CLA_MODIFIER_HPP_062604GER +#define BOOST_RT_CLA_MODIFIER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** environment variable modifiers ************** // +// ************************************************************************** // + +namespace { + +nfp::typed_keyword optional_m; +nfp::named_parameter optional( true ); +nfp::typed_keyword required_m; +nfp::named_parameter required( true ); +nfp::typed_keyword multiplicable_m; +nfp::named_parameter multiplicable( true ); +nfp::typed_keyword guess_name_m; +nfp::named_parameter guess_name( true ); +nfp::typed_keyword ignore_mismatch_m; +nfp::named_parameter ignore_mismatch( true ); +nfp::typed_keyword optional_value_m; +nfp::named_parameter optional_value( true ); + +nfp::typed_keyword input_separator; +nfp::typed_keyword prefix; +nfp::typed_keyword name; +nfp::typed_keyword separator; +nfp::typed_keyword description; +nfp::typed_keyword default_refer_to; + +nfp::keyword default_value; +nfp::keyword handler; +nfp::keyword interpreter; +nfp::keyword assign_to; + +} // local namespace + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_MODIFIER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/named_parameter.cpp b/include/boost/test/utils/runtime/cla/named_parameter.cpp new file mode 100755 index 00000000..09853ced --- /dev/null +++ b/include/boost/test/utils/runtime/cla/named_parameter.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : offline implementation of named parameter +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/named_parameter.hpp b/include/boost/test/utils/runtime/cla/named_parameter.hpp new file mode 100755 index 00000000..9ed38d17 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/named_parameter.hpp @@ -0,0 +1,102 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines model of named parameter +// *************************************************************************** + +#ifndef BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** string_name_policy ************** // +// ************************************************************************** // + +class string_name_policy : public basic_naming_policy { +public: + // Constructor + string_name_policy(); + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~string_name_policy() {} + + // policy interface + virtual bool responds_to( cstring name ) const; + virtual bool conflict_with( identification_policy const& ) const; + + // Accept modifier + template + void accept_modifier( Modifier const& m ) + { + basic_naming_policy::accept_modifier( m ); + + if( m.has( guess_name_m ) ) + m_guess_name = true; + } + +private: + // Naming policy interface + virtual bool match_name( argv_traverser& tr ) const; + + // Data members + bool m_guess_name; +}; + +// ************************************************************************** // +// ************** runtime::cla::named_parameter ************** // +// ************************************************************************** // + +template +class named_parameter_t : public basic_parameter { + typedef basic_parameter base; +public: + // Constructors + explicit named_parameter_t( cstring name ) : base( name ) {} +}; + +//____________________________________________________________________________// + +BOOST_RT_CLA_NAMED_PARAM_GENERATORS( named_parameter ) + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_NAMED_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/named_parameter.ipp b/include/boost/test/utils/runtime/cla/named_parameter.ipp new file mode 100755 index 00000000..c7004ac2 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/named_parameter.ipp @@ -0,0 +1,125 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : implements model of named parameter +// *************************************************************************** + +#ifndef BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER +#define BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** string_name_policy ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE +string_name_policy::string_name_policy() +: basic_naming_policy( rtti::type_id() ) +, m_guess_name( false ) +{ + assign_op( m_prefix, BOOST_RT_PARAM_CSTRING_LITERAL( "-" ), 0 ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +string_name_policy::responds_to( cstring name ) const +{ + std::pair mm_pos; + + mm_pos = unit_test::mismatch( name.begin(), name.end(), m_name.begin(), m_name.end() ); + + return mm_pos.first == name.end() && (m_guess_name || (mm_pos.second == m_name.end()) ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +string_name_policy::conflict_with( identification_policy const& id ) const +{ + if( id.p_type_id == p_type_id ) { + string_name_policy const& snp = polymorphic_downcast( id ); + + if( m_name.empty() || snp.m_name.empty() ) + return false; + + std::pair mm_pos = + unit_test::mismatch( m_name.begin(), m_name.end(), snp.m_name.begin(), snp.m_name.end() ); + + return mm_pos.first != m_name.begin() && // there is common substring + (m_guess_name || (mm_pos.first == m_name.end()) ) && // that match me + (snp.m_guess_name || (mm_pos.second == snp.m_name.end()) ); // and snp + } + + if( id.p_type_id == rtti::type_id() ) { + char_name_policy const& cnp = polymorphic_downcast( id ); + + return m_guess_name && unit_test::first_char( cstring( m_name ) ) == unit_test::first_char( cnp.id_2_report() ); + } + + return false; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE bool +string_name_policy::match_name( argv_traverser& tr ) const +{ + if( !m_guess_name ) + return basic_naming_policy::match_name( tr ); + else { + cstring in = tr.input(); + + std::pair mm_pos; + + mm_pos = unit_test::mismatch( in.begin(), in.end(), m_name.begin(), m_name.end() ); + + if( mm_pos.first == in.begin() ) + return false; + + tr.trim( mm_pos.first - in.begin() ); + } + + return true; +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_NAMED_PARAMETER_IPP_062904GER diff --git a/include/boost/test/utils/runtime/cla/parameter.hpp b/include/boost/test/utils/runtime/cla/parameter.hpp new file mode 100755 index 00000000..379769fb --- /dev/null +++ b/include/boost/test/utils/runtime/cla/parameter.hpp @@ -0,0 +1,159 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines model of formal parameter +// *************************************************************************** + +#ifndef BOOST_RT_CLA_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include +#include + +#include +#include +#include +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::parameter ************** // +// ************************************************************************** // + +class parameter : public BOOST_RT_PARAM_NAMESPACE::parameter { +public: + parameter( identification_policy& ID, argument_factory& F ) + : p_optional( false ) + , p_multiplicable( false ) + , p_optional_value( false ) + , m_id_policy( ID ) + , m_arg_factory( F ) + {} + + // Destructor + virtual ~parameter() {} + + unit_test::readwrite_property p_optional; + unit_test::readwrite_property p_multiplicable; + unit_test::readwrite_property p_optional_value; + unit_test::readwrite_property p_description; + + // parameter properties modification + template + void accept_modifier( Modifier const& m ) + { + if( m.has( optional_m ) ) + p_optional.value = true; + + if( m.has( required_m ) ) + p_optional.value = false; + + if( m.has( multiplicable_m ) ) + p_multiplicable.value = true; + + if( m.has( optional_value_m ) ) + p_optional_value.value = true; + + nfp::optionally_assign( p_description.value, m, description ); + } + + // access methods + bool has_argument() const { return m_actual_argument; } + argument const& actual_argument() const { return *m_actual_argument; } + argument_ptr actual_argument() { return m_actual_argument; } + + + // identification interface + bool responds_to( cstring name ) const { return m_id_policy.responds_to( name ); } + bool conflict_with( parameter const& p ) const + { + return id_2_report() == p.id_2_report() && !id_2_report().is_empty() || + m_id_policy.conflict_with( p.m_id_policy ) || + p.m_id_policy.conflict_with( m_id_policy ); + } + cstring id_2_report() const { return m_id_policy.id_2_report(); } + void usage_info( format_stream& fs ) const + { + m_id_policy.usage_info( fs ); + if( p_optional_value ) + fs << BOOST_RT_PARAM_LITERAL( '[' ); + + m_arg_factory.argument_usage_info( fs ); + + if( p_optional_value ) + fs << BOOST_RT_PARAM_LITERAL( ']' ); + } + + // argument match/produce based on input + bool matching( argv_traverser& tr, bool primary ) const + { + return m_id_policy.matching( *this, tr, primary ); + } + + // argument production based on different source + void produce_argument( argv_traverser& tr ) + { + m_id_policy.matching( *this, tr, true ); // !! could we save this position somehow + m_actual_argument = m_arg_factory.produce_using( *this, tr ); + } + void produce_argument( parser const& p ) + { + m_actual_argument = m_arg_factory.produce_using( *this, p ); + } + +private: + //Data members + identification_policy& m_id_policy; + argument_factory& m_arg_factory; + argument_ptr m_actual_argument; +}; + +//____________________________________________________________________________// + +template +inline shared_ptr +operator-( shared_ptr p, Modifier const& m ) +{ + p->accept_modifier( m ); + + return p; +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/parser.cpp b/include/boost/test/utils/runtime/cla/parser.cpp new file mode 100755 index 00000000..c149224e --- /dev/null +++ b/include/boost/test/utils/runtime/cla/parser.cpp @@ -0,0 +1,27 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : offline implementation for parser +// *************************************************************************** + +#include + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/parser.hpp b/include/boost/test/utils/runtime/cla/parser.hpp new file mode 100755 index 00000000..e98f5188 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/parser.hpp @@ -0,0 +1,162 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines parser - public interface for CLA parsing and accessing +// *************************************************************************** + +#ifndef BOOST_RT_CLA_PARSER_HPP_062604GER +#define BOOST_RT_CLA_PARSER_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include +#include + +#include +#include +#include + +// Boost +#include + +// STL +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::parser ************** // +// ************************************************************************** // + +namespace cla_detail { + +template +class global_mod_parser { +public: + global_mod_parser( parser& p, Modifier const& m ) + : m_parser( p ) + , m_modifiers( m ) + {} + + template + global_mod_parser const& + operator<<( shared_ptr param ) const + { + param->accept_modifier( m_modifiers ); + + m_parser << param; + + return *this; + } + +private: + // Data members; + parser& m_parser; + Modifier const& m_modifiers; +}; + +} + +// ************************************************************************** // +// ************** runtime::cla::parser ************** // +// ************************************************************************** // + +class parser { +public: + typedef std::list::const_iterator param_iterator; + + // Constructor + explicit parser( cstring program_name = cstring() ); + + // parameter list construction interface + parser& operator<<( parameter_ptr param ); + + // parser and global parameters modifiers + template + cla_detail::global_mod_parser + operator-( Modifier const& m ) + { + nfp::optionally_assign( m_traverser.p_separator.value, m, input_separator ); + nfp::optionally_assign( m_traverser.p_ignore_mismatch.value, m, ignore_mismatch_m ); + + return cla_detail::global_mod_parser( *this, m ); + } + + // input processing method + void parse( int& argc, char_type** argv ); + + // parameters access + param_iterator first_param() const; + param_iterator last_param() const; + + // arguments access + const_argument_ptr operator[]( cstring string_id ) const; + cstring get( cstring string_id ) const; + + template + T const& get( cstring string_id ) const + { + return arg_value( valid_argument( string_id ) ); + } + + template + void get( cstring string_id, boost::optional& res ) const + { + const_argument_ptr arg = (*this)[string_id]; + + if( arg ) + res = arg_value( *arg ); + else + res.reset(); + } + + // help/usage + void usage( out_stream& ostr ); + void help( out_stream& ostr ); + +private: + argument const& valid_argument( cstring string_id ) const; + + // Data members + argv_traverser m_traverser; + std::list m_parameters; + dstring m_program_name; +}; + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_PARSER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/parser.ipp b/include/boost/test/utils/runtime/cla/parser.ipp new file mode 100755 index 00000000..23afbea0 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/parser.ipp @@ -0,0 +1,270 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : implements parser - public interface for CLA parsing and accessing +// *************************************************************************** + +#ifndef BOOST_RT_CLA_PARSER_IPP_062904GER +#define BOOST_RT_CLA_PARSER_IPP_062904GER + +// Boost.Runtime.Parameter +#include +#include +#include + +#include +#include +#include +#include +#include + +// Boost.Test +#include +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::parser ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE +parser::parser( cstring program_name ) +{ + assign_op( m_program_name, program_name, 0 ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE parser::param_iterator +parser::first_param() const +{ + return m_parameters.begin(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE parser::param_iterator +parser::last_param() const +{ + return m_parameters.end(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE argument const& +parser::valid_argument( cstring string_id ) const +{ + const_argument_ptr arg = (*this)[string_id]; + + BOOST_RT_PARAM_VALIDATE_LOGIC( !!arg, "Actual argument for parameter " << string_id << " is not present" ); + + return *arg; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE parser& +parser::operator<<( parameter_ptr new_param ) +{ + BOOST_TEST_FOREACH( parameter_ptr, old_param, m_parameters ) { + BOOST_RT_PARAM_VALIDATE_LOGIC( !old_param->conflict_with( *new_param ) && + !new_param->conflict_with( *old_param ), + BOOST_RT_PARAM_LITERAL( "Definition of parameter " ) << new_param->id_2_report() << + BOOST_RT_PARAM_LITERAL( " conflicts with defintion of parameter " ) << old_param->id_2_report() ); + } + + m_parameters.push_back( new_param ); + + return *this; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +parser::parse( int& argc, char_type** argv ) +{ + if( m_program_name.empty() ) { + m_program_name.assign( argv[0] ); + dstring::size_type pos = m_program_name.find_last_of( BOOST_RT_PARAM_LITERAL( "/\\" ) ); + + if( pos != cstring::npos ) + m_program_name.erase( 0, pos+1 ); + } + + m_traverser.init( argc, argv ); + + try { + while( !m_traverser.eoi() ) { + parameter_ptr found_param; + + BOOST_RT_PARAM_TRACE( "Total " << m_parameters.size() << " parameters registered" ); + + BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) { + BOOST_RT_PARAM_TRACE( "Try parameter " << curr_param->id_2_report() ); + + if( curr_param->matching( m_traverser, !found_param ) ) { + BOOST_RT_PARAM_TRACE( "Match found" ); + BOOST_RT_CLA_VALIDATE_INPUT( !found_param, (m_traverser.rollback(),m_traverser), "Ambiguous input" ); + + found_param = curr_param; + } + + m_traverser.rollback(); + } + + if( !found_param ) { + BOOST_RT_PARAM_TRACE( "No match found" ); + BOOST_RT_CLA_VALIDATE_INPUT( m_traverser.handle_mismatch(), m_traverser, + BOOST_RT_PARAM_LITERAL( "Unexpected input" ) ); + + continue; + } + + BOOST_RT_PARAM_TRACE( "Parse argument value" ); + found_param->produce_argument( m_traverser ); + + m_traverser.commit(); + } + + BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) { + if( !curr_param->p_optional && !curr_param->actual_argument() ) { + curr_param->produce_argument( *this ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( curr_param->actual_argument(), + BOOST_RT_PARAM_LITERAL( "Required argument for parameter " ) << curr_param->id_2_report() + << BOOST_RT_PARAM_LITERAL( " is missing" ) ); + } + } + } + catch( bad_lexical_cast const& ) { + BOOST_RT_PARAM_REPORT_LOGIC_ERROR( + BOOST_RT_PARAM_LITERAL( "String to value convertion error during input parsing" ) ); + } + + m_traverser.remainder( argc, argv ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE const_argument_ptr +parser::operator[]( cstring string_id ) const +{ + parameter_ptr found_param; + + BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) { + if( curr_param->responds_to( string_id ) ) { + BOOST_RT_PARAM_VALIDATE_LOGIC( !found_param, + BOOST_RT_PARAM_LITERAL( "Ambiguous parameter string id: " ) << string_id ); + + found_param = curr_param; + } + } + + BOOST_RT_PARAM_VALIDATE_LOGIC( found_param, BOOST_RT_PARAM_LITERAL( "Unknown parameter: " ) << string_id ); + + return found_param->actual_argument(); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE cstring +parser::get( cstring string_id ) const +{ + return get( string_id ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +parser::usage( out_stream& ostr ) +{ + if( m_program_name.empty() ) + assign_op( m_program_name, BOOST_RT_PARAM_CSTRING_LITERAL( "" ), 0 ); + + format_stream fs; + + fs << m_program_name; + + BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) { + fs << BOOST_RT_PARAM_LITERAL( ' ' ); + + if( curr_param->p_optional ) + fs << BOOST_RT_PARAM_LITERAL( '[' ); + + curr_param->usage_info( fs ); + + if( curr_param->p_optional ) + fs << BOOST_RT_PARAM_LITERAL( ']' ); + + if( curr_param->p_multiplicable ) { + fs << BOOST_RT_PARAM_CSTRING_LITERAL( " ... " ); + + if( curr_param->p_optional ) + fs << BOOST_RT_PARAM_LITERAL( '[' ); + + curr_param->usage_info( fs ); + + if( curr_param->p_optional ) + fs << BOOST_RT_PARAM_LITERAL( ']' ); + } + } + + ostr << BOOST_RT_PARAM_CSTRING_LITERAL( "Usage:\n" ) << fs.str() << std::endl; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +parser::help( out_stream& ostr ) +{ + usage( ostr ); + + bool need_where = true; + + BOOST_TEST_FOREACH( parameter_ptr const&, curr_param, m_parameters ) { + if( curr_param->p_description->empty() ) + continue; + + if( need_where ) { + ostr << BOOST_RT_PARAM_CSTRING_LITERAL( "where:\n" ); + need_where = false; + } + + ostr << curr_param->id_2_report() << BOOST_RT_PARAM_CSTRING_LITERAL( " - " ) << curr_param->p_description << std::endl; + } +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_PARSER_IPP_062904GER diff --git a/include/boost/test/utils/runtime/cla/positional_parameter.hpp b/include/boost/test/utils/runtime/cla/positional_parameter.hpp new file mode 100755 index 00000000..0eb76ba9 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/positional_parameter.hpp @@ -0,0 +1,100 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : positional parameter model +// *************************************************************************** + +#ifndef BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** single_name_policy ************** // +// ************************************************************************** // + +class trivial_id_policy : public identification_policy { +public: + trivial_id_policy() + : identification_policy( rtti::type_id() ) + {} + BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~trivial_id_policy() {} + + virtual bool responds_to( cstring name ) const { return m_name == name; } + virtual bool conflict_with( identification_policy const& id ) const { return false; } + virtual cstring id_2_report() const { return m_name; } + virtual void usage_info( format_stream& fs ) const + { + if( !m_name.empty() ) + fs << BOOST_RT_PARAM_LITERAL( '<' ) << m_name << BOOST_RT_PARAM_LITERAL( '>' ); + else + fs << BOOST_RT_PARAM_CSTRING_LITERAL( "" );; + } + + virtual bool matching( parameter const& p, argv_traverser& tr, bool primary ) const + { + return primary && ( !p.has_argument() || p.p_multiplicable ); + } + + template + void accept_modifier( Modifier const& m ) + { + nfp::optionally_assign( m_name, m, name ); + } + +private: + // Data members + dstring m_name; +}; + +// ************************************************************************** // +// ************** runtime::cla::positional_parameter ************** // +// ************************************************************************** // + +template +class positional_parameter_t : public basic_parameter { + typedef basic_parameter base; +public: + // Constructors + explicit positional_parameter_t( cstring name ) + : base( name ) + {} +}; + +//____________________________________________________________________________// + +BOOST_RT_CLA_NAMED_PARAM_GENERATORS( positional_parameter ) + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_POSITIONAL_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/typed_parameter.hpp b/include/boost/test/utils/runtime/cla/typed_parameter.hpp new file mode 100755 index 00000000..acc13b99 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/typed_parameter.hpp @@ -0,0 +1,77 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : generic typed parameter model +// *************************************************************************** + +#ifndef BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER +#define BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +#include +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::typed_parameter ************** // +// ************************************************************************** // + +template +class typed_parameter : public cla::parameter { +public: + explicit typed_parameter( identification_policy& ID ) : cla::parameter( ID, m_arg_factory ) {} + + // parameter properties modification + template + void accept_modifier( Modifier const& m ) + { + cla::parameter::accept_modifier( m ); + + m_arg_factory.accept_modifier( m ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( !p_optional || !m_arg_factory.m_value_generator, + BOOST_RT_PARAM_LITERAL( "couldn't define a value generator for optional parameter " ) << id_2_report() ); + } + +private: + // Data members + typed_argument_factory m_arg_factory; +}; + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_TYPED_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/validation.cpp b/include/boost/test/utils/runtime/cla/validation.cpp new file mode 100755 index 00000000..125dbee1 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/validation.cpp @@ -0,0 +1,25 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : input validation helpers offline implementation +// *************************************************************************** + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/cla/validation.hpp b/include/boost/test/utils/runtime/cla/validation.hpp new file mode 100755 index 00000000..e2cce566 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/validation.hpp @@ -0,0 +1,64 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : input validation helpers definition +// *************************************************************************** + +#ifndef BOOST_RT_CLA_VALIDATION_HPP_062604GER +#define BOOST_RT_CLA_VALIDATION_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::report_input_error ************** // +// ************************************************************************** // + +void report_input_error( argv_traverser const& tr, format_stream& msg ); + +//____________________________________________________________________________// + +#define BOOST_RT_CLA_VALIDATE_INPUT( b, tr, msg ) \ + if( b ) ; else ::boost::BOOST_RT_PARAM_NAMESPACE::cla::report_input_error( tr, format_stream().ref() << msg ) + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +# define BOOST_RT_PARAM_INLINE inline +# include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_VALIDATION_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/validation.ipp b/include/boost/test/utils/runtime/cla/validation.ipp new file mode 100755 index 00000000..e05c2211 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/validation.ipp @@ -0,0 +1,73 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : input validation helpers implementation +// *************************************************************************** + +#ifndef BOOST_RT_CLA_VALIDATION_IPP_070604GER +#define BOOST_RT_CLA_VALIDATION_IPP_070604GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +// Boost +#include + +// STL + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +// ************************************************************************** // +// ************** runtime::cla::validation ************** // +// ************************************************************************** // + +BOOST_RT_PARAM_INLINE void +report_input_error( argv_traverser const& tr, format_stream& msg ) +{ + if( tr.eoi() ) + msg << BOOST_RT_PARAM_LITERAL( " at the end of input" ); + else { + msg << BOOST_RT_PARAM_LITERAL( " in the following position: " ); + + if( tr.input().size() > 5 ) + msg << tr.input().substr( 0, 5 ) << BOOST_RT_PARAM_LITERAL( "..." ); + else + msg << tr.input(); + } + + throw BOOST_RT_PARAM_NAMESPACE::logic_error( msg.str() ); +} + +//____________________________________________________________________________// + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_VALIDATION_IPP_070604GER diff --git a/include/boost/test/utils/runtime/cla/value_generator.hpp b/include/boost/test/utils/runtime/cla/value_generator.hpp new file mode 100755 index 00000000..d6de2ce1 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/value_generator.hpp @@ -0,0 +1,90 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : specific value generators +// *************************************************************************** + +#ifndef BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER +#define BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +namespace rt_cla_detail { + +// ************************************************************************** // +// ************** runtime::cla::const_generator ************** // +// ************************************************************************** // + +template +class const_generator { +public: + // Constructor + explicit const_generator( T const& t ) : m_const_value( t ) {} + + // generator interface + void operator()( parser const&, boost::optional& t ) const { t = m_const_value; } + +private: + // Data members + T m_const_value; +}; + +// ************************************************************************** // +// ************** runtime::cla::ref_generator ************** // +// ************************************************************************** // + +template +class ref_generator { +public: + // Constructor + explicit ref_generator( cstring ref_id ) : m_ref_id( ref_id ) {} + + // generator interface + void operator()( parser const& p, boost::optional& t ) const + { + p.get( m_ref_id, t ); + } + +private: + // Data members + cstring m_ref_id; +}; + +//____________________________________________________________________________// + +} // namespace rt_cla_detail + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_VALUE_GENERATOR_HPP_062604GER diff --git a/include/boost/test/utils/runtime/cla/value_handler.hpp b/include/boost/test/utils/runtime/cla/value_handler.hpp new file mode 100755 index 00000000..ab5b5d10 --- /dev/null +++ b/include/boost/test/utils/runtime/cla/value_handler.hpp @@ -0,0 +1,66 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : specific value handlers +// *************************************************************************** + +#ifndef BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER +#define BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace cla { + +namespace rt_cla_detail { + +// ************************************************************************** // +// ************** runtime::cla::assigner ************** // +// ************************************************************************** // + +template +class assigner { +public: + // Constructor + explicit assigner( T& loc ) : m_target( loc ) {} + + // value handler implementation + void operator()( parameter const&, T& t ) { m_target = t; } + +private: + // Data members + T& m_target; +}; + +} // namespace rt_cla_detail + +} // namespace cla + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CLA_VALUE_HANDLER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/config.hpp b/include/boost/test/utils/runtime/config.hpp new file mode 100755 index 00000000..bdc1f930 --- /dev/null +++ b/include/boost/test/utils/runtime/config.hpp @@ -0,0 +1,110 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : Runtime.Param library configuration +// *************************************************************************** + +#ifndef BOOST_RT_CONFIG_HPP_062604GER +#define BOOST_RT_CONFIG_HPP_062604GER + +// Boost +#include +#ifdef BOOST_MSVC +# pragma warning(disable: 4511) // copy constructor could not be generated +# pragma warning(disable: 4512) // assignment operator could not be generated +# pragma warning(disable: 4181) // qualifier applied to reference type; ignored +# pragma warning(disable: 4675) // resolved overload was found by argument-dependent lookup +#endif + +// Boost.Test +#include +#include +#include + +// STL +#include + +//____________________________________________________________________________// + +#ifndef BOOST_RT_PARAM_CUSTOM_STRING +# ifndef BOOST_RT_PARAM_WIDE_STRING +# define BOOST_RT_PARAM_NAMESPACE runtime +# else +# define BOOST_RT_PARAM_NAMESPACE wide_runtime +# endif +#endif + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +#ifndef BOOST_RT_PARAM_CUSTOM_STRING +# ifndef BOOST_RT_PARAM_WIDE_STRING + +typedef char char_type; +typedef std::string dstring; +typedef unit_test::const_string cstring; +typedef unit_test::literal_string literal_cstring; +typedef wrap_stringstream format_stream; + +#ifdef BOOST_CLASSIC_IOSTREAMS +typedef std::ostream out_stream; +#else +typedef std::basic_ostream out_stream; +#endif + +#define BOOST_RT_PARAM_LITERAL( l ) l +#define BOOST_RT_PARAM_CSTRING_LITERAL( l ) cstring( l, sizeof( l ) - 1 ) +#define BOOST_RT_PARAM_GETENV getenv +#define BOOST_RT_PARAM_PUTENV putenv +#define BOOST_RT_PARAM_EXCEPTION_INHERIT_STD + +//____________________________________________________________________________// + +# else + +typedef wchar_t char_type; +typedef std::basic_string dstring; +typedef unit_test::basic_cstring cstring; +typedef const unit_test::basic_cstring literal_cstring; +typedef wrap_wstringstream format_stream; +typedef std::wostream out_stream; + +#define BOOST_RT_PARAM_LITERAL( l ) L ## l +#define BOOST_RT_PARAM_CSTRING_LITERAL( l ) cstring( L ## l, sizeof( L ## l )/sizeof(wchar_t) - 1 ) +#define BOOST_RT_PARAM_GETENV wgetenv +#define BOOST_RT_PARAM_PUTENV wputenv + +# endif +#endif + +#ifdef __GNUC__ +#define BOOST_RT_PARAM_UNNEEDED_VIRTUAL virtual +#else +#define BOOST_RT_PARAM_UNNEEDED_VIRTUAL +#endif + +//____________________________________________________________________________// + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CONFIG_HPP_062604GER diff --git a/include/boost/test/utils/runtime/configuration.hpp b/include/boost/test/utils/runtime/configuration.hpp new file mode 100755 index 00000000..9f7c6fca --- /dev/null +++ b/include/boost/test/utils/runtime/configuration.hpp @@ -0,0 +1,70 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : abstract interface for the formal parameter +// *************************************************************************** + +#ifndef BOOST_RT_CONFIGURATION_HPP_062604GER +#define BOOST_RT_CONFIGURATION_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::configuration ************** // +// ************************************************************************** // + +class config_source { + virtual parameter const& config_param_begin() const = 0; + virtual parameter const& config_param_end() const = 0; + +protected: + config_source() {} + ~config_source() {} +}; + +// ************************************************************************** // +// ************** runtime::configuration ************** // +// ************************************************************************** // + +template +class configuration : public StoragePolicy, public IdentificationPlicy, public ConflictResolutionPolicy { +public: + // Constructor + configuration(); + + void use( config_source const& ) + { + + } +private: +}; + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_CONFIGURATION_HPP_062604GER diff --git a/include/boost/test/utils/runtime/env/environment.cpp b/include/boost/test/utils/runtime/env/environment.cpp new file mode 100755 index 00000000..25e5c67c --- /dev/null +++ b/include/boost/test/utils/runtime/env/environment.cpp @@ -0,0 +1,32 @@ +// (C) Copyright Gennadiy Rozental 2004. +// 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$ +// +// Description : implements offline model of program environment +// *************************************************************************** + +#include + +#ifdef BOOST_MSVC +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4701) // local environment 'result' may be used without having been initialized +#endif + +#define BOOST_RT_PARAM_INLINE +#include + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/env/environment.hpp b/include/boost/test/utils/runtime/env/environment.hpp new file mode 100755 index 00000000..701f8db8 --- /dev/null +++ b/include/boost/test/utils/runtime/env/environment.hpp @@ -0,0 +1,175 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : defines and implements inline model of program environment +// *************************************************************************** + +#ifndef BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER +#define BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include +#include +#include + +#include +#include +#include + +// Boost.Test +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::environment implementation ************** // +// ************************************************************************** // + +namespace environment { + +namespace rt_env_detail { + +template +variable_data& +init_new_var( cstring var_name, Modifiers m = nfp::no_params ) +{ + rt_env_detail::variable_data& new_vd = new_var_record( var_name ); + + cstring str_value = sys_read_var( new_vd.m_var_name ); + + if( !str_value.is_empty() ) { + try { + boost::optional value; + + m.has( interpreter ) + ? m[interpreter]( str_value, value ) + : interpret_argument_value( str_value, value, 0 ); + + if( !!value ) { + new_vd.m_value.reset( new typed_argument( new_vd ) ); + + arg_value( *new_vd.m_value ) = *value; + } + } + catch( ... ) { // !! could we do that + // !! should we report an error? + } + } + + if( !new_vd.m_value && m.has( default_value ) ) { + new_vd.m_value.reset( new typed_argument( new_vd ) ); + + nfp::optionally_assign( arg_value( *new_vd.m_value ), m[default_value] ); + } + + nfp::optionally_assign( new_vd.m_global_id, m, global_id ); + + return new_vd; +} + +//____________________________________________________________________________// + +} // namespace rt_env_detail + +} // namespace environment + +// ************************************************************************** // +// ************** runtime::environment ************** // +// ************************************************************************** // + +namespace environment { + + // variable access + variable_base + var( cstring var_name ); + + //________________________________________________________________________// + + template + inline variable + var( cstring var_name ) + { + rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name ); + + return environment::variable( !vd ? rt_env_detail::init_new_var( var_name, nfp::no_params ) : *vd ); + } + + //________________________________________________________________________// + + template + inline variable + var( cstring var_name, Modifiers const& m ) + { + rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name ); + + return environment::variable( !vd ? rt_env_detail::init_new_var( var_name, m ) : *vd ); + } + + //________________________________________________________________________// + + // direct variable value access + inline cstring + get( cstring var_name ) + { + return environment::var( var_name ).value(); + } + + //________________________________________________________________________// + + template + inline T const& + get( cstring var_name ) + { + return environment::var( var_name ).value(); + } + + //________________________________________________________________________// + + template + inline void + get( cstring var_name, boost::optional& res ) + { + environment::var( var_name ).value( res ); + } + + //________________________________________________________________________// + +} // namespace environment + +namespace env = environment; + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +#ifndef BOOST_RT_PARAM_OFFLINE + +#define BOOST_RT_PARAM_INLINE inline +#include + +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER diff --git a/include/boost/test/utils/runtime/env/environment.ipp b/include/boost/test/utils/runtime/env/environment.ipp new file mode 100755 index 00000000..e1c0e942 --- /dev/null +++ b/include/boost/test/utils/runtime/env/environment.ipp @@ -0,0 +1,136 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : implements model of program environment +// *************************************************************************** + +#ifndef BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER +#define BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER + +// Boost.Runtime.Parameter +#include +#include + +#include + +// Boost.Test +#include +#include + +// STL +#include +#include +#include + +# define BOOST_NO_STDC_NAMESPACE + +# ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::BOOST_RT_PARAM_GETENV; using ::BOOST_RT_PARAM_PUTENV; } +# endif + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace environment { + +// ************************************************************************** // +// ************** runtime::environment ************** // +// ************************************************************************** // + +namespace rt_env_detail { + +typedef std::map registry; +typedef std::list keys; + +BOOST_RT_PARAM_INLINE registry& s_registry() { static registry instance; return instance; } +BOOST_RT_PARAM_INLINE keys& s_keys() { static keys instance; return instance; } + +BOOST_RT_PARAM_INLINE variable_data& +new_var_record( cstring var_name ) +{ + // save the name in list of keys + s_keys().push_back( dstring() ); + dstring& key = s_keys().back(); + assign_op( key, var_name, 0 ); + + // create and return new record + variable_data& new_var_data = s_registry()[key]; + + new_var_data.m_var_name = key; + + return new_var_data; +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE variable_data* +find_var_record( cstring var_name ) +{ + registry::iterator it = s_registry().find( var_name ); + + return it == s_registry().end() ? 0 : &(it->second); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE cstring +sys_read_var( cstring var_name ) +{ + return std::BOOST_RT_PARAM_GETENV( var_name.begin() ); +} + +//____________________________________________________________________________// + +BOOST_RT_PARAM_INLINE void +sys_write_var( cstring var_name, format_stream& var_value ) +{ + format_stream fs; + + fs << var_name << '=' << var_value.str(); + + std::BOOST_RT_PARAM_PUTENV( fs.str().c_str() ); +} + +//____________________________________________________________________________// + +} // namespace rt_env_detail + +BOOST_RT_PARAM_INLINE variable_base +var( cstring var_name ) +{ + rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( !!vd, + BOOST_RT_PARAM_LITERAL( "First access to the environment variable " ) + << var_name << BOOST_RT_PARAM_LITERAL( " should be typed" ) ); + + return variable_base( *vd ); +} + +//____________________________________________________________________________// + +} // namespace environment + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ENV_ENVIRONMENT_IPP_062904GER diff --git a/include/boost/test/utils/runtime/env/fwd.hpp b/include/boost/test/utils/runtime/env/fwd.hpp new file mode 100755 index 00000000..947fb30e --- /dev/null +++ b/include/boost/test/utils/runtime/env/fwd.hpp @@ -0,0 +1,57 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : environment subsystem forward declarations +// *************************************************************************** + +#ifndef BOOST_RT_ENV_FWD_HPP_062604GER +#define BOOST_RT_ENV_FWD_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace environment { + +namespace rt_env_detail { + +struct variable_data; + +variable_data& new_var_record( cstring var_name ); +variable_data* find_var_record( cstring var_name ); + +cstring sys_read_var( cstring var_name ); +void sys_write_var( cstring var_name, format_stream& var_value ); + +} + +class variable_base; +template class variable; + +} // namespace environment + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ENV_FWD_HPP_062604GER diff --git a/include/boost/test/utils/runtime/env/modifier.hpp b/include/boost/test/utils/runtime/env/modifier.hpp new file mode 100755 index 00000000..424b8cc9 --- /dev/null +++ b/include/boost/test/utils/runtime/env/modifier.hpp @@ -0,0 +1,56 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines variable modifiers +// *************************************************************************** + +#ifndef BOOST_RT_ENV_MODIFIER_HPP_062604GER +#define BOOST_RT_ENV_MODIFIER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost.Test +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace environment { + +// ************************************************************************** // +// ************** environment variable modifiers ************** // +// ************************************************************************** // + +namespace { + +nfp::typed_keyword global_id; +nfp::keyword default_value; +nfp::keyword interpreter; + +} // local namespace +} // namespace environment + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ENV_MODIFIER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/env/variable.hpp b/include/boost/test/utils/runtime/env/variable.hpp new file mode 100755 index 00000000..ecb0e18e --- /dev/null +++ b/include/boost/test/utils/runtime/env/variable.hpp @@ -0,0 +1,222 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : defines model of program environment variable +// *************************************************************************** + +#ifndef BOOST_RT_ENV_VARIABLE_HPP_062604GER +#define BOOST_RT_ENV_VARIABLE_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include +#include +#include + +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace environment { + +// ************************************************************************** // +// ************** runtime::environment::variable_data ************** // +// ************************************************************************** // + +namespace rt_env_detail { + +struct variable_data : public runtime::parameter { + cstring m_var_name; + dstring m_global_id; + argument_ptr m_value; +}; + +} // namespace rt_env_detail + +// ************************************************************************** // +// ************** runtime::environment::variable_base ************** // +// ************************************************************************** // + +class variable_base { +public: + explicit variable_base( rt_env_detail::variable_data& data ) : m_data( &data ) {} + + // arguments access + template + T const& value() const + { + return arg_value( *m_data->m_value ); + } + + template + void value( boost::optional& res ) const + { + if( has_value() ) + res = arg_value( *m_data->m_value ); + else + res.reset(); + } + + bool has_value() const { return m_data->m_value; } + cstring name() const { return m_data->m_var_name; } + +protected: + // Data members + rt_env_detail::variable_data* m_data; +} ; + +// ************************************************************************** // +// ************** runtime::environment::variable ************** // +// ************************************************************************** // + +template +class variable : public variable_base { +public: + // Constructors + explicit variable( cstring var_name ); + + template + explicit variable( cstring var_name, Modifiers const& m ); + + explicit variable( rt_env_detail::variable_data& data ) + : variable_base( data ) {} + + // other variable assignment + void operator=( variable const& v ) { m_data = v.m_data; } + + // access methods + T const& value() const { return variable_base::value(); } + + using variable_base::value; + + // Value assignment + template + void operator=( V const& v ) + { + if( !has_value() ) + m_data->m_value.reset( new typed_argument( *m_data ) ); + + arg_value( *m_data->m_value ) = v; + + rt_env_detail::sys_write_var( m_data->m_var_name, format_stream().ref() << value() ); + } +}; // class variable + +//____________________________________________________________________________// + +template +inline std::basic_ostream& +operator<<( std::basic_ostream& os, variable const& v ) +{ + os << v.name() << '='; + + if( v.has_value() ) + os << v.value(); + + return os; +} + +//____________________________________________________________________________// + +template +inline bool +operator==( variable ev, V const& v ) +{ + return ev.has_value() && ev.value() == v; +} + +//____________________________________________________________________________// + +template +inline bool +operator==( V const& v, variable ev ) +{ + return ev.has_value() && ev.value() == v; +} + +//____________________________________________________________________________// + +template +inline bool +operator!=( variable ev, V const& v ) +{ + return !ev.has_value() || ev.value() != v; +} + +//____________________________________________________________________________// + +template +inline bool +operator!=( V const& v, variable ev ) +{ + return !ev.has_value() || ev.value() != v; +} + +//____________________________________________________________________________// + +} // namespace environment + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// ************************************************************************** // +// Implementation + +#include + +// ************************************************************************** // +// ************** runtime::environment::variable ************** // +// ************************************************************************** // + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace environment { + +template +variable::variable( cstring var_name ) +: variable_base( environment::var( var_name ) ) +{} + +//____________________________________________________________________________// + +template +template +variable::variable( cstring var_name, Modifiers const& m ) +: variable_base( environment::var( var_name, m ) ) +{} + +//____________________________________________________________________________// + +} // namespace environment + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_ENV_VARIABLE_HPP_062604GER diff --git a/include/boost/test/utils/runtime/file/config_file.cpp b/include/boost/test/utils/runtime/file/config_file.cpp new file mode 100755 index 00000000..9a1552a7 --- /dev/null +++ b/include/boost/test/utils/runtime/file/config_file.cpp @@ -0,0 +1,256 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// 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 + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:43 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/file/config_file.hpp b/include/boost/test/utils/runtime/file/config_file.hpp new file mode 100755 index 00000000..c3c30f0d --- /dev/null +++ b/include/boost/test/utils/runtime/file/config_file.hpp @@ -0,0 +1,191 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : defines models configuration file, it's parameter and parameter namespaces +// *************************************************************************** + +#ifndef BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER +#define BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER + +// Boost.Runtime.Parameter +#include + +#include + +// Boost.Test +#include +#include + +// Boost +#include + +// STL +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace file { + +// ************************************************************************** // +// ************** runtime::file::parameter ************** // +// ************************************************************************** // + +class param_namespace; + +class parameter { +public: + // Constructor + parameter( cstring name, cstring value, param_namespace const& parent ); + + BOOST_READONLY_PROPERTY( dstring, (parameter)) p_name; + BOOST_READONLY_PROPERTY( dstring, (parameter)) p_value; + + friend std::ostream& operator<<( std::ostream& os, parameter const& ); + +private: + // Data members + param_namespace const& m_parent; +}; + +// ************************************************************************** // +// ************** runtime::file::modifiers ************** // +// ************************************************************************** // + +namespace { +nfp::typed_keyword value_marker; +nfp::typed_keyword value_delimeter; +nfp::typed_keyword namespace_delimeter; +} // local namespace + +// ************************************************************************** // +// ************** runtime::file::param_namespace ************** // +// ************************************************************************** // + +class param_namespace { +public: + typedef std::list::iterator iterator; + typedef std::list::const_iterator const_iterator; + typedef std::list::iterator sub_ns_iterator; + typedef std::list::const_iterator sub_ns_const_iterator; + + // Public properties + BOOST_READONLY_PROPERTY( dstring, (param_namespace)) p_name; + unit_test::readonly_property p_parent; + + void load( config_file_iterator cf_it ) { load( cf_it, nfp::no_params ); } + template + void load( config_file_iterator cf_it, Modifier const& m ) + { + cstring vm = m.has( value_marker ) ? m[value_marker] : BOOST_RT_PARAM_CSTRING_LITERAL( "\"" ); + cstring vd = m.has( value_delimeter ) ? m[value_delimeter] : BOOST_RT_PARAM_CSTRING_LITERAL( "= \t\n\r" ); + cstring nd = m.has( namespace_delimeter ) ? m[namespace_delimeter] : BOOST_RT_PARAM_CSTRING_LITERAL( "::" ); + + load_impl( cf_it, vm, vd, nd ); + } + void load( cstring file_name ) + { + load( file_name, nfp::no_params ); + } + template + void load( cstring file_name, Modifier const& m ) + { + config_file_iterator cfi( file_name, m ); + + load( cfi, m ); + } + + void insert_param( cstring param_name, cstring param_value ); + param_namespace& subnamespace( cstring namespace_name ); // find and insert if not present + void clear(); + + iterator begin() { return m_parameters.begin(); } + const_iterator begin() const { return m_parameters.begin(); } + + iterator end() { return m_parameters.end(); } + const_iterator end() const { return m_parameters.end(); } + + sub_ns_iterator sub_ns_begin() { return m_subnamespaces.begin(); } + sub_ns_const_iterator sub_ns_begin() const { return m_subnamespaces.begin(); } + + sub_ns_iterator sub_ns_end() { return m_subnamespaces.end(); } + sub_ns_const_iterator sub_ns_end() const { return m_subnamespaces.end(); } + + void print_full_name( std::ostream& os ) const; + +protected: + explicit param_namespace( cstring name, param_namespace const* parent = 0 ); + +private: + void load_impl( config_file_iterator cf_it, + cstring value_marker_, cstring value_delimeter_, cstring namespace_delimeter_ ); + + // Data members + std::list m_parameters; + std::list m_subnamespaces; +}; + +//____________________________________________________________________________// + +boost::optional +get_param_value( param_namespace const& where_from, + cstring name_part1, + cstring name_part2 = cstring(), + cstring name_part3 = cstring(), + cstring name_part4 = cstring(), + cstring name_part5 = cstring() ); + +//____________________________________________________________________________// + +cstring +get_requ_param_value( param_namespace const& where_from, + cstring name_part1, + cstring name_part2 = cstring(), + cstring name_part3 = cstring(), + cstring name_part4 = cstring(), + cstring name_part5 = cstring() ); + +//____________________________________________________________________________// + +param_namespace const* +get_param_subns( param_namespace const& where_from, + cstring namespace_name ); + +//____________________________________________________________________________// + +// ************************************************************************** // +// ************** runtime::file::config_file ************** // +// ************************************************************************** // + +class config_file : public param_namespace { +public: + // Constructor + config_file(); + config_file( cstring file_name ); +}; + +} // namespace file + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:44 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_FILE_CONFIG_FILE_HPP_010105GER diff --git a/include/boost/test/utils/runtime/file/config_file_iterator.cpp b/include/boost/test/utils/runtime/file/config_file_iterator.cpp new file mode 100755 index 00000000..4ea2e0fa --- /dev/null +++ b/include/boost/test/utils/runtime/file/config_file_iterator.cpp @@ -0,0 +1,687 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : flexible configuration file iterator implementation +// *************************************************************************** + +// Boost.Runtime.Parameter +#include + +#include +#include + +#include + +// Boost +#include +#include +#include + +// Boost.Test +#include +#include +#include +#include + +// STL +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace file { + +// ************************************************************************** // +// ************** symbol_to_value_map ************** // +// ************************************************************************** // + +template +struct symbol_to_value_map : std::map { + template + void add( cstring name, ParamType const& value ) + { + using namespace unit_test; + + m_name_store.push_back( dstring() ); + + assign_op( m_name_store.back(), name, 0 ); + assign_op( (*this)[m_name_store.back()], value, 0 ); + } + void remove( cstring name ) + { + std::list::iterator it = std::find( m_name_store.begin(), m_name_store.end(), name ); + + m_name_store.erase( it ); + + erase( name ); + } + +private: + std::list m_name_store; +}; + +// ************************************************************************** // +// ************** symbol_table_t ************** // +// ************************************************************************** // + +typedef symbol_to_value_map symbol_table_t; + +// ************************************************************************** // +// ************** command_handler_map ************** // +// ************************************************************************** // + +typedef symbol_to_value_map command_handler_map; + +// ************************************************************************** // +// ************** is_valid_identifier ************** // +// ************************************************************************** // + +static bool +is_valid_identifier( cstring const& source ) +{ + if( source.is_empty() ) + return false; + + cstring::const_iterator it = source.begin(); + + if( !std::isalpha( *it ) ) + return false; + + while( ++it < source.end() ) { + if( !std::isalnum( *it ) && *it != BOOST_RT_PARAM_LITERAL( '_' ) && *it != BOOST_RT_PARAM_LITERAL( '-' ) ) + return false; + } + + return true; +} + +// ************************************************************************** // +// ************** include_level ************** // +// ************************************************************************** // + +struct include_level; +typedef std::auto_ptr include_level_ptr; + +struct include_level : noncopyable +{ + // Constructor + explicit include_level( cstring file_name, cstring path_separators, include_level* parent = 0 ); + + // Data members + std::ifstream m_stream; + location m_curr_location; + include_level_ptr m_parent; +}; + +//____________________________________________________________________________// + +include_level::include_level( cstring file_name, cstring path_separators, include_level* parent_ ) +: m_parent( parent_ ) +{ + if( file_name.is_empty() ) + return; + + assign_op( m_curr_location.first, file_name, 0 ); + m_curr_location.second = 0; + + m_stream.open( m_curr_location.first.c_str() ); + + if( !m_stream.is_open() && !!m_parent.get() ) { + cstring parent_path = m_parent->m_curr_location.first; + cstring::iterator it = unit_test::find_last_of( parent_path.begin(), parent_path.end(), + path_separators.begin(), + path_separators.end() ); + + if( it != parent_path.end() ) { + assign_op( m_curr_location.first, cstring( parent_path.begin(), it+1 ), 0 ); + m_curr_location.first.append( file_name.begin(), file_name.end() ); + m_stream.clear(); + m_stream.open( m_curr_location.first.c_str() ); + } + } + + BOOST_RT_PARAM_VALIDATE_LOGIC( m_stream.is_open(), BOOST_RT_PARAM_LITERAL( "couldn't open file " ) << file_name ); +} + +//____________________________________________________________________________// + +// ************************************************************************** // +// ************** config_file_iterator::Impl ************** // +// ************************************************************************** // + +struct config_file_iterator::Impl : noncopyable { + // Constructor + Impl(); + + bool get_next_line( cstring& next_line ); + + void process_command_line( cstring line ); + void process_include( cstring line ); + void process_define( cstring line ); + void process_undef( cstring line ); + void process_ifdef( cstring line ); + void process_ifndef( cstring line ); + void process_else( cstring line ); + void process_endif( cstring line ); + + boost::optional + get_macro_value( cstring macro_name, bool ignore_missing = true ); + void substitute_macros( cstring& where ); + + bool is_active_line() { return m_inactive_ifdef_level == 0; } + + static bool match_front( cstring str, cstring pattern ) + { + return str.size() >= pattern.size() && str.substr( 0, pattern.size() ) == pattern; + } + static bool match_back( cstring str, cstring pattern ) + { + return str.size() >= pattern.size() && str.substr( str.size() - pattern.size() ) == pattern; + } + + // Configurable parameters + dstring m_path_separators; + char_type m_line_delimeter; + dstring m_sl_comment_delimeter; + dstring m_command_delimeter; + dstring m_line_beak; + dstring m_macro_ref_begin; + dstring m_macro_ref_end; + + dstring m_include_kw; + dstring m_define_kw; + dstring m_undef_kw; + dstring m_ifdef_kw; + dstring m_ifndef_kw; + dstring m_else_kw; + dstring m_endif_kw; + + std::size_t m_buffer_size; + + bool m_trim_trailing_spaces; + bool m_trim_leading_spaces; + bool m_skip_empty_lines; + bool m_detect_missing_macro; + + // Data members + dstring m_post_subst_line; + scoped_array m_buffer; + include_level_ptr m_curr_level; + symbol_table_t m_symbols_table; + std::vector m_conditional_states; + std::size_t m_inactive_ifdef_level; + command_handler_map m_command_handler_map; +}; + +//____________________________________________________________________________// + +config_file_iterator::Impl::Impl() +: m_path_separators( BOOST_RT_PARAM_LITERAL( "/\\" ) ) +, m_line_delimeter( BOOST_RT_PARAM_LITERAL( '\n' ) ) +, m_sl_comment_delimeter( BOOST_RT_PARAM_LITERAL( "#" ) ) +, m_command_delimeter( BOOST_RT_PARAM_LITERAL( "$" ) ) +, m_line_beak( BOOST_RT_PARAM_LITERAL( "\\" ) ) +, m_macro_ref_begin( BOOST_RT_PARAM_LITERAL( "$" ) ) +, m_macro_ref_end( BOOST_RT_PARAM_LITERAL( "$" ) ) + +, m_include_kw( BOOST_RT_PARAM_LITERAL( "include" ) ) +, m_define_kw( BOOST_RT_PARAM_LITERAL( "define" ) ) +, m_undef_kw( BOOST_RT_PARAM_LITERAL( "undef" ) ) +, m_ifdef_kw( BOOST_RT_PARAM_LITERAL( "ifdef" ) ) +, m_ifndef_kw( BOOST_RT_PARAM_LITERAL( "ifndef" ) ) +, m_else_kw( BOOST_RT_PARAM_LITERAL( "else" ) ) +, m_endif_kw( BOOST_RT_PARAM_LITERAL( "endif" ) ) + +, m_buffer_size( 8192 ) + +, m_trim_trailing_spaces( true ) +, m_trim_leading_spaces( false ) +, m_skip_empty_lines( true ) +, m_detect_missing_macro( true ) + +, m_inactive_ifdef_level( 0 ) +{} + +//____________________________________________________________________________// + +bool +config_file_iterator::Impl::get_next_line( cstring& line ) +{ + bool broken_line = false; + + line.clear(); + + while( !m_curr_level->m_stream.eof() || !!m_curr_level->m_parent.get() ) { + // 10. Switch to upper include level if current one is finished + // 20. Read/append next file line + // 30. Increment line number + // 40. Remove comments + // 50. Remove trailing and leading spaces + // 60. Skip empty string + // 70. Concatenate broken lines if needed. Put the result into line + // 80. If line is not completed, try to finish it by reading the next line + // 90. Process command line + // 100. Substitute macros references with their definitions + // 110. Next line found. + + if( m_curr_level->m_stream.eof() ) { // 10 // + m_curr_level = m_curr_level->m_parent; + continue; + } + + std::ifstream& input = m_curr_level->m_stream; + char_type* buffer_insert_pos = broken_line ? m_buffer.get() + line.size() : m_buffer.get(); + + input.getline( buffer_insert_pos, (std::streamsize)(m_buffer_size - line.size()), // 20 // + m_line_delimeter ); + + cstring next_line( buffer_insert_pos, + input.gcount() > 0 + ? buffer_insert_pos + (input.eof() ? input.gcount() : (input.gcount()-1)) + : buffer_insert_pos ); + + + m_curr_level->m_curr_location.second++; // 30 // + + cstring::size_type comment_pos = next_line.find( m_sl_comment_delimeter ); + if( comment_pos != cstring::npos ) + next_line.trim_right( next_line.begin()+comment_pos ); // 40 // + + if( m_trim_trailing_spaces ) // 50 // + next_line.trim_right(); + if( m_trim_leading_spaces && !broken_line ) + next_line.trim_left(); + + if( next_line.is_empty() ) { // 60 // + if( m_skip_empty_lines ) + continue; + else + next_line.assign( buffer_insert_pos, buffer_insert_pos ); + } + + line = broken_line ? cstring( line.begin(), next_line.end() ) : next_line; // 70 // + + broken_line = match_back( line, m_line_beak ); + if( broken_line ) { // 80 // + line.trim_right( 1 ); + continue; + } + + if( match_front( line, m_command_delimeter ) ) { // 90 // + process_command_line( line ); + continue; + } + + if( !is_active_line() ) + continue; + + substitute_macros( line ); // 100 // + + return true; // 110 // + } + + BOOST_RT_PARAM_VALIDATE_LOGIC( !broken_line, BOOST_RT_PARAM_LITERAL( "broken line is not completed" ) ); + BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() == 0, + BOOST_RT_PARAM_LITERAL( "matching endif command is missing" ) ); + + return false; +} + +//____________________________________________________________________________// + +boost::optional +config_file_iterator::Impl::get_macro_value( cstring macro_name, bool ignore_missing ) +{ + symbol_table_t::const_iterator it = m_symbols_table.find( macro_name ); + + if( it == m_symbols_table.end() ) { + boost::optional macro_value; // !! variable actually may have different type + + env::get( macro_name, macro_value ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( macro_value || ignore_missing || !m_detect_missing_macro, + BOOST_RT_PARAM_LITERAL( "Unknown macro \"" ) << macro_name << BOOST_RT_PARAM_LITERAL( "\"" ) ); + + if( !macro_value ) { + if( !ignore_missing ) + macro_value = cstring(); + } + else + m_symbols_table.add( macro_name, *macro_value ); + + return macro_value; + } + + return boost::optional( cstring( it->second ) ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_command_line( cstring line ) +{ + line.trim_left( m_command_delimeter.size() ); + + unit_test::string_token_iterator tit( line, unit_test::max_tokens = 2 ); + + command_handler_map::const_iterator it = m_command_handler_map.find( *tit ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( it != m_command_handler_map.end(), BOOST_RT_PARAM_LITERAL( "Invalid command " ) << *tit ); + + ++tit; + + (it->second)( *tit ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_include( cstring line ) +{ + using namespace unit_test; + + if( !is_active_line() ) + return; + + string_token_iterator tit( line, kept_delimeters = dt_none ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( tit != string_token_iterator(), + BOOST_RT_PARAM_LITERAL( "include file name missing" ) ); + + cstring include_file_name = *tit; + + BOOST_RT_PARAM_VALIDATE_LOGIC( ++tit == string_token_iterator(), + BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of include command" ) ); + + substitute_macros( include_file_name ); + + m_curr_level.reset( new include_level( include_file_name, m_path_separators, m_curr_level.release() ) ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_define( cstring line ) +{ + using namespace unit_test; + + if( !is_active_line() ) + return; + + string_token_iterator tit( line, (kept_delimeters = dt_none, max_tokens = 2 )); + + cstring macro_name = *tit; + BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ), + BOOST_RT_PARAM_LITERAL( "invalid macro name" ) ); + + cstring macro_value = *(++tit); + substitute_macros( macro_value ); + + m_symbols_table.add( macro_name, macro_value ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_undef( cstring line ) +{ + if( !is_active_line() ) + return; + + cstring macro_name = line; + BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ), + BOOST_RT_PARAM_LITERAL( "invalid macro name" ) ); + + m_symbols_table.remove( macro_name ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_ifdef( cstring line ) +{ + m_conditional_states.push_back( true ); + if( !is_active_line() ) + return; + + cstring macro_name = line; + BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ), + BOOST_RT_PARAM_LITERAL( "invalid macro name" ) ); + + if( !get_macro_value( macro_name ) ) + m_inactive_ifdef_level = m_conditional_states.size(); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_ifndef( cstring line ) +{ + m_conditional_states.push_back( true ); + if( !is_active_line() ) + return; + + cstring macro_name = line; + BOOST_RT_PARAM_VALIDATE_LOGIC( is_valid_identifier( macro_name ), + BOOST_RT_PARAM_LITERAL( "invalid macro name" ) ); + + if( get_macro_value( macro_name ) ) + m_inactive_ifdef_level = m_conditional_states.size(); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_else( cstring line ) +{ + BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0 && m_conditional_states.back(), + BOOST_RT_PARAM_LITERAL( "else without matching if" ) ); + + m_inactive_ifdef_level = m_conditional_states.size() == m_inactive_ifdef_level ? 0 : m_conditional_states.size(); + + BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of else command" ) ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::process_endif( cstring line ) +{ + BOOST_RT_PARAM_VALIDATE_LOGIC( m_conditional_states.size() > 0, BOOST_RT_PARAM_LITERAL( "endif without matching if" ) ); + + if( m_conditional_states.size() == m_inactive_ifdef_level ) + m_inactive_ifdef_level = 0; + + m_conditional_states.pop_back(); + BOOST_RT_PARAM_VALIDATE_LOGIC( line.is_empty(), BOOST_RT_PARAM_LITERAL( "unexpected tokens at the end of endif command" ) ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::Impl::substitute_macros( cstring& where ) +{ + m_post_subst_line.clear(); + cstring::size_type pos; + + while( (pos = where.find( m_macro_ref_begin )) != cstring::npos ) { + m_post_subst_line.append( where.begin(), pos ); + + where.trim_left( where.begin() + pos + m_macro_ref_begin.size() ); + + pos = where.find( m_macro_ref_end ); + + BOOST_RT_PARAM_VALIDATE_LOGIC( pos != cstring::npos, BOOST_RT_PARAM_LITERAL( "incomplete macro reference" ) ); + + cstring value = *get_macro_value( where.substr( 0, pos ), false ); + m_post_subst_line.append( value.begin(), value.size() ); + + where.trim_left( where.begin() + pos + m_macro_ref_end.size() ); + } + + if( !m_post_subst_line.empty() ) { + m_post_subst_line.append( where.begin(), where.size() ); + where = m_post_subst_line; + } +} + +//____________________________________________________________________________// + +// ************************************************************************** // +// ************** runtime::file::config_file_iterator ************** // +// ************************************************************************** // + +void +config_file_iterator::construct() +{ + m_pimpl.reset( new Impl ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::load( cstring file_name ) +{ + m_pimpl->m_curr_level.reset( new include_level( file_name, m_pimpl->m_path_separators ) ); + m_pimpl->m_buffer.reset( new char[m_pimpl->m_buffer_size] ); + + register_command_handler( m_pimpl->m_include_kw, bind( &Impl::process_include, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_define_kw, bind( &Impl::process_define, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_undef_kw, bind( &Impl::process_undef, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_ifdef_kw, bind( &Impl::process_ifdef, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_ifndef_kw, bind( &Impl::process_ifndef, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_else_kw, bind( &Impl::process_else, m_pimpl.get(), _1 ) ); + register_command_handler( m_pimpl->m_endif_kw, bind( &Impl::process_endif, m_pimpl.get(), _1 ) ); + + init(); +} + +//____________________________________________________________________________// + +location const& +config_file_iterator::curr_location() +{ + return m_pimpl->m_curr_level->m_curr_location; +} + +//____________________________________________________________________________// + +void +config_file_iterator::register_command_handler( cstring command_kw, command_handler const& ch ) +{ + m_pimpl->m_command_handler_map.add( command_kw, ch ); +} + +//____________________________________________________________________________// + +bool +config_file_iterator::get() +{ + return m_pimpl->get_next_line( m_value ); +} + +//____________________________________________________________________________// + +void +config_file_iterator::set_parameter( rtti::id_t id, cstring value ) +{ + BOOST_RTTI_SWITCH( id ) { + BOOST_RTTI_CASE( cfg_detail::path_separators_t ) + assign_op( m_pimpl->m_path_separators , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::sl_comment_delimeter_t ) + assign_op( m_pimpl->m_sl_comment_delimeter , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::command_delimeter_t ) + assign_op( m_pimpl->m_command_delimeter , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::line_beak_t ) + assign_op( m_pimpl->m_line_beak , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::macro_ref_begin_t ) + assign_op( m_pimpl->m_macro_ref_begin , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::macro_ref_end_t ) + assign_op( m_pimpl->m_macro_ref_end , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::include_kw_t ) + assign_op( m_pimpl->m_include_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::define_kw_t ) + assign_op( m_pimpl->m_define_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::undef_kw_t ) + assign_op( m_pimpl->m_undef_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::ifdef_kw_t ) + assign_op( m_pimpl->m_ifdef_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::ifndef_kw_t ) + assign_op( m_pimpl->m_ifndef_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::else_kw_t ) + assign_op( m_pimpl->m_else_kw , value, 0 ); + BOOST_RTTI_CASE( cfg_detail::endif_kw_t ) + assign_op( m_pimpl->m_endif_kw , value, 0 ); + } +} + +//____________________________________________________________________________// + +void +config_file_iterator::set_parameter( rtti::id_t id, bool value ) +{ + BOOST_RTTI_SWITCH( id ) { + BOOST_RTTI_CASE( cfg_detail::trim_leading_spaces_t ) + m_pimpl->m_trim_leading_spaces = value; + BOOST_RTTI_CASE( cfg_detail::trim_trailing_spaces_t ) + m_pimpl->m_trim_trailing_spaces = value; + BOOST_RTTI_CASE( cfg_detail::skip_empty_lines_t ) + m_pimpl->m_skip_empty_lines = value; + BOOST_RTTI_CASE( cfg_detail::detect_missing_macro_t ) + m_pimpl->m_detect_missing_macro = value; + } +} + +//____________________________________________________________________________// + +void +config_file_iterator::set_parameter( rtti::id_t id, char_type value ) +{ + BOOST_RTTI_SWITCH( id ) { + BOOST_RTTI_CASE( cfg_detail::line_delimeter_t ) + m_pimpl->m_line_delimeter = value; + } +} + +//____________________________________________________________________________// + +void +config_file_iterator::set_parameter( rtti::id_t id, std::size_t value ) +{ + BOOST_RTTI_SWITCH( id ) { + BOOST_RTTI_CASE( cfg_detail::buffer_size_t ) + m_pimpl->m_buffer_size = value; + } +} + +//____________________________________________________________________________// + +} // namespace file + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:44 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // diff --git a/include/boost/test/utils/runtime/file/config_file_iterator.hpp b/include/boost/test/utils/runtime/file/config_file_iterator.hpp new file mode 100755 index 00000000..d55b8709 --- /dev/null +++ b/include/boost/test/utils/runtime/file/config_file_iterator.hpp @@ -0,0 +1,175 @@ +// (C) Copyright Gennadiy Rozental 2005. +// 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$ +// +// Description : flexible configuration file iterator definition +// *************************************************************************** + +#ifndef BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER +#define BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#include + +// Boost.Test +#include +#include +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +namespace file { + +// Public typedef +typedef std::pair location; + +// ************************************************************************** // +// ************** modifiers ************** // +// ************************************************************************** // + +namespace cfg_detail { + struct path_separators_t; + struct line_delimeter_t; + struct sl_comment_delimeter_t; + struct command_delimeter_t; + struct line_beak_t; + struct macro_ref_begin_t; + struct macro_ref_end_t; + struct include_kw_t; + struct define_kw_t; + struct undef_kw_t; + struct ifdef_kw_t; + struct ifndef_kw_t; + struct else_kw_t; + struct endif_kw_t; + + struct buffer_size_t; + + struct trim_leading_spaces_t; + struct trim_trailing_spaces_t; + struct skip_empty_lines_t; + struct detect_missing_macro_t; +} // namespace cfg_detail + +namespace { + +nfp::typed_keyword path_separators; +nfp::typed_keyword line_delimeter; +nfp::typed_keyword single_line_comment_delimeter; +nfp::typed_keyword command_delimeter; +nfp::typed_keyword line_beak; +nfp::typed_keyword macro_ref_begin; +nfp::typed_keyword macro_ref_end; +nfp::typed_keyword include_kw; +nfp::typed_keyword define_kw; +nfp::typed_keyword undef_kw; +nfp::typed_keyword ifdef_kw; +nfp::typed_keyword ifndef_kw; +nfp::typed_keyword else_kw; +nfp::typed_keyword endif_kw; + +nfp::typed_keyword buffer_size; + +nfp::typed_keyword trim_leading_spaces; +nfp::typed_keyword trim_trailing_spaces; +nfp::typed_keyword skip_empty_lines; +nfp::typed_keyword detect_missing_macro; + +} // local namespace + +// ************************************************************************** // +// ************** runtime::file::config_file_iterator ************** // +// ************************************************************************** // + +class config_file_iterator : public unit_test::input_iterator_facade { + typedef unit_test::input_iterator_facade base; +public: + // Public typedefs + typedef unit_test::callback1 command_handler; + + // Constructors + config_file_iterator() {} + explicit config_file_iterator( cstring file_name ) + { + construct(); + load( file_name ); + } + template + config_file_iterator( cstring file_name, Modifiers const& m ) + { + construct(); + m.apply_to( *this ); + load( file_name ); + } + explicit config_file_iterator( config_file_iterator const& rhs ) + : base( rhs ) + , m_pimpl( rhs.m_pimpl ) + { + rhs.m_valid = false; + } + + void operator=( config_file_iterator const& rhs ) + { + if( this == &rhs ) + return; + + (base&)(*this) = rhs; + m_pimpl = rhs.m_pimpl; + rhs.m_valid = false; + } // Assignment + + + // Access methods + location const& curr_location(); + void register_command_handler( cstring command_kw, command_handler const& ); + + // Parameters setters + void set_parameter( rtti::id_t, cstring ); + void set_parameter( rtti::id_t, bool ); + void set_parameter( rtti::id_t, char_type ); + void set_parameter( rtti::id_t, std::size_t ); + +private: + friend class unit_test::input_iterator_core_access; + + void construct(); + void load( cstring file_name ); + + // increment implementation + bool get(); + + // Data members + struct Impl; + shared_ptr m_pimpl; +}; + +} // namespace file + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:44 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_FILE_CONFIG_FILE_ITERATOR_HPP_062604GER diff --git a/include/boost/test/utils/runtime/fwd.hpp b/include/boost/test/utils/runtime/fwd.hpp new file mode 100755 index 00000000..8bc8f0b0 --- /dev/null +++ b/include/boost/test/utils/runtime/fwd.hpp @@ -0,0 +1,50 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : global framework level forward declaration +// *************************************************************************** + +#ifndef BOOST_RT_FWD_HPP_062604GER +#define BOOST_RT_FWD_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +class parameter; + +class argument; +typedef shared_ptr argument_ptr; +typedef shared_ptr const_argument_ptr; + +template class value_interpreter; +template class typed_argument; + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_FWD_HPP_062604GER diff --git a/include/boost/test/utils/runtime/interpret_argument_value.hpp b/include/boost/test/utils/runtime/interpret_argument_value.hpp new file mode 100755 index 00000000..ff7d2207 --- /dev/null +++ b/include/boost/test/utils/runtime/interpret_argument_value.hpp @@ -0,0 +1,172 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : default algorithms for string to specific type convertions +// *************************************************************************** + +#ifndef BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER +#define BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER + +// Boost.Runtime.Parameter +#include +#include + +// Boost.Test +#include +#include + +// Boost +#include +#include + +// STL +// !! could we eliminate these includes? +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::interpret_argument_value ************** // +// ************************************************************************** // +// returns true if source is used false otherwise + +// generic case +template +struct interpret_argument_value_impl { + static bool _( cstring source, boost::optional& res ) + { + BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl<" << typeid(T).name() << ">" ); + + res = lexical_cast( source ); + + BOOST_RT_PARAM_TRACE( "String " << source << " is interpreted as " << *res ); + return true; + } +}; + + +//____________________________________________________________________________// + +// dstring case +template<> +struct interpret_argument_value_impl { + static bool _( cstring source, boost::optional& res ) + { + BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl" ); + + res = dstring(); + assign_op( *res, source, 0 ); + + return true; + } +}; + +//____________________________________________________________________________// + +// cstring case +template<> +struct interpret_argument_value_impl { + static bool _( cstring source, boost::optional& res ) + { + BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl" ); + + res = source; + + return true; + } +}; + +//____________________________________________________________________________// + +// specialization for type bool +template<> +struct interpret_argument_value_impl { + static bool _( cstring source, boost::optional& res ) + { + BOOST_RT_PARAM_TRACE( "In interpret_argument_value_impl" ); + + static literal_cstring YES( BOOST_RT_PARAM_CSTRING_LITERAL( "YES" ) ); + static literal_cstring Y( BOOST_RT_PARAM_CSTRING_LITERAL( "Y" ) ); + static literal_cstring NO( BOOST_RT_PARAM_CSTRING_LITERAL( "NO" ) ); + static literal_cstring N( BOOST_RT_PARAM_CSTRING_LITERAL( "N" ) ); + static literal_cstring one( BOOST_RT_PARAM_CSTRING_LITERAL( "1" ) ); + static literal_cstring zero( BOOST_RT_PARAM_CSTRING_LITERAL( "0" ) ); + + source.trim(); + + if( case_ins_eq( source, YES ) || case_ins_eq( source, Y ) || case_ins_eq( source, one ) ) { + res = true; + return true; + } + else if( case_ins_eq( source, NO ) || case_ins_eq( source, N ) || case_ins_eq( source, zero ) ) { + res = false; + return true; + } + else { + res = true; + return false; + } + } +}; + +//____________________________________________________________________________// + +template +inline bool +interpret_argument_value( cstring source, boost::optional& res, long ) +{ + return interpret_argument_value_impl::_( source, res ); +} + +//____________________________________________________________________________// + +// specialization for list of values +template +inline bool +interpret_argument_value( cstring source, boost::optional >& res, int ) +{ + BOOST_RT_PARAM_TRACE( "In interpret_argument_value>" ); + + res = std::list(); + + while( !source.is_empty() ) { + // !! should we use token_iterator + cstring::iterator single_value_end = std::find( source.begin(), source.end(), BOOST_RT_PARAM_LITERAL( ',' ) ); + + boost::optional value; + interpret_argument_value( cstring( source.begin(), single_value_end ), value, 0 ); + + res->push_back( *value ); + + source.trim_left( single_value_end + 1 ); + } + + return true; +} + +//____________________________________________________________________________// + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_INTERPRET_ARGUMENT_VALUE_HPP_062604GER diff --git a/include/boost/test/utils/runtime/parameter.hpp b/include/boost/test/utils/runtime/parameter.hpp new file mode 100755 index 00000000..07a387d8 --- /dev/null +++ b/include/boost/test/utils/runtime/parameter.hpp @@ -0,0 +1,47 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : abstract interface for the formal parameter +// *************************************************************************** + +#ifndef BOOST_RT_PARAMETER_HPP_062604GER +#define BOOST_RT_PARAMETER_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::parameter ************** // +// ************************************************************************** // + +class parameter { +public: + virtual ~parameter() {} +}; + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_PARAMETER_HPP_062604GER diff --git a/include/boost/test/utils/runtime/trace.hpp b/include/boost/test/utils/runtime/trace.hpp new file mode 100755 index 00000000..f2d5d8dc --- /dev/null +++ b/include/boost/test/utils/runtime/trace.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : optional internal tracing +// *************************************************************************** + +#ifndef BOOST_RT_TRACE_HPP_062604GER +#define BOOST_RT_TRACE_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +#ifdef BOOST_RT_PARAM_DEBUG + +#include + +# define BOOST_RT_PARAM_TRACE( str ) std::cerr << str << std::endl +#else +# define BOOST_RT_PARAM_TRACE( str ) +#endif + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_TRACE_HPP_062604GER diff --git a/include/boost/test/utils/runtime/validation.hpp b/include/boost/test/utils/runtime/validation.hpp new file mode 100755 index 00000000..9d437b11 --- /dev/null +++ b/include/boost/test/utils/runtime/validation.hpp @@ -0,0 +1,91 @@ +// (C) Copyright Gennadiy Rozental 2005. +// Distributed under 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$ +// +// Description : defines exceptions and validation tools +// *************************************************************************** + +#ifndef BOOST_RT_VALIDATION_HPP_062604GER +#define BOOST_RT_VALIDATION_HPP_062604GER + +// Boost.Runtime.Parameter +#include + +// Boost.Test +#include + +// Boost +#include + +// STL +#ifdef BOOST_RT_PARAM_EXCEPTION_INHERIT_STD +#include +#endif + +namespace boost { + +namespace BOOST_RT_PARAM_NAMESPACE { + +// ************************************************************************** // +// ************** runtime::logic_error ************** // +// ************************************************************************** // + +class logic_error +#ifdef BOOST_RT_PARAM_EXCEPTION_INHERIT_STD +: public std::exception +#endif +{ + typedef shared_ptr dstring_ptr; +public: + // Constructor // !! could we eliminate shared_ptr + explicit logic_error( cstring msg ) : m_msg( new dstring( msg.begin(), msg.size() ) ) {} + ~logic_error() throw() {} + + dstring const& msg() const { return *m_msg; } + virtual char_type const* what() const throw() { return m_msg->c_str(); } + +private: + dstring_ptr m_msg; +}; + +// ************************************************************************** // +// ************** runtime::report_logic_error ************** // +// ************************************************************************** // + +inline void +report_logic_error( format_stream& msg ) +{ + throw BOOST_RT_PARAM_NAMESPACE::logic_error( msg.str() ); +} + +//____________________________________________________________________________// + +#define BOOST_RT_PARAM_REPORT_LOGIC_ERROR( msg ) \ + boost::BOOST_RT_PARAM_NAMESPACE::report_logic_error( format_stream().ref() << msg ) + +#define BOOST_RT_PARAM_VALIDATE_LOGIC( b, msg ) \ + if( b ) {} else BOOST_RT_PARAM_REPORT_LOGIC_ERROR( msg ) + +//____________________________________________________________________________// + +} // namespace BOOST_RT_PARAM_NAMESPACE + +} // namespace boost + +// ************************************************************************** // +// Revision History: +// +// $Log$ +// Revision 1.1 2005/04/12 06:42:42 rogeeff +// Runtime.Param library initial commit +// +// ************************************************************************** // + +#endif // BOOST_RT_VALIDATION_HPP_062604GER