1 //===-- LogFilterRegex.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "LogFilterRegex.h"
13 #include "LogMessage.h"
15 //----------------------------------------------------------------------
16 // Enable enhanced mode if it is available. This allows for things like
17 // \d for digit, \s for space, and many more, but it isn't available
19 //----------------------------------------------------------------------
20 #if defined(REG_ENHANCED)
21 #define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
23 #define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
26 LogFilterRegex::LogFilterRegex(bool match_accepts, FilterTarget filter_target,
27 const std::string ®ex)
28 : LogFilter(match_accepts), m_filter_target(filter_target),
29 m_regex_text(regex), m_regex(), m_is_valid(false), m_error_text() {
31 memset(&m_regex, 0, sizeof(m_regex));
35 auto comp_err = ::regcomp(&m_regex, regex.c_str(), DEFAULT_COMPILE_FLAGS);
36 m_is_valid = (comp_err == 0);
40 ::regerror(comp_err, &m_regex, buffer, sizeof(buffer));
41 m_error_text = buffer;
46 LogFilterRegex::~LogFilterRegex() {
48 // Free the regex internals.
53 bool LogFilterRegex::DoesMatch(const LogMessage &message) const {
54 switch (m_filter_target) {
55 case eFilterTargetActivity:
56 // Empty fields never match a condition.
57 if (!message.HasActivity())
59 return ::regexec(&m_regex, message.GetActivity(), 0, nullptr, 0) == 0;
60 case eFilterTargetActivityChain:
61 // Empty fields never match a condition.
62 if (!message.HasActivity())
64 return ::regexec(&m_regex, message.GetActivityChain().c_str(), 0, nullptr,
66 case eFilterTargetCategory:
67 // Empty fields never match a condition.
68 if (!message.HasCategory())
70 return ::regexec(&m_regex, message.GetCategory(), 0, nullptr, 0) == 0;
71 case eFilterTargetMessage: {
72 const char *message_text = message.GetMessage();
74 DNBLogThreadedIf(LOG_DARWIN_LOG,
75 "LogFilterRegex: regex "
76 "\"%s\" no match due to nullptr message.",
77 m_regex_text.c_str());
81 bool match = ::regexec(&m_regex, message_text, 0, nullptr, 0) == 0;
82 DNBLogThreadedIf(LOG_DARWIN_LOG, "LogFilterRegex: regex "
83 "\"%s\" %s message \"%s\".",
84 m_regex_text.c_str(), match ? "matches" : "does not match",
88 case eFilterTargetSubsystem:
89 // Empty fields never match a condition.
90 if (!message.HasSubsystem())
92 return ::regexec(&m_regex, message.GetSubsystem(), 0, nullptr, 0) == 0;
94 // We don't know this type.