CmdLine.h

Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  *  file:  CmdLine.h
00005  *
00006  *  Copyright (c) 2003, Michael E. Smoot .
00007  *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
00008  *  All rights reverved.
00009  *
00010  *  See the file COPYING in the top directory of this distribution for
00011  *  more information.
00012  *
00013  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
00014  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00015  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00016  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00017  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00018  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00019  *  DEALINGS IN THE SOFTWARE.
00020  *
00021  *****************************************************************************/
00022 
00023 #ifndef TCLAP_CMDLINE_H
00024 #define TCLAP_CMDLINE_H
00025 
00026 #include <tclap/SwitchArg.h>
00027 #include <tclap/MultiSwitchArg.h>
00028 #include <tclap/UnlabeledValueArg.h>
00029 #include <tclap/UnlabeledMultiArg.h>
00030 
00031 #include <tclap/XorHandler.h>
00032 #include <tclap/HelpVisitor.h>
00033 #include <tclap/VersionVisitor.h>
00034 #include <tclap/IgnoreRestVisitor.h>
00035 
00036 #include <tclap/CmdLineOutput.h>
00037 #include <tclap/StdOutput.h>
00038 
00039 #include <tclap/Constraint.h>
00040 #include <tclap/ValuesConstraint.h>
00041 
00042 #include <string>
00043 #include <vector>
00044 #include <list>
00045 #include <iostream>
00046 #include <iomanip>
00047 #include <algorithm>
00048 
00049 namespace TCLAP {
00050 
00055 class CmdLine : public CmdLineInterface
00056 {
00057 protected:
00058 
00063   std::list<Arg*> _argList;
00064 
00068   std::string _progName;
00069 
00073   std::string _message;
00074 
00078   std::string _version;
00079 
00085   int _numRequired;
00086 
00091   char _delimiter;
00092 
00096   XorHandler _xorHandler;
00097 
00103   std::list<Arg*> _argDeleteOnExitList;
00104 
00110   std::list<Visitor*> _visitorDeleteOnExitList;
00111 
00115   CmdLineOutput* _output;
00116 
00123   bool _emptyCombined(const std::string& s);
00124 
00128   void deleteOnExit(Arg* ptr);
00129 
00133   void deleteOnExit(Visitor* ptr);
00134 
00135 private:
00136 
00141   void _constructor();
00142 
00147   bool _userSetOutput;
00148 
00152   bool _helpAndVersion;
00153 
00154 public:
00155 
00168   CmdLine(const std::string& message,
00169           const char delimiter = ' ',
00170           const std::string& version = "none",
00171           bool helpAndVersion = true);
00172 
00176   virtual ~CmdLine();
00177 
00182   void add( Arg& a );
00183 
00188   void add( Arg* a );
00189 
00196   void xorAdd( Arg& a, Arg& b );
00197 
00203   void xorAdd( std::vector<Arg*>& xors );
00204 
00210   void parse(int argc, char** argv);
00211 
00215   CmdLineOutput* getOutput();
00216 
00220   void setOutput(CmdLineOutput* co);
00221 
00225   std::string& getVersion();
00226 
00230   std::string& getProgramName();
00231 
00235   std::list<Arg*>& getArgList();
00236 
00240   XorHandler& getXorHandler();
00241 
00245   char getDelimiter();
00246 
00250   std::string& getMessage();
00251 
00255   bool hasHelpAndVersion();
00256 };
00257 
00258 
00260                 //Begin CmdLine.cpp
00262 
00263                 inline CmdLine::CmdLine(const std::string& m,
00264                 char delim,
00265                                         const std::string& v,
00266                                         bool help )
00267                   : _progName("not_set_yet"),
00268                     _message(m),
00269                     _version(v),
00270                     _numRequired(0),
00271                     _delimiter(delim),
00272                     _userSetOutput(false),
00273                     _helpAndVersion(help)
00274                 {
00275                   _constructor();
00276                 }
00277 
00278 inline CmdLine::~CmdLine()
00279 {
00280   ArgListIterator argIter;
00281   VisitorListIterator visIter;
00282 
00283   for( argIter = _argDeleteOnExitList.begin();
00284        argIter != _argDeleteOnExitList.end();
00285        ++argIter)
00286     delete *argIter;
00287 
00288   for( visIter = _visitorDeleteOnExitList.begin();
00289        visIter != _visitorDeleteOnExitList.end();
00290        ++visIter)
00291     delete *visIter;
00292 
00293   if ( !_userSetOutput )
00294     delete _output;
00295 }
00296 
00297 inline void CmdLine::_constructor()
00298 {
00299   _output = new StdOutput;
00300 
00301   Arg::setDelimiter( _delimiter );
00302 
00303   Visitor* v;
00304 
00305   if ( _helpAndVersion )
00306     {
00307     v = new HelpVisitor( this, &_output );
00308     SwitchArg* help = new SwitchArg("h","help",
00309                                     "Displays usage information and exits.",
00310                                     false, v);
00311     add( help );
00312     deleteOnExit(help);
00313     deleteOnExit(v);
00314 
00315     v = new VersionVisitor( this, &_output );
00316     SwitchArg* vers = new SwitchArg("","version",
00317                                     "Displays version information and exits.",
00318                                     false, v);
00319     add( vers );
00320     deleteOnExit(vers);
00321     deleteOnExit(v);
00322     }
00323 
00324   v = new IgnoreRestVisitor();
00325   SwitchArg* ignore  = new SwitchArg(Arg::flagStartString(),
00326                                      Arg::ignoreNameString(),
00327                                      "Ignores the rest of the labeled arguments following this flag.",
00328                                      false, v);
00329   add( ignore );
00330   deleteOnExit(ignore);
00331   deleteOnExit(v);
00332 }
00333 
00334 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00335 {
00336   _xorHandler.add( ors );
00337 
00338   for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00339     {
00340     (*it)->forceRequired();
00341     (*it)->setRequireLabel( "OR required" );
00342 
00343     add( *it );
00344     }
00345 }
00346 
00347 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00348 {
00349   std::vector<Arg*> ors;
00350   ors.push_back( &a );
00351   ors.push_back( &b );
00352   xorAdd( ors );
00353 }
00354 
00355 inline void CmdLine::add( Arg& a )
00356 {
00357   add( &a );
00358 }
00359 
00360 inline void CmdLine::add( Arg* a )
00361 {
00362   for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00363     if ( *a == *(*it) )
00364       throw( SpecificationException(
00365                "Argument with same flag/name already exists!",
00366                a->longID() ) );
00367 
00368   a->addToList( _argList );
00369 
00370   if ( a->isRequired() )
00371     _numRequired++;
00372 }
00373 
00374 inline void CmdLine::parse(int argc, char** argv)
00375 {
00376   try {
00377 
00378   _progName = argv[0];
00379 
00380   // this step is necessary so that we have easy access to mutable strings.
00381   std::vector<std::string> args;
00382   for (int i = 1; i < argc; i++)
00383     args.push_back(argv[i]);
00384 
00385   int requiredCount = 0;
00386 
00387   for (int i = 0; static_cast<size_t>(i) < args.size(); i++)
00388     {
00389     bool matched = false;
00390     for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00391       {
00392       if ( (*it)->processArg( &i, args ) )
00393         {
00394         requiredCount += _xorHandler.check( *it );
00395         matched = true;
00396         break;
00397         }
00398       }
00399 
00400     // checks to see if the argument is an empty combined switch ...
00401     // and if so, then we've actually matched it
00402     if ( !matched && _emptyCombined( args[i] ) )
00403       matched = true;
00404 
00405     if ( !matched && !Arg::ignoreRest() )
00406       throw(CmdLineParseException("Couldn't find match for argument",
00407                                   args[i]));
00408     }
00409 
00410   if ( requiredCount < _numRequired )
00411     throw(CmdLineParseException("One or more required arguments missing!"));
00412 
00413   if ( requiredCount > _numRequired )
00414     throw(CmdLineParseException("Too many arguments!"));
00415 
00416   } catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
00417 }
00418 
00419 inline bool CmdLine::_emptyCombined(const std::string& s)
00420 {
00421   if ( s[0] != Arg::flagStartChar() )
00422     return false;
00423 
00424   for ( int i = 1; static_cast<size_t>(i) < s.length(); i++ )
00425     if ( s[i] != Arg::blankChar() )
00426       return false;
00427 
00428   return true;
00429 }
00430 
00431 inline void CmdLine::deleteOnExit(Arg* ptr)
00432 {
00433   _argDeleteOnExitList.push_back(ptr);
00434 }
00435 
00436 inline void CmdLine::deleteOnExit(Visitor* ptr)
00437 {
00438   _visitorDeleteOnExitList.push_back(ptr);
00439 }
00440 
00441 inline CmdLineOutput* CmdLine::getOutput()
00442 {
00443   return _output;
00444 }
00445 
00446 inline void CmdLine::setOutput(CmdLineOutput* co)
00447 {
00448   _userSetOutput = true;
00449   _output = co;
00450 }
00451 
00452 inline std::string& CmdLine::getVersion()
00453 {
00454   return _version;
00455 }
00456 
00457 inline std::string& CmdLine::getProgramName()
00458 {
00459   return _progName;
00460 }
00461 
00462 inline std::list<Arg*>& CmdLine::getArgList()
00463 {
00464   return _argList;
00465 }
00466 
00467 inline XorHandler& CmdLine::getXorHandler()
00468 {
00469   return _xorHandler;
00470 }
00471 
00472 inline char CmdLine::getDelimiter()
00473 {
00474   return _delimiter;
00475 }
00476 
00477 inline std::string& CmdLine::getMessage()
00478 {
00479   return _message;
00480 }
00481 
00482 inline bool CmdLine::hasHelpAndVersion()
00483 {
00484   return _helpAndVersion;
00485 }
00486 
00488 //End CmdLine.cpp
00490 
00491 
00492 
00493 } //namespace TCLAP
00494 #endif

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1