You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

267 lines
7.5 KiB

  1. /******************************************************************************
  2. *
  3. * file: SwitchArg.h
  4. *
  5. * Copyright (c) 2003, Michael E. Smoot .
  6. * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
  7. * All rights reverved.
  8. *
  9. * See the file COPYING in the top directory of this distribution for
  10. * more information.
  11. *
  12. * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  18. * DEALINGS IN THE SOFTWARE.
  19. *
  20. *****************************************************************************/
  21. #ifndef TCLAP_SWITCH_ARG_H
  22. #define TCLAP_SWITCH_ARG_H
  23. #include <string>
  24. #include <vector>
  25. #include "Arg.h"
  26. namespace TCLAP {
  27. /**
  28. * A simple switch argument. If the switch is set on the command line, then
  29. * the getValue method will return the opposite of the default value for the
  30. * switch.
  31. */
  32. class SwitchArg : public Arg
  33. {
  34. protected:
  35. /**
  36. * The value of the switch.
  37. */
  38. bool _value;
  39. /**
  40. * Used to support the reset() method so that ValueArg can be
  41. * reset to their constructed value.
  42. */
  43. bool _default;
  44. public:
  45. /**
  46. * SwitchArg constructor.
  47. * \param flag - The one character flag that identifies this
  48. * argument on the command line.
  49. * \param name - A one word name for the argument. Can be
  50. * used as a long flag on the command line.
  51. * \param desc - A description of what the argument is for or
  52. * does.
  53. * \param def - The default value for this Switch.
  54. * \param v - An optional visitor. You probably should not
  55. * use this unless you have a very good reason.
  56. */
  57. SwitchArg(const std::string& flag,
  58. const std::string& name,
  59. const std::string& desc,
  60. bool def = false,
  61. Visitor* v = NULL);
  62. /**
  63. * SwitchArg constructor.
  64. * \param flag - The one character flag that identifies this
  65. * argument on the command line.
  66. * \param name - A one word name for the argument. Can be
  67. * used as a long flag on the command line.
  68. * \param desc - A description of what the argument is for or
  69. * does.
  70. * \param parser - A CmdLine parser object to add this Arg to
  71. * \param def - The default value for this Switch.
  72. * \param v - An optional visitor. You probably should not
  73. * use this unless you have a very good reason.
  74. */
  75. SwitchArg(const std::string& flag,
  76. const std::string& name,
  77. const std::string& desc,
  78. CmdLineInterface& parser,
  79. bool def = false,
  80. Visitor* v = NULL);
  81. /**
  82. * Handles the processing of the argument.
  83. * This re-implements the Arg version of this method to set the
  84. * _value of the argument appropriately.
  85. * \param i - Pointer the the current argument in the list.
  86. * \param args - Mutable list of strings. Passed
  87. * in from main().
  88. */
  89. virtual bool processArg(int* i, std::vector<std::string>& args);
  90. /**
  91. * Checks a string to see if any of the chars in the string
  92. * match the flag for this Switch.
  93. */
  94. bool combinedSwitchesMatch(std::string& combined);
  95. /**
  96. * Returns bool, whether or not the switch has been set.
  97. */
  98. bool getValue();
  99. virtual void reset();
  100. private:
  101. /**
  102. * Checks to see if we've found the last match in
  103. * a combined string.
  104. */
  105. bool lastCombined(std::string& combined);
  106. /**
  107. * Does the common processing of processArg.
  108. */
  109. void commonProcessing();
  110. };
  111. //////////////////////////////////////////////////////////////////////
  112. //BEGIN SwitchArg.cpp
  113. //////////////////////////////////////////////////////////////////////
  114. inline SwitchArg::SwitchArg(const std::string& flag,
  115. const std::string& name,
  116. const std::string& desc,
  117. bool default_val,
  118. Visitor* v )
  119. : Arg(flag, name, desc, false, false, v),
  120. _value( default_val ),
  121. _default( default_val )
  122. { }
  123. inline SwitchArg::SwitchArg(const std::string& flag,
  124. const std::string& name,
  125. const std::string& desc,
  126. CmdLineInterface& parser,
  127. bool default_val,
  128. Visitor* v )
  129. : Arg(flag, name, desc, false, false, v),
  130. _value( default_val ),
  131. _default(default_val)
  132. {
  133. parser.add( this );
  134. }
  135. inline bool SwitchArg::getValue() { return _value; }
  136. inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
  137. {
  138. for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
  139. if ( combinedSwitches[i] != Arg::blankChar() )
  140. return false;
  141. return true;
  142. }
  143. inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
  144. {
  145. // make sure this is actually a combined switch
  146. if ( combinedSwitches.length() > 0 &&
  147. combinedSwitches[0] != Arg::flagStartString()[0] )
  148. return false;
  149. // make sure it isn't a long name
  150. if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
  151. Arg::nameStartString() )
  152. return false;
  153. // make sure the delimiter isn't in the string
  154. if ( combinedSwitches.find_first_of( Arg::delimiter() ) != std::string::npos )
  155. return false;
  156. // ok, we're not specifying a ValueArg, so we know that we have
  157. // a combined switch list.
  158. for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
  159. if ( _flag.length() > 0 &&
  160. combinedSwitches[i] == _flag[0] &&
  161. _flag[0] != Arg::flagStartString()[0] )
  162. {
  163. // update the combined switches so this one is no longer present
  164. // this is necessary so that no unlabeled args are matched
  165. // later in the processing.
  166. //combinedSwitches.erase(i,1);
  167. combinedSwitches[i] = Arg::blankChar();
  168. return true;
  169. }
  170. // none of the switches passed in the list match.
  171. return false;
  172. }
  173. inline void SwitchArg::commonProcessing()
  174. {
  175. if ( _xorSet )
  176. throw(CmdLineParseException(
  177. "Mutually exclusive argument already set!", toString()));
  178. if ( _alreadySet )
  179. throw(CmdLineParseException("Argument already set!", toString()));
  180. _alreadySet = true;
  181. if ( _value == true )
  182. _value = false;
  183. else
  184. _value = true;
  185. _checkWithVisitor();
  186. }
  187. inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
  188. {
  189. if ( _ignoreable && Arg::ignoreRest() )
  190. return false;
  191. // if the whole string matches the flag or name string
  192. if ( argMatches( args[*i] ) )
  193. {
  194. commonProcessing();
  195. return true;
  196. }
  197. // if a substring matches the flag as part of a combination
  198. else if ( combinedSwitchesMatch( args[*i] ) )
  199. {
  200. // check again to ensure we don't misinterpret
  201. // this as a MultiSwitchArg
  202. if ( combinedSwitchesMatch( args[*i] ) )
  203. throw(CmdLineParseException("Argument already set!",
  204. toString()));
  205. commonProcessing();
  206. // We only want to return true if we've found the last combined
  207. // match in the string, otherwise we return true so that other
  208. // switches in the combination will have a chance to match.
  209. return lastCombined( args[*i] );
  210. }
  211. else
  212. return false;
  213. }
  214. inline void SwitchArg::reset()
  215. {
  216. Arg::reset();
  217. _value = _default;
  218. }
  219. //////////////////////////////////////////////////////////////////////
  220. //End SwitchArg.cpp
  221. //////////////////////////////////////////////////////////////////////
  222. } //namespace TCLAP
  223. #endif