Skip to content

Commit

Permalink
added functions Loop::common_prefix() and isame(char, char)
Browse files Browse the repository at this point in the history
use common_prefix() in error message about wrong number of values in loop
  • Loading branch information
wojdyr committed Nov 13, 2023
1 parent e548e58 commit adb2e8f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
4 changes: 3 additions & 1 deletion include/gemmi/cif.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ template<> struct Action<rules::loop> {
assert(last_item.type == ItemType::Loop);
const Loop& loop = last_item.loop;
if (loop.values.size() % loop.tags.size() != 0)
throw pegtl::parse_error("Wrong number of values in the loop", in);
throw pegtl::parse_error(
"Wrong number of values in loop " + loop.common_prefix() + "*",
in);
}
};

Expand Down
13 changes: 13 additions & 0 deletions include/gemmi/cifdoc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,19 @@ struct Loop {
}

void set_all_values(std::vector<std::vector<std::string>> columns);

std::string common_prefix() const {
if (tags.empty())
return {};
size_t len = tags[0].size();
for (auto it = tags.begin() + 1; it != tags.end(); ++it)
for (size_t n = 0; n != len; ++n)
if (!isame(tags[0][n], (*it)[n])) {
len = n;
break;
}
return tags[0].substr(0, len);
}
};


Expand Down
15 changes: 9 additions & 6 deletions include/gemmi/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,23 @@ inline std::string to_upper(std::string str) {
return str;
}

// Case-insensitive comparisons. The second arg must be lowercase.

inline bool iequal(const std::string& str, const std::string& low) {
return str.length() == low.length() &&
std::equal(std::begin(low), std::end(low), str.begin(),
[](char c1, char c2) { return c1 == lower(c2); });
// case-insensitive character comparison
inline bool isame(char a, char b) {
return a == b || ((a^b) == 0x20 && (a|0x20) >= 'a' && (a|0x20) <= 'z');
}

// Case-insensitive comparisons. The second arg must be lowercase.

inline bool iequal_from(const std::string& str, size_t offset, const std::string& low) {
return str.length() == low.length() + offset &&
std::equal(std::begin(low), std::end(low), str.begin() + offset,
[](char c1, char c2) { return c1 == lower(c2); });
}

inline bool iequal(const std::string& str, const std::string& low) {
return iequal_from(str, 0, low);
}

inline bool istarts_with(const std::string& str, const std::string& prefix) {
return str.length() >= prefix.length() &&
std::equal(std::begin(prefix), std::end(prefix), str.begin(),
Expand Down

0 comments on commit adb2e8f

Please sign in to comment.