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