diff --git a/doc/src/Developer_utils.rst b/doc/src/Developer_utils.rst index 44210218c0..60eded42e0 100644 --- a/doc/src/Developer_utils.rst +++ b/doc/src/Developer_utils.rst @@ -334,10 +334,11 @@ arguments of commands in LAMMPS are parsed and to make abstractions of repetitive tasks. The :cpp:class:`LAMMPS_NS::ArgInfo` class provides an abstraction -for parsing references to compute or fix styles or variables. These -would start with a "c\_", "f\_", "v\_" followed by the ID or name of -than instance and may be postfixed with one or two array indices -"[]" with numbers > 0. +for parsing references to compute or fix styles, variables or custom +integer or double properties handled by :doc:`fix property/atom `. +These would start with a "c\_", "f\_", "v\_", "d\_", "d2\_", "i\_", or "i2_" +followed by the ID or name of than instance and may be postfixed with +one or two array indices "[]" with numbers > 0. A typical code segment would look like this: diff --git a/src/arg_info.cpp b/src/arg_info.cpp index a274b47b92..5063b6b471 100644 --- a/src/arg_info.cpp +++ b/src/arg_info.cpp @@ -30,7 +30,8 @@ using namespace LAMMPS_NS; ArgInfo::ArgInfo(const std::string &arg, int allowed) : type(NONE), dim(0), index1(-1), index2(-1) { - if ((arg.size() > 2) && (arg[1] == '_')) { + if (((arg.size() > 3) && (arg[1] == '2') && (arg[2] == '_')) + || ((arg.size() > 2) && (arg[1] == '_'))) { if ((arg[0] == 'c') && (allowed & COMPUTE)) type = COMPUTE; else if ((arg[0] == 'f') && (allowed & FIX)) @@ -46,10 +47,11 @@ ArgInfo::ArgInfo(const std::string &arg, int allowed) : type(NONE), dim(0), inde name = arg; return; } + const int offset = (arg[1] == '_') ? 2 : 3; - std::size_t has_idx1 = arg.find('[', 2); + std::size_t has_idx1 = arg.find('[', offset); if (has_idx1 != std::string::npos) { - name = arg.substr(2, has_idx1 - 2); + name = arg.substr(offset, has_idx1 - offset); dim = 1; std::size_t has_idx2 = arg.find('[', has_idx1 + 1); @@ -79,7 +81,7 @@ ArgInfo::ArgInfo(const std::string &arg, int allowed) : type(NONE), dim(0), inde } } else { index1 = 0; - name = arg.substr(2); + name = arg.substr(offset); } } else { index1 = 0; diff --git a/unittest/utils/test_argutils.cpp b/unittest/utils/test_argutils.cpp index a527df6fe7..c5ef19bc10 100644 --- a/unittest/utils/test_argutils.cpp +++ b/unittest/utils/test_argutils.cpp @@ -169,6 +169,16 @@ TEST(ArgInfo, variable2) ASSERT_THAT(arg.get_name(), StrEq("x")); } +TEST(ArgInfo, variable3) +{ + ArgInfo arg("v_x[11][5]"); + ASSERT_EQ(arg.get_dim(), 2); + ASSERT_EQ(arg.get_type(), ArgInfo::VARIABLE); + ASSERT_EQ(arg.get_index1(), 11); + ASSERT_EQ(arg.get_index2(), 5); + ASSERT_THAT(arg.get_name(), StrEq("x")); +} + TEST(ArgInfo, dname0) { ArgInfo arg("d_text", ArgInfo::DNAME); @@ -179,6 +189,36 @@ TEST(ArgInfo, dname0) ASSERT_THAT(arg.get_name(), StrEq("text")); } +TEST(ArgInfo, dname1) +{ + ArgInfo arg("d2_text", ArgInfo::DNAME | ArgInfo::INAME); + ASSERT_EQ(arg.get_dim(), 0); + ASSERT_EQ(arg.get_type(), ArgInfo::DNAME); + ASSERT_EQ(arg.get_index1(), 0); + ASSERT_EQ(arg.get_index2(), -1); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + +TEST(ArgInfo, dname2) +{ + ArgInfo arg("d2_text[11]", ArgInfo::DNAME); + ASSERT_EQ(arg.get_dim(), 1); + ASSERT_EQ(arg.get_type(), ArgInfo::DNAME); + ASSERT_EQ(arg.get_index1(), 11); + ASSERT_EQ(arg.get_index2(), -1); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + +TEST(ArgInfo, dname3) +{ + ArgInfo arg("d2_text[24][11]", ArgInfo::DNAME); + ASSERT_EQ(arg.get_dim(), 2); + ASSERT_EQ(arg.get_type(), ArgInfo::DNAME); + ASSERT_EQ(arg.get_index1(), 24); + ASSERT_EQ(arg.get_index2(), 11); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + TEST(ArgInfo, iname0) { ArgInfo arg("i_text", ArgInfo::INAME); @@ -189,6 +229,36 @@ TEST(ArgInfo, iname0) ASSERT_THAT(arg.get_name(), StrEq("text")); } +TEST(ArgInfo, iname1) +{ + ArgInfo arg("i2_text", ArgInfo::INAME); + ASSERT_EQ(arg.get_dim(), 0); + ASSERT_EQ(arg.get_type(), ArgInfo::INAME); + ASSERT_EQ(arg.get_index1(), 0); + ASSERT_EQ(arg.get_index2(), -1); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + +TEST(ArgInfo, iname2) +{ + ArgInfo arg("i2_text[2]", ArgInfo::INAME | ArgInfo::DNAME); + ASSERT_EQ(arg.get_dim(), 1); + ASSERT_EQ(arg.get_type(), ArgInfo::INAME); + ASSERT_EQ(arg.get_index1(), 2); + ASSERT_EQ(arg.get_index2(), -1); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + +TEST(ArgInfo, iname3) +{ + ArgInfo arg("i2_text[2][100]", ArgInfo::INAME | ArgInfo::DNAME); + ASSERT_EQ(arg.get_dim(), 2); + ASSERT_EQ(arg.get_type(), ArgInfo::INAME); + ASSERT_EQ(arg.get_index1(), 2); + ASSERT_EQ(arg.get_index2(), 100); + ASSERT_THAT(arg.get_name(), StrEq("text")); +} + TEST(ArgInfo, unsupported1) { ArgInfo arg("v_text[02][05]", ArgInfo::COMPUTE | ArgInfo::FIX);