123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // (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 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 <boost/test/utils/runtime/trace.hpp>
- #include <boost/test/utils/runtime/cla/argv_traverser.hpp>
- // STL
- #include <memory>
- #include <cstring>
- #ifdef BOOST_NO_STDC_NAMESPACE
- namespace std { using ::memcpy; }
- #endif
- 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
- #endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
|