| @@ -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", | |||
| })); | |||
| } | |||