VR-Link API Documentation for HLA 1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  {
413  throw( SpecificationException( "Argument with same flag/name already exists!",
414  a->longID() ) );
415  }
416 
417  a->addToList( _argList );
418 
419  if ( a->isRequired() )
420  _numRequired++;
421  }
422 
423  inline char** CmdLine::checkHelpOption( int & argc, char** argv, bool & result, bool removeFromArgs )
424  {
425  // cache the old argument count
426  int oldArgc = argc;
427 
428  // vector of command line arguments
429  std::vector<std::string> args;
430  for (int i = 1; i < argc; i++)
431  args.push_back(argv[i]);
432 
433  std::vector<std::string>::iterator prev;
434  std::vector<std::string>::iterator cur;
435  std::vector<std::string>::iterator end = args.end();
436 
437  // get the beginning
438  cur = args.begin();
439 
440  // finished early?
441  bool finished = false;
442 
443  while( ( cur != end && finished == false ) )
444  {
445  if( (*cur) == "--help" )
446  {
447  if( removeFromArgs )
448  {
449  // subtract an argument
450  argc--;
451 
452  // erase it
453  args.erase(cur);
454  }
455 
456  // set back to the previous
457  cur = prev;
458 
459  // we've finished
460  finished = true;
461 
462  // break out
463  break;
464  }
465  else
466  {
467  prev = cur;
468  ++cur;
469  }
470  }
471 
472  // set the result
473  result = finished;
474 
475  if( ( removeFromArgs == true ) && ( finished == true ) )
476  {
477  // ok so we found help, and removed it which means we
478  // altered the argv's, we need to reconstruct and give back
479  // otherwise return what we had
480  char ** new_argv = new char * [ args.size() ];
481  for( unsigned int i = 0; i < args.size(); ++i )
482  {
483  new_argv[i] = new char[ args[i].length() + 1 ];
484  memcpy( new_argv[i], args[i].c_str(), args[i].length() );
485  }
486 
487  return new_argv;
488  }
489 
490  // restore the old argc
491  argc = oldArgc;
492  return argv;
493  }
494 
495  inline void CmdLine::parse(int argc, char** argv, bool printOnError)
496  throw(CmdLineParseException)
497  {
498  try {
499 
500  _progName = argv[0];
501 
503  std::vector<std::string> args;
504  int i;
505  for (i = 1; i < argc; i++)
506  args.push_back(argv[i]);
507 
508  int requiredCount = 0;
509 
510  for (i = 0; (unsigned int)i < args.size(); i++)
511  {
512  bool matched = false;
513  for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
514  {
515  if ( (*it)->processArg( &i, args ) )
516  {
517  requiredCount += _xorHandler.check( *it );
518  matched = true;
519  break;
520  }
521  }
522 
525  if ( !matched && _emptyCombined( args[i] ) )
526  matched = true;
527 
528  if ( !matched && !Arg::ignoreRest() )
529  throw(CmdLineParseException("Couldn't find match for argument",
530  args[i]));
531  }
532 
533  if ( requiredCount < _numRequired )
534  throw(CmdLineParseException("One or more required arguments missing!"));
535 
536  if ( requiredCount > _numRequired )
537  throw(CmdLineParseException("Too many arguments!"));
538 
539  } catch ( ArgException e ) {
540 
541  if( printOnError == false )
542  {
543  throw(CmdLineParseException(e.error()));
544  return;
545  }
546  _output->failure(*this,e);
547 
548  int oldNotifyLevel = DtNotifyLevel;
549  DtNotifyLevel = 3;
550 
551  if (myPressAnyKey)
552  {
553  DtInfo << "Press any key to continue" << std::endl;
554 
555  while (DtPollBlockingInputChar() == '\0')
556  {
557  DtSleep(0.1);
558  }
559  }
560 
561  DtNotifyLevel = oldNotifyLevel;
562 
563  exit(1);
564  }
565  }
566 
567  inline bool CmdLine::_emptyCombined(const std::string& s)
568  {
569  if ( s[0] != Arg::flagStartChar() )
570  return false;
571 
572  for ( int i = 1; (unsigned int)i < s.length(); i++ )
573  if ( s[i] != Arg::blankChar() )
574  return false;
575 
576  return true;
577  }
578 
579  inline void CmdLine::deleteOnExit(Arg* ptr)
580  {
581  _argDeleteOnExitList.push_back(ptr);
582  }
583 
584  inline void CmdLine::deleteOnExit(Visitor* ptr)
585  {
586  _visitorDeleteOnExitList.push_back(ptr);
587  }
588 
590  {
591  return _output;
592  }
593 
595  {
596  _userSetOutput = true;
597  _output = co;
598  }
599 
600  inline std::string& CmdLine::getVersion()
601  {
602  return _version;
603  }
604 
605  inline std::string& CmdLine::getProgramName()
606  {
607  return _progName;
608  }
609 
610  inline std::list<Arg*>& CmdLine::getArgList()
611  {
612  return _argList;
613  }
614 
616  {
617  return _xorHandler;
618  }
619 
620  inline char CmdLine::getDelimiter()
621  {
622  return _delimiter;
623  }
624 
625  inline std::string& CmdLine::getMessage()
626  {
627  return _message;
628  }
629 
631  //End CmdLine.cpp
633 
634 
635 
636 } //namespace DtCmdLine
637 
638 #ifdef DtUSE_UTILITIES_NAMESPACE
639 }
640 #endif
641 
642 #endif

Document ID: Generated on Mon Feb 6 18:36:34 EST 2017 from SVN revision 173107
Copyright © 2005-2016 VT MÄK. All Rights Reserved (www.mak.com)