Program Listing for File arg.hpp

Return to documentation for file (/tmp/ws/src/ecl_core/ecl_command_line/include/ecl/command_line/arg.hpp)

/*****************************************************************************
** Ifdefs
*****************************************************************************/


#ifndef TCLAP_ARGUMENT_H
#define TCLAP_ARGUMENT_H

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

#include "arg_exception.hpp"
#include "visitor.hpp"
#include "cmd_line_interface.hpp"

namespace ecl {

class Arg
{
    private:

        static bool& ignoreRestRef() { static bool ign = false; return ign; }

        static char& delimiterRef() { static char delim = ' '; return delim; }

    protected:

        std::string _flag;

        std::string _name;

        std::string _description;

        bool _required;

        std::string _requireLabel;

        bool _valueRequired;

        bool _alreadySet;

        Visitor* _visitor;

        bool _ignoreable;

        bool _xorSet;

        bool _acceptsMultipleValues;

        void _checkWithVisitor() const;

        Arg( const std::string& flag,
             const std::string& name,
             const std::string& desc,
             bool req,
             bool valreq,
             Visitor* v = NULL );

    public:
        virtual ~Arg();

        virtual void addToList( std::list<Arg*>& argList ) const;

        static void beginIgnoring() { ignoreRestRef() = true; }

        static bool ignoreRest() { return ignoreRestRef(); }

        static char delimiter() { return delimiterRef(); }

        static char blankChar() { return '*'; }

        static char flagStartChar() { return '-'; }

        static std::string flagStartString() { return "-"; }

        static std::string nameStartString() { return "--"; }

        static std::string ignoreNameString() { return "ignore_rest"; }

        static void setDelimiter( char c ) { delimiterRef() = c; }

        virtual bool processArg(int *i, std::vector<std::string>& args) = 0;

        virtual bool operator==(const Arg& a) const;

        const std::string& getFlag() const;

        const std::string& getName() const;

        std::string getDescription() const;

        virtual bool isRequired() const;

        void forceRequired();

        void xorSet();

        bool isValueRequired() const;

        bool isSet() const;

        bool isIgnoreable() const;

        virtual bool argMatches( const std::string& s ) const;

        virtual std::string toString() const;

        virtual std::string shortID( const std::string& valueId = "val" ) const;

        virtual std::string longID( const std::string& valueId = "val" ) const;

        virtual void trimFlag( std::string& flag, std::string& value ) const;

        bool _hasBlanks( const std::string& s ) const;

        void setRequireLabel( const std::string& s );

        virtual bool allowMore();
        virtual bool acceptsMultipleValues();

};

typedef std::list<Arg*>::iterator ArgListIterator;

typedef std::vector<Arg*>::iterator ArgVectorIterator;

typedef std::list<Visitor*>::iterator VisitorListIterator;


//BEGIN Arg.cpp

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),
  _acceptsMultipleValues(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() ) );

}

inline Arg::~Arg() { }

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;
}

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;

}

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

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

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

    desc += _description;
    return desc;
}

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

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

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

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

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

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

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

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

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

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

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

    return s;
}

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

inline void Arg::trimFlag(std::string& flag, std::string& value) const
{
    int stop = 0;
    for ( int i = 0; static_cast<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);
    }

}

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

    return false;
}

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

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

inline void Arg::addToList( std::list<Arg*>& argList ) const
{
    argList.push_front( const_cast<Arg*>(this) );
}

inline bool Arg::allowMore()
{
    return false;
}

inline bool Arg::acceptsMultipleValues()
{
    return _acceptsMultipleValues;
}

//END Arg.cpp

} // namespace ecl

#endif