stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// 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_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
|
||||
#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
|
||||
|
||||
// Boost.Test Runtime parameters
|
||||
#include <boost/test/utils/runtime/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace runtime {
|
||||
namespace cla {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** runtime::cla::argv_traverser ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class argv_traverser {
|
||||
typedef char const** argv_type;
|
||||
public:
|
||||
/// Constructs traverser based on argc/argv pair
|
||||
/// argv is taken "by reference" and later can be
|
||||
/// updated in remainder method
|
||||
argv_traverser( int argc, argv_type argv )
|
||||
: m_argc( argc )
|
||||
, m_curr_token( 0 )
|
||||
, m_token_size( 0 )
|
||||
, m_argv( argv )
|
||||
{
|
||||
// save program name
|
||||
save_token();
|
||||
}
|
||||
|
||||
/// Returns new argc
|
||||
int remainder()
|
||||
{
|
||||
return m_argc;
|
||||
}
|
||||
|
||||
/// Returns true, if we reached end on input
|
||||
bool eoi() const
|
||||
{
|
||||
return m_curr_token == m_argc;
|
||||
}
|
||||
|
||||
/// Returns current token in the input
|
||||
cstring current_token()
|
||||
{
|
||||
if( eoi() )
|
||||
return cstring();
|
||||
|
||||
return cstring( m_argv[m_curr_token], m_token_size );
|
||||
}
|
||||
|
||||
/// Saves current token for remainder
|
||||
void save_token()
|
||||
{
|
||||
++m_curr_token;
|
||||
|
||||
if( !eoi() )
|
||||
m_token_size = ::strlen( m_argv[m_curr_token] );
|
||||
}
|
||||
|
||||
/// Commit current token and iterate to next one
|
||||
void next_token()
|
||||
{
|
||||
if( !eoi() ) {
|
||||
for( std::size_t i = m_curr_token; i < m_argc-1; ++i )
|
||||
m_argv[i] = m_argv[i + 1];
|
||||
|
||||
--m_argc;
|
||||
|
||||
m_token_size = ::strlen( m_argv[m_curr_token] );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Data members
|
||||
std::size_t m_argc; // total number of arguments
|
||||
std::size_t m_curr_token; // current token index in argv
|
||||
std::size_t m_token_size; // current token size
|
||||
argv_type m_argv; // all arguments
|
||||
};
|
||||
|
||||
} // namespace cla
|
||||
} // namespace runtime
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
|
||||
@@ -0,0 +1,522 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// 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
|
||||
//!@brief CLA parser
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
|
||||
#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
|
||||
|
||||
// Boost.Test Runtime parameters
|
||||
#include <boost/test/utils/runtime/argument.hpp>
|
||||
#include <boost/test/utils/runtime/modifier.hpp>
|
||||
#include <boost/test/utils/runtime/parameter.hpp>
|
||||
|
||||
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/utils/foreach.hpp>
|
||||
#include <boost/test/utils/algorithm.hpp>
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
|
||||
#include <boost/algorithm/cxx11/all_of.hpp> // !! ?? unnecessary after cxx11
|
||||
|
||||
// STL
|
||||
// !! ?? #include <unordered_set>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace runtime {
|
||||
namespace cla {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** runtime::cla::parameter_trie ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace rt_cla_detail {
|
||||
|
||||
struct parameter_trie;
|
||||
typedef shared_ptr<parameter_trie> parameter_trie_ptr;
|
||||
typedef std::map<char,parameter_trie_ptr> trie_per_char;
|
||||
typedef std::vector<boost::reference_wrapper<parameter_cla_id const> > param_cla_id_list;
|
||||
|
||||
struct parameter_trie {
|
||||
parameter_trie() : m_has_final_candidate( false ) {}
|
||||
|
||||
/// If subtrie corresponding to the char c exists returns it otherwise creates new
|
||||
parameter_trie_ptr make_subtrie( char c )
|
||||
{
|
||||
trie_per_char::const_iterator it = m_subtrie.find( c );
|
||||
|
||||
if( it == m_subtrie.end() )
|
||||
it = m_subtrie.insert( std::make_pair( c, parameter_trie_ptr( new parameter_trie ) ) ).first;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/// Creates series of sub-tries per characters in a string
|
||||
parameter_trie_ptr make_subtrie( cstring s )
|
||||
{
|
||||
parameter_trie_ptr res;
|
||||
|
||||
BOOST_TEST_FOREACH( char, c, s )
|
||||
res = (res ? res->make_subtrie( c ) : make_subtrie( c ));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Registers candidate parameter for this subtrie. If final, it needs to be unique
|
||||
void add_candidate_id( parameter_cla_id const& param_id, basic_param_ptr param_candidate, bool final )
|
||||
{
|
||||
BOOST_TEST_I_ASSRT( !m_has_final_candidate && (!final || m_id_candidates.empty()),
|
||||
conflicting_param() << "Parameter cla id " << param_id.m_tag << " conflicts with the "
|
||||
<< "parameter cla id " << m_id_candidates.back().get().m_tag );
|
||||
|
||||
m_has_final_candidate = final;
|
||||
m_id_candidates.push_back( ref(param_id) );
|
||||
|
||||
if( m_id_candidates.size() == 1 )
|
||||
m_param_candidate = param_candidate;
|
||||
else
|
||||
m_param_candidate.reset();
|
||||
}
|
||||
|
||||
/// Gets subtrie for specified char if present or nullptr otherwise
|
||||
parameter_trie_ptr get_subtrie( char c ) const
|
||||
{
|
||||
trie_per_char::const_iterator it = m_subtrie.find( c );
|
||||
|
||||
return it != m_subtrie.end() ? it->second : parameter_trie_ptr();
|
||||
}
|
||||
|
||||
// Data members
|
||||
trie_per_char m_subtrie;
|
||||
param_cla_id_list m_id_candidates;
|
||||
basic_param_ptr m_param_candidate;
|
||||
bool m_has_final_candidate;
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** runtime::cla::report_foreing_token ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
static void
|
||||
report_foreing_token( cstring program_name, cstring token )
|
||||
{
|
||||
std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
|
||||
<< " and should be placed after all Boost.Test arguments and the -- separator.\n"
|
||||
<< " For example: " << program_name << " --random -- " << token << "\n";
|
||||
}
|
||||
|
||||
} // namespace rt_cla_detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** runtime::cla::parser ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class parser {
|
||||
public:
|
||||
/// Initializes a parser and builds internal trie representation used for
|
||||
/// parsing based on the supplied parameters
|
||||
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
|
||||
template<typename Modifiers=nfp::no_params_type>
|
||||
parser( parameters_store const& parameters, Modifiers const& m = nfp::no_params )
|
||||
#else
|
||||
template<typename Modifiers>
|
||||
parser( parameters_store const& parameters, Modifiers const& m )
|
||||
#endif
|
||||
{
|
||||
nfp::opt_assign( m_end_of_param_indicator, m, end_of_params );
|
||||
nfp::opt_assign( m_negation_prefix, m, negation_prefix );
|
||||
|
||||
BOOST_TEST_I_ASSRT( algorithm::all_of( m_end_of_param_indicator.begin(),
|
||||
m_end_of_param_indicator.end(),
|
||||
parameter_cla_id::valid_prefix_char ),
|
||||
invalid_cla_id() << "End of parameters indicator can only consist of prefix characters." );
|
||||
|
||||
BOOST_TEST_I_ASSRT( algorithm::all_of( m_negation_prefix.begin(),
|
||||
m_negation_prefix.end(),
|
||||
parameter_cla_id::valid_name_char ),
|
||||
invalid_cla_id() << "Negation prefix can only consist of prefix characters." );
|
||||
|
||||
build_trie( parameters );
|
||||
}
|
||||
|
||||
// input processing method
|
||||
int
|
||||
parse( int argc, char** argv, runtime::arguments_store& res )
|
||||
{
|
||||
// save program name for help message
|
||||
m_program_name = argv[0];
|
||||
cstring path_sep( "\\/" );
|
||||
|
||||
cstring::iterator it = unit_test::utils::find_last_of( m_program_name.begin(), m_program_name.end(),
|
||||
path_sep.begin(), path_sep.end() );
|
||||
if( it != m_program_name.end() )
|
||||
m_program_name.trim_left( it + 1 );
|
||||
|
||||
// Set up the traverser
|
||||
argv_traverser tr( argc, (char const**)argv );
|
||||
|
||||
// Loop till we reach end of input
|
||||
while( !tr.eoi() ) {
|
||||
cstring curr_token = tr.current_token();
|
||||
|
||||
cstring prefix;
|
||||
cstring name;
|
||||
cstring value_separator;
|
||||
bool negative_form = false;
|
||||
|
||||
// Perform format validations and split the argument into prefix, name and separator
|
||||
// False return value indicates end of params indicator is met
|
||||
if( !validate_token_format( curr_token, prefix, name, value_separator, negative_form ) ) {
|
||||
// get rid of "end of params" token
|
||||
tr.next_token();
|
||||
break;
|
||||
}
|
||||
|
||||
// Locate trie corresponding to found prefix and skip it in the input
|
||||
trie_ptr curr_trie = m_param_trie[prefix];
|
||||
|
||||
if( !curr_trie ) {
|
||||
// format_error() << "Unrecognized parameter prefix in the argument " << tr.current_token()
|
||||
rt_cla_detail::report_foreing_token( m_program_name, curr_token );
|
||||
tr.save_token();
|
||||
continue;
|
||||
}
|
||||
|
||||
curr_token.trim_left( prefix.size() );
|
||||
|
||||
// Locate parameter based on a name and skip it in the input
|
||||
locate_result locate_res = locate_parameter( curr_trie, name, curr_token );
|
||||
parameter_cla_id const& found_id = locate_res.first;
|
||||
basic_param_ptr found_param = locate_res.second;
|
||||
|
||||
if( negative_form ) {
|
||||
BOOST_TEST_I_ASSRT( found_id.m_negatable,
|
||||
format_error( found_param->p_name )
|
||||
<< "Parameter tag " << found_id.m_tag << " is not negatable." );
|
||||
|
||||
curr_token.trim_left( m_negation_prefix.size() );
|
||||
}
|
||||
|
||||
curr_token.trim_left( name.size() );
|
||||
|
||||
cstring value;
|
||||
|
||||
// Skip validations if parameter has optional value and we are at the end of token
|
||||
if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
|
||||
// Validate and skip value separator in the input
|
||||
BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
|
||||
format_error( found_param->p_name )
|
||||
<< "Invalid separator for the parameter "
|
||||
<< found_param->p_name
|
||||
<< " in the argument " << tr.current_token() );
|
||||
|
||||
curr_token.trim_left( value_separator.size() );
|
||||
|
||||
// Deduce value source
|
||||
value = curr_token;
|
||||
if( value.is_empty() ) {
|
||||
tr.next_token();
|
||||
value = tr.current_token();
|
||||
}
|
||||
|
||||
BOOST_TEST_I_ASSRT( !value.is_empty(),
|
||||
format_error( found_param->p_name )
|
||||
<< "Missing an argument value for the parameter "
|
||||
<< found_param->p_name
|
||||
<< " in the argument " << tr.current_token() );
|
||||
}
|
||||
|
||||
// Validate against argument duplication
|
||||
BOOST_TEST_I_ASSRT( !res.has( found_param->p_name ) || found_param->p_repeatable,
|
||||
duplicate_arg( found_param->p_name )
|
||||
<< "Duplicate argument value for the parameter "
|
||||
<< found_param->p_name
|
||||
<< " in the argument " << tr.current_token() );
|
||||
|
||||
// Produce argument value
|
||||
found_param->produce_argument( value, negative_form, res );
|
||||
|
||||
tr.next_token();
|
||||
}
|
||||
|
||||
// generate the remainder and return it's size
|
||||
return tr.remainder();
|
||||
}
|
||||
|
||||
// help/usage/version
|
||||
void
|
||||
version( std::ostream& ostr )
|
||||
{
|
||||
ostr << "Boost.Test module ";
|
||||
|
||||
#if defined(BOOST_TEST_MODULE)
|
||||
// we do not want to refer to the master test suite there
|
||||
ostr << '\'' << BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ) << "' ";
|
||||
#endif
|
||||
|
||||
ostr << "in executable '" << m_program_name << "'\n";
|
||||
ostr << "Compiled from Boost version "
|
||||
<< BOOST_VERSION/100000 << "."
|
||||
<< BOOST_VERSION/100 % 1000 << "."
|
||||
<< BOOST_VERSION % 100 ;
|
||||
ostr << " with ";
|
||||
#if defined(BOOST_TEST_INCLUDED)
|
||||
ostr << "single header inclusion of";
|
||||
#elif defined(BOOST_TEST_DYN_LINK)
|
||||
ostr << "dynamic linking to";
|
||||
#else
|
||||
ostr << "static linking to";
|
||||
#endif
|
||||
ostr << " Boost.Test\n";
|
||||
ostr << "- Compiler: " << BOOST_COMPILER << '\n'
|
||||
<< "- Platform: " << BOOST_PLATFORM << '\n'
|
||||
<< "- STL : " << BOOST_STDLIB;
|
||||
ostr << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
usage( std::ostream& ostr, cstring param_name = cstring() )
|
||||
{
|
||||
if( !param_name.is_empty() ) {
|
||||
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
|
||||
param->usage( ostr, m_negation_prefix );
|
||||
}
|
||||
else {
|
||||
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << m_end_of_param_indicator << " [custom test module argument]...";
|
||||
ostr << "\n";
|
||||
}
|
||||
|
||||
ostr << "\nFor detailed help on Boost.Test parameters use:\n"
|
||||
<< " " << m_program_name << " --help\n"
|
||||
<< "or\n"
|
||||
<< " " << m_program_name << " --help=<parameter name>\n";
|
||||
}
|
||||
|
||||
void
|
||||
help( std::ostream& ostr, parameters_store const& parameters, cstring param_name )
|
||||
{
|
||||
if( !param_name.is_empty() ) {
|
||||
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
|
||||
param->help( ostr, m_negation_prefix );
|
||||
return;
|
||||
}
|
||||
|
||||
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << m_end_of_param_indicator << " [custom test module argument]...";
|
||||
|
||||
ostr << "\n\nBoost.Test arguments correspond to parameters listed below. "
|
||||
"All parameters are optional. You can use specify parameter value either "
|
||||
"as a command line argument or as a value of corresponding environment "
|
||||
"variable. In case if argument for the same parameter is specified in both "
|
||||
"places, command line is taking precedence. Command line argument format "
|
||||
"supports parameter name guessing, so you can use any unambiguous "
|
||||
"prefix to identify a parameter.";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << " All the arguments after the " << m_end_of_param_indicator << " are ignored by the Boost.Test.";
|
||||
|
||||
ostr << "\n\nBoost.Test supports following parameters:\n";
|
||||
|
||||
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
|
||||
basic_param_ptr param = v.second;
|
||||
|
||||
param->usage( ostr, m_negation_prefix );
|
||||
}
|
||||
|
||||
ostr << "\nUse --help=<parameter name> to display detailed help for specific parameter.\n";
|
||||
}
|
||||
|
||||
private:
|
||||
typedef rt_cla_detail::parameter_trie_ptr trie_ptr;
|
||||
typedef rt_cla_detail::trie_per_char trie_per_char;
|
||||
typedef std::map<cstring,trie_ptr> str_to_trie;
|
||||
|
||||
void
|
||||
build_trie( parameters_store const& parameters )
|
||||
{
|
||||
// Iterate over all parameters
|
||||
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
|
||||
basic_param_ptr param = v.second;
|
||||
|
||||
// Register all parameter's ids in trie.
|
||||
BOOST_TEST_FOREACH( parameter_cla_id const&, id, param->cla_ids() ) {
|
||||
// This is the trie corresponding to the prefix.
|
||||
trie_ptr next_trie = m_param_trie[id.m_prefix];
|
||||
if( !next_trie )
|
||||
next_trie = m_param_trie[id.m_prefix] = trie_ptr( new rt_cla_detail::parameter_trie );
|
||||
|
||||
// Build the trie, by following name's characters
|
||||
// and register this parameter as candidate on each level
|
||||
for( size_t index = 0; index < id.m_tag.size(); ++index ) {
|
||||
next_trie = next_trie->make_subtrie( id.m_tag[index] );
|
||||
|
||||
next_trie->add_candidate_id( id, param, index == (id.m_tag.size() - 1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
validate_token_format( cstring token, cstring& prefix, cstring& name, cstring& separator, bool& negative_form )
|
||||
{
|
||||
// Match prefix
|
||||
cstring::iterator it = token.begin();
|
||||
while( it != token.end() && parameter_cla_id::valid_prefix_char( *it ) )
|
||||
++it;
|
||||
|
||||
prefix.assign( token.begin(), it );
|
||||
|
||||
if( prefix.empty() )
|
||||
return true;
|
||||
|
||||
// Match name
|
||||
while( it != token.end() && parameter_cla_id::valid_name_char( *it ) )
|
||||
++it;
|
||||
|
||||
name.assign( prefix.end(), it );
|
||||
|
||||
if( name.empty() ) {
|
||||
if( prefix == m_end_of_param_indicator )
|
||||
return false;
|
||||
|
||||
BOOST_TEST_I_THROW( format_error() << "Invalid format for an actual argument " << token );
|
||||
}
|
||||
|
||||
// Match value separator
|
||||
while( it != token.end() && parameter_cla_id::valid_separator_char( *it ) )
|
||||
++it;
|
||||
|
||||
separator.assign( name.end(), it );
|
||||
|
||||
// Match negation prefix
|
||||
negative_form = !m_negation_prefix.empty() && ( name.substr( 0, m_negation_prefix.size() ) == m_negation_prefix );
|
||||
if( negative_form )
|
||||
name.trim_left( m_negation_prefix.size() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// C++03: cannot have references as types
|
||||
typedef std::pair<parameter_cla_id, basic_param_ptr> locate_result;
|
||||
|
||||
locate_result
|
||||
locate_parameter( trie_ptr curr_trie, cstring name, cstring token )
|
||||
{
|
||||
std::vector<trie_ptr> typo_candidates;
|
||||
std::vector<trie_ptr> next_typo_candidates;
|
||||
trie_ptr next_trie;
|
||||
|
||||
BOOST_TEST_FOREACH( char, c, name ) {
|
||||
if( curr_trie ) {
|
||||
// locate next subtrie corresponding to the char
|
||||
next_trie = curr_trie->get_subtrie( c );
|
||||
|
||||
if( next_trie )
|
||||
curr_trie = next_trie;
|
||||
else {
|
||||
// Initiate search for typo candicates. We will account for 'wrong char' typo
|
||||
// 'missing char' typo and 'extra char' typo
|
||||
BOOST_TEST_FOREACH( trie_per_char::value_type const&, typo_cand, curr_trie->m_subtrie ) {
|
||||
// 'wrong char' typo
|
||||
typo_candidates.push_back( typo_cand.second );
|
||||
|
||||
// 'missing char' typo
|
||||
if( (next_trie = typo_cand.second->get_subtrie( c )) )
|
||||
typo_candidates.push_back( next_trie );
|
||||
}
|
||||
|
||||
// 'extra char' typo
|
||||
typo_candidates.push_back( curr_trie );
|
||||
|
||||
curr_trie.reset();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// go over existing typo candidates and see if they are still viable
|
||||
BOOST_TEST_FOREACH( trie_ptr, typo_cand, typo_candidates ) {
|
||||
trie_ptr next_typo_cand = typo_cand->get_subtrie( c );
|
||||
|
||||
if( next_typo_cand )
|
||||
next_typo_candidates.push_back( next_typo_cand );
|
||||
}
|
||||
|
||||
next_typo_candidates.swap( typo_candidates );
|
||||
next_typo_candidates.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if( !curr_trie ) {
|
||||
std::vector<cstring> typo_candidate_names;
|
||||
std::set<parameter_cla_id const*> unique_typo_candidate; // !! ?? unordered_set
|
||||
typo_candidate_names.reserve( typo_candidates.size() );
|
||||
// !! ?? unique_typo_candidate.reserve( typo_candidates.size() );
|
||||
|
||||
BOOST_TEST_FOREACH( trie_ptr, trie_cand, typo_candidates ) {
|
||||
// avoid ambiguos candidate trie
|
||||
if( trie_cand->m_id_candidates.size() > 1 )
|
||||
continue;
|
||||
|
||||
BOOST_TEST_FOREACH( parameter_cla_id const&, param_cand, trie_cand->m_id_candidates ) {
|
||||
if( !unique_typo_candidate.insert( ¶m_cand ).second )
|
||||
continue;
|
||||
|
||||
typo_candidate_names.push_back( param_cand.m_tag );
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_TEST_I_THROW( unrecognized_param( std::move(typo_candidate_names) )
|
||||
<< "An unrecognized parameter in the argument "
|
||||
<< token );
|
||||
#else
|
||||
BOOST_TEST_I_THROW( unrecognized_param( typo_candidate_names )
|
||||
<< "An unrecognized parameter in the argument "
|
||||
<< token );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( curr_trie->m_id_candidates.size() > 1 ) {
|
||||
std::vector<cstring> amb_names;
|
||||
BOOST_TEST_FOREACH( parameter_cla_id const&, param_id, curr_trie->m_id_candidates )
|
||||
amb_names.push_back( param_id.m_tag );
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
BOOST_TEST_I_THROW( ambiguous_param( std::move( amb_names ) )
|
||||
<< "An ambiguous parameter name in the argument " << token );
|
||||
#else
|
||||
BOOST_TEST_I_THROW( ambiguous_param( amb_names )
|
||||
<< "An ambiguous parameter name in the argument " << token );
|
||||
#endif
|
||||
}
|
||||
|
||||
return locate_result( curr_trie->m_id_candidates.back().get(), curr_trie->m_param_candidate );
|
||||
}
|
||||
|
||||
// Data members
|
||||
cstring m_program_name;
|
||||
std::string m_end_of_param_indicator;
|
||||
std::string m_negation_prefix;
|
||||
str_to_trie m_param_trie;
|
||||
};
|
||||
|
||||
} // namespace cla
|
||||
} // namespace runtime
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
|
||||
Reference in New Issue
Block a user