- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

options.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
33
34 #ifndef __INCLUDE_MIST_OPTIONS__
35 #define __INCLUDE_MIST_OPTIONS__
36
37
38 #ifndef __INCLUDE_MIST_CONF_H__
39 #include "../config/mist_conf.h"
40 #endif
41
42 #include <iostream>
43 #include <vector>
44 #include <map>
45 #include <string>
46 #include <sstream>
47
48
49 // mist名前空間の始まり
50 _MIST_BEGIN
51
59
60
63 class options : public std::vector< std::string >
64 {
65 public:
66 typedef std::vector< std::string > base;
67
68 private:
70 struct arg
71 {
72 std::string name;
73 std::string comment;
74 std::string value;
75 bool has_value;
76 bool found;
77
79 arg( const std::string &aname = "", const std::string &text = "", const std::string &val = "", bool hasValue = false )
80 : name( aname ), comment( text ), value( val ), has_value( hasValue ), found( false )
81 {
82 }
83
85 arg( const arg &p ) : name( p.name ), comment( p.comment ), value( p.value ), has_value( p.has_value ), found( p.found )
86 {
87 }
88 };
89
90 std::string header_text;
91 std::string footer_text;
92 std::string program_name;
93 std::vector< std::string > option_list;
94 std::map< std::string, arg > args;
95
96 public:
98 options( const std::string header = "", const std::string footer = "" ) : header_text( header ), footer_text( footer )
99 {
100 }
101
103 options( const options &o ) : base( o ), program_name( o.program_name ), args( o.args )
104 {
105 }
106
107 protected:
109 bool __isset__( const std::string &name, std::string &val ) const
110 {
111 std::map< std::string, arg >::const_iterator ite = args.find( name );
112 if( ite != args.end( ) )
113 {
114 const arg &a = ite->second;
115 val = a.value;
116 return( true );
117 }
118 else
119 {
120 return( false );
121 }
122 }
123
124 public:
126 void add( const std::string &name, const std::string &comment )
127 {
128 option_list.push_back( name );
129 args[ name ] = arg( name, comment, "", false );
130 }
131
133 void add( const std::string &name, const std::string &comment, const std::string &default_value )
134 {
135 option_list.push_back( name );
136 args[ name ] = arg( name, comment, default_value, true );
137 }
138
140 void add( const std::string &name, const std::string &comment, int default_value )
141 {
142 char buff[ 50 ];
143 sprintf( buff, "%d", default_value );
144 option_list.push_back( name );
145 args[ name ] = arg( name, comment, buff, true );
146 }
147
149 void add( const std::string &name, const std::string &comment, double default_value )
150 {
151 char buff[ 50 ];
152 sprintf( buff, "%lf", default_value );
153 option_list.push_back( name );
154 args[ name ] = arg( name, comment, buff, true );
155 }
156
158 bool isset( const std::string &name ) const
159 {
160 std::map< std::string, arg >::const_iterator ite = args.find( name );
161 if( ite != args.end( ) )
162 {
163 const arg &a = ite->second;
164 return( a.found );
165 }
166 else
167 {
168 return( false );
169 }
170 }
171
173 const std::string get_string( const std::string &name ) const
174 {
175 std::string val;
176 if( __isset__( name, val ) )
177 {
178 return( val );
179 }
180 else
181 {
182 return( "" );
183 }
184 }
185
187 int get_int( const std::string &name ) const
188 {
189 std::string val;
190 if( __isset__( name, val ) )
191 {
192 return( atoi( val.c_str( ) ) );
193 }
194 else
195 {
196 return( 0 );
197 }
198 }
199
201 double get_double( const std::string &name ) const
202 {
203 std::string val;
204 if( __isset__( name, val ) )
205 {
206 return( atof( val.c_str( ) ) );
207 }
208 else
209 {
210 return( 0.0 );
211 }
212 }
213
214 public:
216 void show_help( ) const
217 {
218 std::stringstream sout;
219
220 // ヘッダ部分を出力する
221 sout << header_text << std::endl;
222
223 size_t max_len = 0;
224 for( size_t i = 0 ; i < option_list.size( ) ; i++ )
225 {
226 if( max_len < option_list[ i ].size( ) )
227 {
228 max_len = option_list[ i ].size( );
229 }
230 }
231
232 for( size_t i = 0 ; i < option_list.size( ) ; i++ )
233 {
234 std::map< std::string, arg >::const_iterator ite = args.find( option_list[ i ] );
235 if( ite != args.end( ) )
236 {
237 const arg &a = ite->second;
238
239 sout << "-";
240 sout << a.name;
241
242 for( size_t i = a.name.size( ) ; i < max_len + 3 ; i++ )
243 {
244 sout << ' ';
245 }
246
247 sout << a.comment;
248
249 if( a.has_value )
250 {
251 sout << "[" << a.value << "]";
252 }
253
254 if( a.found )
255 {
256 sout << "*";
257 }
258 sout << std::endl;
259 }
260 else
261 {
262 std::cerr << "Failed to parse options." << std::endl;
263 }
264 }
265
266 // フッタ部分を出力する
267 sout << footer_text << std::endl;
268
269 puts( sout.str( ).c_str( ) );
270 //std::cout << sout.str( ) << std::endl;
271 }
272
274 bool parse_args( int argc, char *argv[] )
275 {
276 program_name = argv[ 0 ];
277
278 bool ret = true;
279
280 for( int i = 1 ; i < argc ; i++ )
281 {
282 std::string option = argv[ i ];
283
284 if( option[ 0 ] != '-' )
285 {
286 base::push_back( option );
287 }
288 else
289 {
290 option = option.substr( 1 );
291
292 std::map< std::string, arg >::iterator ite = args.find( option );
293 if( ite != args.end( ) )
294 {
295 arg &a = ite->second;
296 a.found = true;
297
298 if( a.has_value )
299 {
300 if( i + 1 < argc && argv[ i + 1 ][ 0 ] != '-' )
301 {
302 a.value = argv[ i + 1 ];
303 i++;
304 }
305 else if( i + 1 < argc && strlen( argv[ i + 1 ] ) > 1 && argv[ i + 1 ][ 0 ] == '-' && '0' <= argv[ i + 1 ][ 1 ] && argv[ i + 1 ][ 1 ] <= '9' )
306 {
307 a.value = argv[ i + 1 ];
308 i++;
309 }
310 else
311 {
312 std::cerr << "Option \"" << option << "\" requires values." << std::endl;
313 ret = false;
314 }
315 }
316 }
317 else
318 {
319 std::cerr << "\"" << option << "\" is an unknown option." << std::endl;
320 ret = false;
321 }
322 }
323 }
324
325 if( !ret )
326 {
327 std::cerr << std::endl;
328 }
329
330 return( ret );
331 }
332 };
333
334 // mist名前空間の終わり
335 _MIST_END
336
338 // コマンドライン引数の解析グループの終わり
339
340 #endif // __INCLUDE_MIST_OPTIONS__
341