Logo Search packages:      
Sourcecode: passwordmaker-cli version File versions  Download package

Arg.h

/****************************************************************************** 
 * 
 *  file:  Arg.h
 * 
 *  Copyright (c) 2003, Michael E. Smoot .
 *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
 *  All rights reverved.
 * 
 *  See the file COPYING in the top directory of this distribution for
 *  more information.
 *  
 *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 *  DEALINGS IN THE SOFTWARE.  
 *  
 *****************************************************************************/ 


#ifndef TCLAP_ARGUMENT_H
#define TCLAP_ARGUMENT_H

#include <string>
#include <vector>
#include <list>
#include <iostream>

#include "tclap/ArgException.h"
#include "tclap/Visitor.h"
#include "tclap/CmdLineInterface.h"

namespace TCLAP {

/** 
 * A virtual base class that defines the essential data for all arguments.
 * This class, or one of its existing children, must be subclassed to do
 * anything. 
 */
00043 class Arg
{
      private: 

            /**
             * Indicates whether the rest of the arguments should be ignored.
             */
00050             static bool& ignoreRestRef() { static bool ign = false; return ign; }

            /**
             * The delimiter that separates an argument flag/name from the
             * value.
             */
00056             static char& delimiterRef() { static char delim = ' '; return delim; } 

      protected:

            /** 
             * The single char flag used to identify the argument.
             * This value (preceded by a dash {-}), can be used to identify 
             * an argument on the command line.  The _flag can be blank, 
             * in fact this is how unlabeled args work.  Unlabeled args must
             * override appropriate functions to get correct handling. Note 
             * that the _flag does NOT include the dash as part of the flag.
             */
00068             std::string _flag;

            /**
             * A single work namd indentifying the argument.
             * This value (preceded by two dashed {--}) can also be used 
             * to identify an argument on the command line.  Note that the
             * _name does NOT include the two dashes as part of the _name. The
             * _name cannot be blank.
             */
00077             std::string _name;

            /**
             * Description of the argument. 
             */
00082             std::string _description;

            /** 
             * Indicating whether the argument is required.
             */
00087             bool _required;

            /**
             * Label to be used in usage description.  Normally set to 
             * "required", but can be changed when necessary.
             */
00093             std::string _requireLabel;

            /**
             * Indicates whether a value is required for the argument.
             * Note that the value may be required but the argument/value
             * combination may not be, as specified by _required.
             */
00100             bool _valueRequired;

            /**
             * Indicates whether the argument has been set.
             * Indicates that a value on the command line has matched the
             * name/flag of this argument and the values have been set accordingly.
             */
00107             bool _alreadySet;

            /**
             * A pointer to a vistitor object.
             * The visitor allows special handling to occur as soon as the
             * argument is matched.  This defaults to NULL and should not
             * be used unless absolutely necessary.
             */
00115             Visitor* _visitor;

            /**
             * Whether this argument can be ignored, if desired.
             */
00120             bool _ignoreable;

            /**
             * Indicates that the arg was set as part of an XOR and not on the
             * command line.
             */
00126             bool _xorSet;

            /**
             * Performs the special handling described by the Vistitor.
             */
            void _checkWithVisitor() const;

            /**
             * Primary constructor. YOU (yes you) should NEVER construct an Arg 
             * directly, this is a base class that is extended by various children
             * that are meant to be used.  Use SwitchArg, ValueArg, MultiArg, 
             * UnlabeledValueArg, or UnlabeledMultiArg instead.
             *
             * \param flag - The flag identifying the argument.
             * \param name - The name identifying the argument.
             * \param desc - The description of the argument, used in the usage.
             * \param req - Whether the argument is required.
             * \param valreq - Whether the a value is required for the argument.
             * \param v - The visitor checked by the argument. Defaults to NULL.
             */
            Arg( const std::string& flag, 
                   const std::string& name, 
                   const std::string& desc, 
                   bool req, 
                   bool valreq,
                   Visitor* v = NULL );

      public:
            /**
             * Destructor.
             */
            virtual ~Arg();

            /**
             * Adds this to the specified list of Args.
             * \param argList - The list to add this to.
             */
            virtual void addToList( std::list<Arg*>& argList ) const;
            
            /**
             * Begin ignoring arguments since the "--" argument was specified.
             */
00168             static void beginIgnoring() { ignoreRestRef() = true; }
            
            /**
             * Whether to ignore the rest.
             */
00173             static bool ignoreRest() { return ignoreRestRef(); }

            /**
             * The delimiter that separates an argument flag/name from the
             * value.
             */
00179             static char delimiter() { return delimiterRef(); } 
            
            /**
             * The char used as a place holder when SwitchArgs are combined.
             * Currently set to '*', which shouldn't cause many problems since
             * *'s are expanded by most shells on the command line.  
             */
00186             static const char blankChar() { return '*'; }
            
            /**
             * The char that indicates the beginning of a flag.  Currently '-'.
             */
00191             static const char flagStartChar() { return '-'; }
            
            /**
             * The sting that indicates the beginning of a flag.  Currently "-".
             * Should be identical to flagStartChar.
             */
00197             static const std::string flagStartString() { return "-"; }
            
            /**
             * The sting that indicates the beginning of a name.  Currently "--".
             * Should be flagStartChar twice.
             */
00203             static const std::string nameStartString() { return "--"; }

            /**
             * The name used to identify the ignore rest argument.
             */
00208             static const std::string ignoreNameString() { return "ignore_rest"; }

            /**
             * Sets the delimiter for all arguments.
             * \param c - The character that delimits flags/names from values.
             */
00214             static void setDelimiter( char c ) { delimiterRef() = c; }

            /**
             * Pure virtual method meant to handle the parsing and value assignment
             * of the string on the command line. 
             * \param i - Pointer the the current argument in the list.
             * \param args - Mutable list of strings. What is 
             * passed in from main.
             */
            virtual bool processArg(int *i, std::vector<std::string>& args) = 0; 

            /**
             * Operator ==.
             * Equality operator. Must be virtual to handle unlabeled args.
             * \param a - The Arg to be compared to this.
             */
            virtual bool operator==(const Arg& a);

            /**
             * Returns the argument flag.
             */
            const std::string& getFlag() const;

            /**
             * Returns the argument name.
             */
            const std::string& getName() const;

            /**
             * Returns the argument description.
             */
            std::string getDescription() const;

            /**
             * Indicates whether the argument is required.
             */
            virtual bool isRequired() const;

            /**
             * Sets _required to true. This is used by the XorHandler.
             * You really have no reason to ever use it.
             */
            void forceRequired();

            /**
             * Sets the _alreadySet value to true.  This is used by the XorHandler.
             * You really have no reason to ever use it.
             */
            void xorSet();

            /**
             * Indicates whether a value must be specified for argument.
             */
            bool isValueRequired() const;

            /**
             * Indicates whether the argument has already been set.  Only true
             * if the arg has been matched on the command line.
             */
            bool isSet() const;

            /**
             * Indicates whether the argument can be ignored, if desired. 
             */
            bool isIgnoreable() const;

            /**
             * A method that tests whether a string matches this argument.
             * This is generally called by the processArg() method.  This
             * method could be re-implemented by a child to change how 
             * arguments are specified on the command line.
             * \param s - The string to be compared to the flag/name to determine
             * whether the arg matches.
             */
            virtual bool argMatches( const std::string& s ) const;

            /**
             * Returns a simple string representation of the argument.
             * Primarily for debugging.
             */
            virtual std::string toString() const;

            /**
             * Returns a short ID for the usage.
             * \param valueId - The value used in the id.
             */
            virtual std::string shortID( const std::string& valueId = "val" ) const;

            /**
             * Returns a long ID for the usage.
             * \param valueId - The value used in the id.
             */
            virtual std::string longID( const std::string& valueId = "val" ) const;

            /**
             * Trims a value off of the flag.
             * \param flag - The string from which the flag and value will be 
             * trimmed. Contains the flag once the value has been trimmed. 
             * \param value - Where the value trimmed from the string will
             * be stored.
             */
            virtual void trimFlag( std::string& flag, std::string& value ) const;

            /**
             * Checks whether a given string has blank chars, indicating that
             * it is a combined SwitchArg.  If so, return true, otherwise return
             * false.
             * \param s - string to be checked.
             */
            bool _hasBlanks( const std::string& s ) const;

            /**
             * Sets the requireLabel. Used by XorHandler.  You shouldn't ever
             * use this.
             * \param s - Set the requireLabel to this value.
             */
            void setRequireLabel( const std::string& s );

};

/**
 * Typedef of an Arg list iterator.
 */
typedef std::list<Arg*>::iterator ArgListIterator;

/**
 * Typedef of an Arg vector iterator.
 */
typedef std::vector<Arg*>::iterator ArgVectorIterator;

/**
 * Typedef of a Visitor list iterator.
 */
typedef std::list<Visitor*>::iterator VisitorListIterator;


//////////////////////////////////////////////////////////////////////
//BEGIN Arg.cpp
//////////////////////////////////////////////////////////////////////

00354 inline Arg::Arg(const std::string& flag, 
         const std::string& name, 
         const std::string& desc, 
         bool req, 
         bool valreq,
         Visitor* v) :
  _flag(flag),
  _name(name),
  _description(desc),
  _required(req),
  _requireLabel("required"),
  _valueRequired(valreq),
  _alreadySet(false),
  _visitor( v ),
  _ignoreable(true),
  _xorSet(false)
{
      if ( _flag.length() > 1 ) 
            throw(SpecificationException(
                        "Argument flag can only be one character long", toString() ) );

      if ( _name != ignoreNameString() &&  
             ( _flag == Arg::flagStartString() || 
               _flag == Arg::nameStartString() || 
               _flag == " " ) )
            throw(SpecificationException("Argument flag cannot be either '" + 
                                          Arg::flagStartString() + "' or '" + 
                                          Arg::nameStartString() + "' or a space.",
                                          toString() ) );

      if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || 
             ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
             ( _name.find( " ", 0 ) != std::string::npos ) )
            throw(SpecificationException("Argument name cannot contain either '" + 
                                          Arg::flagStartString() + "' or '" + 
                                          Arg::nameStartString() + "' or space.",
                                          toString() ) );

}

00394 inline Arg::~Arg() { }

00396 inline std::string Arg::shortID( const std::string& valueId ) const
{
      std::string id = "";

      if ( _flag != "" )
            id = Arg::flagStartString() + _flag;
      else
            id = Arg::nameStartString() + _name;

      std::string delim = " "; 
      delim[0] = Arg::delimiter(); // ugly!!!
      
      if ( _valueRequired )
            id += delim + "<" + valueId  + ">";

      if ( !_required )
            id = "[" + id + "]";

      return id;
}

00417 inline std::string Arg::longID( const std::string& valueId ) const
{
      std::string id = "";

      if ( _flag != "" )
      {
            id += Arg::flagStartString() + _flag;

            if ( _valueRequired )
                  id += " <" + valueId + ">";
            
            id += ",  ";
      }

      id += Arg::nameStartString() + _name;

      if ( _valueRequired )
            id += " <" + valueId + ">";
                  
      return id;

}

00440 inline bool Arg::operator==(const Arg& a)
{
      if ( ( _flag != "" && _flag == a._flag ) || 
             _name == a._name || 
             _description == a._description )
            return true;
      else
            return false;
}

00450 inline std::string Arg::getDescription() const 
{
      std::string desc = "";
      if ( _required )
            desc = "(" + _requireLabel + ")  ";

      if ( _valueRequired )
            desc += "(value required)  ";

      desc += _description;
      return desc; 
}

00463 inline const std::string& Arg::getFlag() const { return _flag; }

00465 inline const std::string& Arg::getName() const { return _name; } 

00467 inline bool Arg::isRequired() const { return _required; }

00469 inline bool Arg::isValueRequired() const { return _valueRequired; }

00471 inline bool Arg::isSet() const 
{ 
      if ( _alreadySet && !_xorSet )
            return true;
      else
            return false;
}

00479 inline bool Arg::isIgnoreable() const { return _ignoreable; }

00481 inline void Arg::setRequireLabel( const std::string& s) 
{ 
      _requireLabel = s;
}

00486 inline bool Arg::argMatches( const std::string& argFlag ) const
{
      if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
             argFlag == Arg::nameStartString() + _name )
            return true;
      else
            return false;
}

00495 inline std::string Arg::toString() const
{
      std::string s = "";

      if ( _flag != "" )
            s += Arg::flagStartString() + _flag + " ";

      s += "(" + Arg::nameStartString() + _name + ")";

      return s;
}

00507 inline void Arg::_checkWithVisitor() const
{
      if ( _visitor != NULL )
            _visitor->visit();
}

/**
 * Implementation of trimFlag.
 */
00516 inline void Arg::trimFlag(std::string& flag, std::string& value) const
{
      int stop = 0;
      for ( int i = 0; (unsigned int)i < flag.length(); i++ )
            if ( flag[i] == Arg::delimiter() )
            {
                  stop = i;
                  break;
            }

      if ( stop > 1 )
      {
            value = flag.substr(stop+1);
            flag = flag.substr(0,stop);
      }

}

/**
 * Implementation of _hasBlanks.
 */
00537 inline bool Arg::_hasBlanks( const std::string& s ) const
{
      for ( int i = 1; (unsigned int)i < s.length(); i++ )
            if ( s[i] == Arg::blankChar() )
                  return true;

      return false;
}

00546 inline void Arg::forceRequired()
{
      _required = true;
}

00551 inline void Arg::xorSet()
{
      _alreadySet = true;
      _xorSet = true;
}

/**
 * Overridden by Args that need to added to the end of the list.
 */
00560 inline void Arg::addToList( std::list<Arg*>& argList ) const
{
      argList.push_front( (Arg*)this );
}

//////////////////////////////////////////////////////////////////////
//END Arg.cpp
//////////////////////////////////////////////////////////////////////

} //namespace TCLAP

#endif


Generated by  Doxygen 1.6.0   Back to index