MultiArg.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
  2. /******************************************************************************
  3. *
  4. * file: MultiArg.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_MULTIPLE_ARGUMENT_H
  24. #define TCLAP_MULTIPLE_ARGUMENT_H
  25. #include <string>
  26. #include <vector>
  27. #include <tclap/Arg.h>
  28. #include <tclap/Constraint.h>
  29. namespace TCLAP {
  30. /**
  31. * An argument that allows multiple values of type T to be specified. Very
  32. * similar to a ValueArg, except a vector of values will be returned
  33. * instead of just one.
  34. */
  35. template<class T>
  36. class MultiArg : public Arg
  37. {
  38. public:
  39. typedef std::vector<T> container_type;
  40. typedef typename container_type::iterator iterator;
  41. typedef typename container_type::const_iterator const_iterator;
  42. protected:
  43. /**
  44. * The list of values parsed from the CmdLine.
  45. */
  46. std::vector<T> _values;
  47. /**
  48. * The description of type T to be used in the usage.
  49. */
  50. std::string _typeDesc;
  51. /**
  52. * A list of constraint on this Arg.
  53. */
  54. Constraint<T>* _constraint;
  55. /**
  56. * Extracts the value from the string.
  57. * Attempts to parse string as type T, if this fails an exception
  58. * is thrown.
  59. * \param val - The string to be read.
  60. */
  61. void _extractValue( const std::string& val );
  62. /**
  63. * Used by XorHandler to decide whether to keep parsing for this arg.
  64. */
  65. bool _allowMore;
  66. public:
  67. /**
  68. * Constructor.
  69. * \param flag - The one character flag that identifies this
  70. * argument on the command line.
  71. * \param name - A one word name for the argument. Can be
  72. * used as a long flag on the command line.
  73. * \param desc - A description of what the argument is for or
  74. * does.
  75. * \param req - Whether the argument is required on the command
  76. * line.
  77. * \param typeDesc - A short, human readable description of the
  78. * type that this object expects. This is used in the generation
  79. * of the USAGE statement. The goal is to be helpful to the end user
  80. * of the program.
  81. * \param v - An optional visitor. You probably should not
  82. * use this unless you have a very good reason.
  83. */
  84. MultiArg( const std::string& flag,
  85. const std::string& name,
  86. const std::string& desc,
  87. bool req,
  88. const std::string& typeDesc,
  89. Visitor* v = NULL);
  90. /**
  91. * Constructor.
  92. * \param flag - The one character flag that identifies this
  93. * argument on the command line.
  94. * \param name - A one word name for the argument. Can be
  95. * used as a long flag on the command line.
  96. * \param desc - A description of what the argument is for or
  97. * does.
  98. * \param req - Whether the argument is required on the command
  99. * line.
  100. * \param typeDesc - A short, human readable description of the
  101. * type that this object expects. This is used in the generation
  102. * of the USAGE statement. The goal is to be helpful to the end user
  103. * of the program.
  104. * \param parser - A CmdLine parser object to add this Arg to
  105. * \param v - An optional visitor. You probably should not
  106. * use this unless you have a very good reason.
  107. */
  108. MultiArg( const std::string& flag,
  109. const std::string& name,
  110. const std::string& desc,
  111. bool req,
  112. const std::string& typeDesc,
  113. CmdLineInterface& parser,
  114. Visitor* v = NULL );
  115. /**
  116. * Constructor.
  117. * \param flag - The one character flag that identifies this
  118. * argument on the command line.
  119. * \param name - A one word name for the argument. Can be
  120. * used as a long flag on the command line.
  121. * \param desc - A description of what the argument is for or
  122. * does.
  123. * \param req - Whether the argument is required on the command
  124. * line.
  125. * \param constraint - A pointer to a Constraint object used
  126. * to constrain this Arg.
  127. * \param v - An optional visitor. You probably should not
  128. * use this unless you have a very good reason.
  129. */
  130. MultiArg( const std::string& flag,
  131. const std::string& name,
  132. const std::string& desc,
  133. bool req,
  134. Constraint<T>* constraint,
  135. Visitor* v = NULL );
  136. /**
  137. * Constructor.
  138. * \param flag - The one character flag that identifies this
  139. * argument on the command line.
  140. * \param name - A one word name for the argument. Can be
  141. * used as a long flag on the command line.
  142. * \param desc - A description of what the argument is for or
  143. * does.
  144. * \param req - Whether the argument is required on the command
  145. * line.
  146. * \param constraint - A pointer to a Constraint object used
  147. * to constrain this Arg.
  148. * \param parser - A CmdLine parser object to add this Arg to
  149. * \param v - An optional visitor. You probably should not
  150. * use this unless you have a very good reason.
  151. */
  152. MultiArg( const std::string& flag,
  153. const std::string& name,
  154. const std::string& desc,
  155. bool req,
  156. Constraint<T>* constraint,
  157. CmdLineInterface& parser,
  158. Visitor* v = NULL );
  159. /**
  160. * Handles the processing of the argument.
  161. * This re-implements the Arg version of this method to set the
  162. * _value of the argument appropriately. It knows the difference
  163. * between labeled and unlabeled.
  164. * \param i - Pointer the the current argument in the list.
  165. * \param args - Mutable list of strings. Passed from main().
  166. */
  167. virtual bool processArg(int* i, std::vector<std::string>& args);
  168. /**
  169. * Returns a vector of type T containing the values parsed from
  170. * the command line.
  171. */
  172. const std::vector<T>& getValue() const { return _values; }
  173. /**
  174. * Returns an iterator over the values parsed from the command
  175. * line.
  176. */
  177. const_iterator begin() const { return _values.begin(); }
  178. /**
  179. * Returns the end of the values parsed from the command
  180. * line.
  181. */
  182. const_iterator end() const { return _values.end(); }
  183. /**
  184. * Returns the a short id string. Used in the usage.
  185. * \param val - value to be used.
  186. */
  187. virtual std::string shortID(const std::string& val="val") const;
  188. /**
  189. * Returns the a long id string. Used in the usage.
  190. * \param val - value to be used.
  191. */
  192. virtual std::string longID(const std::string& val="val") const;
  193. /**
  194. * Once we've matched the first value, then the arg is no longer
  195. * required.
  196. */
  197. virtual bool isRequired() const;
  198. virtual bool allowMore();
  199. virtual void reset();
  200. private:
  201. /**
  202. * Prevent accidental copying
  203. */
  204. MultiArg(const MultiArg<T>& rhs);
  205. MultiArg& operator=(const MultiArg<T>& rhs);
  206. };
  207. template<class T>
  208. MultiArg<T>::MultiArg(const std::string& flag,
  209. const std::string& name,
  210. const std::string& desc,
  211. bool req,
  212. const std::string& typeDesc,
  213. Visitor* v) :
  214. Arg( flag, name, desc, req, true, v ),
  215. _values(std::vector<T>()),
  216. _typeDesc( typeDesc ),
  217. _constraint( NULL ),
  218. _allowMore(false)
  219. {
  220. _acceptsMultipleValues = true;
  221. }
  222. template<class T>
  223. MultiArg<T>::MultiArg(const std::string& flag,
  224. const std::string& name,
  225. const std::string& desc,
  226. bool req,
  227. const std::string& typeDesc,
  228. CmdLineInterface& parser,
  229. Visitor* v)
  230. : Arg( flag, name, desc, req, true, v ),
  231. _values(std::vector<T>()),
  232. _typeDesc( typeDesc ),
  233. _constraint( NULL ),
  234. _allowMore(false)
  235. {
  236. parser.add( this );
  237. _acceptsMultipleValues = true;
  238. }
  239. /**
  240. *
  241. */
  242. template<class T>
  243. MultiArg<T>::MultiArg(const std::string& flag,
  244. const std::string& name,
  245. const std::string& desc,
  246. bool req,
  247. Constraint<T>* constraint,
  248. Visitor* v)
  249. : Arg( flag, name, desc, req, true, v ),
  250. _values(std::vector<T>()),
  251. _typeDesc( Constraint<T>::shortID(constraint) ),
  252. _constraint( constraint ),
  253. _allowMore(false)
  254. {
  255. _acceptsMultipleValues = true;
  256. }
  257. template<class T>
  258. MultiArg<T>::MultiArg(const std::string& flag,
  259. const std::string& name,
  260. const std::string& desc,
  261. bool req,
  262. Constraint<T>* constraint,
  263. CmdLineInterface& parser,
  264. Visitor* v)
  265. : Arg( flag, name, desc, req, true, v ),
  266. _values(std::vector<T>()),
  267. _typeDesc( Constraint<T>::shortID(constraint) ),
  268. _constraint( constraint ),
  269. _allowMore(false)
  270. {
  271. parser.add( this );
  272. _acceptsMultipleValues = true;
  273. }
  274. template<class T>
  275. bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
  276. {
  277. if ( _ignoreable && Arg::ignoreRest() )
  278. return false;
  279. if ( _hasBlanks( args[*i] ) )
  280. return false;
  281. std::string flag = args[*i];
  282. std::string value = "";
  283. trimFlag( flag, value );
  284. if ( argMatches( flag ) )
  285. {
  286. if ( Arg::delimiter() != ' ' && value == "" )
  287. throw( ArgParseException(
  288. "Couldn't find delimiter for this argument!",
  289. toString() ) );
  290. // always take the first one, regardless of start string
  291. if ( value == "" )
  292. {
  293. (*i)++;
  294. if ( static_cast<unsigned int>(*i) < args.size() )
  295. _extractValue( args[*i] );
  296. else
  297. throw( ArgParseException("Missing a value for this argument!",
  298. toString() ) );
  299. }
  300. else
  301. _extractValue( value );
  302. /*
  303. // continuing taking the args until we hit one with a start string
  304. while ( (unsigned int)(*i)+1 < args.size() &&
  305. args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
  306. args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
  307. _extractValue( args[++(*i)] );
  308. */
  309. _alreadySet = true;
  310. _checkWithVisitor();
  311. return true;
  312. }
  313. else
  314. return false;
  315. }
  316. /**
  317. *
  318. */
  319. template<class T>
  320. std::string MultiArg<T>::shortID(const std::string& val) const
  321. {
  322. static_cast<void>(val); // Ignore input, don't warn
  323. return Arg::shortID(_typeDesc) + " ...";
  324. }
  325. /**
  326. *
  327. */
  328. template<class T>
  329. std::string MultiArg<T>::longID(const std::string& val) const
  330. {
  331. static_cast<void>(val); // Ignore input, don't warn
  332. return Arg::longID(_typeDesc) + " (accepted multiple times)";
  333. }
  334. /**
  335. * Once we've matched the first value, then the arg is no longer
  336. * required.
  337. */
  338. template<class T>
  339. bool MultiArg<T>::isRequired() const
  340. {
  341. if ( _required )
  342. {
  343. if ( _values.size() > 1 )
  344. return false;
  345. else
  346. return true;
  347. }
  348. else
  349. return false;
  350. }
  351. template<class T>
  352. void MultiArg<T>::_extractValue( const std::string& val )
  353. {
  354. try {
  355. T tmp;
  356. ExtractValue(tmp, val, typename ArgTraits<T>::ValueCategory());
  357. _values.push_back(tmp);
  358. } catch( ArgParseException &e) {
  359. throw ArgParseException(e.error(), toString());
  360. }
  361. if ( _constraint != NULL )
  362. if ( ! _constraint->check( _values.back() ) )
  363. throw( CmdLineParseException( "Value '" + val +
  364. "' does not meet constraint: " +
  365. _constraint->description(),
  366. toString() ) );
  367. }
  368. template<class T>
  369. bool MultiArg<T>::allowMore()
  370. {
  371. bool am = _allowMore;
  372. _allowMore = true;
  373. return am;
  374. }
  375. template<class T>
  376. void MultiArg<T>::reset()
  377. {
  378. Arg::reset();
  379. _values.clear();
  380. }
  381. } // namespace TCLAP
  382. #endif