VR-Link API Documentation for HLA Evolved
cmdLine.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * file: CmdLine.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 #ifndef DtCmdLine_CMDLINE_H
23 #define DtCmdLine_CMDLINE_H
24 
28 
29 #include "cmdSwitchArg.h"
30 #include "cmdUnlabeledValueArg.h"
31 #include "cmdUnlabeledMultiArg.h"
32 
33 #include "cmdXorHandler.h"
34 #include "cmdHelpVisitor.h"
35 #include "cmdVersionVisitor.h"
36 #include "cmdIgnoreRestVisitor.h"
37 
38 #include "cmdLineOutput.h"
39 #include "cmdStdOutput.h"
40 
41 #include <string>
42 #include <vector>
43 #include <list>
44 #include <iostream>
45 #include <iomanip>
46 #include <algorithm>
47 
49 #include <vlutil/vlKeyboard.h>
50 #include <vlutil/vlPrint.h>
51 
52 #ifdef DtUSE_UTILITIES_NAMESPACE
53 namespace DtUSE_UTILITIES_NAMESPACE
54 {
55 #endif
56 
57 namespace DtCmdLine {
58 
63 
64  class CmdLine : public CmdLineInterface
65  {
66  protected:
67 
72  std::list<Arg*> _argList;
73 
77  std::string _progName;
78 
82  std::string _message;
83 
87  std::string _version;
88 
95 
101 
106 
112  std::list<Arg*> _argDeleteOnExitList;
113 
119  std::list<Visitor*> _visitorDeleteOnExitList;
120 
125 
132  bool _emptyCombined(const std::string& s);
133 
135 
136  private:
137 
142  void _constructor();
143 
147  void deleteOnExit(Arg* ptr);
148 
152  void deleteOnExit(Visitor* ptr);
153 
159 
160  public:
161 
172  CmdLine(const std::string& name,
173  const std::string& message,
174  const std::string& version = "none",
175 #ifdef _WIN32
176  bool pressAnyKey = true);
177 #else
178  bool pressAnyKey = false);
179 #endif
180 
191  CmdLine(const std::string& message,
192  const char delimiter = ' ',
193  const std::string& version = "none",
194 #ifdef _WIN32
195  bool pressAnyKey = true);
196 #else
197  bool pressAnyKey = false);
198 #endif
199 
203  virtual ~CmdLine();
204 
209  void add( Arg& a );
210 
215  void add( Arg* a );
216 
223  void xorAdd( Arg& a, Arg& b );
224 
230  void xorAdd( std::vector<Arg*>& xors );
231 
239  void parse(int argc, char** argv, bool printOnError = true)
240  throw(CmdLineParseException);
241 
251  char** checkHelpOption( int & argc, char** argv, bool & result, bool removeFromArgs = true );
252 
256  CmdLineOutput* getOutput();
257 
261  void setOutput(CmdLineOutput* co);
262 
266  std::string& getVersion();
267 
271  std::string& getProgramName();
272 
276  std::list<Arg*>& getArgList();
277 
281  XorHandler& getXorHandler();
282 
286  char getDelimiter();
287 
291  std::string& getMessage();
292  };
293 
294 
296  //Begin CmdLine.cpp
298 
299  inline CmdLine::CmdLine(const std::string& n,
300  const std::string& m,
301  const std::string& v,
302  bool pressAnyKey)
303  : _progName(n),
304  _message(m),
305  _version(v),
306  _numRequired(0),
307  _delimiter(' '),
308  myPressAnyKey(pressAnyKey),
309  _userSetOutput(false)
310  {
311  _constructor();
312  }
313 
314  inline CmdLine::CmdLine(const std::string& m,
315  char delim,
316  const std::string& v,
317  bool pressAnyKey)
318  : _progName("not_set_yet"),
319  _message(m),
320  _version(v),
321  _numRequired(0),
322  _delimiter(delim),
323  myPressAnyKey(pressAnyKey),
324  _userSetOutput(false)
325  {
326  _constructor();
327  }
328 
330  {
331  ArgListIterator argIter;
332  VisitorListIterator visIter;
333 
334  for( argIter = _argDeleteOnExitList.begin();
335  argIter != _argDeleteOnExitList.end();
336  ++argIter)
337  delete *argIter;
338 
339  for( visIter = _visitorDeleteOnExitList.begin();
340  visIter != _visitorDeleteOnExitList.end();
341  ++visIter)
342  delete *visIter;
343 
344  if ( !_userSetOutput )
345  delete _output;
346  }
347 
348  inline void CmdLine::_constructor()
349  {
350  _output = new StdOutput;
351 
352  Visitor *v;
353 
355 
356  v = new HelpVisitor( this, &_output, myPressAnyKey );
357  SwitchArg* help = new SwitchArg("h","help",
358  "Displays usage information and exits.",
359  false, v);
360  add( help );
361  deleteOnExit(help);
362  deleteOnExit(v);
363 
364  v = new VersionVisitor( this, &_output, myPressAnyKey );
365  SwitchArg* vers = new SwitchArg("v","version",
366  "Displays version information and exits.",
367  false, v);
368  add( vers );
369  deleteOnExit(vers);
370  deleteOnExit(v);
371 
372  v = new IgnoreRestVisitor();
373  SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
375  "Ignores the rest of the labeled arguments following this flag.",
376  false, v);
377  add( ignore );
378  deleteOnExit(ignore);
379  deleteOnExit(v);
380  }
381 
382  inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
383  {
384  _xorHandler.add( ors );
385 
386  for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
387  {
388  (*it)->forceRequired();
389  (*it)->setRequireLabel( "OR required" );
390 
391  add( *it );
392  }
393  }
394 
395  inline void CmdLine::xorAdd( Arg& a, Arg& b )
396  {
397  std::vector<Arg*> ors;
398  ors.push_back( &a );
399  ors.push_back( &b );
400  xorAdd( ors );
401  }
402 
403  inline void CmdLine::add( Arg& a )
404  {
405  add( &a );
406  }
407 
408  inline void CmdLine::add( Arg* a )
409  {
410  for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
411  if ( *a == *(*it) )
412  throw( SpecificationException( "Argument with same flag/name already exists!",
413  a->longID() ) );
414 
415  a->addToList( _argList );
416 
417  if ( a->isRequired() )
418  _numRequired++;
419  }
420 
421  inline char** CmdLine::checkHelpOption( int & argc, char** argv, bool & result, bool removeFromArgs )
422  {
423  // cache the old argument count
424  int oldArgc = argc;
425 
426  // vector of command line arguments
427  std::vector<std::string> args;
428  for (int i = 1; i < argc; i++)
429  args.push_back(argv[i]);
430 
431  std::vector<std::string>::iterator prev;
432  std::vector<std::string>::iterator cur;
433  std::vector<std::string>::iterator end = args.end();
434 
435  // get the beginning
436  cur = args.begin();
437 
438  // finished early?
439  bool finished = false;
440 
441  while( ( cur != end && finished == false ) )
442  {
443  if( (*cur) == "--help" )
444  {
445  if( removeFromArgs )
446  {
447  // subtract an argument
448  argc--;
449 
450  // erase it
451  args.erase(cur);
452  }
453 
454  // set back to the previous
455  cur = prev;
456 
457  // we've finished
458  finished = true;
459 
460  // break out
461  break;
462  }
463  else
464  {
465  prev = cur;
466  ++cur;
467  }
468  }
469 
470  // set the result
471  result = finished;
472 
473  if( ( removeFromArgs == true ) && ( finished == true ) )
474  {
475  // ok so we found help, and removed it which means we
476  // altered the argv's, we need to reconstruct and give back
477  // otherwise return what we had
478  char ** new_argv = new char * [ args.size() ];
479  for( unsigned int i = 0; i < args.size(); ++i )
480  {
481  new_argv[i] = new char[ args[i].length() + 1 ];
482  memcpy( new_argv[i], args[i].c_str(), args[i].length() );
483  }
484 
485  return new_argv;
486  }
487 
488  // restore the old argc
489  argc = oldArgc;
490  return argv;
491  }
492 
493  inline void CmdLine::parse(int argc, char** argv, bool printOnError)
494  throw(CmdLineParseException)
495  {
496  try {
497 
498  _progName = argv[0];
499 
501  std::vector<std::string> args;
502  int i;
503  for (i = 1; i < argc; i++)
504  args.push_back(argv[i]);
505 
506  int requiredCount = 0;
507 
508  for (i = 0; (unsigned int)i < args.size(); i++)
509  {
510  bool matched = false;
511  for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
512  {
513  if ( (*it)->processArg( &i, args ) )
514  {
515  requiredCount += _xorHandler.check( *it );
516  matched = true;
517  break;
518  }
519  }
520 
523  if ( !matched && _emptyCombined( args[i] ) )
524  matched = true;
525 
526  if ( !matched && !Arg::ignoreRest() )
527  throw(CmdLineParseException("Couldn't find match for argument",
528  args[i]));
529  }
530 
531  if ( requiredCount < _numRequired )
532  throw(CmdLineParseException("One or more required arguments missing!"));
533 
534  if ( requiredCount > _numRequired )
535  throw(CmdLineParseException("Too many arguments!"));
536 
537  } catch ( ArgException e ) {
538 
539  if( printOnError == false )
540  {
541  throw(CmdLineParseException(e.error()));
542  return;
543  }
544  _output->failure(*this,e);
545 
546  int oldNotifyLevel = DtNotifyLevel;
547  DtNotifyLevel = 3;
548 
549  if (myPressAnyKey)
550  {
551  DtInfo << "Press any key to continue" << std::endl;
552 
553  while (DtPollBlockingInputChar() == '\0')
554  {
555  DtSleep(0.1);
556  }
557  }
558 
559  DtNotifyLevel = oldNotifyLevel;
560 
561  exit(1);
562  }
563  }
564 
565  inline bool CmdLine::_emptyCombined(const std::string& s)
566  {
567  if ( s[0] != Arg::flagStartChar() )
568  return false;
569 
570  for ( int i = 1; (unsigned int)i < s.length(); i++ )
571  if ( s[i] != Arg::blankChar() )
572  return false;
573 
574  return true;
575  }
576 
577  inline void CmdLine::deleteOnExit(Arg* ptr)
578  {
579  _argDeleteOnExitList.push_back(ptr);
580  }
581 
582  inline void CmdLine::deleteOnExit(Visitor* ptr)
583  {
584  _visitorDeleteOnExitList.push_back(ptr);
585  }
586 
588  {
589  return _output;
590  }
591 
593  {
594  _userSetOutput = true;
595  _output = co;
596  }
597 
598  inline std::string& CmdLine::getVersion()
599  {
600  return _version;
601  }
602 
603  inline std::string& CmdLine::getProgramName()
604  {
605  return _progName;
606  }
607 
608  inline std::list<Arg*>& CmdLine::getArgList()
609  {
610  return _argList;
611  }
612 
614  {
615  return _xorHandler;
616  }
617 
618  inline char CmdLine::getDelimiter()
619  {
620  return _delimiter;
621  }
622 
623  inline std::string& CmdLine::getMessage()
624  {
625  return _message;
626  }
627 
629  //End CmdLine.cpp
631 
632 
633 
634 } //namespace DtCmdLine
635 
636 #ifdef DtUSE_UTILITIES_NAMESPACE
637 }
638 #endif
639 
640 #endif

Document ID: Generated on Wed Oct 23 22:25:48 EDT 2013 from SVN revision 132765
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)