@@ -31,13 +31,17 @@ limitations under the License.
3131#include < llvm/ADT/STLExtras.h>
3232#include < llvm/ADT/StringSet.h>
3333#include < llvm/Support/LineIterator.h>
34+ #include < llvm/Support/Program.h>
3435
3536#include < rapidjson/writer.h>
3637
37- #if defined(__unix__) || defined(__APPLE__)
38- #include < unistd.h>
38+ #ifdef _WIN32
39+ # include < Windows.h>
40+ #else
41+ # include < unistd.h>
3942#endif
4043
44+ #include < array>
4145#include < limits.h>
4246#include < unordered_set>
4347#include < vector>
@@ -308,7 +312,8 @@ int ComputeGuessScore(std::string_view a, std::string_view b) {
308312} // namespace
309313
310314void Project::LoadDirectory (const std::string &root, Project::Folder &folder) {
311- SmallString<256 > Path, CDBDir;
315+ SmallString<256 > CDBDir, Path, StdinPath;
316+ std::string err_msg;
312317 folder.entries .clear ();
313318 if (g_config->compilationDatabaseCommand .empty ()) {
314319 CDBDir = root;
@@ -319,33 +324,49 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
319324 // If `compilationDatabaseCommand` is specified, execute it to get the
320325 // compdb.
321326#ifdef _WIN32
322- // TODO
327+ char tmpdir[L_tmpnam];
328+ tmpnam_s (tmpdir, L_tmpnam);
329+ CDBDir = tmpdir;
330+ if (sys::fs::create_directory (tmpdir, false ))
331+ return ;
323332#else
324333 char tmpdir[] = " /tmp/ccls-compdb-XXXXXX" ;
325334 if (!mkdtemp (tmpdir))
326335 return ;
327336 CDBDir = tmpdir;
328- sys::path::append (Path, CDBDir, " compile_commands.json" );
329- rapidjson::StringBuffer input;
330- rapidjson::Writer<rapidjson::StringBuffer> writer (input);
331- JsonWriter json_writer (&writer);
332- Reflect (json_writer, *g_config);
333- std::string contents = GetExternalCommandOutput (
334- std::vector<std::string>{g_config->compilationDatabaseCommand , root},
335- input.GetString ());
336- FILE *fout = fopen (Path.c_str (), " wb" );
337- fwrite (contents.c_str (), contents.size (), 1 , fout);
338- fclose (fout);
339337#endif
338+ sys::path::append (Path, CDBDir, " compile_commands.json" );
339+ sys::path::append (StdinPath, CDBDir, " stdin" );
340+ {
341+ rapidjson::StringBuffer sb;
342+ rapidjson::Writer<rapidjson::StringBuffer> writer (sb);
343+ JsonWriter json_writer (&writer);
344+ Reflect (json_writer, *g_config);
345+ std::string input = sb.GetString ();
346+ FILE *fout = fopen (StdinPath.c_str (), " wb" );
347+ fwrite (input.c_str (), input.size (), 1 , fout);
348+ fclose (fout);
349+ }
350+ std::array<Optional<StringRef>, 3 > Redir{StringRef (StdinPath),
351+ StringRef (Path), StringRef ()};
352+ std::vector<StringRef> args{g_config->compilationDatabaseCommand , root};
353+ if (sys::ExecuteAndWait (args[0 ], args, llvm::None, Redir, 0 , 0 , &err_msg) <
354+ 0 ) {
355+ LOG_S (ERROR) << " failed to execute " << args[0 ].str () << " "
356+ << args[1 ].str () << " : " << err_msg;
357+ return ;
358+ }
340359 }
341360
342- std::string err_msg;
343361 std::unique_ptr<tooling::CompilationDatabase> CDB =
344362 tooling::CompilationDatabase::loadFromDirectory (CDBDir, err_msg);
345363 if (!g_config->compilationDatabaseCommand .empty ()) {
346364#ifdef _WIN32
347- // TODO
365+ DeleteFileA (StdinPath.c_str ());
366+ DeleteFileA (Path.c_str ());
367+ RemoveDirectoryA (CDBDir.c_str ());
348368#else
369+ unlink (StdinPath.c_str ());
349370 unlink (Path.c_str ());
350371 rmdir (CDBDir.c_str ());
351372#endif
@@ -354,7 +375,9 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
354375 ProjectProcessor proc (folder);
355376 StringSet<> Seen;
356377 std::vector<Project::Entry> result;
357- if (CDB) {
378+ if (!CDB) {
379+ LOG_S (ERROR) << " failed to load " << Path.c_str () << " " << err_msg;
380+ } else {
358381 LOG_S (INFO) << " loaded " << Path.c_str ();
359382 for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands ()) {
360383 static bool once;
0 commit comments