VR-Link API Documentation for DIS
 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  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 
250  char** checkHelpOption( int & argc, char** argv, bool & result, bool removeFromArgs = true );
251 
255  CmdLineOutput* getOutput();
256 
260  void setOutput(CmdLineOutput* co);
261 
265  std::string& getVersion();
266 
270  std::string& getProgramName();
271 
275  std::list<Arg*>& getArgList();
276 
280  XorHandler& getXorHandler();
281 
285  char getDelimiter();
286 
290  std::string& getMessage();
291  };
292 
293 
295  //Begin CmdLine.cpp
297 
298  inline CmdLine::CmdLine(const std::string& n,
299  const std::string& m,
300  const std::string& v,
301  bool pressAnyKey)
302  : _progName(n),
303  _message(m),
304  _version(v),
305  _numRequired(0),
306  _delimiter(' '),
307  myPressAnyKey(pressAnyKey),
308  _userSetOutput(false)
309  {
310  _constructor();
311  }
312 
313  inline CmdLine::CmdLine(const std::string& m,
314  char delim,
315  const std::string& v,
316  bool pressAnyKey)
317  : _progName(m),
318  _message(m),
319  _version(v),
320  _numRequired(0),
321  _delimiter(delim),
322  myPressAnyKey(pressAnyKey),
323  _userSetOutput(false)
324  {
325  _constructor();
326  }
327 
329  {
330  ArgListIterator argIter;
331  VisitorListIterator visIter;
332 
333  for( argIter = _argDeleteOnExitList.begin();
334  argIter != _argDeleteOnExitList.end();
335  ++argIter)
336  delete *argIter;
337 
338  for( visIter = _visitorDeleteOnExitList.begin();
339  visIter != _visitorDeleteOnExitList.end();
340  ++visIter)
341  delete *visIter;
342 
343  if ( !_userSetOutput )
344  delete _output;
345  }
346 
347  inline void CmdLine::_constructor()
348  {
349  _output = new StdOutput;
350 
351  Visitor *v;
352 
354 
355  v = new HelpVisitor( this, &_output, myPressAnyKey );
356  SwitchArg* help = new SwitchArg("h","help",
357  "Displays usage information and exits.",
358  false, v);
359  add( help );
360  deleteOnExit(help);
361  deleteOnExit(v);
362 
363  v = new VersionVisitor( this, &_output, myPressAnyKey );
364  SwitchArg* vers = new SwitchArg("v","version",
365  "Displays version information and exits.",
366  false, v);
367  add( vers );
368  deleteOnExit(vers);
369  deleteOnExit(v);
370 
371  v = new IgnoreRestVisitor();
372  SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
374  "Ignores the rest of the labeled arguments following this flag.",
375  false, v);
376  add( ignore );
377  deleteOnExit(ignore);
378  deleteOnExit(v);
379  }
380 
381  inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
382  {
383  _xorHandler.add( ors );
384 
385  for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
386  {
387  (*it)->forceRequired();
388  (*it)->setRequireLabel( "OR required" );
389 
390  add( *it );
391  }
392  }
393 
394  inline void CmdLine::xorAdd( Arg& a, Arg& b )
395  {
396  std::vector<Arg*> ors;
397  ors.push_back( &a );
398  ors.push_back( &b );
399  xorAdd( ors );
400  }
401 
402  inline void CmdLine::add( Arg& a )
403  {
404  add( &a );
405  }
406 
407  inline void CmdLine::add( Arg* a )
408  {
409  for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
410  if ( *a == *(*it) )
411  {
412  throw( SpecificationException( "Argument with same flag/name already exists!",
413  a->longID() ) );
414  }
415 
416  a->addToList( _argList );
417 
418  if ( a->isRequired() )
419  _numRequired++;
420  }
421 
422  inline char** CmdLine::checkHelpOption( int & argc, char** argv, bool & result, bool removeFromArgs )
423  {
424  // TODO consider making a DtFilename and getting the file's name rather than the (potential) absolute path
425  _progName = argv[0];
426 
427  // cache the old argument count
428  int oldArgc = argc;
429 
430  // vector of command line arguments
431  std::vector<std::string> args;
432  for (int i = 1; i < argc; i++)
433  args.push_back(argv[i]);
434 
435  std::vector<std::string>::iterator prev;
436  std::vector<std::string>::iterator cur;
437  std::vector<std::string>::iterator end = args.end();
438 
439  // get the beginning
440  cur = args.begin();
441 
442  // finished early?
443  bool finished = false;
444 
445  while( ( cur != end && finished == false ) )
446  {
447  if( (*cur) == "--help" )
448  {
449  if( removeFromArgs )
450  {
451  // subtract an argument
452  argc--;
453 
454  // erase it
455  args.erase(cur);
456  }
457 
458  // set back to the previous
459  cur = prev;
460 
461  // we've finished
462  finished = true;
463 
464  // break out
465  break;
466  }
467  // This is necessary due to usage of /SUBSYSTEM:WINDOWS with MSVC
468 #ifdef _WIN32
469  else if ((*cur) == "-h")
470  {
471  if (removeFromArgs)
472  {
473  // subtract an argument
474  argc--;
475 
476  // erase it
477  args.erase(cur);
478  }
479 
480  // set back to the previous
481  cur = prev;
482 
483  // we've finished
484  finished = true;
485 
486  // break out
487  break;
488  }
489 #endif
490  else
491  {
492  prev = cur;
493  ++cur;
494  }
495  }
496 
497  // set the result
498  result = finished;
499 
500  if( ( removeFromArgs == true ) && ( finished == true ) )
501  {
502  // ok so we found help, and removed it which means we
503  // altered the argv's, we need to reconstruct and give back
504  // otherwise return what we had
505  char ** new_argv = new char * [ args.size() ];
506  for( unsigned int i = 0; i < args.size(); ++i )
507  {
508  new_argv[i] = new char[ args[i].length() + 1 ];
509  memcpy( new_argv[i], args[i].c_str(), args[i].length() );
510  }
511 
512  return new_argv;
513  }
514 
515  // restore the old argc
516  argc = oldArgc;
517  return argv;
518  }
519 
520  inline void CmdLine::parse(int argc, char** argv, bool printOnError)
521  {
522  try {
523 
524  _progName = argv[0];
525 
527  std::vector<std::string> args;
528  int i;
529  for (i = 1; i < argc; i++)
530  args.push_back(argv[i]);
531 
532  int requiredCount = 0;
533 
534  for (i = 0; (unsigned int)i < args.size(); i++)
535  {
536  bool matched = false;
537  for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
538  {
539  if ( (*it)->processArg( &i, args ) )
540  {
541  requiredCount += _xorHandler.check( *it );
542  matched = true;
543  break;
544  }
545  }
546 
549  if ( !matched && _emptyCombined( args[i] ) )
550  matched = true;
551 
552  if ( !matched && !Arg::ignoreRest() )
553  throw(CmdLineParseException("Couldn't find match for argument",
554  args[i]));
555  }
556 
557  if ( requiredCount < _numRequired )
558  throw(CmdLineParseException("One or more required arguments missing!"));
559 
560  if ( requiredCount > _numRequired )
561  throw(CmdLineParseException("Too many arguments!"));
562 
563  } catch ( ArgException e ) {
564 
565  if( printOnError == false )
566  {
567  throw(CmdLineParseException(e.error()));
568  return;
569  }
570  _output->failure(*this,e);
571 
572  int oldNotifyLevel = DtNotifyLevel;
573  DtNotifyLevel = 3;
574 
575  if (myPressAnyKey)
576  {
577  DtInfo << "Press any key to continue" << std::endl;
578 
579  while (DtPollBlockingInputChar() == '\0')
580  {
581  DtSleep(0.1);
582  }
583  }
584 
585  DtNotifyLevel = oldNotifyLevel;
586 
587  exit(1);
588  }
589  }
590 
591  inline bool CmdLine::_emptyCombined(const std::string& s)
592  {
593  if ( s[0] != Arg::flagStartChar() )
594  return false;
595 
596  for ( int i = 1; (unsigned int)i < s.length(); i++ )
597  if ( s[i] != Arg::blankChar() )
598  return false;
599 
600  return true;
601  }
602 
603  inline void CmdLine::deleteOnExit(Arg* ptr)
604  {
605  _argDeleteOnExitList.push_back(ptr);
606  }
607 
608  inline void CmdLine::deleteOnExit(Visitor* ptr)
609  {
610  _visitorDeleteOnExitList.push_back(ptr);
611  }
612 
614  {
615  return _output;
616  }
617 
619  {
620  _userSetOutput = true;
621  _output = co;
622  }
623 
624  inline std::string& CmdLine::getVersion()
625  {
626  return _version;
627  }
628 
629  inline std::string& CmdLine::getProgramName()
630  {
631  return _progName;
632  }
633 
634  inline std::list<Arg*>& CmdLine::getArgList()
635  {
636  return _argList;
637  }
638 
640  {
641  return _xorHandler;
642  }
643 
644  inline char CmdLine::getDelimiter()
645  {
646  return _delimiter;
647  }
648 
649  inline std::string& CmdLine::getMessage()
650  {
651  return _message;
652  }
653 
655  //End CmdLine.cpp
657 
658 
659 
660 } //namespace DtCmdLine
661 
662 #ifdef DtUSE_UTILITIES_NAMESPACE
663 }
664 #endif
665 
666 #endif
void add(std::vector< Arg * > &ors)
Add a list of Arg*&#39;s that will be orred together.
Definition: cmdXorHandler.h:105
XorHandler & getXorHandler()
Returns the XorHandler.
Definition: cmdLine.h:639
A base class that defines the interface for visitors.
Definition: cmdVisitor.h:41
void add(Arg &a)
Adds an argument to the list of arguments to be parsed.
Definition: cmdLine.h:402
CmdLine(const std::string &name, const std::string &message, const std::string &version="none", bool pressAnyKey=false)
Command line constructor.
Definition: cmdLine.h:298
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition: cmdArg.h:219
static const char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: cmdArg.h:191
A simple switch argument.
Definition: cmdSwitchArg.h:49
virtual void failure(CmdLineInterface &c, ArgException &e)=0
Generates some sort of output for a failure.
std::list< Arg * > _argList
The list of arguments that will be tested against the command line.
Definition: cmdLine.h:72
This file declares the class DtCmdLine::CmdLineOutput.
This file declares the class DtCmdLine::StdOutput.
A Vistor that tells the CmdLine to begin ignoring arguments after this one is parsed.
Definition: cmdIgnoreRestVisitor.h:45
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
Definition: cmdArgException.h:177
This file declares the class DtCmdLine::VersionVisitor.
std::string & getMessage()
Returns the message string.
Definition: cmdLine.h:649
char DtPollBlockingInputChar(void)
Polls standard input for a single character.
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: cmdArg.h:490
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: cmdArg.h:432
bool _emptyCombined(const std::string &s)
Checks whether a name/flag string matches entirely matches the Arg::blankChar.
Definition: cmdLine.h:591
Functions in vlPrint.h provide an error and print facility for vrlink.
static const std::string flagStartString()
The sting that indicates the beginning of a flag.
Definition: cmdArg.h:202
char ** checkHelpOption(int &argc, char **argv, bool &result, bool removeFromArgs=true)
Checks the command line to see if &quot;--help&quot; if entered.
Definition: cmdLine.h:422
static const char flagStartChar()
The char that indicates the beginning of a flag.
Definition: cmdArg.h:196
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: cmdArgException.h:153
This file declares the class DtCmdLine::IgnoreRestVisitor.
A class that isolates any output from the CmdLine object so that it may be easily modified...
Definition: cmdStdOutput.h:54
This class handles lists of Arg&#39;s that are to be XOR&#39;d on the command line.
Definition: cmdXorHandler.h:48
void _constructor()
Encapsulates the code common to the constructors (which is all of it).
Definition: cmdLine.h:347
A Vistor that will call the version method of the given CmdLineOutput for the specified CmdLine objec...
Definition: cmdVersionVisitor.h:50
void deleteOnExit(Arg *ptr)
Perform a delete ptr; operation on ptr when this object is deleted.
Definition: cmdLine.h:603
std::string _message
A message used to describe the program.
Definition: cmdLine.h:82
virtual void addToList(std::list< Arg * > &argList) const
Adds this to the specified list of Args.
Definition: cmdArg.h:587
std::list< Visitor * >::iterator VisitorListIterator
Typedef of a Visitor list iterator.
Definition: cmdArg.h:362
The base class that manages the command line definition and passes along the parsing to the appropria...
Definition: cmdLine.h:64
std::list< Arg * > & getArgList()
Returns the argList.
Definition: cmdLine.h:634
A simple class that defines and argument exception.
Definition: cmdArgException.h:43
std::string _progName
The name of the program.
Definition: cmdLine.h:77
void DtSleep(DtTime sleep_period)
Puts the process to sleep for the specified number of seconds.
static bool ignoreRest()
Whether to ignore the rest.
Definition: cmdArg.h:178
This file declares the class DtCmdLine::HelpVisitor.
std::string & getVersion()
Returns the version string.
Definition: cmdLine.h:624
void xorAdd(Arg &a, Arg &b)
Add two Args that will be xor&#39;d.
Definition: cmdLine.h:394
int DtNotifyLevel
DtNotifyLevel is used to control the level of diagnostics output by VR-Link.
char _delimiter
The character that is used to separate the argument flag/name from the value.
Definition: cmdLine.h:100
bool _userSetOutput
Is set to true when a user sets the output object.
Definition: cmdLine.h:158
This file declares the class DtCmdLine::XorHandler.
char getDelimiter()
Returns the delimiter string.
Definition: cmdLine.h:644
This file declares the class DtCmdLine::SwitchArg.
A virtual base class that defines the essential data for all arguments.
Definition: cmdArg.h:48
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition: cmdArg.h:213
This file declares the class DtCmdLine::UnlabeledValueArg.
std::string error() const
Returns the error text.
Definition: cmdArgException.h:70
XorHandler _xorHandler
The handler that manages xoring lists of args.
Definition: cmdLine.h:105
int check(const Arg *a)
Checks whether the specified Arg is in one of the xor lists and if it does match one, returns the size of the xor list that the Arg matched.
Definition: cmdXorHandler.h:145
std::string _version
The version to be displayed with the –version switch.
Definition: cmdLine.h:87
int _numRequired
The number of arguments that are required to be present on the command line.
Definition: cmdLine.h:94
CmdLineOutput * getOutput()
Returns the CmdLineOutput object.
Definition: cmdLine.h:613
void setOutput(CmdLineOutput *co)
Definition: cmdLine.h:618
A Visitor object that calls the usage method of the given CmdLineOutput object for the specified CmdL...
Definition: cmdHelpVisitor.h:49
DtOutputStream DtInfo
DtInfo is an global instance of a DtOutputStream.
std::list< Arg * >::iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: cmdArg.h:352
This file contains declarations of classes and functions which aid in keyboard input.
CmdLineOutput * _output
Object that handles all output for the CmdLine.
Definition: cmdLine.h:124
std::string & getProgramName()
Returns the program name string.
Definition: cmdLine.h:629
std::list< Arg * > _argDeleteOnExitList
A list of Args to be explicitly deleted when the destructor is called.
Definition: cmdLine.h:112
std::vector< Arg * >::iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: cmdArg.h:357
void parse(int argc, char **argv, bool printOnError=true)
Parses the command line.
Definition: cmdLine.h:520
ProcControl.h provides operating system independent methods to control processes. ...
std::list< Visitor * > _visitorDeleteOnExitList
A list of Visitors to be explicitly deleted when the destructor is called.
Definition: cmdLine.h:119
The interface that any output object must implement.
Definition: cmdLineOutput.h:51
virtual ~CmdLine()
Deletes any resources allocated by a CmdLine object.
Definition: cmdLine.h:328
This file declares the class DtCmdLine::UnlabeledMultiArg.
bool myPressAnyKey
Definition: cmdLine.h:134

Document ID: Generated on Thu Oct 16 00:12:25 EDT 2025 from SVN revision 280738
Copyright © 1992-2025 MAK Technologies. All Rights Reserved (www.mak.com)