Chris@16: // (C) Copyright Gennadiy Rozental 2005-2008. Chris@16: // Use, modification, and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/libs/test for the library home page. Chris@16: // Chris@16: // File : $RCSfile$ Chris@16: // Chris@101: // Version : $Revision$ Chris@16: // Chris@16: // Description : implements facility to hide input traversing details Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER Chris@16: #define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER Chris@16: Chris@16: // Boost.Runtime.Parameter Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: // STL Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_NO_STDC_NAMESPACE Chris@16: namespace std { using ::memcpy; } Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace BOOST_RT_PARAM_NAMESPACE { Chris@16: Chris@16: namespace cla { Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** runtime::cla::argv_traverser ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: BOOST_RT_PARAM_INLINE Chris@16: argv_traverser::argv_traverser() Chris@16: : p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) ) Chris@16: { Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::init( int argc, char_type** argv ) Chris@16: { Chris@16: for( int index = 1; index < argc; ++index ) { Chris@16: m_buffer += argv[index]; Chris@16: if( index != argc-1 ) Chris@16: m_buffer += BOOST_RT_PARAM_LITERAL( ' ' ); Chris@16: } Chris@16: Chris@16: m_remainder.reset( new char_type[m_buffer.size()+1] ); Chris@16: m_remainder_size = 0; Chris@16: m_work_buffer = m_buffer; Chris@16: m_commited_end = m_work_buffer.begin(); Chris@16: Chris@16: BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer ); Chris@16: Chris@16: next_token(); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::remainder( int& argc, char_type** argv ) Chris@16: { Chris@16: argc = 1; Chris@16: std::size_t pos = 0; Chris@16: while(pos < m_remainder_size ) { Chris@16: argv[argc++] = m_remainder.get() + pos; Chris@16: Chris@16: pos = std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size, Chris@16: BOOST_RT_PARAM_LITERAL( ' ' ) ) - m_remainder.get(); Chris@16: m_remainder[pos++] = BOOST_RT_PARAM_LITERAL( '\0' ); Chris@16: } Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE cstring Chris@16: argv_traverser::token() const Chris@16: { Chris@16: return m_token; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::next_token() Chris@16: { Chris@16: if( m_work_buffer.is_empty() ) Chris@16: return; Chris@16: Chris@16: m_work_buffer.trim_left( m_token.size() ); // skip remainder of current token Chris@16: Chris@16: if( m_work_buffer.size() != m_buffer.size() ) // !! is there a better way to identify first token Chris@16: m_work_buffer.trim_left( 1 ); // skip separator if not first token; Chris@16: Chris@16: m_token.assign( m_work_buffer.begin(), Chris@16: std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE cstring Chris@16: argv_traverser::input() const Chris@16: { Chris@16: return m_work_buffer; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::trim( std::size_t size ) Chris@16: { Chris@16: m_work_buffer.trim_left( size ); Chris@16: Chris@16: if( size <= m_token.size() ) Chris@16: m_token.trim_left( size ); Chris@16: else { Chris@16: m_token.assign( m_work_buffer.begin(), Chris@16: std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); Chris@16: } Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE bool Chris@16: argv_traverser::match_front( cstring str ) Chris@16: { Chris@16: return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE bool Chris@16: argv_traverser::match_front( char_type c ) Chris@16: { Chris@16: return first_char( m_work_buffer ) == c; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE bool Chris@16: argv_traverser::eoi() const Chris@16: { Chris@16: return m_work_buffer.is_empty(); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::commit() Chris@16: { Chris@16: m_commited_end = m_work_buffer.begin(); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE void Chris@16: argv_traverser::rollback() Chris@16: { Chris@16: m_work_buffer.assign( m_commited_end, m_work_buffer.end() ); Chris@16: m_token.assign( m_work_buffer.begin(), Chris@16: std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) ); Chris@16: Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE std::size_t Chris@16: argv_traverser::input_pos() const Chris@16: { Chris@16: return m_work_buffer.begin() - m_commited_end; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: BOOST_RT_PARAM_INLINE bool Chris@16: argv_traverser::handle_mismatch() Chris@16: { Chris@16: if( !p_ignore_mismatch ) Chris@16: return false; Chris@16: Chris@16: std::memcpy( m_remainder.get() + m_remainder_size, token().begin(), token().size() ); Chris@16: m_remainder_size += token().size(); Chris@16: m_remainder[m_remainder_size++] = p_separator; Chris@16: Chris@16: next_token(); Chris@16: commit(); Chris@16: Chris@16: return true; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: } // namespace cla Chris@16: Chris@16: } // namespace BOOST_RT_PARAM_NAMESPACE Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER