12
12
13
13
#include " sourcekitd/sourcekitd.h"
14
14
15
- #include " TestOptions.h"
16
15
#include " SourceKit/Support/Concurrency.h"
17
- #include " clang/Rewrite/Core/RewriteBuffer .h"
16
+ #include " TestOptions .h"
18
17
#include " swift/Demangling/ManglingMacros.h"
18
+ #include " clang/Rewrite/Core/RewriteBuffer.h"
19
19
#include " llvm/ADT/ArrayRef.h"
20
20
#include " llvm/ADT/Optional.h"
21
21
#include " llvm/ADT/StringSwitch.h"
22
22
#include " llvm/Support/CommandLine.h"
23
+ #include " llvm/Support/ConvertUTF.h"
24
+ #include " llvm/Support/FileSystem.h"
25
+ #include " llvm/Support/FormatVariadic.h"
23
26
#include " llvm/Support/MemoryBuffer.h"
24
27
#include " llvm/Support/Regex.h"
25
- #include " llvm/Support/raw_ostream.h"
26
28
#include " llvm/Support/Signals.h"
27
- #include " llvm/Support/FileSystem.h"
28
- #include " llvm/Support/FormatVariadic.h"
29
+ #include " llvm/Support/raw_ostream.h"
29
30
#include < fstream>
30
31
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
31
32
#include < unistd.h>
@@ -48,11 +49,31 @@ namespace {
48
49
int STDOUT_FILENO = _fileno(stdout);
49
50
const constexpr size_t MAXPATHLEN = MAX_PATH + 1 ;
50
51
char *realpath (const char *path, char *resolved_path) {
51
- DWORD dwLength = GetFullPathNameA (path, 0 , nullptr , nullptr );
52
- if (dwLength == 0 )
52
+ wchar_t full_path[MAXPATHLEN] = {0 };
53
+ llvm::SmallVector<llvm::UTF16, 50 > utf16Path;
54
+ llvm::convertUTF8ToUTF16String (path, utf16Path);
55
+
56
+ HANDLE fileHandle = CreateFileW (
57
+ (LPCWSTR)utf16Path.data (), 0 , FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr ,
58
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr );
59
+
60
+ if (fileHandle == INVALID_HANDLE_VALUE)
53
61
return nullptr ;
54
- if ((resolved_path = static_cast <char *>(malloc (dwLength + 1 ))))
55
- GetFullPathNameA (path, dwLength, resolved_path, nullptr );
62
+ DWORD success = GetFinalPathNameByHandleW (fileHandle, full_path, MAX_PATH,
63
+ FILE_NAME_NORMALIZED);
64
+ CloseHandle (fileHandle);
65
+ if (!success) return nullptr ;
66
+
67
+ std::string utf8Path;
68
+ llvm::ArrayRef<char > pathRef ((const char *)full_path,
69
+ (const char *)(full_path + MAX_PATH));
70
+ if (!llvm::convertUTF16ToUTF8String (pathRef, utf8Path))
71
+ return nullptr ;
72
+
73
+ if (!resolved_path) {
74
+ resolved_path = static_cast <char *>(malloc (utf8Path.length () + 1 ));
75
+ }
76
+ std::copy (std::begin (utf8Path), std::end (utf8Path), resolved_path);
56
77
return resolved_path;
57
78
}
58
79
}
0 commit comments