1
// (C) Copyright Gennadiy Rozental 2005-2008.
2
// Use, modification, and distribution are subject to the
3
// Boost Software License, Version 1.0. (See accompanying file
4
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
// See http://www.boost.org/libs/test for the library home page.
10
// Version : $Revision: 49312 $
12
// Description : implements facility to hide input traversing details
13
// ***************************************************************************
15
#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
16
#define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
18
// Boost.Runtime.Parameter
19
#include <boost/test/utils/runtime/trace.hpp>
21
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
27
#ifdef BOOST_NO_STDC_NAMESPACE
28
namespace std { using ::memcpy; }
33
namespace BOOST_RT_PARAM_NAMESPACE {
37
// ************************************************************************** //
38
// ************** runtime::cla::argv_traverser ************** //
39
// ************************************************************************** //
42
argv_traverser::argv_traverser()
43
: p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) )
47
//____________________________________________________________________________//
49
BOOST_RT_PARAM_INLINE void
50
argv_traverser::init( int argc, char_type** argv )
52
for( int index = 1; index < argc; ++index ) {
53
m_buffer += argv[index];
55
m_buffer += BOOST_RT_PARAM_LITERAL( ' ' );
58
m_remainder.reset( new char_type[m_buffer.size()+1] );
60
m_work_buffer = m_buffer;
61
m_commited_end = m_work_buffer.begin();
63
BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer );
68
//____________________________________________________________________________//
70
BOOST_RT_PARAM_INLINE void
71
argv_traverser::remainder( int& argc, char_type** argv )
75
while(pos < m_remainder_size ) {
76
argv[argc++] = m_remainder.get() + pos;
78
pos = std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size,
79
BOOST_RT_PARAM_LITERAL( ' ' ) ) - m_remainder.get();
80
m_remainder[pos++] = BOOST_RT_PARAM_LITERAL( '\0' );
84
//____________________________________________________________________________//
86
BOOST_RT_PARAM_INLINE cstring
87
argv_traverser::token() const
92
//____________________________________________________________________________//
94
BOOST_RT_PARAM_INLINE void
95
argv_traverser::next_token()
97
if( m_work_buffer.is_empty() )
100
m_work_buffer.trim_left( m_token.size() ); // skip remainder of current token
102
if( m_work_buffer.size() != m_buffer.size() ) // !! is there a better way to identify first token
103
m_work_buffer.trim_left( 1 ); // skip separator if not first token;
105
m_token.assign( m_work_buffer.begin(),
106
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
109
//____________________________________________________________________________//
111
BOOST_RT_PARAM_INLINE cstring
112
argv_traverser::input() const
114
return m_work_buffer;
117
//____________________________________________________________________________//
119
BOOST_RT_PARAM_INLINE void
120
argv_traverser::trim( std::size_t size )
122
m_work_buffer.trim_left( size );
124
if( size <= m_token.size() )
125
m_token.trim_left( size );
127
m_token.assign( m_work_buffer.begin(),
128
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
132
//____________________________________________________________________________//
134
BOOST_RT_PARAM_INLINE bool
135
argv_traverser::match_front( cstring str )
137
return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str;
140
//____________________________________________________________________________//
142
BOOST_RT_PARAM_INLINE bool
143
argv_traverser::match_front( char_type c )
145
return first_char( m_work_buffer ) == c;
148
//____________________________________________________________________________//
150
BOOST_RT_PARAM_INLINE bool
151
argv_traverser::eoi() const
153
return m_work_buffer.is_empty();
156
//____________________________________________________________________________//
158
BOOST_RT_PARAM_INLINE void
159
argv_traverser::commit()
161
m_commited_end = m_work_buffer.begin();
164
//____________________________________________________________________________//
166
BOOST_RT_PARAM_INLINE void
167
argv_traverser::rollback()
169
m_work_buffer.assign( m_commited_end, m_work_buffer.end() );
170
m_token.assign( m_work_buffer.begin(),
171
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
175
//____________________________________________________________________________//
177
BOOST_RT_PARAM_INLINE std::size_t
178
argv_traverser::input_pos() const
180
return m_work_buffer.begin() - m_commited_end;
183
//____________________________________________________________________________//
185
BOOST_RT_PARAM_INLINE bool
186
argv_traverser::handle_mismatch()
188
if( !p_ignore_mismatch )
191
std::memcpy( m_remainder.get() + m_remainder_size, token().begin(), token().size() );
192
m_remainder_size += token().size();
193
m_remainder[m_remainder_size++] = p_separator;
201
//____________________________________________________________________________//
205
} // namespace BOOST_RT_PARAM_NAMESPACE
209
#endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER