@@ -44,6 +44,27 @@ deps_info dds::parse_mkfile_deps_str(std::string_view str) { | |||
return ret; | |||
} | |||
msvc_deps_info dds::parse_msvc_output_for_deps(std::string_view output, std::string_view leader) { | |||
auto lines = split_view(output, "\n"); | |||
std::string cleaned_output; | |||
deps_info deps; | |||
for (auto line : lines) { | |||
line = trim_view(line); | |||
if (!starts_with(line, leader)) { | |||
cleaned_output += std::string(line); | |||
cleaned_output.push_back('\n'); | |||
continue; | |||
} | |||
auto remaining = trim_view(line.substr(leader.size())); | |||
deps.inputs.emplace_back(fs::weakly_canonical(remaining)); | |||
} | |||
if (!cleaned_output.empty()) { | |||
// Remove the extra newline at the back | |||
cleaned_output.pop_back(); | |||
} | |||
return {deps, cleaned_output}; | |||
} | |||
void dds::update_deps_info(database& db, const deps_info& deps) { | |||
db.store_mtime(deps.output, fs::last_write_time(deps.output)); | |||
db.store_file_command(deps.output, {deps.command, deps.command_output}); |
@@ -13,6 +13,13 @@ class database; | |||
deps_info parse_mkfile_deps_file(path_ref where); | |||
deps_info parse_mkfile_deps_str(std::string_view str); | |||
struct msvc_deps_info { | |||
struct deps_info deps_info; | |||
std::string cleaned_output; | |||
}; | |||
msvc_deps_info parse_msvc_output_for_deps(std::string_view output, std::string_view leader); | |||
void update_deps_info(database& db, const deps_info&); | |||
struct deps_rebuild_info { | |||
@@ -21,7 +28,6 @@ struct deps_rebuild_info { | |||
std::string previous_command_output; | |||
}; | |||
deps_rebuild_info | |||
get_rebuild_info(database& db, path_ref output_path); | |||
deps_rebuild_info get_rebuild_info(database& db, path_ref output_path); | |||
} // namespace dds |
@@ -23,4 +23,27 @@ TEST_CASE("Invalid deps") { | |||
deps = dds::parse_mkfile_deps_str("foo.c"); | |||
CHECK(deps.output.empty()); | |||
CHECK(deps.inputs.empty()); | |||
} | |||
TEST_CASE("Parse MSVC deps") { | |||
auto mscv_output = R"( | |||
Note: including file: C:\foo\bar\filepath/thing.hpp | |||
Note: including file: C:\foo\bar\filepath/baz.h | |||
Note: including file: C:\foo\bar\filepath/quux.h | |||
Note: including file: C:\foo\bar\filepath/cats/quux.h | |||
Other line | |||
Something else | |||
)"; | |||
auto res = dds::parse_msvc_output_for_deps(mscv_output, "Note: including file:"); | |||
auto& deps = res.deps_info; | |||
auto new_output = res.cleaned_output; | |||
CHECK(new_output == "\nOther line\nSomething else\n"); | |||
CHECK(deps.inputs | |||
== std::vector<dds::fs::path>({ | |||
"C:\\foo\\bar\\filepath/thing.hpp", | |||
"C:\\foo\\bar\\filepath/baz.h", | |||
"C:\\foo\\bar\\filepath/quux.h", | |||
"C:\\foo\\bar\\filepath/cats/quux.h", | |||
})); | |||
} |