2017-03-19 22:06:22 +00:00
|
|
|
#if defined(_WIN32)
|
|
|
|
#include "platform.h"
|
|
|
|
|
2017-03-25 20:27:28 +00:00
|
|
|
#include "utils.h"
|
|
|
|
|
2017-07-28 02:14:33 +00:00
|
|
|
#include <loguru.hpp>
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#include <Windows.h>
|
2017-04-18 02:59:48 +00:00
|
|
|
#include <direct.h>
|
2017-03-25 20:27:28 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <io.h>
|
|
|
|
|
2017-04-20 04:57:44 +00:00
|
|
|
#include <sys/stat.h>
|
2017-09-22 01:14:57 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
2017-03-29 06:33:38 +00:00
|
|
|
#include <algorithm>
|
2017-03-19 22:06:22 +00:00
|
|
|
#include <cassert>
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
|
2017-03-25 20:27:28 +00:00
|
|
|
void PlatformInit() {
|
|
|
|
// We need to write to stdout in binary mode because in Windows, writing
|
|
|
|
// \n will implicitly write \r\n. Language server API will ignore a
|
|
|
|
// \r\r\n split request.
|
|
|
|
_setmode(_fileno(stdout), O_BINARY);
|
|
|
|
_setmode(_fileno(stdin), O_BINARY);
|
|
|
|
}
|
|
|
|
|
2017-12-23 16:01:43 +00:00
|
|
|
// See
|
|
|
|
// https://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from
|
2017-12-14 22:35:21 +00:00
|
|
|
std::string GetExecutablePath() {
|
|
|
|
char result[MAX_PATH] = {0};
|
|
|
|
GetModuleFileName(NULL, result, MAX_PATH);
|
2017-12-16 05:18:23 +00:00
|
|
|
return NormalizePath(result);
|
2017-12-14 22:35:21 +00:00
|
|
|
}
|
|
|
|
|
2017-03-19 22:06:22 +00:00
|
|
|
// See http://stackoverflow.com/a/19535628
|
|
|
|
std::string GetWorkingDirectory() {
|
|
|
|
char result[MAX_PATH];
|
2017-10-25 01:02:15 +00:00
|
|
|
std::string binary_path(result, GetModuleFileName(NULL, result, MAX_PATH));
|
|
|
|
return binary_path.substr(0, binary_path.find_last_of("\\/") + 1);
|
2017-03-19 22:06:22 +00:00
|
|
|
}
|
2017-03-28 05:27:06 +00:00
|
|
|
|
|
|
|
std::string NormalizePath(const std::string& path) {
|
|
|
|
DWORD retval = 0;
|
|
|
|
TCHAR buffer[MAX_PATH] = TEXT("");
|
|
|
|
TCHAR buf[MAX_PATH] = TEXT("");
|
2017-09-22 01:14:57 +00:00
|
|
|
TCHAR** lpp_part = {NULL};
|
2017-03-28 05:27:06 +00:00
|
|
|
|
|
|
|
retval = GetFullPathName(path.c_str(), MAX_PATH, buffer, lpp_part);
|
|
|
|
// fail, return original
|
|
|
|
if (retval == 0)
|
|
|
|
return path;
|
|
|
|
|
2017-03-29 06:33:38 +00:00
|
|
|
std::string result = buffer;
|
|
|
|
std::replace(result.begin(), result.end(), '\\', '/');
|
2017-09-22 01:14:57 +00:00
|
|
|
// std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
2017-03-29 06:33:38 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-04-18 02:59:48 +00:00
|
|
|
bool TryMakeDirectory(const std::string& absolute_path) {
|
|
|
|
if (_mkdir(absolute_path.c_str()) == -1) {
|
|
|
|
// Success if the directory exists.
|
|
|
|
return errno == EEXIST;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2017-04-16 22:48:54 +00:00
|
|
|
|
|
|
|
// See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
|
|
|
const DWORD MS_VC_EXCEPTION = 0x406D1388;
|
2017-09-22 01:14:57 +00:00
|
|
|
#pragma pack(push, 8)
|
|
|
|
typedef struct tagTHREADNAME_INFO {
|
|
|
|
DWORD dwType; // Must be 0x1000.
|
|
|
|
LPCSTR szName; // Pointer to name (in user addr space).
|
|
|
|
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
|
|
|
DWORD dwFlags; // Reserved for future use, must be zero.
|
2017-04-16 22:48:54 +00:00
|
|
|
} THREADNAME_INFO;
|
|
|
|
#pragma pack(pop)
|
|
|
|
void SetCurrentThreadName(const std::string& thread_name) {
|
2017-07-28 02:14:33 +00:00
|
|
|
loguru::set_thread_name(thread_name.c_str());
|
|
|
|
|
2017-04-16 22:48:54 +00:00
|
|
|
THREADNAME_INFO info;
|
|
|
|
info.dwType = 0x1000;
|
|
|
|
info.szName = thread_name.c_str();
|
2017-05-21 23:22:00 +00:00
|
|
|
info.dwThreadID = (DWORD)-1;
|
2017-04-16 22:48:54 +00:00
|
|
|
info.dwFlags = 0;
|
|
|
|
|
|
|
|
__try {
|
2017-09-22 01:14:57 +00:00
|
|
|
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
|
|
|
|
(ULONG_PTR*)&info);
|
|
|
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
2017-04-16 22:48:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-16 05:39:50 +00:00
|
|
|
optional<int64_t> GetLastModificationTime(const std::string& absolute_path) {
|
2017-04-20 04:57:44 +00:00
|
|
|
struct _stat buf;
|
|
|
|
if (_stat(absolute_path.c_str(), &buf) != 0) {
|
|
|
|
switch (errno) {
|
|
|
|
case ENOENT:
|
2017-09-22 01:14:57 +00:00
|
|
|
// std::cerr << "GetLastModificationTime: unable to find file " <<
|
|
|
|
// absolute_path << std::endl;
|
2017-08-16 05:39:50 +00:00
|
|
|
return nullopt;
|
2017-04-20 04:57:44 +00:00
|
|
|
case EINVAL:
|
2017-09-22 01:14:57 +00:00
|
|
|
// std::cerr << "GetLastModificationTime: invalid param to _stat for
|
|
|
|
// file file " << absolute_path << std::endl;
|
2017-08-16 05:39:50 +00:00
|
|
|
return nullopt;
|
2017-04-20 04:57:44 +00:00
|
|
|
default:
|
2017-09-22 01:14:57 +00:00
|
|
|
// std::cerr << "GetLastModificationTime: unhandled for " <<
|
|
|
|
// absolute_path << std::endl; exit(1);
|
2017-08-16 05:39:50 +00:00
|
|
|
return nullopt;
|
2017-04-20 04:57:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf.st_mtime;
|
|
|
|
}
|
|
|
|
|
2017-07-29 00:08:18 +00:00
|
|
|
void MoveFileTo(const std::string& destination, const std::string& source) {
|
2017-09-22 01:14:57 +00:00
|
|
|
MoveFile(source.c_str(), destination.c_str());
|
2017-07-29 00:08:18 +00:00
|
|
|
}
|
|
|
|
|
2017-04-21 06:32:18 +00:00
|
|
|
void CopyFileTo(const std::string& destination, const std::string& source) {
|
2017-09-22 01:14:57 +00:00
|
|
|
CopyFile(source.c_str(), destination.c_str(), false /*failIfExists*/);
|
2017-04-21 06:32:18 +00:00
|
|
|
}
|
|
|
|
|
2017-05-23 07:24:14 +00:00
|
|
|
bool IsSymLink(const std::string& path) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-03-29 06:33:38 +00:00
|
|
|
std::vector<std::string> GetPlatformClangArguments() {
|
2017-12-19 04:39:45 +00:00
|
|
|
//
|
|
|
|
// Found by executing
|
|
|
|
//
|
|
|
|
// $ clang++ -E -x c++ - -v
|
|
|
|
//
|
|
|
|
|
2017-12-23 16:01:43 +00:00
|
|
|
// clang-format off
|
2017-12-19 04:39:45 +00:00
|
|
|
return {
|
2018-01-04 02:32:15 +00:00
|
|
|
"-fms-extensions", "-fms-compatibility", "-fdelayed-template-parsing"
|
2017-12-19 04:39:45 +00:00
|
|
|
};
|
2017-12-23 16:01:43 +00:00
|
|
|
// clang-format on
|
2017-03-28 05:27:06 +00:00
|
|
|
}
|
2017-08-17 18:02:47 +00:00
|
|
|
|
|
|
|
void FreeUnusedMemory() {}
|
|
|
|
|
2017-12-22 17:07:21 +00:00
|
|
|
bool RunObjectiveCIndexTests() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-01-07 07:42:42 +00:00
|
|
|
// TODO Wait for debugger to attach
|
2018-01-11 02:43:01 +00:00
|
|
|
void TraceMe() {}
|
2018-01-07 07:42:42 +00:00
|
|
|
|
2017-03-19 22:06:22 +00:00
|
|
|
#endif
|