Module: check_mk
Branch: master
Commit: 7564e43746d878661265815f4e84ddddcbc3c467
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=7564e43746d878…
Author: Jukka Aro <ja(a)mathias-kettner.de>
Date: Tue Jan 9 16:31:25 2018 +0100
Windows agent: use std::regex instead of strncmp
Refactor and unit test from_string<globline_container>. Use
std::regex_search and std::regex_replace instead of strncmp and
lstrip.
Change-Id: I36942a38fdae39c63668e014a02b45749a45d2e4
---
agents/windows/build_version | 2 +-
agents/windows/sections/SectionLogwatch.cc | 37 ++++++++++------------
agents/windows/sections/SectionLogwatch.h | 19 ++++++++---
agents/windows/stringutil.h | 12 +++++++
.../windows/test/sections/SectionLogwatchTest.cc | 32 +++++++++++++++++--
5 files changed, 73 insertions(+), 29 deletions(-)
diff --git a/agents/windows/build_version b/agents/windows/build_version
index 1a92773..5704f3f 100644
--- a/agents/windows/build_version
+++ b/agents/windows/build_version
@@ -1 +1 @@
-3048
+3050
diff --git a/agents/windows/sections/SectionLogwatch.cc
b/agents/windows/sections/SectionLogwatch.cc
index 9134253..257231e 100644
--- a/agents/windows/sections/SectionLogwatch.cc
+++ b/agents/windows/sections/SectionLogwatch.cc
@@ -64,13 +64,6 @@ inline int find_crnl_end(char *buffer) {
return -1;
}
-inline void rtrim(std::string &s) {
- s.erase(std::find_if(s.rbegin(), s.rend(),
- [](int ch) { return !std::isspace(ch); })
- .base(),
- s.end());
-}
-
file_encoding determine_encoding(const logwatch_textfile &textfile) {
ifstream ifs(textfile.paths.front(), ifstream::in | ifstream::binary);
@@ -762,24 +755,26 @@ globline_container from_string<globline_container>(const
WinApiAdaptor &,
for (; iter != end; ++iter) {
std::string descriptor = iter->str();
- const char *token = lstrip(descriptor.c_str());
+ ltrim(descriptor);
glob_token new_token;
- while (true) {
- if (strncmp(token, "nocontext", 9) == 0) {
- new_token.nocontext = true;
- token = lstrip(token + 9);
- } else if (strncmp(token, "from_start", 10) == 0) {
- new_token.from_start = true;
- token = lstrip(token + 10);
- } else if (strncmp(token, "rotated", 7) == 0) {
- new_token.rotated = true;
- token = lstrip(token + 7);
- } else {
- break;
+ for (const auto &token :
+ std::vector<std::string>{"nocontext",
"from_start", "rotated"}) {
+ std::regex tokenRegex("\\b" + token + "\\b");
+ if (std::regex_search(descriptor, tokenRegex)) {
+ if (token == "nocontext") {
+ new_token.nocontext = true;
+ } else if (token == "from_start") {
+ new_token.from_start = true;
+ } else if (token == "rotated") {
+ new_token.rotated = true;
+ }
+ descriptor = std::regex_replace(descriptor, tokenRegex, "");
+ ltrim(descriptor);
}
}
- new_token.pattern = token;
+
+ new_token.pattern = descriptor;
tokens.push_back(new_token);
}
diff --git a/agents/windows/sections/SectionLogwatch.h
b/agents/windows/sections/SectionLogwatch.h
index 6dda17d..cadd163 100644
--- a/agents/windows/sections/SectionLogwatch.h
+++ b/agents/windows/sections/SectionLogwatch.h
@@ -37,10 +37,21 @@ template <>
globline_container from_string<globline_container>(const WinApiAdaptor
&winapi,
const std::string &value);
-// A bogus stream operator for globline_container just to enable template
-// instantiation for ListConfigurable<GlobListT>.
-inline std::ostream &operator<<(std::ostream &os, const globline_container
&) {
- return os << "[reference to globline_container instance]";
+inline std::ostream &operator<<(std::ostream &os, const globline_container
&g) {
+ os << "\n[tokens]\n";
+ for (const auto &token : g.tokens) {
+ os << "<pattern: " << token.pattern
+ << ", nocontext: " << std::boolalpha <<
token.nocontext
+ << ", from_start: " << token.from_start
+ << ", rotated: " << token.rotated
+ << ", found_match: " << token.found_match <<
">\n";
+ }
+ os << "[patterns]\n";
+ for (const auto &pattern : g.patterns) {
+ os << "<state: " << pattern.state
+ << ", glob_pattern: " << pattern.glob_pattern <<
">\n";
+ }
+ return os;
}
class GlobListConfigurable
diff --git a/agents/windows/stringutil.h b/agents/windows/stringutil.h
index 72f21ba..6a6f0a9 100644
--- a/agents/windows/stringutil.h
+++ b/agents/windows/stringutil.h
@@ -44,6 +44,18 @@ const char *lstrip(const char *s);
char *rstrip(char *s);
char *strip(char *s);
+inline void ltrim(std::string &s) {
+ s.erase(s.begin(), std::find_if(s.cbegin(), s.cend(),
+ [](int ch) { return !std::isspace(ch); }));
+}
+
+inline void rtrim(std::string &s) {
+ s.erase(std::find_if(s.crbegin(), s.crend(),
+ [](int ch) { return !std::isspace(ch); })
+ .base(),
+ s.end());
+}
+
std::vector<const char *> split_line(char *pos, int (*split_pred)(int));
char *next_word(char **line);
diff --git a/agents/windows/test/sections/SectionLogwatchTest.cc
b/agents/windows/test/sections/SectionLogwatchTest.cc
index ce4d002..03b4f42 100644
--- a/agents/windows/test/sections/SectionLogwatchTest.cc
+++ b/agents/windows/test/sections/SectionLogwatchTest.cc
@@ -1,6 +1,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "sections/SectionLogwatch.h"
+#include "test/MockWinApi.h"
#include "types.h"
using namespace ::testing;
@@ -8,7 +9,7 @@ using namespace ::testing;
class wa_SectionLogwatchTest : public Test {};
bool operator==(const condition_pattern &c1, const condition_pattern &c2) {
- return c1.state == c2.state && c2.glob_pattern == c2.glob_pattern;
+ return c1.state == c2.state && c1.glob_pattern == c2.glob_pattern;
}
bool operator==(const logwatch_textfile &t1, const logwatch_textfile &t2) {
@@ -16,8 +17,17 @@ bool operator==(const logwatch_textfile &t1, const
logwatch_textfile &t2) {
t1.file_id == t2.file_id && t1.file_size == t2.file_size &&
t1.offset == t2.offset && t1.missing == t2.missing &&
t1.nocontext == t2.nocontext && t1.rotated == t2.rotated &&
- t1.encoding == t2.encoding &&
- t1.patterns.get() == t2.patterns.get();
+ t1.encoding == t2.encoding && t1.patterns.get() == t2.patterns.get();
+}
+
+bool operator==(const glob_token &t1, const glob_token &t2) {
+ return t1.pattern == t2.pattern && t1.nocontext == t2.nocontext &&
+ t1.from_start == t2.from_start && t1.rotated == t2.rotated &&
+ t1.found_match == t2.found_match;
+}
+
+bool operator==(const globline_container &g1, const globline_container &g2) {
+ return g1.tokens == g2.tokens && g1.patterns == g2.patterns;
}
TEST_F(wa_SectionLogwatchTest, parseLogwatchStateLine_valid) {
@@ -73,3 +83,19 @@ TEST_F(wa_SectionLogwatchTest, parseLogwatchStateLine_conversion_error)
{
char line[] = "M:\\log1.log|foo|bar|baz";
ASSERT_THROW(parseLogwatchStateLine(line), StateParseError);
}
+
+TEST_F(wa_SectionLogwatchTest, from_string) {
+ StrictMock<MockWinApi> mockwinapi;
+ const std::string line =
+ "from_start nocontext rotated C:\\foo\\bar"
+ "| rotated D:\\baz\\qux*"
+ "|nocontext from_start rotated E:\\quux\\corge*"
+ "| F:\\grault\\garply";
+ const globline_container expected{
+ {{"C:\\foo\\bar", true, true, true, false},
+ {"D:\\baz\\qux*", false, false, true, false},
+ {"E:\\quux\\corge*", true, true, true, false},
+ {"F:\\grault\\garply", false, false, false, false}},
+ {}};
+ ASSERT_EQ(expected, from_string<globline_container>(mockwinapi, line));
+}