}
}
+} // namespace
+
+namespace core {
+
+void
+ensure_dir_exists(const fs::path& dir)
+{
+ if (auto result = fs::create_directories(dir); !result) {
+ throw core::Fatal(
+ FMT("Failed to create directory {}: {}", dir, result.error().message()));
+ }
+}
+
std::string
rewrite_stderr_to_absolute_paths(std::string_view text)
{
"\n",
Tokenizer::Mode::include_empty,
Tokenizer::IncludeDelimiter::yes)) {
- // Rewrite <path> to <absolute path> in the following two cases, where X may
- // be optional ANSI CSI sequences:
- //
- // In file included from X<path>X:1:
- // X<path>X:1:2: ...
-
if (util::starts_with(line, in_file_included_from)) {
result += in_file_included_from;
line = line.substr(in_file_included_from.length());
return result;
}
-} // namespace
-
-namespace core {
-
-void
-ensure_dir_exists(const fs::path& dir)
-{
- if (auto result = fs::create_directories(dir); !result) {
- throw core::Fatal(
- FMT("Failed to create directory {}: {}", dir, result.error().message()));
- }
-}
-
void
send_to_console(const Context& ctx, std::string_view text, int fd)
{
// Like std::filesystem::create_directories but throws core::Fatal on error.
void ensure_dir_exists(const std::filesystem::path& dir);
+// Rewrite path to absolute path in `text` in the following two cases, where X
+// may be optional ANSI CSI sequences:
+//
+// X<path>[:1:2]X: ...
+// In file included from X<path>[:1:2]X:
+std::string rewrite_stderr_to_absolute_paths(std::string_view text);
+
// Send `text` to file descriptor `fd` (typically stdout or stderr, which
// potentially is connected to a console), optionally stripping ANSI color
// sequences if `ctx.args_info.strip_diagnostics_colors` is true and rewriting
#include <core/common.hpp>
#include <util/DirEntry.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
+#include <util/fmtmacros.hpp>
#include <third_party/doctest.h>
+namespace fs = util::filesystem;
+
using TestUtil::TestContext;
using util::DirEntry;
doctest::Contains("Failed to create directory create/dir/file:"));
}
+TEST_CASE("core::rewrite_stderr_to_absolute_paths")
+{
+ TestContext test_context;
+ util::write_file("existing", "");
+
+ std::string input =
+ "a:1:2\n"
+ "existing:3:4\n"
+ "c:5:6\n"
+ "\x1b[01m\x1b[Kexisting:\x1b[m\x1b[K: foo\n"
+ "\x1b[01m\x1b[Kexisting:47:11:\x1b[m\x1b[K: foo\n"
+ "In file included from \x1b[01m\x1b[Kexisting:\x1b[m\x1b[K: foo\n"
+ "In file included from \x1b[01m\x1b[Kexisting:47:11:\x1b[m\x1b[K: foo\n";
+ std::string expected = FMT(
+ "a:1:2\n"
+ "{0}:3:4\n"
+ "c:5:6\n"
+ "\x1b[01m\x1b[K{0}:\x1b[m\x1b[K: foo\n"
+ "\x1b[01m\x1b[K{0}:47:11:\x1b[m\x1b[K: foo\n"
+ "In file included from \x1b[01m\x1b[K{0}:\x1b[m\x1b[K: foo\n"
+ "In file included from \x1b[01m\x1b[K{0}:47:11:\x1b[m\x1b[K: foo\n",
+ *fs::canonical("existing"));
+ CHECK(core::rewrite_stderr_to_absolute_paths(input) == expected);
+}
+
TEST_CASE("core::strip_ansi_csi_seqs")
{
const char input[] =