Normalize paths on Windows

1. Normalize paths in LSP document URIs and project root to forward
slash and uppercase drive letters.
2. Normalize paths in compile_commands.json to forward slash and
uppercase drive letters.
3. Normalize paths from directory listing to forward slash. (Drive
letter should be same as input dir path, which is already uppercase
since path of project root dir is normalized)
4. Add llvm::sys::path::convert_to_slash after certain llvm::sys::path
and llvm::fs calls.
This commit is contained in:
Riatre Foo 2018-09-12 03:13:54 +08:00 committed by Fangrui Song
parent fa8b032301
commit 082096b613
7 changed files with 31 additions and 12 deletions

View File

@ -28,7 +28,7 @@ namespace {
std::string StripFileType(const std::string &path) {
SmallString<128> Ret;
sys::path::append(Ret, sys::path::parent_path(path), sys::path::stem(path));
return Ret.str();
return sys::path::convert_to_slash(Ret);
}
bool LocationInRange(SourceLocation L, CharSourceRange R,

View File

@ -22,7 +22,7 @@ std::string FileName(const FileEntry &file) {
if (!StartsWith(ret, g_config->projectRoot)) {
SmallString<256> dest;
sys::fs::real_path(ret, dest);
ret = dest.str();
ret = sys::path::convert_to_slash(dest.str());
}
return ret;
}

View File

@ -47,7 +47,7 @@ void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix,
if (sys::fs::is_regular_file(Status)) {
if (!dir_prefix)
path = path.substr(folder.size());
handler(path);
handler(sys::path::convert_to_slash(path));
} else if (recursive && sys::fs::is_directory(Status) &&
!seen.count(ID = Status.getUniqueID())) {
curr.push_back(path);

View File

@ -552,7 +552,7 @@ public:
if (!llvm::sys::path::is_absolute(Path) &&
!SM.getFileManager().makeAbsolutePath(Path))
return -1;
it->second.second = Path.str();
it->second.second = llvm::sys::path::convert_to_slash(Path.str());
}
return it->second.first;
}

View File

@ -8,6 +8,7 @@
#include <rapidjson/writer.h>
#include <algorithm>
#include <stdio.h>
MessageRegistry *MessageRegistry::instance_ = nullptr;
@ -208,10 +209,15 @@ void lsDocumentUri::SetPath(const std::string &path) {
}
std::string lsDocumentUri::GetPath() const {
if (raw_uri.compare(0, 8, "file:///"))
if (raw_uri.compare(0, 7, "file://")) {
LOG_S(WARNING)
<< "Received potentially bad URI (not starting with file://): "
<< raw_uri;
return raw_uri;
}
std::string ret;
#ifdef _WIN32
// Skipping the initial "/" on Windows
size_t i = 8;
#else
size_t i = 7;
@ -224,8 +230,14 @@ std::string lsDocumentUri::GetPath() const {
ret.push_back(from_hex(raw_uri[i + 1]) * 16 + from_hex(raw_uri[i + 2]));
i += 2;
} else
ret.push_back(raw_uri[i] == '\\' ? '/' : raw_uri[i]);
ret.push_back(raw_uri[i]);
}
#ifdef _WIN32
std::replace(ret.begin(), ret.end(), '\\', '/');
if (ret.size() > 1 && ret[0] >= 'a' && ret[0] <= 'z' && ret[1] == ':') {
ret[0] = toupper(ret[0]);
}
#endif
return ret;
}

View File

@ -23,14 +23,19 @@ std::string NormalizePath(const std::string &path) {
TCHAR buffer[MAX_PATH] = TEXT("");
TCHAR **lpp_part = {NULL};
std::string result;
retval = GetFullPathName(path.c_str(), MAX_PATH, buffer, lpp_part);
// fail, return original
if (retval == 0)
return path;
result = path;
else
result = buffer;
std::string result = buffer;
std::replace(result.begin(), result.end(), '\\', '/');
// std::transform(result.begin(), result.end(), result.begin(), ::tolower);
// Normalize drive letter.
if (result.size() > 1 && result[0] >= 'a' && result[0] <= 'z' &&
result[1] == ':')
result[0] = toupper(result[0]);
return result;
}

View File

@ -160,7 +160,8 @@ struct ProjectProcessor {
HeaderSearchOptions &HeaderOpts = CI->getHeaderSearchOpts();
for (auto &E : HeaderOpts.UserEntries) {
std::string path = ResolveIfRelative(entry.directory, E.Path);
std::string path =
NormalizePath(ResolveIfRelative(entry.directory, E.Path));
switch (E.Group) {
default:
config->angle_dirs.insert(path);
@ -315,8 +316,9 @@ LoadEntriesFromDirectory(ProjectConfig *project,
ProjectProcessor proc(project);
for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) {
Project::Entry entry;
entry.directory = std::move(Cmd.Directory);
entry.filename = ResolveIfRelative(entry.directory, Cmd.Filename);
entry.directory = NormalizePath(Cmd.Directory);
entry.filename =
NormalizePath(ResolveIfRelative(entry.directory, Cmd.Filename));
entry.args = std::move(Cmd.CommandLine);
proc.Process(entry);
if (Seen.insert(entry.filename).second)