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.
 
 
 

302 lines
9.4 KiB

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