BASIS  version 1.2.3 (revision 2104)
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 _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