VR-Link API Documentation for DIS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cmdMultiArg.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * file: MultiArg.h
4  *
5  * Copyright (c) 2003, Michael E. Smoot .
6  * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
7  * All rights reverved.
8  *
9  * See the file COPYING in the top directory of this distribution for
10  * more information.
11  *
12  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
13  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18  * DEALINGS IN THE SOFTWARE.
19  *
20  *****************************************************************************/
21 
22 
23 #ifndef DtCmdLine_MULTIPLE_ARGUMENT_H
24 #define DtCmdLine_MULTIPLE_ARGUMENT_H
25 
29 
30 #include <cstdio>
31 
32 #include <string>
33 #include <vector>
34 
35 #include "cmdArg.h"
36 
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #else
40 #define HAVE_SSTREAM
41 
42 #endif
43 
44 #if defined(HAVE_SSTREAM)
45 #include <sstream>
46 #elif defined(HAVE_STRSTREAM)
47 #include <strstream>
48 #else
49 #error "Need a stringstream (sstream or strstream) to compile!"
50 #endif
51 
52 #ifdef DtUSE_UTILITIES_NAMESPACE
53 namespace DtUSE_UTILITIES_NAMESPACE
54 {
55 #endif
56 
57 namespace DtCmdLine {
58 
59  template<class T> class MultiArg;
60 
61  namespace MULTI_ARG_HELPER {
62 
64 
74 
75  template<class T>
77  {
78  friend class MultiArg<T>;
79 
80  private:
81 
86  std::vector<T> &_values;
87 
92  ValueExtractor(std::vector<T> &values) : _values(values) {}
93 
99  int extractValue( const std::string& val )
100  {
101  T temp;
102 
103 #if defined(HAVE_SSTREAM)
104  std::istringstream is(val);
105 #elif defined(HAVE_STRSTREAM)
106  std::istrstream is(val.c_str());
107 #else
108 #error "Need a stringstream (sstream or strstream) to compile!"
109 #endif
110 
111  int valuesRead = 0;
112 
113  while ( is.good() )
114  {
115  if ( is.peek() != EOF )
116  is >> temp;
117  else
118  break;
119 
120  valuesRead++;
121  }
122 
123  if ( is.fail() )
124  return EXTRACT_FAILURE;
125 
126  if ( valuesRead > 1 )
127  return EXTRACT_TOO_MANY;
128 
129  _values.push_back(temp);
130 
131  return 0;
132  }
133  };
134 
140  template<>
141  class ValueExtractor<std::string>
142  {
143  friend class MultiArg<std::string>;
144 
145  private:
146 
151  std::vector<std::string> &_values;
152 
157  ValueExtractor(std::vector<std::string> &values) : _values(values) {}
158 
164  int extractValue( const std::string& val )
165  {
166  _values.push_back( val );
167  return 0;
168  }
169  };
170 
171  } //namespace MULTI_ARG_HELPER
172 
178 
179  template<class T>
180  class MultiArg : public Arg
181  {
182  protected:
183 
187  std::vector<T> _values;
188 
195  std::vector<T> _allowed;
196 
200  std::string _typeDesc;
201 
208  void _extractValue( const std::string& val );
209 
214  void _checkAllowed( const std::string& val );
215 
216  public:
217 
235  MultiArg( const std::string& flag,
236  const std::string& name,
237  const std::string& desc,
238  bool req,
239  const std::string& typeDesc,
240  Visitor* v = NULL);
241 
260  MultiArg( const std::string& flag,
261  const std::string& name,
262  const std::string& desc,
263  bool req,
264  const std::string& typeDesc,
265  CmdLineInterface& parser,
266  Visitor* v = NULL );
267 
283  MultiArg( const std::string& flag,
284  const std::string& name,
285  const std::string& desc,
286  bool req,
287  const std::vector<T>& allowed,
288  Visitor* v = NULL );
289 
306  MultiArg( const std::string& flag,
307  const std::string& name,
308  const std::string& desc,
309  bool req,
310  const std::vector<T>& allowed,
311  CmdLineInterface& parser,
312  Visitor* v = NULL );
313 
322  virtual bool processArg(int* i, std::vector<std::string>& args);
323 
328  const std::vector<T>& getValue() const;
329 
334  virtual std::string shortID(const std::string& val="val") const;
335 
340  virtual std::string longID(const std::string& val="val") const;
341 
346  virtual bool isRequired() const;
347 
348  private:
349 
353  void allowedInit();
354  };
355 
359  template<class T>
361  {
362  for ( unsigned int i = 0; i < _allowed.size(); i++ )
363  {
364 
365 #if defined(HAVE_SSTREAM)
366  std::ostringstream os;
367 #elif defined(HAVE_STRSTREAM)
368  std::ostrstream os;
369 #else
370 #error "Need a stringstream (sstream or strstream) to compile!"
371 #endif
372 
373  os << _allowed[i];
374 
375  std::string temp( os.str() );
376 
377  if ( i > 0 )
378  _typeDesc += "|";
379 
380  _typeDesc += temp;
381  }
382  }
383 
387  template<class T>
388  MultiArg<T>::MultiArg(const std::string& flag,
389  const std::string& name,
390  const std::string& desc,
391  bool req,
392  const std::string& typeDesc,
393  Visitor* v)
394  : Arg( flag, name, desc, req, true, v ),
395  _typeDesc( typeDesc )
396  { }
397 
398  template<class T>
399  MultiArg<T>::MultiArg(const std::string& flag,
400  const std::string& name,
401  const std::string& desc,
402  bool req,
403  const std::string& typeDesc,
404  CmdLineInterface& parser,
405  Visitor* v)
406  : Arg( flag, name, desc, req, true, v ),
407  _typeDesc( typeDesc )
408  {
409  parser.add( this );
410  }
411 
415  template<class T>
416  MultiArg<T>::MultiArg(const std::string& flag,
417  const std::string& name,
418  const std::string& desc,
419  bool req,
420  const std::vector<T>& allowed,
421  Visitor* v)
422  : Arg( flag, name, desc, req, true, v ),
423  _allowed( allowed )
424  {
425  allowedInit();
426  }
427 
428  template<class T>
429  MultiArg<T>::MultiArg(const std::string& flag,
430  const std::string& name,
431  const std::string& desc,
432  bool req,
433  const std::vector<T>& allowed,
434  CmdLineInterface& parser,
435  Visitor* v)
436  : Arg( flag, name, desc, req, true, v ),
437  _allowed( allowed )
438  {
439  allowedInit();
440  parser.add( this );
441  }
442 
446  template<class T>
447  const std::vector<T>& MultiArg<T>::getValue() const { return _values; }
448 
452  template<class T>
453  bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
454  {
455  if ( _ignoreable && Arg::ignoreRest() )
456  return false;
457 
458  if ( _hasBlanks( args[*i] ) )
459  return false;
460 
461  std::string flag = args[*i];
462  std::string value = "";
463 
464  trimFlag( flag, value );
465 
466  if ( argMatches( flag ) )
467  {
468  if ( Arg::delimiter() != ' ' && value == "" )
469  throw( ArgParseException(
470  "Couldn't find delimiter for this argument!",
471  toString() ) );
472 
473  if ( value == "" )
474  {
475  (*i)++;
476  if ( (unsigned int)*i < args.size() )
477  _extractValue( args[*i] );
478  else
479  throw( ArgParseException("Missing a value for this argument!",
480  toString() ) );
481  }
482  else
483  _extractValue( value );
484 
485  _checkWithVisitor();
486 
487  return true;
488  }
489  else
490  return false;
491  }
492 
496  template<class T>
497  void MultiArg<T>::_checkAllowed( const std::string& val )
498  {
499  if ( _allowed.size() > 0 )
500  if ( std::find(_allowed.begin(),_allowed.end(),_values.back())
501  == _allowed.end() )
502  throw( CmdLineParseException( "Couldn't find '" + val +
503  "' in allowed list.", toString() ) );
504  }
505 
509  template<class T>
510  std::string MultiArg<T>::shortID(const std::string& val) const
511  {
512  std::string id = Arg::shortID(_typeDesc) + " ... ";
513 
514  return id;
515  }
516 
520  template<class T>
521  std::string MultiArg<T>::longID(const std::string& val) const
522  {
523  std::string id = Arg::longID(_typeDesc) + " (accepted multiple times)";
524 
525  return id;
526  }
527 
532  template<class T>
534  {
535  if ( _required )
536  {
537  if ( _values.size() > 1 )
538  return false;
539  else
540  return true;
541  }
542  else
543  return false;
544 
545  }
546 
547  template<class T>
548  void MultiArg<T>::_extractValue( const std::string& val )
549  {
551 
552  int err = ve.extractValue(val);
553 
555  throw( ArgParseException("Couldn't read argument value "
556  "from string '" + val + "'", toString() ) );
557 
559  throw( ArgParseException("More than one valid value "
560  "parsed from string '" + val + "'",
561  toString() ) );
562  _checkAllowed( val );
563  }
564 
565 
566 }
567 
568 #ifdef DtUSE_UTILITIES_NAMESPACE
569 }
570 #endif
571 
572 #endif

Document ID: Generated on Tue Mar 1 02:56:17 EST 2016 from SVN revision 162687
Copyright © 2005-2014 VT MÄK. All Rights Reserved (www.mak.com)