Add option to toggle exact match
This commit is contained in:
parent
539ea7aa27
commit
27ed96e13b
40
filters.cpp
40
filters.cpp
|
@ -46,8 +46,8 @@ bool IntegerFilter::match(const LogcatEntry& entry) const {
|
|||
}
|
||||
|
||||
|
||||
StringFilter::StringFilter(FilterKey key_, std::string other_, bool inverted_, bool disabled)
|
||||
: key(key_), other(std::move(other_)), inverted(inverted_), _disabled(disabled) {
|
||||
StringFilter::StringFilter(FilterKey key_, std::string other_, bool inverted_, bool exact_match_, bool disabled)
|
||||
: key(key_), other(std::move(other_)), inverted(inverted_), exact_match(exact_match_), _disabled(disabled) {
|
||||
if (key_ != FilterKey::User && key_ != FilterKey::Tag && key_ != FilterKey::Message) {
|
||||
throw std::runtime_error("StringFilter is passed a non-string key");
|
||||
}
|
||||
|
@ -86,13 +86,33 @@ void StringFilter::disabled(bool disabled) {
|
|||
}
|
||||
|
||||
std::unique_ptr<Filter> StringFilter::clone() const {
|
||||
return std::make_unique<StringFilter>(this->key, this->other, this->inverted, this->_disabled);
|
||||
return std::make_unique<StringFilter>(this->key, this->other, this->inverted, this->exact_match, this->_disabled);
|
||||
}
|
||||
|
||||
const std::string* StringFilter::error() const {
|
||||
return !this->_error.empty() ? &this->_error : nullptr;
|
||||
}
|
||||
|
||||
bool StringFilter::_match_no_regex(const LogcatEntry& entry) const {
|
||||
bool matched;
|
||||
if (this->exact_match) {
|
||||
switch (this->key) {
|
||||
case FilterKey::User: matched = entry.user.value_or("") == this->other; break;
|
||||
case FilterKey::Tag: matched = entry.tag == this->other; break;
|
||||
case FilterKey::Message: matched = entry.message == this->other; break;
|
||||
default: throw std::runtime_error("StringFilter::match received unhandled key");
|
||||
}
|
||||
} else {
|
||||
switch (this->key) {
|
||||
case FilterKey::User: matched = entry.user.value_or("").find(this->other) != std::string::npos; break;
|
||||
case FilterKey::Tag: matched = entry.tag.find(this->other) != std::string::npos; break;
|
||||
case FilterKey::Message: matched = entry.message.find(this->other) != std::string::npos; break;
|
||||
default: throw std::runtime_error("StringFilter::match received unhandled key");
|
||||
}
|
||||
}
|
||||
return !this->inverted ? matched : !matched;
|
||||
}
|
||||
|
||||
bool StringFilter::match(const LogcatEntry& entry) const {
|
||||
bool matched;
|
||||
|
||||
|
@ -101,13 +121,7 @@ bool StringFilter::match(const LogcatEntry& entry) const {
|
|||
return true;
|
||||
}
|
||||
if (!this->other.starts_with("regex:")) {
|
||||
switch (this->key) {
|
||||
case FilterKey::User: matched = entry.user.value_or("") == this->other; break;
|
||||
case FilterKey::Tag: matched = entry.tag == this->other; break;
|
||||
case FilterKey::Message: matched = entry.message == this->other; break;
|
||||
default: throw std::runtime_error("StringFilter::match received unhandled key");
|
||||
}
|
||||
return !this->inverted ? matched : !matched;
|
||||
return this->_match_no_regex(entry);
|
||||
}
|
||||
if (!this->_regex) {
|
||||
log("StringFilter::match called with a regex despite there being no regex");
|
||||
|
@ -125,8 +139,10 @@ bool StringFilter::match(const LogcatEntry& entry) const {
|
|||
pmatch[0].rm_so = 0;
|
||||
pmatch[0].rm_eo = static_cast<regoff_t>(str.size());
|
||||
|
||||
matched = this->_regex->match(str.data(), 1, pmatch, REG_STARTEND)
|
||||
&& pmatch[0].rm_so == 0 && static_cast<size_t>(pmatch[0].rm_eo) == str.size();
|
||||
matched = this->_regex->match(str.data(), 1, pmatch, REG_STARTEND);
|
||||
if (this->exact_match) {
|
||||
matched = matched && pmatch[0].rm_so == 0 && static_cast<size_t>(pmatch[0].rm_eo) == str.size();
|
||||
}
|
||||
return !this->inverted ? matched : !matched;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
StringFilter(const StringFilter&) = delete;
|
||||
StringFilter& operator=(const StringFilter&) = delete;
|
||||
|
||||
StringFilter(FilterKey key_, std::string other_, bool inverted_ = false, bool disabled = false);
|
||||
StringFilter(FilterKey key_, std::string other_, bool inverted_ = false, bool exact_match_ = true, bool disabled = false);
|
||||
|
||||
void updated() override;
|
||||
bool disabled() const override;
|
||||
|
@ -69,8 +69,11 @@ public:
|
|||
FilterKey key;
|
||||
std::string other;
|
||||
bool inverted;
|
||||
bool exact_match;
|
||||
|
||||
private:
|
||||
bool _match_no_regex(const LogcatEntry& entry) const;
|
||||
|
||||
std::string _error;
|
||||
std::optional<Pcre2Regex> _regex;
|
||||
bool _disabled;
|
||||
|
|
|
@ -52,6 +52,10 @@ static void render_filter(Filter* filter, std::string* title, bool* request_remo
|
|||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Inverted", sfilter ? &sfilter->inverted : &ifilter->inverted);
|
||||
}
|
||||
if (sfilter) {
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Exact match", &sfilter->exact_match);
|
||||
}
|
||||
}
|
||||
|
||||
if (filter->error()) {
|
||||
|
@ -103,7 +107,9 @@ static inline void render_string_filter(StringFilter* filter) {
|
|||
};
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("%s is%s", head, filter->inverted ? " not" : "");
|
||||
ImGui::Text("%s %s", head, filter->exact_match
|
||||
? (filter->inverted ? "is not" : "is")
|
||||
: (filter->inverted ? "doesn't have" : "has"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##str", &filter->other)) {
|
||||
filter->updated();
|
||||
|
|
Loading…
Reference in New Issue