aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--buildconf/common.ninja3
-rw-r--r--log.h96
-rw-r--r--log_test.cc60
-rwxr-xr-xscripts/run_all_tests24
5 files changed, 184 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 7ad1c3c..4afd7d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,6 @@
# the License.
*.o
+*_test
.ninja_*
gsrsup
diff --git a/buildconf/common.ninja b/buildconf/common.ninja
index 82223b0..6ec7e96 100644
--- a/buildconf/common.ninja
+++ b/buildconf/common.ninja
@@ -30,5 +30,8 @@ rule link
build gsrsup.o: cxx gsrsup.cc
build gsrsup: link gsrsup.o
+build log_test.o: cxx log_test.cc
+build log_test: link log_test.o
+ libs = -lgmock_main -lgmock -lgtest -labsl_strings -pthread
default gsrsup
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..fe2015b
--- /dev/null
+++ b/log.h
@@ -0,0 +1,96 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// A basic logging system built with command-line utilities in mind.
+
+#ifndef GSRSUP_LOG_H_
+#define GSRSUP_LOG_H_
+
+#include <limits>
+#include <ostream>
+#include <string>
+
+#include <absl/strings/str_cat.h>
+#include <absl/strings/string_view.h>
+#include <stdlib.h>
+
+namespace gsrsup {
+
+// A logger object backed by a std::ostream (or by nothing, if the ostream is
+// null).
+//
+// This class inherits the thread-safety properties of its underlying ostream.
+class Log final {
+ public:
+ enum Level : int {
+ kDebug = 0,
+ kInfo = 1,
+ kWarning = 2,
+ kError = 3,
+ kNeverPrint = std::numeric_limits<int>::max(),
+ };
+
+ explicit Log(absl::string_view program, Level minimum_level,
+ std::ostream* out)
+ : prefix_(program), minimum_level_(minimum_level), out_(out) {}
+
+ explicit Log(absl::string_view program, Level minimum_level,
+ std::ostream& out)
+ : Log(program, minimum_level, &out) {}
+
+ explicit Log(absl::string_view program, std::ostream* out)
+ : Log(program, kInfo, out) {}
+
+ explicit Log(absl::string_view program, std::ostream& out)
+ : Log(program, &out) {}
+
+ Log(const Log&) = default;
+ Log& operator=(const Log&) = default;
+
+ template <typename... Args>
+ void Message(Level, Args...);
+
+ private:
+ std::string prefix_;
+ Level minimum_level_;
+ std::ostream* out_;
+};
+
+template <typename... Args>
+void Log::Message(Level level, Args... args) {
+ if (level < minimum_level_ || out_ == nullptr) {
+ return;
+ }
+
+ absl::string_view level_str;
+ switch (level) {
+ case kDebug:
+ level_str = "debug: ";
+ break;
+ case kWarning:
+ level_str = "warning: ";
+ break;
+ case kError:
+ level_str = "error: ";
+ break;
+ default:
+ break;
+ }
+ std::string message = absl::StrCat(prefix_, ": ", level_str, args..., "\n");
+ out_->write(message.data(), message.size());
+}
+
+} // namespace gsrsup
+
+#endif // GSRSUP_LOG_H_
diff --git a/log_test.cc b/log_test.cc
new file mode 100644
index 0000000..cec1199
--- /dev/null
+++ b/log_test.cc
@@ -0,0 +1,60 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include "log.h"
+
+#include <iostream>
+#include <sstream>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace gsrsup {
+namespace {
+
+using ::testing::HasSubstr;
+using ::testing::IsEmpty;
+
+TEST(LogTest, FormatsProgramAndMessage) {
+ std::ostringstream s;
+ Log("program", s).Message(Log::kInfo, "message");
+ EXPECT_EQ(s.str(), "program: message\n");
+}
+
+TEST(LogTest, FormatsLevelDebug) {
+ std::ostringstream s;
+ Log("program", Log::kDebug, s).Message(Log::kDebug, "message");
+ EXPECT_THAT(s.str(), HasSubstr("debug:"));
+}
+
+TEST(LogTest, FormatsLevelWarning) {
+ std::ostringstream s;
+ Log("program", s).Message(Log::kWarning, "message");
+ EXPECT_THAT(s.str(), HasSubstr("warning:"));
+}
+
+TEST(LogTest, FormatsLevelError) {
+ std::ostringstream s;
+ Log("program", s).Message(Log::kError, "message");
+ EXPECT_THAT(s.str(), HasSubstr("error:"));
+}
+
+TEST(LogTest, HidesUninterestingMessages) {
+ std::ostringstream s;
+ Log("program", Log::kError, s).Message(Log::kDebug, "some debug message");
+ EXPECT_THAT(s.str(), IsEmpty());
+}
+
+} // namespace
+} // namespace gsrsup
diff --git a/scripts/run_all_tests b/scripts/run_all_tests
new file mode 100755
index 0000000..3d133de
--- /dev/null
+++ b/scripts/run_all_tests
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Copyright 2021 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+set -eu
+
+readonly TESTS=log_test
+
+cd "$(dirname "$(realpath "$0")")/.."
+ninja $TESTS
+for test in $TESTS; do
+ ./$test
+done