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 classes in abstractoption.h and abstractoptionstorage.h.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_options
38 #include "gromacs/options/abstractoption.h"
40 #include "gromacs/options/abstractoptionstorage.h"
41 #include "gromacs/options/optionflags.h"
42 #include "gromacs/options/optioninfo.h"
43 #include "gromacs/utility/exceptions.h"
44 #include "gromacs/utility/gmxassert.h"
46 #include "basicoptionstorage.h"
51 /********************************************************************
52 * AbstractOptionStorage
55 AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings,
56 OptionFlags staticFlags)
57 : flags_(settings.flags_ | staticFlags),
58 minValueCount_(settings.minValueCount_),
59 maxValueCount_(settings.maxValueCount_),
60 bInSet_(false), bSetValuesHadErrors_(false)
62 // Check that user has not provided incorrect values for vectors.
63 if (hasFlag(efOption_Vector) && (minValueCount_ > 1 || maxValueCount_ < 1))
65 GMX_THROW(APIError("Inconsistent value counts for vector values"));
68 if (settings.name_ != NULL)
70 name_ = settings.name_;
72 descr_ = settings.createDescription();
73 setFlag(efOption_ClearOnNextSet);
76 AbstractOptionStorage::~AbstractOptionStorage()
80 bool AbstractOptionStorage::isBoolean() const
82 return dynamic_cast<const BooleanOptionStorage *>(this) != NULL;
85 void AbstractOptionStorage::startSource()
87 setFlag(efOption_ClearOnNextSet);
90 void AbstractOptionStorage::startSet()
92 GMX_RELEASE_ASSERT(!bInSet_, "finishSet() not called");
93 // The last condition takes care of the situation where multiple
94 // sources are used, and a later source should be able to reassign
95 // the value even though the option is already set.
96 if (isSet() && !hasFlag(efOption_MultipleTimes)
97 && !hasFlag(efOption_ClearOnNextSet))
99 GMX_THROW(InvalidInputError("Option specified multiple times"));
103 bSetValuesHadErrors_ = false;
106 void AbstractOptionStorage::appendValue(const std::string &value)
108 GMX_RELEASE_ASSERT(bInSet_, "startSet() not called");
115 bSetValuesHadErrors_ = true;
120 void AbstractOptionStorage::finishSet()
122 GMX_RELEASE_ASSERT(bInSet_, "startSet() not called");
124 // We mark the option as set even when there are errors to avoid additional
125 // errors from required options not set.
126 // TODO: There could be a separate flag for this purpose.
127 setFlag(efOption_Set);
128 if (!bSetValuesHadErrors_)
130 // TODO: Correct handling of the efOption_ClearOnNextSet requires
131 // processSet() and/or convertValue() to check it internally.
132 // OptionStorageTemplate takes care of it, but it's error-prone if
133 // a custom option is implemented that doesn't use it.
136 bSetValuesHadErrors_ = false;
137 clearFlag(efOption_ClearOnNextSet);
141 void AbstractOptionStorage::finish()
143 GMX_RELEASE_ASSERT(!bInSet_, "finishSet() not called");
145 if (isRequired() && !isSet())
147 GMX_THROW(InvalidInputError("Option is required, but not set"));
151 void AbstractOptionStorage::setMinValueCount(int count)
153 GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
154 "setMinValueCount() not supported with efOption_MultipleTimes");
155 GMX_RELEASE_ASSERT(count >= 0, "Invalid value count");
156 minValueCount_ = count;
157 if (isSet() && !hasFlag(efOption_DontCheckMinimumCount)
158 && valueCount() < minValueCount_)
160 GMX_THROW(InvalidInputError("Too few values"));
164 void AbstractOptionStorage::setMaxValueCount(int count)
166 GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
167 "setMaxValueCount() not supported with efOption_MultipleTimes");
168 GMX_RELEASE_ASSERT(count >= -1, "Invalid value count");
169 maxValueCount_ = count;
170 if (isSet() && maxValueCount_ >= 0 && valueCount() > maxValueCount_)
172 GMX_THROW(InvalidInputError("Too many values"));
176 /********************************************************************
181 OptionInfo::OptionInfo(AbstractOptionStorage *option)
187 OptionInfo::~OptionInfo()
191 bool OptionInfo::isSet() const
193 return option().isSet();
196 bool OptionInfo::isHidden() const
198 return option().isHidden();
201 bool OptionInfo::isRequired() const
203 return option().isRequired();
206 const std::string &OptionInfo::name() const
208 return option().name();
211 const std::string &OptionInfo::description() const
213 return option().description();
216 const char *OptionInfo::type() const
218 return option().typeString();
221 int OptionInfo::valueCount() const
223 return option().valueCount();
226 std::string OptionInfo::formatValue(int i) const
228 return option().formatValue(i);
231 std::string OptionInfo::formatDefaultValueIfSet() const
233 return option().formatDefaultValueIfSet();