@@ -26,35 +26,56 @@ inline llvm::Error make_string_error(const llvm::Twine &Message) {
26
26
llvm::inconvertibleErrorCode ());
27
27
}
28
28
29
+ bool isWindowsPath (llvm::StringRef Path) {
30
+ return Path.size () > 1 && llvm::isAlpha (Path[0 ]) && Path[1 ] == ' :' ;
31
+ }
32
+
33
+ bool isNetworkPath (llvm::StringRef Path) {
34
+ return Path.size () > 2 && Path[0 ] == Path[1 ] &&
35
+ llvm::sys::path::is_separator (Path[0 ]);
36
+ }
37
+
29
38
// / This manages file paths in the file system. All paths in the scheme
30
39
// / are absolute (with leading '/').
31
40
// / Note that this scheme is hardcoded into the library and not registered in
32
41
// / registry.
33
42
class FileSystemScheme : public URIScheme {
34
43
public:
35
44
llvm::Expected<std::string>
36
- getAbsolutePath (llvm::StringRef /* Authority*/ , llvm::StringRef Body,
45
+ getAbsolutePath (llvm::StringRef Authority, llvm::StringRef Body,
37
46
llvm::StringRef /* HintPath*/ ) const override {
38
47
if (!Body.startswith (" /" ))
39
48
return make_string_error (" File scheme: expect body to be an absolute "
40
49
" path starting with '/': " +
41
50
Body);
42
- // For Windows paths e.g. /X:
43
- if (Body.size () > 2 && Body[0 ] == ' /' && Body[2 ] == ' :' )
51
+ llvm::SmallString<128 > Path;
52
+ if (!Authority.empty ()) {
53
+ // Windows UNC paths e.g. file://server/share => \\server\share
54
+ (" //" + Authority).toVector (Path);
55
+ } else if (isWindowsPath (Body.substr (1 ))) {
56
+ // Windows paths e.g. file:///X:/path => X:\path
44
57
Body.consume_front (" /" );
45
- llvm::SmallVector<char , 16 > Path (Body.begin (), Body.end ());
58
+ }
59
+ Path.append (Body);
46
60
llvm::sys::path::native (Path);
47
- return std::string (Path. begin (), Path. end () );
61
+ return std::string (Path);
48
62
}
49
63
50
64
llvm::Expected<URI>
51
65
uriFromAbsolutePath (llvm::StringRef AbsolutePath) const override {
52
66
std::string Body;
53
- // For Windows paths e.g. X:
54
- if (AbsolutePath.size () > 1 && AbsolutePath[1 ] == ' :' )
67
+ llvm::StringRef Authority;
68
+ llvm::StringRef Root = llvm::sys::path::root_name (AbsolutePath);
69
+ if (isNetworkPath (Root)) {
70
+ // Windows UNC paths e.g. \\server\share => file://server/share
71
+ Authority = Root.drop_front (2 );
72
+ AbsolutePath.consume_front (Root);
73
+ } else if (isWindowsPath (Root)) {
74
+ // Windows paths e.g. X:\path => file:///X:/path
55
75
Body = " /" ;
76
+ }
56
77
Body += llvm::sys::path::convert_to_slash (AbsolutePath);
57
- return URI (" file" , /* Authority= */ " " , Body);
78
+ return URI (" file" , Authority, Body);
58
79
}
59
80
};
60
81
@@ -96,13 +117,13 @@ bool shouldEscape(unsigned char C) {
96
117
void percentEncode (llvm::StringRef Content, std::string &Out) {
97
118
std::string Result;
98
119
for (unsigned char C : Content)
99
- if (shouldEscape (C))
100
- {
120
+ if (shouldEscape (C)) {
101
121
Out.push_back (' %' );
102
122
Out.push_back (llvm::hexdigit (C / 16 ));
103
123
Out.push_back (llvm::hexdigit (C % 16 ));
104
- } else
105
- { Out.push_back (C); }
124
+ } else {
125
+ Out.push_back (C);
126
+ }
106
127
}
107
128
108
129
// / Decodes a string according to percent-encoding.
0 commit comments