Fix incorrect results for non-regex skip tags searches

Closes #1865.
This commit is contained in:
Thomas Goyne 2015-07-27 09:46:28 -07:00
parent 74ac2ab1fe
commit 3c55d4fde4
2 changed files with 48 additions and 5 deletions

View file

@ -61,7 +61,7 @@ void parse_blocks(std::vector<std::pair<size_t, size_t>>& blocks, std::string co
if (c == '{' && ovr_start == bad_pos)
ovr_start = i;
else if (c == '}' && ovr_start != bad_pos) {
blocks.emplace_back(ovr_start, i);
blocks.emplace_back(ovr_start, i + 1);
ovr_start = bad_pos;
}
++i;
@ -152,10 +152,10 @@ std::string tagless_find_helper::strip_tags(std::string const& str, size_t s) {
size_t last = s;
for (auto const& block : blocks) {
if (block.second < s) continue;
if (block.second <= s) continue;
if (block.first > last)
out.append(str.begin() + last, str.begin() + block.first);
last = block.second + 1;
last = block.second;
}
if (last < str.size())
@ -178,7 +178,7 @@ void tagless_find_helper::map_range(size_t &s, size_t &e) {
// < should only happen if the cursor was within an override block
// when the user started a search
if (block.first <= s) {
size_t len = block.second - std::max(block.first, s) + 1;
size_t len = block.second - std::max(block.first, start);
s += len;
e += len;
continue;
@ -190,7 +190,7 @@ void tagless_find_helper::map_range(size_t &s, size_t &e) {
// Extend the match to include blocks within the match
// Note that blocks cannot be partially within the match
e += block.second - block.first + 1;
e += block.second - block.first;
}
}
} // namespace util

View file

@ -73,3 +73,46 @@ TEST(lagi_ifind, correct_index_with_shrunk_character_before_match) {
// U+FB00 turns into "ff", which is one byte shorter in UTF-8
EXPECT_IFIND(" \xEF\xAC\x80 a ", "a", 5, 6);
}
TEST(lagi_skip_tags, tag_stripping) {
agi::util::tagless_find_helper helper;
EXPECT_EQ("", helper.strip_tags("", 0));
EXPECT_EQ("", helper.strip_tags("{}", 0));
EXPECT_EQ("abc", helper.strip_tags("{}abc", 0));
EXPECT_EQ("abc", helper.strip_tags("a{}bc", 0));
EXPECT_EQ("abc", helper.strip_tags("abc{}", 0));
EXPECT_EQ("abc", helper.strip_tags("{}a{}bc{}", 0));
EXPECT_EQ("abc", helper.strip_tags("{}abc", 1));
EXPECT_EQ("abc", helper.strip_tags("{}abc", 2));
EXPECT_EQ("bc", helper.strip_tags("{}abc", 3));
EXPECT_EQ("c", helper.strip_tags("{}abc", 4));
}
static void test_range_map(const char *str, size_t start, size_t& s, size_t& e) {
agi::util::tagless_find_helper helper;
helper.strip_tags(str, start);
helper.map_range(s, e);
}
#define EXPECT_RANGE(str, start, match_start, match_end, result_start, result_end) \
do { \
size_t s = match_start, e = match_end; \
test_range_map(str, start, s, e); \
EXPECT_EQ(result_start, s); \
EXPECT_EQ(result_end, e); \
} while (0)
TEST(lagi_skip_tags, range_mapping) {
EXPECT_RANGE("", 0, 0, 0, 0, 0);
EXPECT_RANGE("a", 0, 0, 1, 0, 1);
EXPECT_RANGE("{}a", 0, 0, 1, 2, 3);
EXPECT_RANGE("{cc}ab", 0, 1, 2, 5, 6);
EXPECT_RANGE("{cc}ab{cc}b", 0, 1, 2, 5, 6);
EXPECT_RANGE("{cc}ab{cc}b", 0, 1, 3, 5, 11);
EXPECT_RANGE("{cc}ab{cc}b", 3, 1, 3, 5, 11);
EXPECT_RANGE("{cc}ab{cc}b", 4, 1, 3, 5, 11);
EXPECT_RANGE("{cc}ab{cc}b", 5, 0, 2, 5, 11);
}