1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
3 /******************************************************************************
7 * Copyright (c) 2003, Michael E. Smoot .
8 * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
11 * See the file COPYING in the top directory of this distribution for
14 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
22 *****************************************************************************/
24 #ifndef TCLAP_CMDLINE_H
25 #define TCLAP_CMDLINE_H
27 #include <tclap/SwitchArg.h>
28 #include <tclap/MultiSwitchArg.h>
29 #include <tclap/UnlabeledValueArg.h>
30 #include <tclap/UnlabeledMultiArg.h>
32 #include <tclap/XorHandler.h>
33 #include <tclap/HelpVisitor.h>
34 #include <tclap/VersionVisitor.h>
35 #include <tclap/IgnoreRestVisitor.h>
37 #include <tclap/CmdLineOutput.h>
38 #include <tclap/StdOutput.h>
40 #include <tclap/Constraint.h>
41 #include <tclap/ValuesConstraint.h>
49 #include <stdlib.h> // Needed for exit(), which isn't defined in some envs.
53 template<typename T> void DelPtr(T ptr)
58 template<typename C> void ClearContainer(C &c)
60 typedef typename C::value_type value_type;
61 std::for_each(c.begin(), c.end(), DelPtr<value_type>);
67 * The base class that manages the command line definition and passes
68 * along the parsing to the appropriate Arg classes.
70 class CmdLine : public CmdLineInterface
75 * The list of arguments that will be tested against the
78 std::list<Arg*> _argList;
81 * The name of the program. Set to argv[0].
83 std::string _progName;
86 * A message used to describe the program. Used in the usage output.
91 * The version to be displayed with the --version switch.
96 * The number of arguments that are required to be present on
97 * the command line. This is set dynamically, based on the
98 * Args added to the CmdLine object.
103 * The character that is used to separate the argument flag/name
104 * from the value. Defaults to ' ' (space).
109 * The handler that manages xoring lists of args.
111 XorHandler _xorHandler;
114 * A list of Args to be explicitly deleted when the destructor
115 * is called. At the moment, this only includes the three default
118 std::list<Arg*> _argDeleteOnExitList;
121 * A list of Visitors to be explicitly deleted when the destructor
122 * is called. At the moment, these are the Visitors created for the
125 std::list<Visitor*> _visitorDeleteOnExitList;
128 * Object that handles all output for the CmdLine.
130 CmdLineOutput* _output;
133 * Should CmdLine handle parsing exceptions internally?
135 bool _handleExceptions;
138 * Throws an exception listing the missing args.
140 void missingArgsException();
143 * Checks whether a name/flag string matches entirely matches
144 * the Arg::blankChar. Used when multiple switches are combined
145 * into a single argument.
146 * \param s - The message to be used in the usage.
148 bool _emptyCombined(const std::string& s);
151 * Perform a delete ptr; operation on ptr when this object is deleted.
153 void deleteOnExit(Arg* ptr);
156 * Perform a delete ptr; operation on ptr when this object is deleted.
158 void deleteOnExit(Visitor* ptr);
163 * Prevent accidental copying.
165 CmdLine(const CmdLine& rhs);
166 CmdLine& operator=(const CmdLine& rhs);
169 * Encapsulates the code common to the constructors
170 * (which is all of it).
176 * Is set to true when a user sets the output object. We use this so
177 * that we don't delete objects that are created outside of this lib.
182 * Whether or not to automatically create help and version switches.
184 bool _helpAndVersion;
187 * Whether or not to ignore unmatched args.
189 bool _ignoreUnmatched;
194 * Command line constructor. Defines how the arguments will be
196 * \param message - The message to be used in the usage
198 * \param delimiter - The character that is used to separate
199 * the argument flag/name from the value. Defaults to ' ' (space).
200 * \param version - The version number to be used in the
202 * \param helpAndVersion - Whether or not to create the Help and
203 * Version switches. Defaults to true.
205 CmdLine(const std::string& message,
206 const char delimiter = ' ',
207 const std::string& version = "none",
208 bool helpAndVersion = true);
211 * Deletes any resources allocated by a CmdLine object.
216 * Adds an argument to the list of arguments to be parsed.
217 * \param a - Argument to be added.
222 * An alternative add. Functionally identical.
223 * \param a - Argument to be added.
228 * Add two Args that will be xor'd. If this method is used, add does
229 * not need to be called.
230 * \param a - Argument to be added and xor'd.
231 * \param b - Argument to be added and xor'd.
233 void xorAdd( Arg& a, Arg& b );
236 * Add a list of Args that will be xor'd. If this method is used,
237 * add does not need to be called.
238 * \param xors - List of Args to be added and xor'd.
240 void xorAdd( const std::vector<Arg*>& xors );
243 * Parses the command line.
244 * \param argc - Number of arguments.
245 * \param argv - Array of arguments.
247 void parse(int argc, const char * const * argv);
250 * Parses the command line.
251 * \param args - A vector of strings representing the args.
252 * args[0] is still the program name.
254 void parse(std::vector<std::string>& args);
259 CmdLineOutput* getOutput();
264 void setOutput(CmdLineOutput* co);
269 std::string& getVersion();
274 std::string& getProgramName();
279 std::list<Arg*>& getArgList();
284 XorHandler& getXorHandler();
294 std::string& getMessage();
299 bool hasHelpAndVersion();
302 * Disables or enables CmdLine's internal parsing exception handling.
304 * @param state Should CmdLine handle parsing exceptions internally?
306 void setExceptionHandling(const bool state);
309 * Returns the current state of the internal exception handling.
311 * @retval true Parsing exceptions are handled internally.
312 * @retval false Parsing exceptions are propagated to the caller.
314 bool getExceptionHandling() const;
317 * Allows the CmdLine object to be reused.
322 * Allows unmatched args to be ignored. By default false.
324 * @param ignore If true the cmdline will ignore any unmatched args
325 * and if false it will behave as normal.
327 void ignoreUnmatched(const bool ignore);
331 ///////////////////////////////////////////////////////////////////////////////
333 ///////////////////////////////////////////////////////////////////////////////
335 inline CmdLine::CmdLine(const std::string& m,
337 const std::string& v,
340 _argList(std::list<Arg*>()),
341 _progName("not_set_yet"),
346 _xorHandler(XorHandler()),
347 _argDeleteOnExitList(std::list<Arg*>()),
348 _visitorDeleteOnExitList(std::list<Visitor*>()),
350 _handleExceptions(true),
351 _userSetOutput(false),
352 _helpAndVersion(help),
353 _ignoreUnmatched(false)
358 inline CmdLine::~CmdLine()
360 ClearContainer(_argDeleteOnExitList);
361 ClearContainer(_visitorDeleteOnExitList);
363 if ( !_userSetOutput ) {
369 inline void CmdLine::_constructor()
371 _output = new StdOutput;
373 Arg::setDelimiter( _delimiter );
377 if ( _helpAndVersion )
379 v = new HelpVisitor( this, &_output );
380 SwitchArg* help = new SwitchArg("h","help",
381 "Displays usage information and exits.",
387 v = new VersionVisitor( this, &_output );
388 SwitchArg* vers = new SwitchArg("","version",
389 "Displays version information and exits.",
396 v = new IgnoreRestVisitor();
397 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
398 Arg::ignoreNameString(),
399 "Ignores the rest of the labeled arguments following this flag.",
402 deleteOnExit(ignore);
406 inline void CmdLine::xorAdd( const std::vector<Arg*>& ors )
408 _xorHandler.add( ors );
410 for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
412 (*it)->forceRequired();
413 (*it)->setRequireLabel( "OR required" );
418 inline void CmdLine::xorAdd( Arg& a, Arg& b )
420 std::vector<Arg*> ors;
426 inline void CmdLine::add( Arg& a )
431 inline void CmdLine::add( Arg* a )
433 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
435 throw( SpecificationException(
436 "Argument with same flag/name already exists!",
439 a->addToList( _argList );
441 if ( a->isRequired() )
446 inline void CmdLine::parse(int argc, const char * const * argv)
448 // this step is necessary so that we have easy access to
450 std::vector<std::string> args;
451 for (int i = 0; i < argc; i++)
452 args.push_back(argv[i]);
457 inline void CmdLine::parse(std::vector<std::string>& args)
459 bool shouldExit = false;
463 _progName = args.front();
464 args.erase(args.begin());
466 int requiredCount = 0;
468 for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
470 bool matched = false;
471 for (ArgListIterator it = _argList.begin();
472 it != _argList.end(); it++) {
473 if ( (*it)->processArg( &i, args ) )
475 requiredCount += _xorHandler.check( *it );
481 // checks to see if the argument is an empty combined
482 // switch and if so, then we've actually matched it
483 if ( !matched && _emptyCombined( args[i] ) )
486 if ( !matched && !Arg::ignoreRest() && !_ignoreUnmatched)
487 throw(CmdLineParseException("Couldn't find match "
492 if ( requiredCount < _numRequired )
493 missingArgsException();
495 if ( requiredCount > _numRequired )
496 throw(CmdLineParseException("Too many arguments!"));
498 } catch ( ArgException& e ) {
499 // If we're not handling the exceptions, rethrow.
500 if ( !_handleExceptions) {
505 _output->failure(*this,e);
506 } catch ( ExitException &ee ) {
507 estat = ee.getExitStatus();
510 } catch (ExitException &ee) {
511 // If we're not handling the exceptions, rethrow.
512 if ( !_handleExceptions) {
516 estat = ee.getExitStatus();
524 inline bool CmdLine::_emptyCombined(const std::string& s)
526 if ( s.length() > 0 && s[0] != Arg::flagStartChar() )
529 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
530 if ( s[i] != Arg::blankChar() )
536 inline void CmdLine::missingArgsException()
540 std::string missingArgList;
541 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
543 if ( (*it)->isRequired() && !(*it)->isSet() )
545 missingArgList += (*it)->getName();
546 missingArgList += ", ";
550 missingArgList = missingArgList.substr(0,missingArgList.length()-2);
554 msg = "Required arguments missing: ";
556 msg = "Required argument missing: ";
558 msg += missingArgList;
560 throw(CmdLineParseException(msg));
563 inline void CmdLine::deleteOnExit(Arg* ptr)
565 _argDeleteOnExitList.push_back(ptr);
568 inline void CmdLine::deleteOnExit(Visitor* ptr)
570 _visitorDeleteOnExitList.push_back(ptr);
573 inline CmdLineOutput* CmdLine::getOutput()
578 inline void CmdLine::setOutput(CmdLineOutput* co)
580 if ( !_userSetOutput )
582 _userSetOutput = true;
586 inline std::string& CmdLine::getVersion()
591 inline std::string& CmdLine::getProgramName()
596 inline std::list<Arg*>& CmdLine::getArgList()
601 inline XorHandler& CmdLine::getXorHandler()
606 inline char CmdLine::getDelimiter()
611 inline std::string& CmdLine::getMessage()
616 inline bool CmdLine::hasHelpAndVersion()
618 return _helpAndVersion;
621 inline void CmdLine::setExceptionHandling(const bool state)
623 _handleExceptions = state;
626 inline bool CmdLine::getExceptionHandling() const
628 return _handleExceptions;
631 inline void CmdLine::reset()
633 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
639 inline void CmdLine::ignoreUnmatched(const bool ignore)
641 _ignoreUnmatched = ignore;
644 ///////////////////////////////////////////////////////////////////////////////
646 ///////////////////////////////////////////////////////////////////////////////