Main MRPT website > C++ reference
MRPT logo

Arg.h

Go to the documentation of this file.
00001 
00002 /****************************************************************************** 
00003  * 
00004  *  file:  Arg.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 
00024 #ifndef TCLAP_ARGUMENT_H
00025 #define TCLAP_ARGUMENT_H
00026 
00027 #include <string>
00028 #include <vector>
00029 #include <list>
00030 #include <iostream>
00031 
00032 #include <mrpt/otherlibs/tclap/ArgException.h>
00033 #include <mrpt/otherlibs/tclap/Visitor.h>
00034 #include <mrpt/otherlibs/tclap/CmdLineInterface.h>
00035 
00036 namespace TCLAP {
00037 
00038 /** 
00039  * A virtual base class that defines the essential data for all arguments.
00040  * This class, or one of its existing children, must be subclassed to do
00041  * anything. 
00042  */
00043 class Arg
00044 {
00045         private: 
00046 
00047                 /**
00048                  * Indicates whether the rest of the arguments should be ignored.
00049                  */
00050                 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00051 
00052                 /**
00053                  * The delimiter that separates an argument flag/name from the
00054                  * value.
00055                  */
00056                 static char& delimiterRef() { static char delim = ' '; return delim; } 
00057 
00058         protected:
00059 
00060                 /** 
00061                  * The single char flag used to identify the argument.
00062                  * This value (preceded by a dash {-}), can be used to identify 
00063                  * an argument on the command line.  The _flag can be blank, 
00064                  * in fact this is how unlabeled args work.  Unlabeled args must
00065                  * override appropriate functions to get correct handling. Note 
00066                  * that the _flag does NOT include the dash as part of the flag.
00067                  */
00068                 std::string _flag;
00069 
00070                 /**
00071                  * A single work namd indentifying the argument.
00072                  * This value (preceded by two dashed {--}) can also be used 
00073                  * to identify an argument on the command line.  Note that the
00074                  * _name does NOT include the two dashes as part of the _name. The
00075                  * _name cannot be blank.
00076                  */
00077                 std::string _name;
00078 
00079                 /**
00080                  * Description of the argument. 
00081                  */
00082                 std::string _description;
00083 
00084                 /** 
00085                  * Indicating whether the argument is required.
00086                  */
00087                 bool _required;
00088 
00089                 /**
00090                  * Label to be used in usage description.  Normally set to 
00091                  * "required", but can be changed when necessary.
00092                  */
00093                 std::string _requireLabel;
00094 
00095                 /**
00096                  * Indicates whether a value is required for the argument.
00097                  * Note that the value may be required but the argument/value
00098                  * combination may not be, as specified by _required.
00099                  */
00100                 bool _valueRequired;
00101 
00102                 /**
00103                  * Indicates whether the argument has been set.
00104                  * Indicates that a value on the command line has matched the
00105                  * name/flag of this argument and the values have been set accordingly.
00106                  */
00107                 bool _alreadySet;
00108 
00109                 /**
00110                  * A pointer to a vistitor object.
00111                  * The visitor allows special handling to occur as soon as the
00112                  * argument is matched.  This defaults to NULL and should not
00113                  * be used unless absolutely necessary.
00114                  */
00115                 Visitor* _visitor;
00116 
00117                 /**
00118                  * Whether this argument can be ignored, if desired.
00119                  */
00120                 bool _ignoreable;
00121 
00122                 /**
00123                  * Indicates that the arg was set as part of an XOR and not on the
00124                  * command line.
00125                  */
00126                 bool _xorSet;
00127 
00128                 bool _acceptsMultipleValues;
00129 
00130                 /**
00131                  * Performs the special handling described by the Vistitor.
00132                  */
00133                 void _checkWithVisitor() const;
00134 
00135                 /**
00136                  * Primary constructor. YOU (yes you) should NEVER construct an Arg 
00137                  * directly, this is a base class that is extended by various children
00138                  * that are meant to be used.  Use SwitchArg, ValueArg, MultiArg, 
00139                  * UnlabeledValueArg, or UnlabeledMultiArg instead.
00140                  *
00141                  * \param flag - The flag identifying the argument.
00142                  * \param name - The name identifying the argument.
00143                  * \param desc - The description of the argument, used in the usage.
00144                  * \param req - Whether the argument is required.
00145                  * \param valreq - Whether the a value is required for the argument.
00146                  * \param v - The visitor checked by the argument. Defaults to NULL.
00147                  */
00148                 Arg( const std::string& flag, 
00149                          const std::string& name, 
00150                          const std::string& desc, 
00151                          bool req, 
00152                          bool valreq,
00153                          Visitor* v = NULL );
00154 
00155         public:
00156                 /**
00157                  * Destructor.
00158                  */
00159                 virtual ~Arg();
00160 
00161                 /**
00162                  * Adds this to the specified list of Args.
00163                  * \param argList - The list to add this to.
00164                  */
00165                 virtual void addToList( std::list<Arg*>& argList ) const;
00166                 
00167                 /**
00168                  * Begin ignoring arguments since the "--" argument was specified.
00169                  */
00170                 static void beginIgnoring() { ignoreRestRef() = true; }
00171                 
00172                 /**
00173                  * Whether to ignore the rest.
00174                  */
00175                 static bool ignoreRest() { return ignoreRestRef(); }
00176 
00177                 /**
00178                  * The delimiter that separates an argument flag/name from the
00179                  * value.
00180                  */
00181                 static char delimiter() { return delimiterRef(); } 
00182                 
00183                 /**
00184                  * The char used as a place holder when SwitchArgs are combined.
00185                  * Currently set to '*', which shouldn't cause many problems since
00186                  * *'s are expanded by most shells on the command line.  
00187                  */
00188                 static const char blankChar() { return '*'; }
00189                 
00190                 /**
00191                  * The char that indicates the beginning of a flag.  Currently '-'.
00192                  */
00193                 static const char flagStartChar() { return '-'; }
00194                 
00195                 /**
00196                  * The sting that indicates the beginning of a flag.  Currently "-".
00197                  * Should be identical to flagStartChar.
00198                  */
00199                 static const std::string flagStartString() { return "-"; }
00200                 
00201                 /**
00202                  * The sting that indicates the beginning of a name.  Currently "--".
00203                  * Should be flagStartChar twice.
00204                  */
00205                 static const std::string nameStartString() { return "--"; }
00206 
00207                 /**
00208                  * The name used to identify the ignore rest argument.
00209                  */
00210                 static const std::string ignoreNameString() { return "ignore_rest"; }
00211 
00212                 /**
00213                  * Sets the delimiter for all arguments.
00214                  * \param c - The character that delimits flags/names from values.
00215                  */
00216                 static void setDelimiter( char c ) { delimiterRef() = c; }
00217 
00218                 /**
00219                  * Pure virtual method meant to handle the parsing and value assignment
00220                  * of the string on the command line. 
00221                  * \param i - Pointer the the current argument in the list.
00222                  * \param args - Mutable list of strings. What is 
00223                  * passed in from main.
00224                  */
00225                 virtual bool processArg(int *i, std::vector<std::string>& args) = 0; 
00226 
00227                 /**
00228                  * Operator ==.
00229                  * Equality operator. Must be virtual to handle unlabeled args.
00230                  * \param a - The Arg to be compared to this.
00231                  */
00232                 virtual bool operator==(const Arg& a) const;
00233 
00234                 /**
00235                  * Returns the argument flag.
00236                  */
00237                 const std::string& getFlag() const;
00238 
00239                 /**
00240                  * Returns the argument name.
00241                  */
00242                 const std::string& getName() const;
00243 
00244                 /**
00245                  * Returns the argument description.
00246                  */
00247                 std::string getDescription() const;
00248 
00249                 /**
00250                  * Indicates whether the argument is required.
00251                  */
00252                 virtual bool isRequired() const;
00253 
00254                 /**
00255                  * Sets _required to true. This is used by the XorHandler.
00256                  * You really have no reason to ever use it.
00257                  */
00258                 void forceRequired();
00259 
00260                 /**
00261                  * Sets the _alreadySet value to true.  This is used by the XorHandler.
00262                  * You really have no reason to ever use it.
00263                  */
00264                 void xorSet();
00265 
00266                 /**
00267                  * Indicates whether a value must be specified for argument.
00268                  */
00269                 bool isValueRequired() const;
00270 
00271                 /**
00272                  * Indicates whether the argument has already been set.  Only true
00273                  * if the arg has been matched on the command line.
00274                  */
00275                 bool isSet() const;
00276 
00277                 /**
00278                  * Indicates whether the argument can be ignored, if desired. 
00279                  */
00280                 bool isIgnoreable() const;
00281 
00282                 /**
00283                  * A method that tests whether a string matches this argument.
00284                  * This is generally called by the processArg() method.  This
00285                  * method could be re-implemented by a child to change how 
00286                  * arguments are specified on the command line.
00287                  * \param s - The string to be compared to the flag/name to determine
00288                  * whether the arg matches.
00289                  */
00290                 virtual bool argMatches( const std::string& s ) const;
00291 
00292                 /**
00293                  * Returns a simple string representation of the argument.
00294                  * Primarily for debugging.
00295                  */
00296                 virtual std::string toString() const;
00297 
00298                 /**
00299                  * Returns a short ID for the usage.
00300                  * \param valueId - The value used in the id.
00301                  */
00302                 virtual std::string shortID( const std::string& valueId = "val" ) const;
00303 
00304                 /**
00305                  * Returns a long ID for the usage.
00306                  * \param valueId - The value used in the id.
00307                  */
00308                 virtual std::string longID( const std::string& valueId = "val" ) const;
00309 
00310                 /**
00311                  * Trims a value off of the flag.
00312                  * \param flag - The string from which the flag and value will be 
00313                  * trimmed. Contains the flag once the value has been trimmed. 
00314                  * \param value - Where the value trimmed from the string will
00315                  * be stored.
00316                  */
00317                 virtual void trimFlag( std::string& flag, std::string& value ) const;
00318 
00319                 /**
00320                  * Checks whether a given string has blank chars, indicating that
00321                  * it is a combined SwitchArg.  If so, return true, otherwise return
00322                  * false.
00323                  * \param s - string to be checked.
00324                  */
00325                 bool _hasBlanks( const std::string& s ) const;
00326 
00327                 /**
00328                  * Sets the requireLabel. Used by XorHandler.  You shouldn't ever
00329                  * use this.
00330                  * \param s - Set the requireLabel to this value.
00331                  */
00332                 void setRequireLabel( const std::string& s );
00333 
00334                 virtual bool allowMore();
00335                 virtual bool acceptsMultipleValues();
00336 
00337 };
00338 
00339 /**
00340  * Typedef of an Arg list iterator.
00341  */
00342 typedef std::list<Arg*>::iterator ArgListIterator;
00343 
00344 /**
00345  * Typedef of an Arg vector iterator.
00346  */
00347 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00348 
00349 /**
00350  * Typedef of a Visitor list iterator.
00351  */
00352 typedef std::list<Visitor*>::iterator VisitorListIterator;
00353 
00354 
00355 //////////////////////////////////////////////////////////////////////
00356 //BEGIN Arg.cpp
00357 //////////////////////////////////////////////////////////////////////
00358 
00359 inline Arg::Arg(const std::string& flag, 
00360          const std::string& name, 
00361          const std::string& desc, 
00362          bool req, 
00363          bool valreq,
00364          Visitor* v) :
00365   _flag(flag),
00366   _name(name),
00367   _description(desc),
00368   _required(req),
00369   _requireLabel("required"),
00370   _valueRequired(valreq),
00371   _alreadySet(false),
00372   _visitor( v ),
00373   _ignoreable(true),
00374   _xorSet(false),
00375   _acceptsMultipleValues(false)
00376 {
00377         if ( _flag.length() > 1 ) 
00378                 throw(SpecificationException(
00379                                 "Argument flag can only be one character long", toString() ) );
00380 
00381         if ( _name != ignoreNameString() &&  
00382                  ( _flag == Arg::flagStartString() || 
00383                    _flag == Arg::nameStartString() || 
00384                    _flag == " " ) )
00385                 throw(SpecificationException("Argument flag cannot be either '" + 
00386                                                         Arg::flagStartString() + "' or '" + 
00387                                                         Arg::nameStartString() + "' or a space.",
00388                                                         toString() ) );
00389 
00390         if ( /*( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || */
00391                  ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00392                  ( _name.find( " ", 0 ) != std::string::npos ) )
00393                 throw(SpecificationException("Argument name cannot contain either '" + 
00394                                                         Arg::flagStartString() + "' or '" + 
00395                                                         Arg::nameStartString() + "' or space.",
00396                                                         toString() ) );
00397 
00398 }
00399 
00400 inline Arg::~Arg() { }
00401 
00402 inline std::string Arg::shortID( const std::string& valueId ) const
00403 {
00404         std::string id = "";
00405 
00406         if ( _flag != "" )
00407                 id = Arg::flagStartString() + _flag;
00408         else
00409                 id = Arg::nameStartString() + _name;
00410 
00411         std::string delim = " "; 
00412         delim[0] = Arg::delimiter(); // ugly!!!
00413         
00414         if ( _valueRequired )
00415                 id += delim + "<" + valueId  + ">";
00416 
00417         if ( !_required )
00418                 id = "[" + id + "]";
00419 
00420         return id;
00421 }
00422 
00423 inline std::string Arg::longID( const std::string& valueId ) const
00424 {
00425         std::string id = "";
00426 
00427         if ( _flag != "" )
00428         {
00429                 id += Arg::flagStartString() + _flag;
00430 
00431                 if ( _valueRequired )
00432                         id += " <" + valueId + ">";
00433                 
00434                 id += ",  ";
00435         }
00436 
00437         id += Arg::nameStartString() + _name;
00438 
00439         if ( _valueRequired )
00440                 id += " <" + valueId + ">";
00441                         
00442         return id;
00443 
00444 }
00445 
00446 inline bool Arg::operator==(const Arg& a) const
00447 {
00448         if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00449                 return true;
00450         else
00451                 return false;
00452 }
00453 
00454 inline std::string Arg::getDescription() const 
00455 {
00456         std::string desc = "";
00457         if ( _required )
00458                 desc = "(" + _requireLabel + ")  ";
00459 
00460 //      if ( _valueRequired )
00461 //              desc += "(value required)  ";
00462 
00463         desc += _description;
00464         return desc; 
00465 }
00466 
00467 inline const std::string& Arg::getFlag() const { return _flag; }
00468 
00469 inline const std::string& Arg::getName() const { return _name; } 
00470 
00471 inline bool Arg::isRequired() const { return _required; }
00472 
00473 inline bool Arg::isValueRequired() const { return _valueRequired; }
00474 
00475 inline bool Arg::isSet() const 
00476 { 
00477         if ( _alreadySet && !_xorSet )
00478                 return true;
00479         else
00480                 return false;
00481 }
00482 
00483 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00484 
00485 inline void Arg::setRequireLabel( const std::string& s) 
00486 { 
00487         _requireLabel = s;
00488 }
00489 
00490 inline bool Arg::argMatches( const std::string& argFlag ) const
00491 {
00492         if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00493                  argFlag == Arg::nameStartString() + _name )
00494                 return true;
00495         else
00496                 return false;
00497 }
00498 
00499 inline std::string Arg::toString() const
00500 {
00501         std::string s = "";
00502 
00503         if ( _flag != "" )
00504                 s += Arg::flagStartString() + _flag + " ";
00505 
00506         s += "(" + Arg::nameStartString() + _name + ")";
00507 
00508         return s;
00509 }
00510 
00511 inline void Arg::_checkWithVisitor() const
00512 {
00513         if ( _visitor != NULL )
00514                 _visitor->visit();
00515 }
00516 
00517 /**
00518  * Implementation of trimFlag.
00519  */
00520 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00521 {
00522         int stop = 0;
00523         for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00524                 if ( flag[i] == Arg::delimiter() )
00525                 {
00526                         stop = i;
00527                         break;
00528                 }
00529 
00530         if ( stop > 1 )
00531         {
00532                 value = flag.substr(stop+1);
00533                 flag = flag.substr(0,stop);
00534         }
00535 
00536 }
00537 
00538 /**
00539  * Implementation of _hasBlanks.
00540  */
00541 inline bool Arg::_hasBlanks( const std::string& s ) const
00542 {
00543         for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00544                 if ( s[i] == Arg::blankChar() )
00545                         return true;
00546 
00547         return false;
00548 }
00549 
00550 inline void Arg::forceRequired()
00551 {
00552         _required = true;
00553 }
00554 
00555 inline void Arg::xorSet()
00556 {
00557         _alreadySet = true;
00558         _xorSet = true;
00559 }
00560 
00561 /**
00562  * Overridden by Args that need to added to the end of the list.
00563  */
00564 inline void Arg::addToList( std::list<Arg*>& argList ) const
00565 {
00566         argList.push_front( const_cast<Arg*>(this) );
00567 }
00568 
00569 inline bool Arg::allowMore()
00570 {
00571         return false;
00572 }
00573 
00574 inline bool Arg::acceptsMultipleValues()
00575 {
00576         return _acceptsMultipleValues;
00577 }
00578 
00579 //////////////////////////////////////////////////////////////////////
00580 //END Arg.cpp
00581 //////////////////////////////////////////////////////////////////////
00582 
00583 } //namespace TCLAP
00584 
00585 #endif
00586 



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN:exported at Tue Jan 25 21:56:31 UTC 2011