Regex: Fix handling of ^ and $ in backward matching mode
This commit is contained in:
parent
3c999aba37
commit
2b97e4e124
|
@ -1192,6 +1192,12 @@ auto test_regex = UnitTest{[]{
|
||||||
kak_assert(StringView{vm.captures()[0], vm.captures()[1]} == "boz");
|
kak_assert(StringView{vm.captures()[0], vm.captures()[1]} == "boz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
TestVM<MatchDirection::Backward> vm{R"($)"};
|
||||||
|
kak_assert(vm.exec("foo\nbar\nbaz\nqux", RegexExecFlags::Search | RegexExecFlags::NotEndOfLine));
|
||||||
|
kak_assert(StringView{vm.captures()[0]} == "\nqux");
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TestVM<> vm{R"(()*)"};
|
TestVM<> vm{R"(()*)"};
|
||||||
kak_assert(not vm.exec(" "));
|
kak_assert(not vm.exec(" "));
|
||||||
|
|
|
@ -130,23 +130,28 @@ public:
|
||||||
|
|
||||||
bool exec(Iterator begin, Iterator end, RegexExecFlags flags)
|
bool exec(Iterator begin, Iterator end, RegexExecFlags flags)
|
||||||
{
|
{
|
||||||
const bool forward = direction == MatchDirection::Forward;
|
if (flags & RegexExecFlags::NotInitialNull and begin == end)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
constexpr bool forward = direction == MatchDirection::Forward;
|
||||||
const bool prev_avail = flags & RegexExecFlags::PrevAvailable;
|
const bool prev_avail = flags & RegexExecFlags::PrevAvailable;
|
||||||
|
|
||||||
m_begin = Utf8It{utf8::iterator<Iterator>{forward ? begin : end,
|
m_begin = Utf8It{utf8::iterator<Iterator>{forward ? begin : end,
|
||||||
prev_avail ? begin-1 : begin, end}};
|
prev_avail ? begin-1 : begin, end}};
|
||||||
m_end = Utf8It{utf8::iterator<Iterator>{forward ? end : begin,
|
m_end = Utf8It{utf8::iterator<Iterator>{forward ? end : begin,
|
||||||
prev_avail ? begin-1 : begin, end}};
|
prev_avail ? begin-1 : begin, end}};
|
||||||
m_flags = flags;
|
if (forward)
|
||||||
|
m_flags = flags;
|
||||||
if (flags & RegexExecFlags::NotInitialNull and m_begin == m_end)
|
else // Flip line begin/end flags as we flipped the instructions on compilation.
|
||||||
return false;
|
m_flags = (RegexExecFlags)(flags & ~(RegexExecFlags::NotEndOfLine | RegexExecFlags::NotBeginOfLine)) |
|
||||||
|
((flags & RegexExecFlags::NotEndOfLine) ? RegexExecFlags::NotBeginOfLine : RegexExecFlags::None) |
|
||||||
|
((flags & RegexExecFlags::NotBeginOfLine) ? RegexExecFlags::NotEndOfLine : RegexExecFlags::None);
|
||||||
|
|
||||||
|
|
||||||
const bool no_saves = (m_flags & RegexExecFlags::NoSaves);
|
const bool no_saves = (flags & RegexExecFlags::NoSaves);
|
||||||
Utf8It start{m_begin};
|
Utf8It start{m_begin};
|
||||||
|
|
||||||
const bool* start_chars = m_program.start_chars ? m_program.start_chars->map : nullptr;
|
const bool* start_chars = m_program.start_chars ? m_program.start_chars->map : nullptr;
|
||||||
|
|
||||||
if (flags & RegexExecFlags::Search)
|
if (flags & RegexExecFlags::Search)
|
||||||
to_next_start(start, m_end, start_chars);
|
to_next_start(start, m_end, start_chars);
|
||||||
|
|
||||||
|
|
|
@ -881,7 +881,7 @@ Selection find_next_match(const Context& context, const Selection& sel, const Re
|
||||||
wrapped = false;
|
wrapped = false;
|
||||||
const bool found = (direction == MatchDirection::Forward) ?
|
const bool found = (direction == MatchDirection::Forward) ?
|
||||||
find_next(buffer, utf8::next(pos, buffer.end()), matches, regex, wrapped)
|
find_next(buffer, utf8::next(pos, buffer.end()), matches, regex, wrapped)
|
||||||
: find_prev(buffer, pos, matches, regex, wrapped);
|
: find_prev(buffer, utf8::previous(pos, buffer.begin()), matches, regex, wrapped);
|
||||||
|
|
||||||
if (not found or matches[0].first == buffer.end())
|
if (not found or matches[0].first == buffer.end())
|
||||||
throw runtime_error(format("'{}': no matches found", regex.str()));
|
throw runtime_error(format("'{}': no matches found", regex.str()));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user