Regex: Correctly handle ignore case mode for start chars computation

This commit is contained in:
Maxime Coste 2017-10-13 10:58:09 +08:00
parent b8495f0953
commit 52d443f764

View File

@ -770,7 +770,15 @@ private:
{ {
case ParsedRegex::Literal: case ParsedRegex::Literal:
if (node->value < start_chars_count) if (node->value < start_chars_count)
accepted[node->value] = true; {
if (node->ignore_case)
{
accepted[to_lower(node->value)] = true;
accepted[to_upper(node->value)] = true;
}
else
accepted[node->value] = true;
}
return node->quantifier.allows_none(); return node->quantifier.allows_none();
case ParsedRegex::AnyChar: case ParsedRegex::AnyChar:
for (auto& b : accepted) for (auto& b : accepted)
@ -819,9 +827,13 @@ private:
auto& child = m_forward ? node->children.front() : node->children.back(); auto& child = m_forward ? node->children.front() : node->children.back();
if (child->op == ParsedRegex::Literal and child->value < start_chars_count) if (child->op == ParsedRegex::Literal and child->value < start_chars_count)
{ {
// Any other char is rejected // Every other char is rejected
std::fill(rejected, rejected + child->value, true); for (Codepoint c = 0; c < start_chars_count; ++c)
std::fill(rejected + child->value + 1, rejected + start_chars_count, true); {
if ((not child->ignore_case and c != child->value) or
(c != to_lower(child->value) and c != to_upper(child->value)))
rejected[c] = true;
}
} }
} }
return true; return true;
@ -832,7 +844,15 @@ private:
{ {
auto& child = node->children.front(); auto& child = node->children.front();
if (child->op == ParsedRegex::Literal and child->value < start_chars_count) if (child->op == ParsedRegex::Literal and child->value < start_chars_count)
rejected[child->value] = true; {
if (child->ignore_case)
{
rejected[to_lower(child->value)] = true;
rejected[to_upper(child->value)] = true;
}
else
rejected[child->value] = true;
}
} }
return true; return true;
} }
@ -1242,6 +1262,11 @@ auto test_regex = UnitTest{[]{
kak_assert(vm.exec("")); kak_assert(vm.exec(""));
} }
{
TestVM<> vm{R"((?i)FOO)"};
kak_assert(vm.exec("foo", RegexExecFlags::Search));
}
{ {
TestVM<> vm{R"((?i)(?=Foo))"}; TestVM<> vm{R"((?i)(?=Foo))"};
kak_assert(vm.exec("fOO", RegexExecFlags::Search)); kak_assert(vm.exec("fOO", RegexExecFlags::Search));