ccls/src/match.cc

90 lines
2.3 KiB
C++
Raw Normal View History

#include "match.h"
2017-04-15 01:40:01 +00:00
#include "language_server_api.h"
2018-01-11 02:43:01 +00:00
#include "queue_manager.h"
2017-04-15 01:40:01 +00:00
#include <doctest/doctest.h>
2017-05-21 21:00:48 +00:00
#include <iostream>
2017-04-15 01:40:01 +00:00
2017-05-21 21:00:48 +00:00
// static
optional<Matcher> Matcher::Create(const std::string& search) {
2017-04-16 23:52:42 +00:00
/*
2017-04-15 01:40:01 +00:00
std::string real_search;
real_search.reserve(search.size() * 3 + 2);
for (auto c : search) {
real_search += ".*";
real_search += c;
}
real_search += ".*";
2017-04-16 23:52:42 +00:00
*/
2017-04-15 01:40:01 +00:00
2017-05-21 21:00:48 +00:00
try {
Matcher m;
m.regex_string = search;
2017-09-22 01:14:57 +00:00
m.regex = std::regex(
2018-01-11 02:43:01 +00:00
search, std::regex_constants::ECMAScript | std::regex_constants::icase |
std::regex_constants::optimize
2017-09-22 01:14:57 +00:00
// std::regex_constants::nosubs
2018-01-11 02:43:01 +00:00
);
2017-05-21 21:00:48 +00:00
return m;
2017-09-22 01:14:57 +00:00
} catch (std::exception e) {
Out_ShowLogMessage out;
out.display_type = Out_ShowLogMessage::DisplayType::Show;
out.params.type = lsMessageType::Error;
2017-09-22 01:14:57 +00:00
out.params.message = "cquery: Parsing EMCAScript regex \"" + search +
"\" failed; " + e.what();
2017-12-24 00:25:18 +00:00
QueueManager::WriteStdout(IpcId::Unknown, out);
2017-05-21 21:00:48 +00:00
return nullopt;
}
2017-04-15 01:40:01 +00:00
}
2017-04-16 23:52:42 +00:00
bool Matcher::IsMatch(const std::string& value) const {
2017-09-22 01:14:57 +00:00
// std::smatch match;
// return std::regex_match(value, match, regex);
return std::regex_search(value, regex, std::regex_constants::match_any);
2017-04-15 01:40:01 +00:00
}
2017-09-22 01:14:57 +00:00
GroupMatch::GroupMatch(const std::vector<std::string>& whitelist,
const std::vector<std::string>& blacklist) {
2017-05-21 21:00:48 +00:00
for (const std::string& entry : whitelist) {
optional<Matcher> m = Matcher::Create(entry);
if (m)
this->whitelist.push_back(*m);
}
for (const std::string& entry : blacklist) {
optional<Matcher> m = Matcher::Create(entry);
if (m)
this->blacklist.push_back(*m);
}
}
2017-09-22 01:14:57 +00:00
bool GroupMatch::IsMatch(const std::string& value,
std::string* match_failure_reason) const {
for (const Matcher& m : whitelist) {
if (m.IsMatch(value))
return true;
}
for (const Matcher& m : blacklist) {
if (m.IsMatch(value)) {
if (match_failure_reason)
*match_failure_reason = "blacklist \"" + m.regex_string + "\"";
return false;
}
}
return true;
}
2017-11-19 18:05:06 +00:00
TEST_SUITE("Matcher") {
TEST_CASE("sanity") {
// Matcher m("abc");
// TODO: check case
// CHECK(m.IsMatch("abc"));
// CHECK(m.IsMatch("fooabc"));
// CHECK(m.IsMatch("abc"));
// CHECK(m.IsMatch("abcfoo"));
// CHECK(m.IsMatch("11a11b11c11"));
}
2017-04-15 01:40:01 +00:00
}