$search
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