implement utils::is_type() convenience function

This commit is contained in:
Axel Kohlmeyer
2022-09-03 23:18:44 -04:00
parent 81b0cec887
commit ca6222c12b
4 changed files with 92 additions and 0 deletions

View File

@ -175,6 +175,12 @@ and parsing files or arguments.
.. doxygenfunction:: is_double .. doxygenfunction:: is_double
:project: progguide :project: progguide
.. doxygenfunction:: is_id
:project: progguide
.. doxygenfunction:: is_type
:project: progguide
Potential file functions Potential file functions
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1139,6 +1139,34 @@ bool utils::is_id(const std::string &str)
return true; return true;
} }
/* ----------------------------------------------------------------------
Check whether string is a valid type or type label string
------------------------------------------------------------------------- */
int utils::is_type(const std::string &str)
{
if (str.empty()) return -1;
bool numeric = true;
int nstar = 0;
for (auto c : str) {
if (isdigit(c)) continue;
if (c == '*') {
++nstar;
continue;
}
numeric = false;
}
if (numeric && (nstar < 2)) return 0;
// TODO: the first two checks below are not really needed with this function.
// If a type label has at least one character that is not a digit or '*'
// it can be identified by this function as type label due to the check above.
if (isdigit(str[0]) || (str[0] == '*') || (str[0] == '#')) return -1;
if (str.find_first_of(" \t\r\n\f") != std::string::npos) return -1;
return 1;
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
try to find potential file as specified by name try to find potential file as specified by name
search current directory and the LAMMPS_POTENTIALS directory if search current directory and the LAMMPS_POTENTIALS directory if

View File

@ -544,6 +544,19 @@ namespace utils {
bool is_id(const std::string &str); bool is_id(const std::string &str);
/*! Check if string is a valid type label, or numeric type, or numeric type range.
* Numeric type or type range may only contain digits or the '*' character.
* Type label strings may not contain a digit, or a '*', or a '#' character as the
* first character to distinguish them from comments and numeric types or type ranges.
* They also may not contain any whitespace. If the string is a valid numeric type
* or type range the function returns 0, if it is a valid type label the function
* returns 1, otherwise it returns -1.
*
* \param str string that should be checked
* \return 0, 1, or -1, depending on whether the string is valid numeric type, valid type label or neither, respectively */
int is_type(const std::string &str);
/*! Determine full path of potential file. If file is not found in current directory, /*! Determine full path of potential file. If file is not found in current directory,
* search directories listed in LAMMPS_POTENTIALS environment variable * search directories listed in LAMMPS_POTENTIALS environment variable
* *

View File

@ -440,6 +440,51 @@ TEST(Utils, invalid_id4)
ASSERT_FALSE(utils::is_id("a$12")); ASSERT_FALSE(utils::is_id("a$12"));
} }
TEST(Utils, valid_numeric)
{
ASSERT_EQ(utils::is_type("1"), 0);
ASSERT_EQ(utils::is_type("21"), 0);
ASSERT_EQ(utils::is_type("05"), 0);
ASSERT_EQ(utils::is_type("1*"), 0);
ASSERT_EQ(utils::is_type("*2"), 0);
ASSERT_EQ(utils::is_type("1*4"), 0);
}
TEST(Utils, invalid_numeric)
{
ASSERT_EQ(utils::is_type("1*2*"), -1);
ASSERT_EQ(utils::is_type("**2"), -1);
ASSERT_EQ(utils::is_type("*4*"), -1);
ASSERT_EQ(utils::is_type("30**"), -1);
}
TEST(Utils, valid_label)
{
ASSERT_EQ(utils::is_type("A"), 1);
ASSERT_EQ(utils::is_type("c1"), 1);
ASSERT_EQ(utils::is_type("o1_"), 1);
ASSERT_EQ(utils::is_type("C1'"), 1);
ASSERT_EQ(utils::is_type("N2\"-C1'"), 1);
ASSERT_EQ(utils::is_type("[N2\"][C1']"), 1);
ASSERT_EQ(utils::is_type("@X2=&X1"), 1);
ASSERT_EQ(utils::is_type("|Na|Cl|H2O|"), 1);
ASSERT_EQ(utils::is_type("CA(1)/CB(1)"), 1);
}
TEST(Utils, invalid_label)
{
ASSERT_EQ(utils::is_type("1A"), -1);
ASSERT_EQ(utils::is_type("#c"), -1);
ASSERT_EQ(utils::is_type("*B"), -1);
ASSERT_EQ(utils::is_type(" B"), -1);
ASSERT_EQ(utils::is_type("A "), -1);
ASSERT_EQ(utils::is_type("A B"), -1);
ASSERT_EQ(utils::is_type("\tB"), -1);
ASSERT_EQ(utils::is_type("C\n"), -1);
ASSERT_EQ(utils::is_type("d\r"), -1);
ASSERT_EQ(utils::is_type(""), -1);
}
TEST(Utils, strmatch_beg) TEST(Utils, strmatch_beg)
{ {
ASSERT_TRUE(utils::strmatch("rigid/small/omp", "^rigid")); ASSERT_TRUE(utils::strmatch("rigid/small/omp", "^rigid"));