ValueArg.h
Go to the documentation of this file.
1 // ===========================================================================
2 // Copyright (c) 2011-2012 University of Pennsylvania
3 // Copyright (c) 2013-2016 Andreas Schuh
4 // All rights reserved.
5 //
6 // See COPYING file for license information or visit
7 // https://cmake-basis.github.io/download.html#license
8 // ===========================================================================
9 
10 /**
11  * @file basis/ValueArg.h
12  * @brief Extends TCLAP's ValueArg implementation.
13  *
14  * Instead of throwing an exception if an argument is set more than once,
15  * this argument type optionally allows the value to be overwritten.
16  */
17 
18 #pragma once
19 #ifndef _BASIS_VALUEARG_H
20 #define _BASIS_VALUEARG_H
21 
22 
23 #include "tclap/ValueArg.h"
24 
25 
26 namespace basis {
27 
28 
29 /**
30  * @brief An argument that allows multiple values of type T to be specified.
31  *
32  * Unlike TCLAP::ValueArg, this argument optionally allows the assignement
33  * of a value more than once, overwriting the previously set argument value.
34  * This is useful when a visitor set on another option consumed the previously
35  * set argument already and thus the value can be overwritten before the
36  * next appearance of this option. See the basistest-driver executable,
37  * for example, where the tolerances are stored in a structure every time
38  * a --compare option is encountered and the tolerances can then be overwritten
39  * for the next --compare statement.
40  *
41  * Copyright (c) 2012 University of Pennsylvania. All rights reserved.<br />
42  * See http://www.rad.upenn.edu/sbia/software/license.html or COPYING file.
43  *
44  * @ingroup CxxCmdLine
45  */
46 template <class T>
47 class ValueArg : public TCLAP::ValueArg<T>
48 {
49  // -----------------------------------------------------------------------
50  // construction / destruction
51 public:
52 
53  /**
54  * @brief Constructor.
55  *
56  * @param [in] flag The one character flag that identifies this
57  * argument on the command line.
58  * @param [in] name A one word name for the argument. Can be
59  * used as a long flag on the command line.
60  * @param [in] desc A description of what the argument is for or does.
61  * @param [in] req Whether the argument is required on the command-line.
62  * @param [in] value The default value assigned to this argument if it
63  * is not present on the command line.
64  * @param [in] typeDesc A short, human readable description of the
65  * type that this object expects. This is used in
66  * the generation of the USAGE statement. The goal
67  * is to be helpful to the end user of the program.
68  * @param [in] allowOverwrite Whether value can be overwritten by another
69  * occurrence of the argument on the command-line.
70  * @param [in] v An optional visitor. You probably should not
71  * use this unless you have a very good reason.
72  */
73  ValueArg(const std::string& flag,
74  const std::string& name,
75  const std::string& desc,
76  bool req,
77  T value,
78  const std::string& typeDesc,
79  bool allowOverwrite = false,
80  TCLAP::Visitor* v = NULL);
81 
82  /**
83  * @brief Constructor.
84  *
85  * @param [in] flag The one character flag that identifies this
86  * argument on the command line.
87  * @param [in] name A one word name for the argument. Can be
88  * used as a long flag on the command line.
89  * @param [in] desc A description of what the argument is for or does.
90  * @param [in] req Whether the argument is required on the command-line.
91  * @param [in] value The default value assigned to this argument if it
92  * is not present on the command line.
93  * @param [in] typeDesc A short, human readable description of the
94  * type that this object expects. This is used in
95  * the generation of the USAGE statement. The goal
96  * is to be helpful to the end user of the program.
97  * @param [in] parser A CmdLine parser object to add this Arg to.
98  * @param [in] allowOverwrite Whether value can be overwritten by another
99  * occurrence of the argument on the command-line.
100  * @param [in] v An optional visitor. You probably should not
101  * use this unless you have a very good reason.
102  */
103  ValueArg(const std::string& flag,
104  const std::string& name,
105  const std::string& desc,
106  bool req,
107  T value,
108  const std::string& typeDesc,
109  TCLAP::CmdLineInterface& parser,
110  bool allowOverwrite = false,
111  TCLAP::Visitor* v = NULL);
112 
113  /**
114  * @brief Constructor.
115  *
116  * @param [in] flag The one character flag that identifies this
117  * argument on the command line.
118  * @param [in] name A one word name for the argument. Can be
119  * used as a long flag on the command line.
120  * @param [in] desc A description of what the argument is for or does.
121  * @param [in] req Whether the argument is required on the command-line.
122  * @param [in] value The default value assigned to this argument if it
123  * is not present on the command line.
124  * @param [in] constraint A pointer to a Constraint object used
125  * to constrain this Arg.
126  * @param [in] parser A CmdLine parser object to add this Arg to.
127  * @param [in] allowOverwrite Whether value can be overwritten by another
128  * occurrence of the argument on the command-line.
129  * @param [in] v An optional visitor. You probably should not
130  * use this unless you have a very good reason.
131  */
132  ValueArg(const std::string& flag,
133  const std::string& name,
134  const std::string& desc,
135  bool req,
136  T value,
137  TCLAP::Constraint<T>* constraint,
138  TCLAP::CmdLineInterface& parser,
139  bool allowOverwrite = false,
140  TCLAP::Visitor* v = NULL);
141 
142  /**
143  * @brief Constructor.
144  *
145  * @param [in] flag The one character flag that identifies this
146  * argument on the command line.
147  * @param [in] name A one word name for the argument. Can be
148  * used as a long flag on the command line.
149  * @param [in] desc A description of what the argument is for or does.
150  * @param [in] req Whether the argument is required on the command-line.
151  * @param [in] value The default value assigned to this argument if it
152  * is not present on the command line.
153  * @param [in] constraint A pointer to a Constraint object used
154  * to constrain this Arg.
155  * @param [in] allowOverwrite Whether value can be overwritten by another
156  * occurrence of the argument on the command-line.
157  * @param [in] v An optional visitor. You probably should not
158  * use this unless you have a very good reason.
159  */
160  ValueArg(const std::string& flag,
161  const std::string& name,
162  const std::string& desc,
163  bool req,
164  T value,
165  TCLAP::Constraint<T>* constraint,
166  bool allowOverwrite = false,
167  TCLAP::Visitor* v = NULL);
168 
169  // -----------------------------------------------------------------------
170  // parsing
171 public:
172 
173  /**
174  * @brief Handles the processing of the argument.
175  *
176  * This re-implements the TCLAP::ValueArg version of this method to
177  * ignore the _alreadySet flag if _allowOverwrite is true.
178  *
179  * @param [in, out] i Pointer to the current argument in the list.
180  * @param [in, out] args Mutable list of strings. Passed from main().
181  */
182  virtual bool processArg(int* i, std::vector<std::string>& args);
183 
184  // -----------------------------------------------------------------------
185  // unsupported
186 private:
187  ValueArg<T>(const ValueArg<T>&); ///< Not implemented.
188  ValueArg<T>& operator=(const ValueArg<T>&); ///< Not implemented.
189 
190  // -----------------------------------------------------------------------
191  // member variables
192 protected:
193 
194  bool _allowOverwrite; ///< Whether argument value can be overwritten by
195  ///< another occurrence of this argument.
196 
197 }; // class ValueArg
198 
199 
200 // ===========================================================================
201 // template definitions
202 // ===========================================================================
203 
204 // ---------------------------------------------------------------------------
205 template <class T>
206 ValueArg<T>::ValueArg(const std::string& flag,
207  const std::string& name,
208  const std::string& desc,
209  bool req,
210  T val,
211  const std::string& typeDesc,
212  bool allowOverwrite,
213  TCLAP::Visitor* v)
214 :
215  TCLAP::ValueArg<T>(flag, name, desc, req, val, typeDesc, v),
216  _allowOverwrite(allowOverwrite)
217 {
218 }
219 
220 // ---------------------------------------------------------------------------
221 template <class T>
222 ValueArg<T>::ValueArg(const std::string& flag,
223  const std::string& name,
224  const std::string& desc,
225  bool req,
226  T val,
227  const std::string& typeDesc,
228  TCLAP::CmdLineInterface& parser,
229  bool allowOverwrite,
230  TCLAP::Visitor* v)
231 :
232  TCLAP::ValueArg<T>(flag, name, desc, req, val, typeDesc, parser, v),
233  _allowOverwrite(allowOverwrite)
234 {
235 }
236 
237 // ---------------------------------------------------------------------------
238 template <class T>
239 ValueArg<T>::ValueArg(const std::string& flag,
240  const std::string& name,
241  const std::string& desc,
242  bool req,
243  T val,
244  TCLAP::Constraint<T>* constraint,
245  bool allowOverwrite,
246  TCLAP::Visitor* v)
247 :
248  TCLAP::ValueArg<T>(flag, name, desc, req, val, constraint, v),
249  _allowOverwrite(allowOverwrite)
250 {
251 }
252 
253 // ---------------------------------------------------------------------------
254 template <class T>
255 ValueArg<T>::ValueArg(const std::string& flag,
256  const std::string& name,
257  const std::string& desc,
258  bool req,
259  T val,
260  TCLAP::Constraint<T>* constraint,
261  TCLAP::CmdLineInterface& parser,
262  bool allowOverwrite,
263  TCLAP::Visitor* v)
264 :
265  TCLAP::ValueArg<T>(flag, name, desc, req, val, constraint, parser, v),
266  _allowOverwrite(allowOverwrite)
267 {
268 }
269 
270 // ---------------------------------------------------------------------------
271 template <class T>
272 bool ValueArg<T>::processArg(int* i, std::vector<std::string>& args)
273 {
274  if (TCLAP::ValueArg<T>::_ignoreable && TCLAP::ValueArg<T>::ignoreRest()) return false;
275  if (TCLAP::ValueArg<T>::_hasBlanks(args[*i])) return false;
276 
277  std::string flag = args[*i];
278 
279  std::string value = "";
280  TCLAP::ValueArg<T>::trimFlag(flag, value);
281 
282  if (TCLAP::ValueArg<T>::argMatches(flag)) {
283  if (!_allowOverwrite && TCLAP::ValueArg<T>::_alreadySet) {
284  if (TCLAP::ValueArg<T>::_xorSet) {
285  throw TCLAP::CmdLineParseException("Mutually exclusive argument already set!",
286  TCLAP::ValueArg<T>::toString());
287  } else {
288  throw TCLAP::CmdLineParseException("Argument already set!",
289  TCLAP::ValueArg<T>::toString());
290  }
291  }
292 
293  if (TCLAP::Arg::delimiter() != ' ' && value == "") {
294  throw TCLAP::ArgParseException("Couldn't find delimiter for this argument!",
295  TCLAP::ValueArg<T>::toString());
296  }
297 
298  if (value == "") {
299  (*i)++;
300  if (static_cast<unsigned int>(*i) < args.size()) {
301  TCLAP::ValueArg<T>::_extractValue(args[*i]);
302  } else {
303  throw TCLAP::ArgParseException("Missing a value for this argument!",
304  TCLAP::ValueArg<T>::toString());
305  }
306  } else {
307  TCLAP::ValueArg<T>::_extractValue(value);
308  }
309 
310  TCLAP::ValueArg<T>::_alreadySet = true;
311  TCLAP::ValueArg<T>::_checkWithVisitor();
312  return true;
313  } else {
314  return false;
315  }
316 }
317 
318 
319 } // namespace basis
320 
321 
322 #endif // _BASIS_VALUEARG_H
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: ValueArg.h:272
Definition: basis.h:34
TCLAP::ArgParseException ArgParseException
Exception thrown on command-line argument parsing error.
Definition: except.h:67
bool _allowOverwrite
Definition: ValueArg.h:194
ValueArg(const std::string &flag, const std::string &name, const std::string &desc, bool req, T value, const std::string &typeDesc, bool allowOverwrite=false, TCLAP::Visitor *v=NULL)
Constructor.
Definition: ValueArg.h:206
TCLAP::CmdLineParseException CmdLineParseException
Exception thrown on command-line parsing error.
Definition: except.h:70
An argument that allows multiple values of type T to be specified.
Definition: ValueArg.h:47