SwitchArg.h 7.7 KB

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