]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add some C++-ified utility functions
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 7 Aug 2019 19:52:15 +0000 (21:52 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 14 Aug 2019 19:42:34 +0000 (21:42 +0200)
Makefile.in
dev.mk.in
src/util.cpp
src/util.hpp [new file with mode: 0644]
unittest/test_util.cpp [new file with mode: 0644]

index 46bea4f0a9e74c51ed7b681b674f17dae6c4c201..f6809abdbe585d5a3d9fa149c0049debbeb86418 100644 (file)
@@ -89,6 +89,7 @@ test_suites += unittest/test_hashutil.cpp
 test_suites += unittest/test_legacy_util.cpp
 test_suites += unittest/test_lockfile.cpp
 test_suites += unittest/test_stats.cpp
+test_suites += unittest/test_util.cpp
 
 test_sources = unittest/main.cpp unittest/framework.cpp unittest/util.cpp
 test_sources += $(test_suites)
index b8281d73d9fc937834d0a7b3601e9dffb6ad6c8c..d4faad47387ec9c4f60288a233848498e3657fc5 100644 (file)
--- a/dev.mk.in
+++ b/dev.mk.in
@@ -55,6 +55,7 @@ non_third_party_headers = \
     src/result.hpp \
     src/system.hpp \
     src/unify.hpp \
+    src/util.hpp \
     unittest/framework.hpp \
     unittest/util.hpp
 third_party_headers = \
index 26c7e499e74bfb305a44a92586da0f557dd228fe..b50bf23c41c1aac593fa3e4d0b6c513dae326b7c 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "util.hpp"
+
+#include "Error.hpp"
 #include "ccache.hpp"
 
+#include <algorithm>
+#include <fmt/core.h>
+#include <fstream>
+#include <string>
+
 #ifdef HAVE_PWD_H
 #  include <pwd.h>
 #endif
@@ -1793,3 +1801,54 @@ time_seconds(void)
   return (double)time(NULL);
 #endif
 }
+
+namespace util {
+
+std::string
+read_file(const std::string& path)
+{
+  std::ifstream file(path);
+  if (!file) {
+    throw Error(fmt::format("{}: {}", path, strerror(errno)));
+  }
+  return std::string(std::istreambuf_iterator<char>(file),
+                     std::istreambuf_iterator<char>());
+}
+
+bool
+starts_with(const std::string& string, const std::string& prefix)
+{
+  return prefix.length() <= string.length()
+         && string.compare(0, prefix.length(), prefix) == 0;
+}
+
+std::string
+strip_whitespace(const std::string& string)
+{
+  auto is_space = [](int ch) { return std::isspace(ch); };
+  auto start = std::find_if_not(string.begin(), string.end(), is_space);
+  auto end = std::find_if_not(string.rbegin(), string.rend(), is_space).base();
+  return start < end ? std::string(start, end) : std::string();
+}
+
+std::string
+to_lowercase(const std::string& string)
+{
+  std::string result = string;
+  std::transform(result.begin(), result.end(), result.begin(), tolower);
+  return result;
+}
+
+// Write file data from a string.
+void
+write_file(const std::string& path, const std::string& data, bool binary)
+{
+  std::ofstream file(path,
+                     binary ? std::ios::out | std::ios::binary : std::ios::out);
+  if (!file) {
+    throw Error(fmt::format("{}: {}", path, strerror(errno)));
+  }
+  file << data;
+}
+
+} // namespace util
diff --git a/src/util.hpp b/src/util.hpp
new file mode 100644 (file)
index 0000000..47536bc
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include <string>
+
+namespace util {
+
+// Read file data as a string.
+std::string read_file(const std::string& path);
+
+// Return true if prefix is a prefix of string.
+bool starts_with(const std::string& string, const std::string& prefix);
+
+// Strip whitespace from left and right side of a string.
+[[gnu::warn_unused_result]] std::string
+strip_whitespace(const std::string& string);
+
+// Convert a string to lowercase.
+[[gnu::warn_unused_result]] std::string to_lowercase(const std::string& string);
+
+// Write file data from a string.
+void write_file(const std::string& path,
+                const std::string& data,
+                bool binary = false);
+
+} // namespace util
diff --git a/unittest/test_util.cpp b/unittest/test_util.cpp
new file mode 100644 (file)
index 0000000..fcd4d15
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2019 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "../src/util.hpp"
+
+#include "third_party/catch.hpp"
+
+TEST_CASE("util::read_file and util::write_file")
+{
+  util::write_file("test", "foo\nbar\n");
+  std::string data = util::read_file("test");
+  CHECK(data == "foo\nbar\n");
+}
+
+TEST_CASE("util::starts_with")
+{
+  CHECK(util::starts_with("", ""));
+  CHECK(util::starts_with("x", ""));
+  CHECK(util::starts_with("x", "x"));
+  CHECK(util::starts_with("xy", ""));
+  CHECK(util::starts_with("xy", "x"));
+  CHECK(util::starts_with("xy", "xy"));
+  CHECK(util::starts_with("xyz", ""));
+  CHECK(util::starts_with("xyz", "x"));
+  CHECK(util::starts_with("xyz", "xy"));
+  CHECK(util::starts_with("xyz", "xyz"));
+
+  CHECK_FALSE(util::starts_with("", "x"));
+  CHECK_FALSE(util::starts_with("x", "y"));
+  CHECK_FALSE(util::starts_with("x", "xy"));
+}
+
+TEST_CASE("util::strip_whitespace")
+{
+  CHECK(util::strip_whitespace("") == "");
+  CHECK(util::strip_whitespace("x") == "x");
+  CHECK(util::strip_whitespace(" x") == "x");
+  CHECK(util::strip_whitespace("x ") == "x");
+  CHECK(util::strip_whitespace(" x ") == "x");
+  CHECK(util::strip_whitespace(" \n\tx \n\t") == "x");
+  CHECK(util::strip_whitespace("  x  y  ") == "x  y");
+}
+
+TEST_CASE("util::to_lowercase")
+{
+  CHECK(util::to_lowercase("") == "");
+  CHECK(util::to_lowercase("x") == "x");
+  CHECK(util::to_lowercase("X") == "x");
+  CHECK(util::to_lowercase(" x_X@") == " x_x@");
+}