/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
//! Enum values for plot formats.
const char *const g_plotFormats[] = {
- "none", "xmgrace", "xmgr", NULL
+ "none", "xmgrace", "xmgr"
};
} // namespace
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
.timeValue().defaultValue(10.0));
options.addOption(StringOption("string").description("String option")
.defaultValue("test"));
- const char * const enumValues[] = {"no", "opt1", "opt2", NULL};
+ const char * const enumValues[] = { "no", "opt1", "opt2" };
options.addOption(StringOption("enum").description("Enum option")
.enumValue(enumValues).defaultEnumIndex(0));
enumIndexStore_ = settings.enumIndexStore_;
const std::string *defaultValue = settings.defaultValue();
int match = -1;
- for (int i = 0; settings.enumValues_[i] != NULL; ++i)
+ int count = settings.enumValuesCount_;
+ if (count < 0)
{
+ count = 0;
+ while (settings.enumValues_[count] != NULL)
+ {
+ ++count;
+ }
+ }
+ for (int i = 0; i < count; ++i)
+ {
+ if (settings.enumValues_[i] == NULL)
+ {
+ GMX_THROW(APIError("Enumeration value cannot be NULL"));
+ }
if (defaultValue != NULL && settings.enumValues_[i] == *defaultValue)
{
match = i;
std::string str;
options.addOption(StringOption("str").store(&str));
// Option that only accepts predefined values
- const char * const allowed[] = { "atom", "residue", "molecule", NULL };
+ const char * const allowed[] = { "atom", "residue", "molecule" };
std::string str;
int type;
options.addOption(StringOption("type").enumValue(allowed).store(&str)
//! Initializes an option with the given name.
explicit StringOption(const char *name)
- : MyBase(name), enumValues_(NULL), defaultEnumIndex_(-1),
- enumIndexStore_(NULL)
+ : MyBase(name), enumValues_(NULL), enumValuesCount_(0),
+ defaultEnumIndex_(-1), enumIndexStore_(NULL)
{
}
/*! \brief
* Sets the option to only accept one of a fixed set of strings.
*
- * \param[in] values Array of strings to accept, a NULL pointer
- * following the last string.
+ * \param[in] values Array of strings to accept.
*
* Also accepts prefixes of the strings; if a prefix matches more than
* one of the possible strings, the shortest one is used (in a tie, the
*
* The strings are copied once the option is created.
*/
- MyClass &enumValue(const char *const *values)
- { enumValues_ = values; return me(); }
+ template <size_t count>
+ MyClass &enumValue(const char *const (&values)[count])
+ {
+ GMX_ASSERT(enumValues_ == NULL,
+ "Multiple sets of enumerated values specified");
+ enumValues_ = values;
+ enumValuesCount_ = count;
+ return me();
+ }
+ /*! \brief
+ * Sets the option to only accept one of a fixed set of strings.
+ *
+ * \param[in] values Array of strings to accept, with a NULL pointer
+ * following the last string.
+ *
+ * Works otherwise as the array version, but accepts a pointer to
+ * an array of undetermined length. The end of the array is indicated
+ * by a NULL pointer in the array.
+ *
+ * \see enumValue()
+ */
+ MyClass &enumValueFromNullTerminatedArray(const char *const *values)
+ {
+ GMX_ASSERT(enumValues_ == NULL,
+ "Multiple sets of enumerated values specified");
+ enumValues_ = values;
+ enumValuesCount_ = -1;
+ return me();
+ }
/*! \brief
* Sets the default value using an index into the enumeration table.
*
*/
MyClass &defaultEnumIndex(int index)
{
- GMX_RELEASE_ASSERT(index >= 0, "Invalid enumeration index");
+ GMX_ASSERT(index >= 0, "Invalid enumeration index");
defaultEnumIndex_ = index;
return me();
}
* and there is no default value, -1 is stored.
*
* Cannot be specified without enumValue().
+ *
+ * \todo
+ * Implement this such that it is also possible to store the value
+ * directly into a real enum type.
*/
MyClass &storeEnumIndex(int *store)
{ enumIndexStore_ = store; return me(); }
virtual AbstractOptionStoragePointer createStorage() const;
const char *const *enumValues_;
+ int enumValuesCount_;
int defaultEnumIndex_;
int *enumIndexStore_;
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
using gmx::StringOption;
ASSERT_THROW(options.addOption(StringOption("name").store(&value)
.enumValue(allowed)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
int index = -1;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
EXPECT_EQ(1, index);
}
-TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
+TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
{
gmx::Options options(NULL, NULL);
std::string value;
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValueFromNullTerminatedArray(allowed)
+ .storeEnumIndex(&index)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("value"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
+
+ EXPECT_EQ("value", value);
+ EXPECT_EQ(2, index);
+}
+
+TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
+{
+ gmx::Options options(NULL, NULL);
+ std::string value;
+ const char * const allowed[] = { "none", "test", "value" };
+ int index = -1;
+ using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
StringOption("p").store(&value)
.enumValue(allowed).storeEnumIndex(&index)));
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
int index = -1;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
int index = -3;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
int index = -1;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
{
gmx::Options options(NULL, NULL);
std::string value;
- const char * const allowed[] = { "none", "test", "value", NULL };
+ const char * const allowed[] = { "none", "test", "value" };
int index = -1;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
* These must correspond to the TimeUnit enum in the header!
*/
const char *const g_timeUnits[] = {
- "fs", "ps", "ns", "us", "ms", "s", NULL
+ "fs", "ps", "ns", "us", "ms", "s"
};
/*! \brief
* Scaling factors from each time unit to internal units (=picoseconds).
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
void
SelectionCollection::initOptions(Options *options)
{
- static const char * const debug_levels[]
- = {"no", "basic", "compile", "eval", "full", NULL};
+ const char * const debug_levels[]
+ = {"no", "basic", "compile", "eval", "full" };
/*
static const char * const desc[] = {
"This program supports selections in addition to traditional",
*/
const char *const *postypes = PositionCalculationCollection::typeEnumValues;
- options->addOption(StringOption("selrpos").enumValue(postypes)
+ options->addOption(StringOption("selrpos")
+ .enumValueFromNullTerminatedArray(postypes)
.store(&impl_->rpost_).defaultValue(postypes[0])
.description("Selection reference positions"));
- options->addOption(StringOption("seltype").enumValue(postypes)
+ options->addOption(StringOption("seltype")
+ .enumValueFromNullTerminatedArray(postypes)
.store(&impl_->spost_).defaultValue(postypes[0])
.description("Default selection output positions"));
GMX_RELEASE_ASSERT(impl_->debugLevel_ >= 0 && impl_->debugLevel_ <= 4,
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
*/
};
static const char *const cGroup1TypeEnum[] =
- { "angle", "dihedral", "vector", "plane", NULL };
+ { "angle", "dihedral", "vector", "plane" };
static const char *const cGroup2TypeEnum[] =
- { "none", "vector", "plane", "t0", "z", "sphnorm", NULL };
+ { "none", "vector", "plane", "t0", "z", "sphnorm" };
options->setDescription(concatenateStrings(desc));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
* David van der Spoel, Berk Hess, Erik Lindahl, and including many
* others, as listed in the AUTHORS file in the top-level source
* directory and at http://www.gromacs.org.
.description("Normalize by total number of positions with -os"));
options->addOption(BooleanOption("cfnorm").store(&bFracNorm_)
.description("Normalize by covered fraction with -os"));
- const char *const cResNumberEnum[] = { "number", "index", NULL };
+ const char *const cResNumberEnum[] = { "number", "index" };
options->addOption(StringOption("resnr").store(&resNumberType_)
.enumValue(cResNumberEnum).defaultEnumIndex(0)
.description("Residue number output type with -oi and -on"));
- const char *const cPDBAtomsEnum[] = { "all", "maxsel", "selected", NULL };
+ const char *const cPDBAtomsEnum[] = { "all", "maxsel", "selected" };
options->addOption(StringOption("pdbatoms").store(&pdbAtoms_)
.enumValue(cPDBAtomsEnum).defaultEnumIndex(0)
.description("Atoms to write with -ofpdb"));