Bazel client, Windows: path casing bugfixes 

Change blaze::ConvertPath to lower-case its result
for sake of deterministic comparison later.
Change blaze::CompareAbsolutePaths to call
blaze::ConvertPath before comparison.

The ConvertPath method normalizes its input then
converts it to lowercase, meaning
ConvertPath("c:/Foo") and ConvertPath("C:\FOO\.")
will give the same result.

Thanks to this we will no longer kill the Bazel
server if the --output_user_root changes but only
in casing, or by adding/removing trailing
slash/backslash.

Fixes https://github.com/bazelbuild/bazel/issues/2714

--
Change-Id: I36c13378a9e3567862ee1c611f56b0c3ab465da8
Reviewed-on: https://cr.bazel.build/9517
PiperOrigin-RevId: 151425571
MOS_MIGRATED_REVID=151425571
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index dbc5e32..0b4f52d 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -928,20 +928,26 @@
 
 string ConvertPath(const string& path) {
 #ifdef COMPILER_MSVC
-  // This isn't needed when the binary isn't linked against msys-2.0.dll (when
-  // we build with MSVC): MSYS converts all Unix paths to Windows paths for such
-  // binaries.
-  return path;
+  // The path may not be Windows-style and may not be normalized, so convert it.
+  wstring wpath;
+  if (!blaze_util::AsWindowsPathWithUncPrefix(path, &wpath)) {
+    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "ConvertPath(path=%s)",
+         path.c_str());
+  }
+  std::transform(wpath.begin(), wpath.end(), wpath.begin(), ::towlower);
+  return string(blaze_util::WstringToCstring(wpath.c_str()).get());
 #else  // not COMPILER_MSVC
   // If the path looks like %USERPROFILE%/foo/bar, don't convert.
   if (path.empty() || path[0] == '%') {
-    return path;
+    // It's fine to convert to lower-case even if the path contains environment
+    // variable names, since Windows can look them up case-insensitively.
+    return blaze_util::AsLower(path);
   }
   char* wpath = static_cast<char*>(cygwin_create_path(
       CCP_POSIX_TO_WIN_A, static_cast<const void*>(path.c_str())));
   string result(wpath);
   free(wpath);
-  return result;
+  return blaze_util::AsLower(result);
 #endif  // COMPILER_MSVC
 }
 
@@ -1081,18 +1087,7 @@
 }
 
 bool CompareAbsolutePaths(const string& a, const string& b) {
-  // `a` and `b` may not be Windows-style and may not be normalized, so convert
-  // them both before comparing them.
-  wstring a_real, b_real;
-  if (!blaze_util::AsWindowsPathWithUncPrefix(a, &a_real)) {
-    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
-         "CompareAbsolutePaths(a=%s, b=%s)", a.c_str(), b.c_str());
-  }
-  if (!blaze_util::AsWindowsPathWithUncPrefix(b, &b_real)) {
-    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
-         "CompareAbsolutePaths(a=%s, b=%s)", a.c_str(), b.c_str());
-  }
-  return a_real == b_real;
+  return ConvertPath(a) == ConvertPath(b);
 }
 
 #ifndef STILL_ACTIVE