add utils::logical() function to complement the *numeric() functions
This commit is contained in:
@ -60,6 +60,9 @@ silently returning the result of a partial conversion or zero in cases
|
|||||||
where the string is not a valid number. This behavior allows to more
|
where the string is not a valid number. This behavior allows to more
|
||||||
easily detect typos or issues when processing input files.
|
easily detect typos or issues when processing input files.
|
||||||
|
|
||||||
|
Similarly the :cpp:func:`logical() <LAMMPS_NS::utils::logical>` function
|
||||||
|
will convert a string into a boolean and will only accept certain words.
|
||||||
|
|
||||||
The *do_abort* flag should be set to ``true`` in case this function
|
The *do_abort* flag should be set to ``true`` in case this function
|
||||||
is called only on a single MPI rank, as that will then trigger the
|
is called only on a single MPI rank, as that will then trigger the
|
||||||
a call to ``Error::one()`` for errors instead of ``Error::all()``
|
a call to ``Error::one()`` for errors instead of ``Error::all()``
|
||||||
@ -83,6 +86,9 @@ strings for compliance without conversion.
|
|||||||
.. doxygenfunction:: tnumeric
|
.. doxygenfunction:: tnumeric
|
||||||
:project: progguide
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: logical
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
|
|
||||||
String processing
|
String processing
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -345,6 +346,48 @@ std::string utils::check_packages_for_style(const std::string &style, const std:
|
|||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
read a boolean value from a string
|
||||||
|
transform to lower case before checking
|
||||||
|
generate an error if is not a legitimate boolean
|
||||||
|
called by various commands to check validity of their arguments
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool utils::logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (str) n = strlen(str);
|
||||||
|
if (n == 0) {
|
||||||
|
const char msg[] = "Expected boolean parameter instead of NULL or empty string "
|
||||||
|
"in input script or data file";
|
||||||
|
if (do_abort)
|
||||||
|
lmp->error->one(file, line, msg);
|
||||||
|
else
|
||||||
|
lmp->error->all(file, line, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to ascii and lowercase
|
||||||
|
std::string buf(str);
|
||||||
|
if (has_utf8(buf)) buf = utf8_subst(buf);
|
||||||
|
std::transform(buf.begin(), buf.end(), buf.begin(), tolower);
|
||||||
|
|
||||||
|
bool rv = false;
|
||||||
|
if ((buf == "yes") || (buf == "on") || (buf == "true") || (buf == "1")) {
|
||||||
|
rv = true;
|
||||||
|
} else if ((buf == "no") || (buf == "off") || (buf == "false") || (buf == "0")) {
|
||||||
|
rv = false;
|
||||||
|
} else {
|
||||||
|
std::string msg("Expected boolean parameter instead of '");
|
||||||
|
msg += buf + "' in input script or data file";
|
||||||
|
if (do_abort)
|
||||||
|
lmp->error->one(file, line, msg);
|
||||||
|
else
|
||||||
|
lmp->error->all(file, line, msg);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
read a floating point value from a string
|
read a floating point value from a string
|
||||||
generate an error if not a legitimate floating point value
|
generate an error if not a legitimate floating point value
|
||||||
|
|||||||
13
src/utils.h
13
src/utils.h
@ -160,6 +160,19 @@ namespace utils {
|
|||||||
std::string check_packages_for_style(const std::string &style, const std::string &name,
|
std::string check_packages_for_style(const std::string &style, const std::string &name,
|
||||||
LAMMPS *lmp);
|
LAMMPS *lmp);
|
||||||
|
|
||||||
|
/*! Convert a string to a boolean while checking whether it is a valid boolean term.
|
||||||
|
* Valid terms are 'yes', 'no', 'true', 'false', 'on', 'off', '1', '0'. Capilatization
|
||||||
|
* will be ignored (thus 'yEs' or 'nO' are valid, 'yay' or 'nay' are not).
|
||||||
|
*
|
||||||
|
* \param file name of source file for error message
|
||||||
|
* \param line line number in source file for error message
|
||||||
|
* \param str string to be converted to logical
|
||||||
|
* \param do_abort determines whether to call Error::one() or Error::all()
|
||||||
|
* \param lmp pointer to top-level LAMMPS class instance
|
||||||
|
* \return boolean */
|
||||||
|
|
||||||
|
bool logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
|
||||||
|
|
||||||
/*! Convert a string to a floating point number while checking
|
/*! Convert a string to a floating point number while checking
|
||||||
* if it is a valid floating point or integer number
|
* if it is a valid floating point or integer number
|
||||||
*
|
*
|
||||||
|
|||||||
@ -7,6 +7,10 @@ add_executable(test_image_flags test_image_flags.cpp)
|
|||||||
target_link_libraries(test_image_flags PRIVATE lammps GTest::GMock GTest::GTest)
|
target_link_libraries(test_image_flags PRIVATE lammps GTest::GMock GTest::GTest)
|
||||||
add_test(NAME ImageFlags COMMAND test_image_flags WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
add_test(NAME ImageFlags COMMAND test_image_flags WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
add_executable(test_input_convert test_input_convert.cpp)
|
||||||
|
target_link_libraries(test_input_convert PRIVATE lammps GTest::GMockMain GTest::GMock GTest::GTest)
|
||||||
|
add_test(NAME InputConvert COMMAND test_input_convert WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
add_executable(test_molecule_file test_molecule_file.cpp)
|
add_executable(test_molecule_file test_molecule_file.cpp)
|
||||||
target_link_libraries(test_molecule_file PRIVATE lammps GTest::GMock GTest::GTest)
|
target_link_libraries(test_molecule_file PRIVATE lammps GTest::GMock GTest::GTest)
|
||||||
add_test(NAME MoleculeFile COMMAND test_molecule_file WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
add_test(NAME MoleculeFile COMMAND test_molecule_file WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|||||||
121
unittest/formats/test_input_convert.cpp
Normal file
121
unittest/formats/test_input_convert.cpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
https://www.lammps.org/, Sandia National Laboratories
|
||||||
|
Steve Plimpton, sjplimp@sandia.gov
|
||||||
|
|
||||||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||||
|
certain rights in this software. This software is distributed under
|
||||||
|
the GNU General Public License.
|
||||||
|
|
||||||
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "../testing/core.h"
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "library.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
|
||||||
|
bool verbose = false;
|
||||||
|
|
||||||
|
using LAMMPS_NS::utils::split_words;
|
||||||
|
|
||||||
|
namespace LAMMPS_NS {
|
||||||
|
using ::testing::Eq;
|
||||||
|
|
||||||
|
class InputConvertTest : public LAMMPSTest {
|
||||||
|
protected:
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
testbinary = "InputConvertTest";
|
||||||
|
LAMMPSTest::SetUp();
|
||||||
|
ASSERT_NE(lmp, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override { LAMMPSTest::TearDown(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(InputConvertTest, logical)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "yes", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "Yes", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "YES", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "yEs", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "true", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "True", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "TRUE", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "on", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "On", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "ON", false, lmp));
|
||||||
|
EXPECT_TRUE(utils::logical(FLERR, "1", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "no", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "No", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "NO", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "nO", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "off", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "Off", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "OFF", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "OfF", false, lmp));
|
||||||
|
EXPECT_FALSE(utils::logical(FLERR, "0", false, lmp));
|
||||||
|
|
||||||
|
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
|
||||||
|
utils::logical(FLERR, "yay", false, lmp););
|
||||||
|
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
|
||||||
|
utils::logical(FLERR, "xxx", false, lmp););
|
||||||
|
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
|
||||||
|
utils::logical(FLERR, "none", false, lmp););
|
||||||
|
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
|
||||||
|
utils::logical(FLERR, "5", false, lmp););
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InputConvertTest, numeric)
|
||||||
|
{
|
||||||
|
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "0", false, lmp), 0);
|
||||||
|
|
||||||
|
TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "yay", false, lmp););
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InputConvertTest, inumeric)
|
||||||
|
{
|
||||||
|
EXPECT_DOUBLE_EQ(utils::inumeric(FLERR, "0", false, lmp), 0);
|
||||||
|
|
||||||
|
TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "yay", false, lmp););
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InputConvertTest, bnumeric)
|
||||||
|
{
|
||||||
|
EXPECT_DOUBLE_EQ(utils::bnumeric(FLERR, "0", false, lmp), 0);
|
||||||
|
|
||||||
|
TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "yay", false, lmp););
|
||||||
|
}
|
||||||
|
TEST_F(InputConvertTest, tnumeric)
|
||||||
|
{
|
||||||
|
EXPECT_DOUBLE_EQ(utils::tnumeric(FLERR, "0", false, lmp), 0);
|
||||||
|
|
||||||
|
TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "yay", false, lmp););
|
||||||
|
}
|
||||||
|
} // namespace LAMMPS_NS
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
lammps_mpi_init();
|
||||||
|
::testing::InitGoogleMock(&argc, argv);
|
||||||
|
|
||||||
|
// handle arguments passed via environment variable
|
||||||
|
if (const char *var = getenv("TEST_ARGS")) {
|
||||||
|
auto env = split_words(var);
|
||||||
|
for (auto arg : env) {
|
||||||
|
if (arg == "-v") {
|
||||||
|
verbose = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
|
||||||
|
|
||||||
|
int rv = RUN_ALL_TESTS();
|
||||||
|
lammps_mpi_finalize();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user