internal static bool FromMSBuildPath (string basePath, string relPath, out string resultPath)
{
resultPath = relPath;
if (string.IsNullOrEmpty (relPath))
return false;
string path = UnescapePath (relPath);
if (char.IsLetter (path [0]) && path.Length > 1 && path[1] == ':') {
if (Platform.IsWindows) {
resultPath = path; // Return the escaped value
return true;
} else
return false;
}
bool isRooted = Path.IsPathRooted (path);
if (!isRooted && basePath != null) {
path = Path.Combine (basePath, path);
isRooted = Path.IsPathRooted (path);
}
// Return relative paths as-is, we can't do anything else with them
if (!isRooted) {
resultPath = FileService.NormalizeRelativePath (path);
return true;
}
// If we're on Windows, don't need to fix file casing.
if (Platform.IsWindows) {
resultPath = FileService.GetFullPath (path);
return true;
}
// If the path exists with the exact casing specified, then we're done
if (System.IO.File.Exists (path) || System.IO.Directory.Exists (path)){
resultPath = Path.GetFullPath (path);
return true;
}
// Not on Windows, file doesn't exist. That could mean the project was brought from Windows
// and the filename case in the project doesn't match the file on disk, because Windows is
// case-insensitive. Since we have an absolute path, search the directory for the file with
// the correct case.
string[] names = path.Substring (1).Split ('/');
string part = "/";
for (int n=0; n<names.Length; n++) {
string[] entries;
if (names [n] == ".."){
if (part == "/")
return false; // Can go further back. It's not an existing file
part = Path.GetFullPath (part + "/..");
continue;
}
entries = Directory.GetFileSystemEntries (part);
string fpath = null;
foreach (string e in entries) {
if (string.Compare (Path.GetFileName (e), names [n], StringComparison.OrdinalIgnoreCase) == 0) {
fpath = e;
break;
}
}
if (fpath == null) {
// Part of the path does not exist. Can't do any more checking.
part = Path.GetFullPath (part);
for (; n < names.Length; n++)
part += "/" + names[n];
resultPath = part;
return true;
}
part = fpath;
}
resultPath = Path.GetFullPath (part);
return true;
}