VR-Link API Documentation for HLA 1.3
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 
237  void parse(int argc, char** argv);
238 
242  CmdLineOutput* getOutput();
243 
247  void setOutput(CmdLineOutput* co);
248 
252  std::string& getVersion();
253 
257  std::string& getProgramName();
258 
262  std::list<Arg*>& getArgList();
263 
267  XorHandler& getXorHandler();
268 
272  char getDelimiter();
273 
277  std::string& getMessage();
278  };
279 
280 
282  //Begin CmdLine.cpp
284 
285  inline CmdLine::CmdLine(const std::string& n,
286  const std::string& m,
287  const std::string& v,
288  bool pressAnyKey)
289  : _progName(n),
290  _message(m),
291  _version(v),
292  _numRequired(0),
293  _delimiter(' '),
294  myPressAnyKey(pressAnyKey),
295  _userSetOutput(false)
296  {
297  _constructor();
298  }
299 
300  inline CmdLine::CmdLine(const std::string& m,
301  char delim,
302  const std::string& v,
303  bool pressAnyKey)
304  : _progName("not_set_yet"),
305  _message(m),
306  _version(v),
307  _numRequired(0),
308  _delimiter(delim),
309  myPressAnyKey(pressAnyKey),
310  _userSetOutput(false)
311  {
312  _constructor();
313  }
314 
316  {
317  ArgListIterator argIter;
318  VisitorListIterator visIter;
319 
320  for( argIter = _argDeleteOnExitList.begin();
321  argIter != _argDeleteOnExitList.end();
322  ++argIter)
323  delete *argIter;
324 
325  for( visIter = _visitorDeleteOnExitList.begin();
326  visIter != _visitorDeleteOnExitList.end();
327  ++visIter)
328  delete *visIter;
329 
330  if ( !_userSetOutput )
331  delete _output;
332  }
333 
334  inline void CmdLine::_constructor()
335  {
336  _output = new StdOutput;
337 
338  Visitor *v;
339 
341 
342  v = new HelpVisitor( this, &_output, myPressAnyKey );
343  SwitchArg* help = new SwitchArg("h","help",
344  "Displays usage information and exits.",
345  false, v);
346  add( help );
347  deleteOnExit(help);
348  deleteOnExit(v);
349 
350  v = new VersionVisitor( this, &_output, myPressAnyKey );
351  SwitchArg* vers = new SwitchArg("v","version",
352  "Displays version information and exits.",
353  false, v);
354  add( vers );
355  deleteOnExit(vers);
356  deleteOnExit(v);
357 
358  v = new IgnoreRestVisitor();
359  SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
361  "Ignores the rest of the labeled arguments following this flag.",
362  false, v);
363  add( ignore );
364  deleteOnExit(ignore);
365  deleteOnExit(v);
366  }
367 
368  inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
369  {
370  _xorHandler.add( ors );
371 
372  for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
373  {
374  (*it)->forceRequired();
375  (*it)->setRequireLabel( "OR required" );
376 
377  add( *it );
378  }
379  }
380 
381  inline void CmdLine::xorAdd( Arg& a, Arg& b )
382  {
383  std::vector<Arg*> ors;
384  ors.push_back( &a );
385  ors.push_back( &b );
386  xorAdd( ors );
387  }
388 
389  inline void CmdLine::add( Arg& a )
390  {
391  add( &a );
392  }
393 
394  inline void CmdLine::add( Arg* a )
395  {
396  for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
397  if ( *a == *(*it) )
398  throw( SpecificationException( "Argument with same flag/name already exists!",
399  a->longID() ) );
400 
401  a->addToList( _argList );
402 
403  if ( a->isRequired() )
404  _numRequired++;
405  }
406 
407  inline void CmdLine::parse(int argc, char** argv)
408  {
409  try {
410 
411  _progName = argv[0];
412 
414  std::vector<std::string> args;
415  int i;
416  for (i = 1; i < argc; i++)
417  args.push_back(argv[i]);
418 
419  int requiredCount = 0;
420 
421  for (i = 0; (unsigned int)i < args.size(); i++)
422  {
423  bool matched = false;
424  for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
425  {
426  if ( (*it)->processArg( &i, args ) )
427  {
428  requiredCount += _xorHandler.check( *it );
429  matched = true;
430  break;
431  }
432  }
433 
436  if ( !matched && _emptyCombined( args[i] ) )
437  matched = true;
438 
439  if ( !matched && !Arg::ignoreRest() )
440  throw(CmdLineParseException("Couldn't find match for argument",
441  args[i]));
442  }
443 
444  if ( requiredCount < _numRequired )
445  throw(CmdLineParseException("One or more required arguments missing!"));
446 
447  if ( requiredCount > _numRequired )
448  throw(CmdLineParseException("Too many arguments!"));
449 
450  } catch ( ArgException e ) {
451  _output->failure(*this,e);
452 
453  int oldNotifyLevel = DtNotifyLevel;
454  DtNotifyLevel = 3;
455 
456  if (myPressAnyKey)
457  {
458  DtInfo << "Press any key to continue" << std::endl;
459 
460  while (DtPollBlockingInputChar() == '\0')
461  {
462  DtSleep(0.1);
463  }
464  }
465 
466  DtNotifyLevel = oldNotifyLevel;
467 
468  exit(1);
469  }
470  }
471 
472  inline bool CmdLine::_emptyCombined(const std::string& s)
473  {
474  if ( s[0] != Arg::flagStartChar() )
475  return false;
476 
477  for ( int i = 1; (unsigned int)i < s.length(); i++ )
478  if ( s[i] != Arg::blankChar() )
479  return false;
480 
481  return true;
482  }
483 
484  inline void CmdLine::deleteOnExit(Arg* ptr)
485  {
486  _argDeleteOnExitList.push_back(ptr);
487  }
488 
489  inline void CmdLine::deleteOnExit(Visitor* ptr)
490  {
491  _visitorDeleteOnExitList.push_back(ptr);
492  }
493 
495  {
496  return _output;
497  }
498 
500  {
501  _userSetOutput = true;
502  _output = co;
503  }
504 
505  inline std::string& CmdLine::getVersion()
506  {
507  return _version;
508  }
509 
510  inline std::string& CmdLine::getProgramName()
511  {
512  return _progName;
513  }
514 
515  inline std::list<Arg*>& CmdLine::getArgList()
516  {
517  return _argList;
518  }
519 
521  {
522  return _xorHandler;
523  }
524 
525  inline char CmdLine::getDelimiter()
526  {
527  return _delimiter;
528  }
529 
530  inline std::string& CmdLine::getMessage()
531  {
532  return _message;
533  }
534 
536  //End CmdLine.cpp
538 
539 
540 
541 } //namespace DtCmdLine
542 
543 #ifdef DtUSE_UTILITIES_NAMESPACE
544 }
545 #endif
546 
547 #endif

Document ID: Generated on Wed Aug 14 15:35:11 EDT 2013 from SVN revision 130445
Copyright © 2005-2013 VT MÄK. All Rights Reserved (www.mak.com)