- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# SwitchArg.h

Go to the documentation of this file.

    00001
    00002 /******************************************************************************
    00003  *
    00004  *  file:  SwitchArg.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_SWITCH_ARG_H
    00025 #define TCLAP_SWITCH_ARG_H
    00026
    00027 #include <string>
    00028 #include <vector>
    00029
    00030 #include <tclap/Arg.h>
    00031
    00032 namespace TCLAP {
    00033
    00039 class SwitchArg : public Arg
    00040 {
    00041     protected:
    00042
    00046         bool _value;
    00047
    00052         bool _default;
    00053
    00054     public:
    00055
    00068         SwitchArg(const std::string& flag,
    00069                   const std::string& name,
    00070                   const std::string& desc,
    00071                   bool def = false,
    00072                   Visitor* v = NULL);
    00073
    00074
    00088         SwitchArg(const std::string& flag,
    00089                   const std::string& name,
    00090                   const std::string& desc,
    00091                   CmdLineInterface& parser,
    00092                   bool def = false,
    00093                   Visitor* v = NULL);
    00094
    00095
    00104         virtual bool processArg(int* i, std::vector<std::string>& args);
    00105
    00110         bool combinedSwitchesMatch(std::string& combined);
    00111
    00115         bool getValue();
    00116
    00117         virtual void reset();
    00118
    00119     private:
    00124         bool lastCombined(std::string& combined);
    00125
    00129         void commonProcessing();
    00130 };
    00131
    00133 //BEGIN SwitchArg.cpp
    00135 inline SwitchArg::SwitchArg(const std::string& flag,
    00136                             const std::string& name,
    00137                             const std::string& desc,
    00138                             bool default_val,
    00139                             Visitor* v )
    00140 : Arg(flag, name, desc, false, false, v),
    00141   _value( default_val ),
    00142   _default( default_val )
    00143 { }
    00144
    00145 inline SwitchArg::SwitchArg(const std::string& flag,
    00146                             const std::string& name,
    00147                             const std::string& desc,
    00148                             CmdLineInterface& parser,
    00149                             bool default_val,
    00150                             Visitor* v )
    00151 : Arg(flag, name, desc, false, false, v),
    00152   _value( default_val ),
    00153   _default(default_val)
    00154 {
    00155     parser.add( this );
    00156 }
    00157
    00158 inline bool SwitchArg::getValue() { return _value; }
    00159
    00160 inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
    00161 {
    00162     for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
    00163         if ( combinedSwitches[i] != Arg::blankChar() )
    00164             return false;
    00165
    00166     return true;
    00167 }
    00168
    00169 inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
    00170 {
    00171     // make sure this is actually a combined switch
    00172     if ( combinedSwitches.length() > 0 &&
    00173          combinedSwitches[0] != Arg::flagStartString()[0] )
    00174         return false;
    00175
    00176     // make sure it isn't a long name
    00177     if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
    00178          Arg::nameStartString() )
    00179         return false;
    00180
    00181     // make sure the delimiter isn't in the string
    00182     if ( combinedSwitches.find_first_of( Arg::delimiter() ) != std::string::npos )
    00183         return false;
    00184
    00185     // ok, we're not specifying a ValueArg, so we know that we have
    00186     // a combined switch list.
    00187     for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
    00188         if ( _flag.length() > 0 &&
    00189              combinedSwitches[i] == _flag[0] &&
    00190              _flag[0] != Arg::flagStartString()[0] )
    00191         {
    00192             // update the combined switches so this one is no longer present
    00193             // this is necessary so that no unlabeled args are matched
    00194             // later in the processing.
    00195             //combinedSwitches.erase(i,1);
    00196             combinedSwitches[i] = Arg::blankChar();
    00197             return true;
    00198         }
    00199
    00200     // none of the switches passed in the list match.
    00201     return false;
    00202 }
    00203
    00204 inline void SwitchArg::commonProcessing()
    00205 {
    00206     if ( _xorSet )
    00207         throw(CmdLineParseException(
    00208               "Mutually exclusive argument already set!", toString()));
    00209
    00210     if ( _alreadySet )
    00211         throw(CmdLineParseException("Argument already set!", toString()));
    00212
    00213     _alreadySet = true;
    00214
    00215     if ( _value == true )
    00216         _value = false;
    00217     else
    00218         _value = true;
    00219
    00220     _checkWithVisitor();
    00221 }
    00222
    00223 inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
    00224 {
    00225     if ( _ignoreable && Arg::ignoreRest() )
    00226         return false;
    00227
    00228     // if the whole string matches the flag or name string
    00229     if ( argMatches( args[*i] ) )
    00230     {
    00231         commonProcessing();
    00232
    00233         return true;
    00234     }
    00235     // if a substring matches the flag as part of a combination
    00236     else if ( combinedSwitchesMatch( args[*i] ) )
    00237     {
    00238         // check again to ensure we don't misinterpret
    00239         // this as a MultiSwitchArg
    00240         if ( combinedSwitchesMatch( args[*i] ) )
    00241             throw(CmdLineParseException("Argument already set!",
    00242                                         toString()));
    00243
    00244         commonProcessing();
    00245
    00246         // We only want to return true if we've found the last combined
    00247         // match in the string, otherwise we return true so that other
    00248         // switches in the combination will have a chance to match.
    00249         return lastCombined( args[*i] );
    00250     }
    00251     else
    00252         return false;
    00253 }
    00254
    00255 inline void SwitchArg::reset()
    00256 {
    00257     Arg::reset();
    00258     _value = _default;
    00259 }
    00261 //End SwitchArg.cpp
    00263
    00264 } //namespace TCLAP
    00265
    00266 #endif