Merge branch 'release-4-5-patches'
[alexxy/gromacs.git] / src / gromacs / options / optionsassigner.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
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.
13
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.
18  *
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.
25  *
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.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \libinternal \file
32  * \brief
33  * Declares gmx::OptionsAssigner.
34  *
35  * This header is only needed when implementing option parsers.
36  *
37  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
38  * \inlibraryapi
39  * \ingroup module_options
40  */
41 #ifndef GMX_OPTIONS_OPTIONSASSIGNER_H
42 #define GMX_OPTIONS_OPTIONSASSIGNER_H
43
44 #include <string>
45
46 namespace gmx
47 {
48
49 class AbstractErrorReporter;
50
51 class Options;
52
53 /*! \libinternal \brief
54  * Decorator class for assigning values to Options.
55  *
56  * This class extends the interface of an Options object by providing methods
57  * to set values for options.  It also keeps track of necessary state variables
58  * to assign values to options in subsections within the Options object.
59  * Typical use (without error checking):
60  * \code
61 gmx::options::Options options("name", "Title");
62 // Set up options
63
64 gmx::error::StandardReporter errors;
65 gmx::options::OptionsAssigner assigner(&options, &errors);
66 assigner.startOption("opt1");
67 assigner.appendValue("3");
68 assigner.startSubSection("section");
69 assigner.startOption("opt2"); // Now in the subsection
70 assigner.appendValue("yes");
71 assigner.finishSubSection()
72 assigner.startOption("opt3"); // Again in the main options
73 assigner.appendValue("2");
74 assigner.finish(); // At minimum, the return value of finish() should be checked.
75  * \endcode
76  *
77  * As shown in the example, calling finishOption() or finishSubSection() is
78  * optional; they are automatically called when appropriate by startOption(),
79  * startSubSection(), and finish().
80  * However, you need to call them explicitly if you want to act on the return
81  * value: these calls do not influence the return value of
82  * startOption() / startSubSection().
83  * They do influence the return value of finish(), however.
84  * The finish() method should always be called.
85  *
86  * \inlibraryapi
87  * \ingroup module_options
88  */
89 class OptionsAssigner
90 {
91     public:
92         /*! \brief
93          * Creates an object that assigns to the given object.
94          */
95         OptionsAssigner(Options *options, AbstractErrorReporter *errors);
96         ~OptionsAssigner();
97
98         /*! \brief
99          * Returns the error reporter object passed to the constructor.
100          *
101          * This method is provided for convenience such that users of this
102          * class do not need to store a separate pointer to the error reporter
103          * if they need to use it.
104          */
105         AbstractErrorReporter *errorReporter() const;
106
107         /*! \brief
108          * Sets the assigner to recognize boolean options with a "no" prefix.
109          *
110          * With this option set, \c startOption("noname") is interpreted as
111          * \c startOption("name") followed by \c appendValue("no"), if there is
112          * no option by the name "noname", but there is a boolean option with
113          * name "name".
114          *
115          * By default, the prefix is not recognized.
116          *
117          * Can be set or cleared at any time, and will have effect on all
118          * subsequent calls of startOption().
119          */
120         void setAcceptBooleanNoPrefix(bool enabled);
121         /*! \brief
122          * Sets the assigner to find options in non-active sections.
123          *
124          * By default, options are only looked for in the currently active
125          * subsection.  With this option set, if no matching option is found in
126          * the current section, a breadth-first search is performed, first on
127          * all subsections of the current section, and then going up one level
128          * at a time.  The first matching option is used, and the current
129          * section is changed to the section that contains the matching option.
130          *
131          * Can be set or cleared at any time, and will have effect on all
132          * subsequent calls of startOption().
133          */
134         void setNoStrictSectioning(bool enabled);
135
136         /*! \brief
137          * Start assigning values.
138          *
139          * \retval 0 on success.
140          */
141         int start();
142         /*! \brief
143          * Start assigning values to options in a subsection.
144          *
145          * \param[in] name  Name of the subsection to start assigning to.
146          * \retval 0 if assignment can proceed.
147          *
148          * Does not call finishSubSection() automatically to enable nested
149          * sections.
150          */
151         int startSubSection(const char *name);
152         /*! \brief
153          * Start assigning values for an option.
154          *
155          * \param[in] name  Name of the option to start assigning to.
156          * \retval 0 if assignment can proceed.
157          */
158         int startOption(const char *name);
159         /*! \brief
160          * Appends a value to the value list of the current option.
161          *
162          * \param[in] value  String representation of the value to assign.
163          * \retval 0 if assignment was successful.
164          */
165         int appendValue(const std::string &value);
166         /*! \brief
167          * Finish assigning values for the current option.
168          *
169          * \retval 0 if there were no errors in the assignment.
170          *
171          * This function returns non-zero only if the error could not have been
172          * detected earlier, i.e., from the return value of appendValue().
173          */
174         int finishOption();
175         /*! \brief
176          * Finish assigning values to a subsection.
177          *
178          * \retval 0 for success.
179          *
180          * This function returns non-zero only if the error could not have been
181          * detected earlier.
182          */
183         int finishSubSection();
184         /*! \brief
185          * Finish assigning options through the object.
186          *
187          * \retval 0 if there were no errors in the assignment.
188          *
189          * If an error was detected in any of the other calls to this class,
190          * this function returns the error code of the first of such errors.
191          */
192         int finish();
193
194     private:
195         class Impl;
196
197         Impl                   *_impl;
198
199         // Disallow copy and assign.
200         OptionsAssigner(const OptionsAssigner &);
201         void operator =(const OptionsAssigner &);
202 };
203
204 } // namespace gmx
205
206 #endif