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)
src/result.hpp \
src/system.hpp \
src/unify.hpp \
+ src/util.hpp \
unittest/framework.hpp \
unittest/util.hpp
third_party_headers = \
// 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
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
--- /dev/null
+// 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
--- /dev/null
+// 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@");
+}