From 5a0ca392d2e910fe6d51fc2a21b04f2d260f6fa5 Mon Sep 17 00:00:00 2001 From: i-ky Date: Sat, 25 Feb 2023 22:26:38 +0000 Subject: [PATCH] Output JSON compilation database --- src/basset.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/basset.cpp b/src/basset.cpp index b7fb57f..ff914dc 100644 --- a/src/basset.cpp +++ b/src/basset.cpp @@ -17,16 +17,87 @@ #include #include #include +#include +#include using std::cerr; using std::cout; +using std::forward; using std::ifstream; using std::ofstream; using std::ostream; using std::string; using std::to_string; +using std::vector; using std::literals::string_literals::operator""s; +class CompilationDatabase : ofstream { +public: + template explicit CompilationDatabase(Args &&...); + CompilationDatabase(const CompilationDatabase &) = delete; + CompilationDatabase(CompilationDatabase &&) = delete; + CompilationDatabase &operator=(const CompilationDatabase &) = delete; + CompilationDatabase &operator=(CompilationDatabase &&) = delete; + ~CompilationDatabase() override; + using ofstream::operator!; + void add(const string &directory, const vector &command); + +private: + bool first{true}; +}; + +template +CompilationDatabase::CompilationDatabase(Args &&... args) + : ofstream(forward(args)...) { + *this << "["; +} + +void CompilationDatabase::add(const string &directory, + const vector &command) { + if (first) { + first = false; + } else { + *this << ','; + } + + vector files; + + files.emplace_back(command.back()); // FIXME + + for (const auto &file : files) { + *this << "\n" + " {\n" + // clang-format off + " \"directory\": \"" << directory << "\",\n" + // clang-format on + " \"arguments\": ["; + + bool first{true}; + + for (const auto &arg : command) { + if (first) { + first = false; + } else { + *this << ','; + } + + *this << "\n" + // clang-format off + " \"" << arg << '\"'; + // clang-format on + } + + *this << "\n" + " ],\n" + // clang-format off + " \"file\": \"" << file << "\"\n" + // clang-format on + " }"; + } +} + +CompilationDatabase::~CompilationDatabase() { *this << "\n]\n"; } + int main(int argc, char *argv[]) { const string progname{*argv++}; @@ -105,9 +176,9 @@ int main(int argc, char *argv[]) { return -1; } - ofstream out(output); + CompilationDatabase cdb(output); - if (!out) { + if (!cdb) { cerr << "cannot open '" << output << "'\n"; return -1; } @@ -151,12 +222,11 @@ int main(int argc, char *argv[]) { return -1; } - out << string(cwd, ret) << '\n'; - ifstream cmdline("/proc/" + to_string(pid) + "/cmdline"); + vector cmd; for (string arg; getline(cmdline, arg, '\0');) { - out << '\t' << arg.data() << '\n'; + cmd.emplace_back(arg); } if (!cmdline.eof()) { @@ -169,6 +239,8 @@ int main(int argc, char *argv[]) { return -1; } + cdb.add(string(cwd, ret), cmd); + continue; } case PTRACE_EVENT_CLONE: