3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
33 * Implements gmx::CommandLineParser.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_commandline
38 #include "cmdlineparser.h"
45 #include "gromacs/options/optionsassigner.h"
46 #include "gromacs/utility/exceptions.h"
51 /********************************************************************
52 * CommandLineParser::Impl
56 * Private implementation class for CommandLineParser.
58 * \ingroup module_commandline
60 class CommandLineParser::Impl
63 //! Sets the options object to parse to.
64 explicit Impl(Options *options);
66 //! Helper object for assigning the options.
67 OptionsAssigner assigner_;
70 CommandLineParser::Impl::Impl(Options *options)
73 assigner_.setAcceptBooleanNoPrefix(true);
74 assigner_.setNoStrictSectioning(true);
77 /********************************************************************
81 CommandLineParser::CommandLineParser(Options *options)
82 : impl_(new Impl(options))
86 CommandLineParser::~CommandLineParser()
90 void CommandLineParser::parse(int *argc, char *argv[])
92 std::vector<std::string> commandLine;
93 for (int i = 0; i < *argc; ++i)
95 commandLine.push_back(argv[i]);
100 void CommandLineParser::parse(std::vector<std::string> *commandLine)
102 ExceptionInitializer errors("Invalid command-line options");
103 std::string currentContext;
104 // Start in the discard phase to skip options that can't be understood.
105 bool bDiscard = true;
107 impl_->assigner_.start();
108 std::vector<std::string>::const_iterator arg;
109 for (arg = commandLine->begin() + 1; arg != commandLine->end(); ++arg)
111 // Lone '-' and numbers are passed as values.
112 if ((*arg)[0] == '-' && std::isalpha((*arg)[1]))
118 impl_->assigner_.finishOption();
120 catch (UserInputError &ex)
122 ex.prependContext(currentContext);
123 errors.addCurrentExceptionAsNested();
125 currentContext.clear();
127 currentContext = "In command-line option " + *arg;
131 const char *name = arg->c_str() + 1;
132 impl_->assigner_.startOption(name);
134 catch (UserInputError &ex)
137 ex.prependContext(currentContext);
138 errors.addCurrentExceptionAsNested();
139 currentContext.clear();
146 impl_->assigner_.appendValue(*arg);
148 catch (UserInputError &ex)
150 ex.prependContext(currentContext);
151 errors.addCurrentExceptionAsNested();
159 impl_->assigner_.finishOption();
161 catch (UserInputError &ex)
163 ex.prependContext(currentContext);
164 errors.addCurrentExceptionAsNested();
167 impl_->assigner_.finish();
168 if (errors.hasNestedExceptions())
170 // TODO: This exception type may not always be appropriate.
171 GMX_THROW(InvalidInputError(errors));