parser.ipp
来自「Boost provides free peer-reviewed portab」· IPP 代码 · 共 262 行
IPP
262 行
// (C) Copyright Gennadiy Rozental 2005-2008.// Use, modification, and distribution are subject to the// Boost Software License, Version 1.0. (See accompanying file// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)// See http://www.boost.org/libs/test for the library home page.//// File : $RCSfile$//// Version : $Revision: 49312 $//// Description : implements 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 <boost/test/utils/runtime/config.hpp>#include <boost/test/utils/runtime/trace.hpp>#include <boost/test/utils/runtime/argument.hpp>#include <boost/test/utils/runtime/cla/argv_traverser.hpp>#include <boost/test/utils/runtime/cla/parameter.hpp>#include <boost/test/utils/runtime/cla/modifier.hpp>#include <boost/test/utils/runtime/cla/validation.hpp>#include <boost/test/utils/runtime/cla/parser.hpp>// Boost.Test#include <boost/test/utils/basic_cstring/io.hpp>#include <boost/test/utils/foreach.hpp>// Boost#include <boost/lexical_cast.hpp>namespace boost {namespace BOOST_RT_PARAM_NAMESPACE {namespace cla {// ************************************************************************** //// ************** runtime::cla::parser ************** //// ************************************************************************** //BOOST_RT_PARAM_INLINEparser::parser( cstring program_name ){ assign_op( m_program_name, program_name, 0 );}//____________________________________________________________________________//BOOST_RT_PARAM_INLINE parser::param_iteratorparser::first_param() const{ return m_parameters.begin();}//____________________________________________________________________________//BOOST_RT_PARAM_INLINE parser::param_iteratorparser::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 voidparser::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_ptrparser::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 cstringparser::get( cstring string_id ) const{ return get<cstring>( string_id );}//____________________________________________________________________________//BOOST_RT_PARAM_INLINE voidparser::usage( out_stream& ostr ){ if( m_program_name.empty() ) assign_op( m_program_name, BOOST_RT_PARAM_CSTRING_LITERAL( "<program>" ), 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 voidparser::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#endif // BOOST_RT_CLA_PARSER_IPP_062904GER
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?