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名前空間の始まり
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 

Generated on Wed Nov 12 2014 19:44:21 for MIST by doxygen 1.8.1.2