cmd_line.hpp
Go to the documentation of this file.
00001 
00011 /*****************************************************************************
00012 ** Ifdefs
00013 *****************************************************************************/
00014 
00015 #ifndef TCLAP_CMDLINE_H
00016 #define TCLAP_CMDLINE_H
00017 
00018 #include "switch_arg.hpp"
00019 #include "multi_switch_arg.hpp"
00020 #include "unlabeled_value_arg.hpp"
00021 #include "unlabeled_multi_arg.hpp"
00022 
00023 #include "xor_handler.hpp"
00024 #include "help_visitor.hpp"
00025 #include "version_visitor.hpp"
00026 #include "ignore_rest_visitor.hpp"
00027 
00028 #include "cmd_line_output.hpp"
00029 #include "std_output.hpp"
00030 
00031 #include "constraint.hpp"
00032 #include "values_constraint.hpp"
00033 
00034 #include <string>
00035 #include <vector>
00036 #include <list>
00037 #include <iostream>
00038 #include <iomanip>
00039 #include <algorithm>
00040 
00041 namespace ecl {
00042 
00049 class CmdLine : public CmdLineInterface
00050 {
00051         protected:
00052 
00057                 std::list<Arg*> _argList;
00058 
00062                 std::string _progName;
00063 
00067                 std::string _message;
00068 
00072                 std::string _version;
00073 
00079                 int _numRequired;
00080 
00085                 char _delimiter;
00086 
00090                 XorHandler _xorHandler;
00091 
00097                 std::list<Arg*> _argDeleteOnExitList;
00098 
00104                 std::list<Visitor*> _visitorDeleteOnExitList;
00105 
00109                 CmdLineOutput* _output;
00110 
00117                 bool _emptyCombined(const std::string& s);
00118 
00122                 void deleteOnExit(Arg* ptr);
00123 
00127                 void deleteOnExit(Visitor* ptr);
00128 
00129         private:
00130 
00135                 void _constructor();
00136 
00141                 bool _userSetOutput;
00142 
00146                 bool _helpAndVersion;
00147 
00148         public:
00149 
00162                 CmdLine(const std::string& message,
00163                                 const char delimiter = ' ',
00164                                 const std::string& version = "none",
00165                                 bool helpAndVersion = true);
00166 
00170                 virtual ~CmdLine();
00171 
00176                 void add( Arg& a );
00177 
00182                 void add( Arg* a );
00183 
00190                 void xorAdd( Arg& a, Arg& b );
00191 
00197                 void xorAdd( std::vector<Arg*>& xors );
00198 
00204                 void parse(int argc, char** argv);
00205 
00209                 CmdLineOutput* getOutput();
00210 
00214                 void setOutput(CmdLineOutput* co);
00215 
00219                 std::string& getVersion();
00220 
00224                 std::string& getProgramName();
00225 
00229                 std::list<Arg*>& getArgList();
00230 
00234                 XorHandler& getXorHandler();
00235 
00239                 char getDelimiter();
00240 
00244                 std::string& getMessage();
00245 
00249                 bool hasHelpAndVersion();
00250 };
00251 
00252 
00254 //Begin CmdLine.cpp
00256 
00257 inline CmdLine::CmdLine(const std::string& m,
00258                                         char delim,
00259                                                 const std::string& v,
00260                                                 bool help )
00261 : _progName("not_set_yet"),
00262   _message(m),
00263   _version(v),
00264   _numRequired(0),
00265   _delimiter(delim),
00266   _userSetOutput(false),
00267   _helpAndVersion(help)
00268 {
00269         _constructor();
00270 }
00271 
00272 inline CmdLine::~CmdLine()
00273 {
00274         ArgListIterator argIter;
00275         VisitorListIterator visIter;
00276 
00277         for( argIter = _argDeleteOnExitList.begin();
00278                  argIter != _argDeleteOnExitList.end();
00279                  ++argIter)
00280                 delete *argIter;
00281 
00282         for( visIter = _visitorDeleteOnExitList.begin();
00283                  visIter != _visitorDeleteOnExitList.end();
00284                  ++visIter)
00285                 delete *visIter;
00286 
00287         if ( !_userSetOutput )
00288                 delete _output;
00289 }
00290 
00291 inline void CmdLine::_constructor()
00292 {
00293         _output = new StdOutput;
00294 
00295         Arg::setDelimiter( _delimiter );
00296 
00297         Visitor* v;
00298 
00299         if ( _helpAndVersion )
00300         {
00301                 v = new HelpVisitor( this, &_output );
00302                 SwitchArg* help = new SwitchArg("h","help",
00303                                                 "Displays usage information and exits.",
00304                                                 false, v);
00305                 add( help );
00306                 deleteOnExit(help);
00307                 deleteOnExit(v);
00308 
00309                 v = new VersionVisitor( this, &_output );
00310                 SwitchArg* vers = new SwitchArg("","version",
00311                                         "Displays version information and exits.",
00312                                         false, v);
00313                 add( vers );
00314                 deleteOnExit(vers);
00315                 deleteOnExit(v);
00316         }
00317 
00318         v = new IgnoreRestVisitor();
00319         SwitchArg* ignore  = new SwitchArg(Arg::flagStartString(),
00320                                            Arg::ignoreNameString(),
00321                            "Ignores the rest of the labeled arguments following this flag.",
00322                                            false, v);
00323         add( ignore );
00324         deleteOnExit(ignore);
00325         deleteOnExit(v);
00326 }
00327 
00328 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00329 {
00330         _xorHandler.add( ors );
00331 
00332         for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00333         {
00334                 (*it)->forceRequired();
00335                 (*it)->setRequireLabel( "OR required" );
00336 
00337                 add( *it );
00338         }
00339 }
00340 
00341 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00342 {
00343     std::vector<Arg*> ors;
00344     ors.push_back( &a );
00345     ors.push_back( &b );
00346         xorAdd( ors );
00347 }
00348 
00349 inline void CmdLine::add( Arg& a )
00350 {
00351         add( &a );
00352 }
00353 
00354 inline void CmdLine::add( Arg* a )
00355 {
00356         for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00357                 if ( *a == *(*it) )
00358                         throw( SpecificationException(
00359                                 "Argument with same flag/name already exists!",
00360                                         a->longID() ) );
00361 
00362         a->addToList( _argList );
00363 
00364         if ( a->isRequired() )
00365                 _numRequired++;
00366 }
00367 
00368 inline void CmdLine::parse(int argc, char** argv)
00369 {
00370         try {
00371 
00372         _progName = argv[0];
00373 
00374         // this step is necessary so that we have easy access to mutable strings.
00375         std::vector<std::string> args;
00376         for (int i = 1; i < argc; i++)
00377                 args.push_back(argv[i]);
00378 
00379         int requiredCount = 0;
00380 
00381         for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
00382         {
00383                 bool matched = false;
00384                 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00385         {
00386                         if ( (*it)->processArg( &i, args ) )
00387                         {
00388                                 requiredCount += _xorHandler.check( *it );
00389                                 matched = true;
00390                                 break;
00391                         }
00392         }
00393 
00394                 // checks to see if the argument is an empty combined switch ...
00395                 // and if so, then we've actually matched it
00396                 if ( !matched && _emptyCombined( args[i] ) )
00397                         matched = true;
00398 
00399                 if ( !matched && !Arg::ignoreRest() )
00400                         throw(CmdLineParseException("Couldn't find match for argument",
00401                                                      args[i]));
00402     }
00403 
00404         if ( requiredCount < _numRequired )
00405                 throw(CmdLineParseException("One or more required arguments missing!"));
00406 
00407         if ( requiredCount > _numRequired )
00408                 throw(CmdLineParseException("Too many arguments!"));
00409 
00410         } catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
00411 }
00412 
00413 inline bool CmdLine::_emptyCombined(const std::string& s)
00414 {
00415         if ( s[0] != Arg::flagStartChar() )
00416                 return false;
00417 
00418         for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00419                 if ( s[i] != Arg::blankChar() )
00420                         return false;
00421 
00422         return true;
00423 }
00424 
00425 inline void CmdLine::deleteOnExit(Arg* ptr)
00426 {
00427         _argDeleteOnExitList.push_back(ptr);
00428 }
00429 
00430 inline void CmdLine::deleteOnExit(Visitor* ptr)
00431 {
00432         _visitorDeleteOnExitList.push_back(ptr);
00433 }
00434 
00435 inline CmdLineOutput* CmdLine::getOutput()
00436 {
00437         return _output;
00438 }
00439 
00440 inline void CmdLine::setOutput(CmdLineOutput* co)
00441 {
00442         _userSetOutput = true;
00443         _output = co;
00444 }
00445 
00446 inline std::string& CmdLine::getVersion()
00447 {
00448         return _version;
00449 }
00450 
00451 inline std::string& CmdLine::getProgramName()
00452 {
00453         return _progName;
00454 }
00455 
00456 inline std::list<Arg*>& CmdLine::getArgList()
00457 {
00458         return _argList;
00459 }
00460 
00461 inline XorHandler& CmdLine::getXorHandler()
00462 {
00463         return _xorHandler;
00464 }
00465 
00466 inline char CmdLine::getDelimiter()
00467 {
00468         return _delimiter;
00469 }
00470 
00471 inline std::string& CmdLine::getMessage()
00472 {
00473         return _message;
00474 }
00475 
00476 inline bool CmdLine::hasHelpAndVersion()
00477 {
00478         return _helpAndVersion;
00479 }
00480 
00482 //End CmdLine.cpp
00484 
00485 }; // namespace ecl
00486 
00487 #endif


ecl_command_line
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:37