BASIS  version 1.2.3 (revision 2104)
SwitchArg.h
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 <sbia/tclap/Arg.h>
00031 
00032 namespace TCLAP {
00033 
00034 /**
00035  * A simple switch argument.  If the switch is set on the command line, then
00036  * the getValue method will return the opposite of the default value for the
00037  * switch.
00038  */
00039 class SwitchArg : public Arg
00040 {
00041     protected:
00042 
00043         /**
00044          * The value of the switch.
00045          */
00046         bool _value;
00047 
00048         /**
00049          * Used to support the reset() method so that ValueArg can be
00050          * reset to their constructed value.
00051          */
00052         bool _default;
00053 
00054     public:
00055 
00056         /**
00057          * SwitchArg constructor.
00058          * \param flag - The one character flag that identifies this
00059          * argument on the command line.
00060          * \param name - A one word name for the argument.  Can be
00061          * used as a long flag on the command line.
00062          * \param desc - A description of what the argument is for or
00063          * does.
00064          * \param def - The default value for this Switch. 
00065          * \param v - An optional visitor.  You probably should not
00066          * use this unless you have a very good reason.
00067          */
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                   
00075         /**
00076          * SwitchArg constructor.
00077          * \param flag - The one character flag that identifies this
00078          * argument on the command line.
00079          * \param name - A one word name for the argument.  Can be
00080          * used as a long flag on the command line.
00081          * \param desc - A description of what the argument is for or
00082          * does.
00083          * \param parser - A CmdLine parser object to add this Arg to
00084          * \param def - The default value for this Switch.
00085          * \param v - An optional visitor.  You probably should not
00086          * use this unless you have a very good reason.
00087          */
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                   
00096         /**
00097          * Handles the processing of the argument.
00098          * This re-implements the Arg version of this method to set the
00099          * _value of the argument appropriately.
00100          * \param i - Pointer the the current argument in the list.
00101          * \param args - Mutable list of strings. Passed
00102          * in from main().
00103          */
00104         virtual bool processArg(int* i, std::vector<std::string>& args); 
00105 
00106         /**
00107          * Checks a string to see if any of the chars in the string
00108          * match the flag for this Switch.
00109          */
00110         bool combinedSwitchesMatch(std::string& combined);
00111 
00112         /**
00113          * Returns bool, whether or not the switch has been set.
00114          */
00115         bool getValue();
00116         
00117         virtual void reset();
00118 
00119     private:
00120         /**
00121          * Checks to see if we've found the last match in
00122          * a combined string.
00123          */
00124         bool lastCombined(std::string& combined);
00125 
00126         /**
00127          * Does the common processing of processArg.
00128          */
00129         void commonProcessing();
00130 };
00131 
00132 //////////////////////////////////////////////////////////////////////
00133 //BEGIN SwitchArg.cpp
00134 //////////////////////////////////////////////////////////////////////
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 }
00260 //////////////////////////////////////////////////////////////////////
00261 //End SwitchArg.cpp
00262 //////////////////////////////////////////////////////////////////////
00263 
00264 } //namespace TCLAP
00265 
00266 #endif