UnlabeledMultiArg.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
  2. /******************************************************************************
  3. *
  4. * file: UnlabeledMultiArg.h
  5. *
  6. * Copyright (c) 2003, Michael E. Smoot.
  7. * Copyright (c) 2017, Google LLC
  8. * All rights reserved.
  9. *
  10. * See the file COPYING in the top directory of this distribution for
  11. * more information.
  12. *
  13. * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
  14. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  16. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  19. * DEALINGS IN THE SOFTWARE.
  20. *
  21. *****************************************************************************/
  22. #ifndef TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H
  23. #define TCLAP_MULTIPLE_UNLABELED_ARGUMENT_H
  24. #include <string>
  25. #include <vector>
  26. #include <tclap/MultiArg.h>
  27. #include <tclap/OptionalUnlabeledTracker.h>
  28. namespace TCLAP {
  29. /**
  30. * Just like a MultiArg, except that the arguments are unlabeled. Basically,
  31. * this Arg will slurp up everything that hasn't been matched to another
  32. * Arg.
  33. */
  34. template<class T>
  35. class UnlabeledMultiArg : public MultiArg<T>
  36. {
  37. // If compiler has two stage name lookup (as gcc >= 3.4 does)
  38. // this is required to prevent undef. symbols
  39. using MultiArg<T>::_ignoreable;
  40. using MultiArg<T>::_hasBlanks;
  41. using MultiArg<T>::_extractValue;
  42. using MultiArg<T>::_typeDesc;
  43. using MultiArg<T>::_name;
  44. using MultiArg<T>::_description;
  45. using MultiArg<T>::_alreadySet;
  46. using MultiArg<T>::toString;
  47. public:
  48. /**
  49. * Constructor.
  50. * \param name - The name of the Arg. Note that this is used for
  51. * identification, not as a long flag.
  52. * \param desc - A description of what the argument is for or
  53. * does.
  54. * \param req - Whether the argument is required on the command
  55. * line.
  56. * \param typeDesc - A short, human readable description of the
  57. * type that this object expects. This is used in the generation
  58. * of the USAGE statement. The goal is to be helpful to the end user
  59. * of the program.
  60. * \param ignoreable - Whether or not this argument can be ignored
  61. * using the "--" flag.
  62. * \param v - An optional visitor. You probably should not
  63. * use this unless you have a very good reason.
  64. */
  65. UnlabeledMultiArg( const std::string& name,
  66. const std::string& desc,
  67. bool req,
  68. const std::string& typeDesc,
  69. bool ignoreable = false,
  70. Visitor* v = NULL );
  71. /**
  72. * Constructor.
  73. * \param name - The name of the Arg. Note that this is used for
  74. * identification, not as a long flag.
  75. * \param desc - A description of what the argument is for or
  76. * does.
  77. * \param req - Whether the argument is required on the command
  78. * line.
  79. * \param typeDesc - A short, human readable description of the
  80. * type that this object expects. This is used in the generation
  81. * of the USAGE statement. The goal is to be helpful to the end user
  82. * of the program.
  83. * \param parser - A CmdLine parser object to add this Arg to
  84. * \param ignoreable - Whether or not this argument can be ignored
  85. * using the "--" flag.
  86. * \param v - An optional visitor. You probably should not
  87. * use this unless you have a very good reason.
  88. */
  89. UnlabeledMultiArg( const std::string& name,
  90. const std::string& desc,
  91. bool req,
  92. const std::string& typeDesc,
  93. CmdLineInterface& parser,
  94. bool ignoreable = false,
  95. Visitor* v = NULL );
  96. /**
  97. * Constructor.
  98. * \param name - The name of the Arg. Note that this is used for
  99. * identification, not as a long flag.
  100. * \param desc - A description of what the argument is for or
  101. * does.
  102. * \param req - Whether the argument is required on the command
  103. * line.
  104. * \param constraint - A pointer to a Constraint object used
  105. * to constrain this Arg.
  106. * \param ignoreable - Whether or not this argument can be ignored
  107. * using the "--" flag.
  108. * \param v - An optional visitor. You probably should not
  109. * use this unless you have a very good reason.
  110. */
  111. UnlabeledMultiArg( const std::string& name,
  112. const std::string& desc,
  113. bool req,
  114. Constraint<T>* constraint,
  115. bool ignoreable = false,
  116. Visitor* v = NULL );
  117. /**
  118. * Constructor.
  119. * \param name - The name of the Arg. Note that this is used for
  120. * identification, not as a long flag.
  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 parser - A CmdLine parser object to add this Arg to
  128. * \param ignoreable - Whether or not this argument can be ignored
  129. * using the "--" flag.
  130. * \param v - An optional visitor. You probably should not
  131. * use this unless you have a very good reason.
  132. */
  133. UnlabeledMultiArg( const std::string& name,
  134. const std::string& desc,
  135. bool req,
  136. Constraint<T>* constraint,
  137. CmdLineInterface& parser,
  138. bool ignoreable = false,
  139. Visitor* v = NULL );
  140. /**
  141. * Handles the processing of the argument.
  142. * This re-implements the Arg version of this method to set the
  143. * _value of the argument appropriately. It knows the difference
  144. * between labeled and unlabeled.
  145. * \param i - Pointer the the current argument in the list.
  146. * \param args - Mutable list of strings. Passed from main().
  147. */
  148. virtual bool processArg(int* i, std::vector<std::string>& args);
  149. /**
  150. * Returns the a short id string. Used in the usage.
  151. * \param val - value to be used.
  152. */
  153. virtual std::string shortID(const std::string& val="val") const;
  154. /**
  155. * Returns the a long id string. Used in the usage.
  156. * \param val - value to be used.
  157. */
  158. virtual std::string longID(const std::string& val="val") const;
  159. /**
  160. * Operator ==.
  161. * \param a - The Arg to be compared to this.
  162. */
  163. virtual bool operator==(const Arg& a) const;
  164. /**
  165. * Pushes this to back of list rather than front.
  166. * \param argList - The list this should be added to.
  167. */
  168. virtual void addToList( std::list<Arg*>& argList ) const;
  169. };
  170. template<class T>
  171. UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
  172. const std::string& desc,
  173. bool req,
  174. const std::string& typeDesc,
  175. bool ignoreable,
  176. Visitor* v)
  177. : MultiArg<T>("", name, desc, req, typeDesc, v)
  178. {
  179. _ignoreable = ignoreable;
  180. OptionalUnlabeledTracker::check(true, toString());
  181. }
  182. template<class T>
  183. UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
  184. const std::string& desc,
  185. bool req,
  186. const std::string& typeDesc,
  187. CmdLineInterface& parser,
  188. bool ignoreable,
  189. Visitor* v)
  190. : MultiArg<T>("", name, desc, req, typeDesc, v)
  191. {
  192. _ignoreable = ignoreable;
  193. OptionalUnlabeledTracker::check(true, toString());
  194. parser.add( this );
  195. }
  196. template<class T>
  197. UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
  198. const std::string& desc,
  199. bool req,
  200. Constraint<T>* constraint,
  201. bool ignoreable,
  202. Visitor* v)
  203. : MultiArg<T>("", name, desc, req, constraint, v)
  204. {
  205. _ignoreable = ignoreable;
  206. OptionalUnlabeledTracker::check(true, toString());
  207. }
  208. template<class T>
  209. UnlabeledMultiArg<T>::UnlabeledMultiArg(const std::string& name,
  210. const std::string& desc,
  211. bool req,
  212. Constraint<T>* constraint,
  213. CmdLineInterface& parser,
  214. bool ignoreable,
  215. Visitor* v)
  216. : MultiArg<T>("", name, desc, req, constraint, v)
  217. {
  218. _ignoreable = ignoreable;
  219. OptionalUnlabeledTracker::check(true, toString());
  220. parser.add( this );
  221. }
  222. template<class T>
  223. bool UnlabeledMultiArg<T>::processArg(int *i, std::vector<std::string>& args)
  224. {
  225. if ( _hasBlanks( args[*i] ) )
  226. return false;
  227. // never ignore an unlabeled multi arg
  228. // always take the first value, regardless of the start string
  229. _extractValue( args[(*i)] );
  230. /*
  231. // continue taking args until we hit the end or a start string
  232. while ( (unsigned int)(*i)+1 < args.size() &&
  233. args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
  234. args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
  235. _extractValue( args[++(*i)] );
  236. */
  237. _alreadySet = true;
  238. return true;
  239. }
  240. template<class T>
  241. std::string UnlabeledMultiArg<T>::shortID(const std::string& val) const
  242. {
  243. static_cast<void>(val); // Ignore input, don't warn
  244. return std::string("<") + _typeDesc + "> ...";
  245. }
  246. template<class T>
  247. std::string UnlabeledMultiArg<T>::longID(const std::string& val) const
  248. {
  249. static_cast<void>(val); // Ignore input, don't warn
  250. return std::string("<") + _typeDesc + "> (accepted multiple times)";
  251. }
  252. template<class T>
  253. bool UnlabeledMultiArg<T>::operator==(const Arg& a) const
  254. {
  255. if ( _name == a.getName() || _description == a.getDescription() )
  256. return true;
  257. else
  258. return false;
  259. }
  260. template<class T>
  261. void UnlabeledMultiArg<T>::addToList( std::list<Arg*>& argList ) const
  262. {
  263. argList.push_back( const_cast<Arg*>(static_cast<const Arg* const>(this)) );
  264. }
  265. }
  266. #endif