Skip to content

Commit 9b8aed9

Browse files
authored
feat: display C++ warnings/errors as messages (#74)
1 parent 82aa0f1 commit 9b8aed9

File tree

3 files changed

+110
-2
lines changed

3 files changed

+110
-2
lines changed

ecsact/cli/commands/build/recipe/cook.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# include "tools/cpp/runfiles/runfiles.h"
2222
#endif
2323

24+
using ecsact::cli::message_variant_t;
25+
2426
namespace fs = std::filesystem;
2527

2628
using namespace std::string_view_literals;
@@ -426,6 +428,7 @@ auto cl_compile(compile_options options) -> int {
426428

427429
cl_args.push_back("/nologo");
428430
cl_args.push_back("/std:c++20");
431+
cl_args.push_back("/diagnostics:column");
429432

430433
// TODO(zaucy): Add debug mode
431434
// if(options.debug) {
@@ -485,9 +488,37 @@ auto cl_compile(compile_options options) -> int {
485488

486489
cl_args.push_back(std::format("/OUT:{}", options.output_path.string()));
487490

488-
auto compile_exit_code = ecsact::cli::detail::spawn_and_report_output(
491+
struct : ecsact::cli::detail::spawn_reporter {
492+
auto on_std_out(std::string_view line) -> std::optional<message_variant_t> {
493+
auto index = line.find("): ");
494+
if(index == std::string::npos) {
495+
return {};
496+
}
497+
498+
auto msg_content = line.substr(index + 3);
499+
500+
if(msg_content.starts_with("warning")) {
501+
return ecsact::cli::warning_message{
502+
.content = std::string{line},
503+
};
504+
} else if(msg_content.starts_with("error")) {
505+
return ecsact::cli::error_message{
506+
.content = std::string{line},
507+
};
508+
}
509+
510+
return {};
511+
}
512+
513+
auto on_std_err(std::string_view line) -> std::optional<message_variant_t> {
514+
return {};
515+
}
516+
} reporter;
517+
518+
auto compile_exit_code = ecsact::cli::detail::spawn_and_report(
489519
options.compiler.compiler_path,
490-
cl_args
520+
cl_args,
521+
reporter
491522
);
492523

493524
if(compile_exit_code != 0) {

ecsact/cli/detail/proc_exec.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,61 @@ auto ecsact::cli::detail::which(std::string_view prog
2222
}
2323
}
2424

25+
auto ecsact::cli::detail::spawn_and_report( //
26+
std::filesystem::path exe,
27+
std::vector<std::string> args,
28+
spawn_reporter& reporter,
29+
std::filesystem::path start_dir
30+
) -> int {
31+
auto proc_stdout = bp::ipstream{};
32+
auto proc_stderr = bp::ipstream{};
33+
34+
auto proc = bp::child{
35+
bp::exe(fs::absolute(exe).string()),
36+
bp::start_dir(start_dir.string()),
37+
bp::args(args),
38+
bp::std_out > proc_stdout,
39+
bp::std_err > proc_stderr,
40+
};
41+
42+
auto subcommand_id = static_cast<subcommand_id_t>(proc.id());
43+
44+
ecsact::cli::report(subcommand_start_message{
45+
.id = subcommand_id,
46+
.executable = exe.string(),
47+
.arguments = args,
48+
});
49+
50+
auto line = std::string{};
51+
52+
while(proc_stdout && std::getline(proc_stdout, line)) {
53+
auto msg = reporter.on_std_out(line).value_or(subcommand_stdout_message{
54+
.id = subcommand_id,
55+
.line = line,
56+
});
57+
ecsact::cli::report(msg);
58+
}
59+
60+
while(proc_stderr && std::getline(proc_stderr, line)) {
61+
auto msg = reporter.on_std_err(line).value_or(subcommand_stderr_message{
62+
.id = subcommand_id,
63+
.line = line,
64+
});
65+
ecsact::cli::report(msg);
66+
}
67+
68+
proc.wait();
69+
70+
auto proc_exit_code = proc.exit_code();
71+
72+
ecsact::cli::report(subcommand_end_message{
73+
.id = subcommand_id,
74+
.exit_code = proc_exit_code,
75+
});
76+
77+
return proc_exit_code;
78+
}
79+
2580
auto ecsact::cli::detail::spawn_and_report_output( //
2681
std::filesystem::path exe,
2782
std::vector<std::string> args,

ecsact/cli/detail/proc_exec.hh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <string_view>
66
#include <string>
77
#include <optional>
8+
#include "ecsact/cli/report_message.hh"
89

910
namespace ecsact::cli::detail {
1011

@@ -15,6 +16,27 @@ auto which( //
1516
std::string_view prog
1617
) -> std::optional<std::filesystem::path>;
1718

19+
struct spawn_reporter {
20+
virtual auto on_std_out( //
21+
std::string_view line
22+
) -> std::optional<ecsact::cli::message_variant_t> {
23+
return {};
24+
}
25+
26+
virtual auto on_std_err( //
27+
std::string_view line
28+
) -> std::optional<ecsact::cli::message_variant_t> {
29+
return {};
30+
}
31+
};
32+
33+
auto spawn_and_report(
34+
std::filesystem::path exe,
35+
std::vector<std::string> args,
36+
spawn_reporter& reporter,
37+
std::filesystem::path start_dir = std::filesystem::current_path()
38+
) -> int;
39+
1840
/**
1941
* Spawn a process and report the stdout/stderr
2042
* @returns exit code

0 commit comments

Comments
 (0)