Ignore:
Timestamp:
24/08/10 11:23:06 (21 months ago)
Author:
Freddie Akeroyd
Message:

Update to tclap 1.2.0 from http://tclap.sourceforge.net/
Refs #244

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/third_party/tclap/CmdLine.h

    r857 r1515  
    1  
    2 /******************************************************************************  
    3  *  
     1// -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- 
     2 
     3/****************************************************************************** 
     4 * 
    45 *  file:  CmdLine.h 
    5  *  
     6 * 
    67 *  Copyright (c) 2003, Michael E. Smoot . 
    78 *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. 
    89 *  All rights reverved. 
    9  *  
     10 * 
    1011 *  See the file COPYING in the top directory of this distribution for 
    1112 *  more information. 
    12  *   
    13  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS  
    14  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
    15  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL  
    16  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
    17  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  
    18  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  
    19  *  DEALINGS IN THE SOFTWARE.   
    20  *   
    21  *****************************************************************************/  
     13 * 
     14 *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
     15 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     16 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
     17 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     18 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
     19 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
     20 *  DEALINGS IN THE SOFTWARE. 
     21 * 
     22 *****************************************************************************/ 
    2223 
    2324#ifndef TCLAP_CMDLINE_H 
     
    2526 
    2627#include <tclap/SwitchArg.h> 
     28#include <tclap/MultiSwitchArg.h> 
    2729#include <tclap/UnlabeledValueArg.h> 
    2830#include <tclap/UnlabeledMultiArg.h> 
     
    3537#include <tclap/CmdLineOutput.h> 
    3638#include <tclap/StdOutput.h> 
     39 
     40#include <tclap/Constraint.h> 
     41#include <tclap/ValuesConstraint.h> 
    3742 
    3843#include <string> 
     
    4247#include <iomanip> 
    4348#include <algorithm> 
     49#include <stdlib.h> // Needed for exit(), which isn't defined in some envs. 
    4450 
    4551namespace TCLAP { 
     52 
     53template<typename T> void DelPtr(T ptr) 
     54{ 
     55        delete ptr; 
     56} 
     57 
     58template<typename C> void ClearContainer(C &c) 
     59{ 
     60        typedef typename C::value_type value_type; 
     61        std::for_each(c.begin(), c.end(), DelPtr<value_type>); 
     62        c.clear(); 
     63} 
     64 
    4665 
    4766/** 
     
    7594 
    7695                /** 
    77                  * The number of arguments that are required to be present on  
    78                  * the command line. This is set dynamically, based on the  
     96                 * The number of arguments that are required to be present on 
     97                 * the command line. This is set dynamically, based on the 
    7998                 * Args added to the CmdLine object. 
    8099                 */ 
     
    82101 
    83102                /** 
    84                  * The character that is used to separate the argument flag/name  
     103                 * The character that is used to separate the argument flag/name 
    85104                 * from the value.  Defaults to ' ' (space). 
    86105                 */ 
     
    110129                 */ 
    111130                CmdLineOutput* _output; 
     131 
     132                /** 
     133                 * Should CmdLine handle parsing exceptions internally? 
     134                 */ 
     135                bool _handleExceptions; 
     136 
     137                /** 
     138                 * Throws an exception listing the missing args. 
     139                 */ 
     140                void missingArgsException(); 
    112141 
    113142                /** 
     
    119148                bool _emptyCombined(const std::string& s); 
    120149 
    121         private: 
    122  
    123                 /** 
    124                  * Encapsulates the code common to the constructors (which is all 
    125                  * of it). 
     150                /** 
     151                 * Perform a delete ptr; operation on ptr when this object is deleted. 
     152                 */ 
     153                void deleteOnExit(Arg* ptr); 
     154 
     155                /** 
     156                 * Perform a delete ptr; operation on ptr when this object is deleted. 
     157                 */ 
     158                void deleteOnExit(Visitor* ptr); 
     159 
     160private: 
     161 
     162                /** 
     163                 * Encapsulates the code common to the constructors 
     164                 * (which is all of it). 
    126165                 */ 
    127166                void _constructor(); 
    128167 
    129                 /** 
    130                  * Perform a delete ptr; operation on ptr when this object is deleted. 
    131                  */ 
    132                 void deleteOnExit(Arg* ptr); 
    133  
    134                 /** 
    135                  * Perform a delete ptr; operation on ptr when this object is deleted. 
    136                  */ 
    137                 void deleteOnExit(Visitor* ptr); 
    138168 
    139169                /** 
     
    143173                bool _userSetOutput; 
    144174 
     175                /** 
     176                 * Whether or not to automatically create help and version switches. 
     177                 */ 
     178                bool _helpAndVersion; 
     179 
    145180        public: 
    146  
    147                 /** 
    148                  * Command line constructor. DEPRECATED!!!  This is here to maintain 
    149                  * backwards compatibility with earlier releases.  Note that the 
    150                  * program name will be overwritten with argv[0].  The delimiter 
    151                  * used is ' ' (as before). 
    152                  * \param name - The program name - will be overwritten with argv[0]. 
    153                  * \param message - The message to be used in the usage output. 
    154                  * \param version - The version number to be used in the 
    155                  * --version switch. 
    156                  */ 
    157                 CmdLine(const std::string& name,  
    158                                 const std::string& message, 
    159                                 const std::string& version = "none" ); 
    160181 
    161182                /** 
     
    168189                 * \param version - The version number to be used in the 
    169190                 * --version switch. 
    170                  */ 
    171                 CmdLine(const std::string& message,  
     191                 * \param helpAndVersion - Whether or not to create the Help and 
     192                 * Version switches. Defaults to true. 
     193                 */ 
     194                CmdLine(const std::string& message, 
    172195                                const char delimiter = ' ', 
    173                                 const std::string& version = "none" ); 
    174                  
     196                                const std::string& version = "none", 
     197                                bool helpAndVersion = true); 
     198 
    175199                /** 
    176200                 * Deletes any resources allocated by a CmdLine object. 
     
    180204                /** 
    181205                 * Adds an argument to the list of arguments to be parsed. 
    182                  * \param a - Argument to be added.  
     206                 * \param a - Argument to be added. 
    183207                 */ 
    184208                void add( Arg& a ); 
     
    186210                /** 
    187211                 * An alternative add.  Functionally identical. 
    188                  * \param a - Argument to be added.  
     212                 * \param a - Argument to be added. 
    189213                 */ 
    190214                void add( Arg* a ); 
     
    193217                 * Add two Args that will be xor'd.  If this method is used, add does 
    194218                 * not need to be called. 
    195                  * \param a - Argument to be added and xor'd.  
    196                  * \param b - Argument to be added and xor'd.  
     219                 * \param a - Argument to be added and xor'd. 
     220                 * \param b - Argument to be added and xor'd. 
    197221                 */ 
    198222                void xorAdd( Arg& a, Arg& b ); 
    199223 
    200224                /** 
    201                  * Add a list of Args that will be xor'd.  If this method is used,  
     225                 * Add a list of Args that will be xor'd.  If this method is used, 
    202226                 * add does not need to be called. 
    203                  * \param xors - List of Args to be added and xor'd.  
     227                 * \param xors - List of Args to be added and xor'd. 
    204228                 */ 
    205229                void xorAdd( std::vector<Arg*>& xors ); 
     
    210234                 * \param argv - Array of arguments. 
    211235                 */ 
    212                 void parse(int argc, char** argv); 
     236                void parse(int argc, const char * const * argv); 
     237 
     238                /** 
     239                 * Parses the command line. 
     240                 * \param args - A vector of strings representing the args. 
     241                 * args[0] is still the program name. 
     242                 */ 
     243                void parse(std::vector<std::string>& args); 
    213244 
    214245                /** 
     
    251282                 */ 
    252283                std::string& getMessage(); 
     284 
     285                /** 
     286                 * 
     287                 */ 
     288                bool hasHelpAndVersion(); 
     289 
     290                /** 
     291                 * Disables or enables CmdLine's internal parsing exception handling. 
     292                 * 
     293                 * @param state Should CmdLine handle parsing exceptions internally? 
     294                 */ 
     295                void setExceptionHandling(const bool state); 
     296 
     297                /** 
     298                 * Returns the current state of the internal exception handling. 
     299                 * 
     300                 * @retval true Parsing exceptions are handled internally. 
     301                 * @retval false Parsing exceptions are propagated to the caller. 
     302                 */ 
     303                bool getExceptionHandling() const; 
     304 
     305                /** 
     306                 * Allows the CmdLine object to be reused. 
     307                 */ 
     308                void reset(); 
     309 
    253310}; 
    254311 
     
    258315/////////////////////////////////////////////////////////////////////////////// 
    259316 
    260 inline CmdLine::CmdLine(const std::string& n,  
    261                                         const std::string& m,  
    262                                                 const std::string& v ) 
    263 : _progName(n), 
    264   _message(m), 
    265   _version(v), 
    266   _numRequired(0), 
    267   _delimiter(' '), 
    268   _userSetOutput(false) 
    269 {  
    270         _constructor(); 
    271 } 
    272  
    273 inline CmdLine::CmdLine(const std::string& m,  
    274                                         char delim,  
    275                                                 const std::string& v ) 
     317inline CmdLine::CmdLine(const std::string& m, 
     318                        char delim, 
     319                        const std::string& v, 
     320                        bool help ) 
    276321: _progName("not_set_yet"), 
    277322  _message(m), 
     
    279324  _numRequired(0), 
    280325  _delimiter(delim), 
    281   _userSetOutput(false) 
     326  _handleExceptions(true), 
     327  _userSetOutput(false), 
     328  _helpAndVersion(help) 
    282329{ 
    283330        _constructor(); 
     
    286333inline CmdLine::~CmdLine() 
    287334{ 
    288         ArgListIterator argIter; 
    289         VisitorListIterator visIter; 
    290    
    291         for( argIter = _argDeleteOnExitList.begin();  
    292                  argIter != _argDeleteOnExitList.end();  
    293                  ++argIter) 
    294                 delete *argIter; 
    295    
    296         for( visIter = _visitorDeleteOnExitList.begin();  
    297                  visIter != _visitorDeleteOnExitList.end();  
    298                  ++visIter)  
    299                 delete *visIter; 
    300  
    301         if ( !_userSetOutput ) 
     335        ClearContainer(_argDeleteOnExitList); 
     336        ClearContainer(_visitorDeleteOnExitList); 
     337 
     338        if ( !_userSetOutput ) { 
    302339                delete _output; 
     340                _output = 0; 
     341        } 
    303342} 
    304343 
    305344inline void CmdLine::_constructor() 
    306 {  
     345{ 
    307346        _output = new StdOutput; 
    308347 
    309         Visitor *v; 
    310          
    311348        Arg::setDelimiter( _delimiter ); 
    312349 
    313         v = new HelpVisitor( this, &_output ); 
    314         SwitchArg* help = new SwitchArg("h","help",  
    315                                         "Displays usage information and exits.",  
     350        Visitor* v; 
     351 
     352        if ( _helpAndVersion ) 
     353        { 
     354                v = new HelpVisitor( this, &_output ); 
     355                SwitchArg* help = new SwitchArg("h","help", 
     356                                                "Displays usage information and exits.", 
     357                                                false, v); 
     358                add( help ); 
     359                deleteOnExit(help); 
     360                deleteOnExit(v); 
     361 
     362                v = new VersionVisitor( this, &_output ); 
     363                SwitchArg* vers = new SwitchArg("","version", 
     364                                        "Displays version information and exits.", 
    316365                                        false, v); 
    317         add( help ); 
    318         deleteOnExit(help); 
    319         deleteOnExit(v); 
    320          
    321         v = new VersionVisitor( this, &_output ); 
    322         SwitchArg* vers = new SwitchArg("v","version",  
    323                                         "Displays version information and exits.",  
    324                                         false, v); 
    325         add( vers ); 
    326         deleteOnExit(vers); 
    327         deleteOnExit(v); 
     366                add( vers ); 
     367                deleteOnExit(vers); 
     368                deleteOnExit(v); 
     369        } 
    328370 
    329371        v = new IgnoreRestVisitor(); 
    330         SwitchArg* ignore  = new SwitchArg(Arg::flagStartString(),  
     372        SwitchArg* ignore  = new SwitchArg(Arg::flagStartString(), 
    331373                                           Arg::ignoreNameString(), 
    332374                           "Ignores the rest of the labeled arguments following this flag.", 
     
    350392} 
    351393 
    352 inline void CmdLine::xorAdd( Arg& a, Arg& b )  
     394inline void CmdLine::xorAdd( Arg& a, Arg& b ) 
    353395{ 
    354396    std::vector<Arg*> ors; 
     
    358400} 
    359401 
    360 inline void CmdLine::add( Arg& a )  
    361 {  
     402inline void CmdLine::add( Arg& a ) 
     403{ 
    362404        add( &a ); 
    363405} 
    364406 
    365 inline void CmdLine::add( Arg* a )  
    366 {  
    367         for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )  
    368                 if ( *a == *(*it) )  
    369                         throw( SpecificationException(  
    370                                 "Argument with same flag/name already exists!",  
     407inline void CmdLine::add( Arg* a ) 
     408{ 
     409        for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 
     410                if ( *a == *(*it) ) 
     411                        throw( SpecificationException( 
     412                                "Argument with same flag/name already exists!", 
    371413                                        a->longID() ) ); 
    372414 
    373415        a->addToList( _argList ); 
    374416 
    375         if ( a->isRequired() )  
    376                 _numRequired++;  
    377 } 
    378  
    379 inline void CmdLine::parse(int argc, char** argv) 
    380 { 
     417        if ( a->isRequired() ) 
     418                _numRequired++; 
     419} 
     420 
     421 
     422inline void CmdLine::parse(int argc, const char * const * argv) 
     423{ 
     424                // this step is necessary so that we have easy access to 
     425                // mutable strings. 
     426                std::vector<std::string> args; 
     427                for (int i = 0; i < argc; i++) 
     428                        args.push_back(argv[i]); 
     429 
     430                parse(args); 
     431} 
     432 
     433inline void CmdLine::parse(std::vector<std::string>& args) 
     434{ 
     435        bool shouldExit = false; 
     436        int estat = 0; 
     437 
    381438        try { 
    382  
    383         _progName = argv[0];  
    384  
    385         // this step is necessary so that we have easy access to mutable strings. 
    386         std::vector<std::string> args; 
    387         for (int i = 1; i < argc; i++) 
    388                 args.push_back(argv[i]); 
    389  
    390         int requiredCount = 0; 
    391  
    392         for (int i = 0; (unsigned int)i < args.size(); i++) 
    393         { 
    394                 bool matched = false; 
    395                 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++) 
    396         { 
    397                         if ( (*it)->processArg( &i, args ) ) 
    398                         { 
    399                                 requiredCount += _xorHandler.check( *it ); 
     439                _progName = args.front(); 
     440                args.erase(args.begin()); 
     441 
     442                int requiredCount = 0; 
     443 
     444                for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++) { 
     445                        bool matched = false; 
     446                        for (ArgListIterator it = _argList.begin(); 
     447                                 it != _argList.end(); it++) { 
     448                                if ( (*it)->processArg( &i, args ) ) 
     449                                        { 
     450                                                requiredCount += _xorHandler.check( *it ); 
     451                                                matched = true; 
     452                                                break; 
     453                                        } 
     454                        } 
     455 
     456                        // checks to see if the argument is an empty combined 
     457                        // switch and if so, then we've actually matched it 
     458                        if ( !matched && _emptyCombined( args[i] ) ) 
    400459                                matched = true; 
    401                                 break; 
    402                         } 
    403         } 
    404  
    405                 // checks to see if the argument is an empty combined switch ... 
    406                 // and if so, then we've actually matched it 
    407                 if ( !matched && _emptyCombined( args[i] ) ) 
    408                         matched = true; 
    409  
    410                 if ( !matched && !Arg::ignoreRest() ) 
    411                         throw(CmdLineParseException("Couldn't find match for argument", 
    412                                                      args[i])); 
    413     } 
    414  
    415         if ( requiredCount < _numRequired ) 
    416                 throw(CmdLineParseException("One or more required arguments missing!")); 
    417  
    418         if ( requiredCount > _numRequired ) 
    419                 throw(CmdLineParseException("Too many arguments!")); 
    420  
    421         } catch ( ArgException e ) { _output->failure(*this,e); exit(1); } 
     460 
     461                        if ( !matched && !Arg::ignoreRest() ) 
     462                                throw(CmdLineParseException("Couldn't find match " 
     463                                                                                        "for argument", 
     464                                                                                        args[i])); 
     465                } 
     466 
     467                if ( requiredCount < _numRequired ) 
     468                        missingArgsException(); 
     469 
     470                if ( requiredCount > _numRequired ) 
     471                        throw(CmdLineParseException("Too many arguments!")); 
     472 
     473        } catch ( ArgException& e ) { 
     474                // If we're not handling the exceptions, rethrow. 
     475                if ( !_handleExceptions) { 
     476                        throw; 
     477                } 
     478 
     479                try { 
     480                        _output->failure(*this,e); 
     481                } catch ( ExitException &ee ) { 
     482                        estat = ee.getExitStatus(); 
     483                        shouldExit = true; 
     484                } 
     485        } catch (ExitException &ee) { 
     486                // If we're not handling the exceptions, rethrow. 
     487                if ( !_handleExceptions) { 
     488                        throw; 
     489                } 
     490 
     491                estat = ee.getExitStatus(); 
     492                shouldExit = true; 
     493        } 
     494 
     495        if (shouldExit) 
     496                exit(estat); 
    422497} 
    423498 
    424499inline bool CmdLine::_emptyCombined(const std::string& s) 
    425500{ 
    426         if ( s[0] != Arg::flagStartChar() ) 
     501        if ( s.length() > 0 && s[0] != Arg::flagStartChar() ) 
    427502                return false; 
    428503 
    429         for ( int i = 1; (unsigned int)i < s.length(); i++ ) 
     504        for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ ) 
    430505                if ( s[i] != Arg::blankChar() ) 
    431506                        return false; 
     
    434509} 
    435510 
     511inline void CmdLine::missingArgsException() 
     512{ 
     513                int count = 0; 
     514 
     515                std::string missingArgList; 
     516                for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++) 
     517                { 
     518                        if ( (*it)->isRequired() && !(*it)->isSet() ) 
     519                        { 
     520                                missingArgList += (*it)->getName(); 
     521                                missingArgList += ", "; 
     522                                count++; 
     523                        } 
     524                } 
     525                missingArgList = missingArgList.substr(0,missingArgList.length()-2); 
     526 
     527                std::string msg; 
     528                if ( count > 1 ) 
     529                        msg = "Required arguments missing: "; 
     530                else 
     531                        msg = "Required argument missing: "; 
     532 
     533                msg += missingArgList; 
     534 
     535                throw(CmdLineParseException(msg)); 
     536} 
     537 
    436538inline void CmdLine::deleteOnExit(Arg* ptr) 
    437539{ 
     
    483585{ 
    484586        return _message; 
     587} 
     588 
     589inline bool CmdLine::hasHelpAndVersion() 
     590{ 
     591        return _helpAndVersion; 
     592} 
     593 
     594inline void CmdLine::setExceptionHandling(const bool state) 
     595{ 
     596        _handleExceptions = state; 
     597} 
     598 
     599inline bool CmdLine::getExceptionHandling() const 
     600{ 
     601        return _handleExceptions; 
     602} 
     603 
     604inline void CmdLine::reset() 
     605{ 
     606        for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 
     607        { 
     608                (*it)->reset(); 
     609        } 
     610         
     611        _progName.clear(); 
    485612} 
    486613 
     
    492619 
    493620} //namespace TCLAP 
    494 #endif  
     621#endif 
Note: See TracChangeset for help on using the changeset viewer.