00001 /** 00002 * @file basis/ValueArg.h 00003 * @brief Extends TCLAP's ValueArg implementation. 00004 * 00005 * Instead of throwing an exception if an argument is set more than once, 00006 * this argument type optionally allows the value to be overwritten. 00007 * 00008 * Copyright (c) 2012 University of Pennsylvania. All rights reserved.<br /> 00009 * See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00010 * 00011 * Contact: SBIA Group <sbia-software at uphs.upenn.edu> 00012 */ 00013 00014 #pragma once 00015 #ifndef _SBIA_BASIS_VALUEARG_H 00016 #define _SBIA_BASIS_VALUEARG_H 00017 00018 00019 #include <sbia/tclap/ValueArg.h> 00020 00021 00022 namespace sbia 00023 { 00024 00025 namespace basis 00026 { 00027 00028 00029 /** 00030 * @brief An argument that allows multiple values of type T to be specified. 00031 * 00032 * Unlike TCLAP::ValueArg, this argument optionally allows the assignement 00033 * of a value more than once, overwriting the previously set argument value. 00034 * This is useful when a visitor set on another option consumed the previously 00035 * set argument already and thus the value can be overwritten before the 00036 * next appearance of this option. See the basistest-driver executable, 00037 * for example, where the tolerances are stored in a structure every time 00038 * a --compare option is encountered and the tolerances can then be overwritten 00039 * for the next --compare statement. 00040 * 00041 * Copyright (c) 2012 University of Pennsylvania. All rights reserved.<br /> 00042 * See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00043 * 00044 * @ingroup CxxCmdLine 00045 */ 00046 template <class T> 00047 class ValueArg : public TCLAP::ValueArg<T> 00048 { 00049 // ----------------------------------------------------------------------- 00050 // construction / destruction 00051 public: 00052 00053 /** 00054 * @brief Constructor. 00055 * 00056 * @param [in] flag The one character flag that identifies this 00057 * argument on the command line. 00058 * @param [in] name A one word name for the argument. Can be 00059 * used as a long flag on the command line. 00060 * @param [in] desc A description of what the argument is for or does. 00061 * @param [in] req Whether the argument is required on the command-line. 00062 * @param [in] value The default value assigned to this argument if it 00063 * is not present on the command line. 00064 * @param [in] typeDesc A short, human readable description of the 00065 * type that this object expects. This is used in 00066 * the generation of the USAGE statement. The goal 00067 * is to be helpful to the end user of the program. 00068 * @param [in] allowOverwrite Whether value can be overwritten by another 00069 * occurrence of the argument on the command-line. 00070 * @param [in] v An optional visitor. You probably should not 00071 * use this unless you have a very good reason. 00072 */ 00073 ValueArg(const std::string& flag, 00074 const std::string& name, 00075 const std::string& desc, 00076 bool req, 00077 T value, 00078 const std::string& typeDesc, 00079 bool allowOverwrite = false, 00080 TCLAP::Visitor* v = NULL); 00081 00082 /** 00083 * @brief Constructor. 00084 * 00085 * @param [in] flag The one character flag that identifies this 00086 * argument on the command line. 00087 * @param [in] name A one word name for the argument. Can be 00088 * used as a long flag on the command line. 00089 * @param [in] desc A description of what the argument is for or does. 00090 * @param [in] req Whether the argument is required on the command-line. 00091 * @param [in] value The default value assigned to this argument if it 00092 * is not present on the command line. 00093 * @param [in] typeDesc A short, human readable description of the 00094 * type that this object expects. This is used in 00095 * the generation of the USAGE statement. The goal 00096 * is to be helpful to the end user of the program. 00097 * @param [in] parser A CmdLine parser object to add this Arg to. 00098 * @param [in] allowOverwrite Whether value can be overwritten by another 00099 * occurrence of the argument on the command-line. 00100 * @param [in] v An optional visitor. You probably should not 00101 * use this unless you have a very good reason. 00102 */ 00103 ValueArg(const std::string& flag, 00104 const std::string& name, 00105 const std::string& desc, 00106 bool req, 00107 T value, 00108 const std::string& typeDesc, 00109 TCLAP::CmdLineInterface& parser, 00110 bool allowOverwrite = false, 00111 TCLAP::Visitor* v = NULL); 00112 00113 /** 00114 * @brief Constructor. 00115 * 00116 * @param [in] flag The one character flag that identifies this 00117 * argument on the command line. 00118 * @param [in] name A one word name for the argument. Can be 00119 * used as a long flag on the command line. 00120 * @param [in] desc A description of what the argument is for or does. 00121 * @param [in] req Whether the argument is required on the command-line. 00122 * @param [in] value The default value assigned to this argument if it 00123 * is not present on the command line. 00124 * @param [in] constraint A pointer to a Constraint object used 00125 * to constrain this Arg. 00126 * @param [in] parser A CmdLine parser object to add this Arg to. 00127 * @param [in] allowOverwrite Whether value can be overwritten by another 00128 * occurrence of the argument on the command-line. 00129 * @param [in] v An optional visitor. You probably should not 00130 * use this unless you have a very good reason. 00131 */ 00132 ValueArg(const std::string& flag, 00133 const std::string& name, 00134 const std::string& desc, 00135 bool req, 00136 T value, 00137 TCLAP::Constraint<T>* constraint, 00138 TCLAP::CmdLineInterface& parser, 00139 bool allowOverwrite = false, 00140 TCLAP::Visitor* v = NULL); 00141 00142 /** 00143 * @brief Constructor. 00144 * 00145 * @param [in] flag The one character flag that identifies this 00146 * argument on the command line. 00147 * @param [in] name A one word name for the argument. Can be 00148 * used as a long flag on the command line. 00149 * @param [in] desc A description of what the argument is for or does. 00150 * @param [in] req Whether the argument is required on the command-line. 00151 * @param [in] value The default value assigned to this argument if it 00152 * is not present on the command line. 00153 * @param [in] constraint A pointer to a Constraint object used 00154 * to constrain this Arg. 00155 * @param [in] allowOverwrite Whether value can be overwritten by another 00156 * occurrence of the argument on the command-line. 00157 * @param [in] v An optional visitor. You probably should not 00158 * use this unless you have a very good reason. 00159 */ 00160 ValueArg(const std::string& flag, 00161 const std::string& name, 00162 const std::string& desc, 00163 bool req, 00164 T value, 00165 TCLAP::Constraint<T>* constraint, 00166 bool allowOverwrite = false, 00167 TCLAP::Visitor* v = NULL); 00168 00169 // ----------------------------------------------------------------------- 00170 // parsing 00171 public: 00172 00173 /** 00174 * @brief Handles the processing of the argument. 00175 * 00176 * This re-implements the TCLAP::ValueArg version of this method to 00177 * ignore the _alreadySet flag if _allowOverwrite is true. 00178 * 00179 * @param [in, out] i Pointer to the current argument in the list. 00180 * @param [in, out] args Mutable list of strings. Passed from main(). 00181 */ 00182 virtual bool processArg(int* i, std::vector<std::string>& args); 00183 00184 // ----------------------------------------------------------------------- 00185 // unsupported 00186 private: 00187 ValueArg<T>(const ValueArg<T>&); ///< Not implemented. 00188 ValueArg<T>& operator=(const ValueArg<T>&); ///< Not implemented. 00189 00190 // ----------------------------------------------------------------------- 00191 // member variables 00192 protected: 00193 00194 bool _allowOverwrite; ///< Whether argument value can be overwritten by 00195 ///< another occurrence of this argument. 00196 00197 }; // class ValueArg 00198 00199 00200 // =========================================================================== 00201 // template definitions 00202 // =========================================================================== 00203 00204 // --------------------------------------------------------------------------- 00205 template <class T> 00206 ValueArg<T>::ValueArg(const std::string& flag, 00207 const std::string& name, 00208 const std::string& desc, 00209 bool req, 00210 T val, 00211 const std::string& typeDesc, 00212 bool allowOverwrite, 00213 TCLAP::Visitor* v) 00214 : 00215 TCLAP::ValueArg<T>(flag, name, desc, req, val, typeDesc, v), 00216 _allowOverwrite(allowOverwrite) 00217 { 00218 } 00219 00220 // --------------------------------------------------------------------------- 00221 template <class T> 00222 ValueArg<T>::ValueArg(const std::string& flag, 00223 const std::string& name, 00224 const std::string& desc, 00225 bool req, 00226 T val, 00227 const std::string& typeDesc, 00228 TCLAP::CmdLineInterface& parser, 00229 bool allowOverwrite, 00230 TCLAP::Visitor* v) 00231 : 00232 TCLAP::ValueArg<T>(flag, name, desc, req, val, typeDesc, parser, v), 00233 _allowOverwrite(allowOverwrite) 00234 { 00235 } 00236 00237 // --------------------------------------------------------------------------- 00238 template <class T> 00239 ValueArg<T>::ValueArg(const std::string& flag, 00240 const std::string& name, 00241 const std::string& desc, 00242 bool req, 00243 T val, 00244 TCLAP::Constraint<T>* constraint, 00245 bool allowOverwrite, 00246 TCLAP::Visitor* v) 00247 : 00248 TCLAP::ValueArg<T>(flag, name, desc, req, val, constraint, v), 00249 _allowOverwrite(allowOverwrite) 00250 { 00251 } 00252 00253 // --------------------------------------------------------------------------- 00254 template <class T> 00255 ValueArg<T>::ValueArg(const std::string& flag, 00256 const std::string& name, 00257 const std::string& desc, 00258 bool req, 00259 T val, 00260 TCLAP::Constraint<T>* constraint, 00261 TCLAP::CmdLineInterface& parser, 00262 bool allowOverwrite, 00263 TCLAP::Visitor* v) 00264 : 00265 TCLAP::ValueArg<T>(flag, name, desc, req, val, constraint, parser, v), 00266 _allowOverwrite(allowOverwrite) 00267 { 00268 } 00269 00270 // --------------------------------------------------------------------------- 00271 template <class T> 00272 bool ValueArg<T>::processArg(int* i, std::vector<std::string>& args) 00273 { 00274 if (TCLAP::ValueArg<T>::_ignoreable && TCLAP::ValueArg<T>::ignoreRest()) return false; 00275 if (TCLAP::ValueArg<T>::_hasBlanks(args[*i])) return false; 00276 00277 std::string flag = args[*i]; 00278 00279 std::string value = ""; 00280 TCLAP::ValueArg<T>::trimFlag(flag, value); 00281 00282 if (TCLAP::ValueArg<T>::argMatches(flag)) { 00283 if (!_allowOverwrite && TCLAP::ValueArg<T>::_alreadySet) { 00284 if (TCLAP::ValueArg<T>::_xorSet) { 00285 throw TCLAP::CmdLineParseException("Mutually exclusive argument already set!", 00286 TCLAP::ValueArg<T>::toString()); 00287 } else { 00288 throw TCLAP::CmdLineParseException("Argument already set!", 00289 TCLAP::ValueArg<T>::toString()); 00290 } 00291 } 00292 00293 if (TCLAP::Arg::delimiter() != ' ' && value == "") { 00294 throw TCLAP::ArgParseException("Couldn't find delimiter for this argument!", 00295 TCLAP::ValueArg<T>::toString()); 00296 } 00297 00298 if (value == "") { 00299 (*i)++; 00300 if (static_cast<unsigned int>(*i) < args.size()) { 00301 TCLAP::ValueArg<T>::_extractValue(args[*i]); 00302 } else { 00303 throw TCLAP::ArgParseException("Missing a value for this argument!", 00304 TCLAP::ValueArg<T>::toString()); 00305 } 00306 } else { 00307 TCLAP::ValueArg<T>::_extractValue(value); 00308 } 00309 00310 TCLAP::ValueArg<T>::_alreadySet = true; 00311 TCLAP::ValueArg<T>::_checkWithVisitor(); 00312 return true; 00313 } else { 00314 return false; 00315 } 00316 } 00317 00318 00319 } // namespace basis 00320 00321 } // namespace sbia 00322 00323 00324 #endif // _SBIA_BASIS_VALUEARG_H