source: NonGTP/Boost/boost/test/utils/runtime/cla/argv_traverser.ipp @ 857

Revision 857, 6.4 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Gennadiy Rozental 2005.
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)
5
6//  See http://www.boost.org/libs/test for the library home page.
7//
8//  File        : $RCSfile: argv_traverser.ipp,v $
9//
10//  Version     : $Revision: 1.3 $
11//
12//  Description : implements facility to hide input traversing details
13// ***************************************************************************
14
15#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
16#define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
17
18// Boost.Runtime.Parameter
19#include <boost/test/utils/runtime/trace.hpp>
20
21#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
22
23// STL
24#include <memory>
25#include <cstring>
26
27#ifdef BOOST_NO_STDC_NAMESPACE
28namespace std { using ::memcpy; }
29#endif
30
31namespace boost {
32
33namespace BOOST_RT_PARAM_NAMESPACE {
34
35namespace cla {
36
37// ************************************************************************** //
38// **************          runtime::cla::argv_traverser        ************** //
39// ************************************************************************** //
40
41BOOST_RT_PARAM_INLINE
42argv_traverser::argv_traverser()
43: p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) )
44{
45}
46
47//____________________________________________________________________________//
48
49BOOST_RT_PARAM_INLINE void
50argv_traverser::init( int argc, char_type** argv )
51{
52    for( int index = 1; index < argc; ++index ) {
53        m_buffer += argv[index];
54        if( index != argc-1 )
55            m_buffer += BOOST_RT_PARAM_LITERAL( ' ' );
56    }
57
58    m_remainder.reset( new char_type[m_buffer.size()+1] );
59    m_remainder_size    = 0;
60    m_work_buffer       = m_buffer;
61    m_commited_end      = m_work_buffer.begin();
62
63    BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer );
64
65    next_token();
66}
67
68//____________________________________________________________________________//
69
70BOOST_RT_PARAM_INLINE void
71argv_traverser::remainder( int& argc, char_type** argv )
72{
73    argc = 1;
74    std::size_t pos = 0;
75    while(pos < m_remainder_size ) {
76        argv[argc++] = m_remainder.get() + pos;
77
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' );
81    }
82}
83
84//____________________________________________________________________________//
85
86BOOST_RT_PARAM_INLINE cstring
87argv_traverser::token() const
88{
89    return m_token;
90}
91
92//____________________________________________________________________________//
93
94BOOST_RT_PARAM_INLINE void
95argv_traverser::next_token()
96{
97    if( m_work_buffer.is_empty() )
98        return;
99
100    m_work_buffer.trim_left( m_token.size() ); // skip remainder of current token
101
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;
104
105    m_token.assign( m_work_buffer.begin(),
106                    std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
107}
108
109//____________________________________________________________________________//
110
111BOOST_RT_PARAM_INLINE cstring
112argv_traverser::input() const
113{
114    return m_work_buffer;
115}
116
117//____________________________________________________________________________//
118
119BOOST_RT_PARAM_INLINE void
120argv_traverser::trim( std::size_t size )
121{
122    m_work_buffer.trim_left( size );
123
124    if( size <= m_token.size() )
125        m_token.trim_left( size );
126    else {
127        m_token.assign( m_work_buffer.begin(),
128                        std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
129    }
130}
131
132//____________________________________________________________________________//
133
134BOOST_RT_PARAM_INLINE bool
135argv_traverser::match_front( cstring str )
136{
137    return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str;
138}
139
140//____________________________________________________________________________//
141
142BOOST_RT_PARAM_INLINE bool
143argv_traverser::match_front( char_type c )
144{
145    return first_char( m_work_buffer ) == c;
146}
147
148//____________________________________________________________________________//
149
150BOOST_RT_PARAM_INLINE bool
151argv_traverser::eoi() const
152{
153    return m_work_buffer.is_empty();
154}
155
156//____________________________________________________________________________//
157
158BOOST_RT_PARAM_INLINE void
159argv_traverser::commit()
160{
161    m_commited_end = m_work_buffer.begin();
162}
163
164//____________________________________________________________________________//
165
166BOOST_RT_PARAM_INLINE void
167argv_traverser::rollback()
168{
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 ) );
172
173}
174
175//____________________________________________________________________________//
176
177BOOST_RT_PARAM_INLINE std::size_t
178argv_traverser::input_pos() const
179{
180    return m_work_buffer.begin() - m_commited_end;
181}
182
183//____________________________________________________________________________//
184
185BOOST_RT_PARAM_INLINE bool
186argv_traverser::handle_mismatch()
187{
188    if( !p_ignore_mismatch )
189        return false;
190
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;
194
195    next_token();
196    commit();
197
198    return true;
199}
200
201//____________________________________________________________________________//
202
203} // namespace cla
204
205} // namespace BOOST_RT_PARAM_NAMESPACE
206
207} // namespace boost
208
209// ************************************************************************** //
210//   Revision History:
211//
212//   $Log: argv_traverser.ipp,v $
213//   Revision 1.3  2005/05/05 05:55:45  rogeeff
214//   portability fixes
215//
216//   Revision 1.2  2005/05/03 05:02:49  rogeeff
217//   como fixes
218//
219//   Revision 1.1  2005/04/12 06:42:43  rogeeff
220//   Runtime.Param library initial commit
221//
222// ************************************************************************** //
223
224#endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
Note: See TracBrowser for help on using the repository browser.