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.
 
 
 

426 line
14 KiB

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