Merge TempDir and system_temp_directory.
[oota-llvm.git] / lib / Support / Windows / Path.inc
index 72f21ae5e68ede83f8e1cd0e32cc3529ab9c8f6c..b09c198969938376bde89a2011adce86e9d325bd 100644 (file)
@@ -49,23 +49,6 @@ static std::error_code windows_error(DWORD E) {
   return mapWindowsError(E);
 }
 
-static std::error_code TempDir(SmallVectorImpl<char> &Result) {
-  SmallVector<wchar_t, 64> Res;
-retry_temp_dir:
-  DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin());
-
-  if (Len == 0)
-    return windows_error(::GetLastError());
-
-  if (Len > Res.capacity()) {
-    Res.reserve(Len);
-    goto retry_temp_dir;
-  }
-
-  Res.set_size(Len);
-  return UTF16ToUTF8(Res.begin(), Res.size(), Result);
-}
-
 static bool is_separator(const wchar_t value) {
   switch (value) {
   case L'\\':
@@ -163,11 +146,6 @@ std::error_code create_directory(const Twine &path, bool IgnoreExisting) {
   return std::error_code();
 }
 
-std::error_code normalize_separators(SmallVectorImpl<char> &Path) {
-  (void) Path;
-  return std::error_code();
-}
-
 // We can't use symbolic links for windows.
 std::error_code create_link(const Twine &to, const Twine &from) {
   // Get arguments.
@@ -196,7 +174,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
 
   file_status ST;
   if (std::error_code EC = status(path, ST)) {
-    if (EC != std::errc::no_such_file_or_directory || !IgnoreNonExisting)
+    if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
       return EC;
     return std::error_code();
   }
@@ -208,14 +186,14 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
   if (ST.type() == file_type::directory_file) {
     if (!::RemoveDirectoryW(c_str(path_utf16))) {
       std::error_code EC = windows_error(::GetLastError());
-      if (EC != std::errc::no_such_file_or_directory || !IgnoreNonExisting)
+      if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
         return EC;
     }
     return std::error_code();
   }
   if (!::DeleteFileW(c_str(path_utf16))) {
     std::error_code EC = windows_error(::GetLastError());
-    if (EC != std::errc::no_such_file_or_directory || !IgnoreNonExisting)
+    if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)
       return EC;
   }
   return std::error_code();
@@ -481,7 +459,7 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
         _close(FileDescriptor);
     } else
       ::CloseHandle(FileHandle);
-    return std::make_error_code(std::errc::invalid_argument);
+    return make_error_code(errc::invalid_argument);
   }
 
   DWORD flprotect;
@@ -617,7 +595,7 @@ mapped_file_region::mapped_file_region(int fd,
     if (closefd)
       _close(FileDescriptor);
     FileDescriptor = 0;
-    ec = std::make_error_code(std::errc::bad_file_descriptor);
+    ec = make_error_code(errc::bad_file_descriptor);
     return;
   }
 
@@ -779,7 +757,7 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD) {
     if (LastError != ERROR_ACCESS_DENIED)
       return EC;
     if (is_directory(Name))
-      return std::make_error_code(std::errc::is_a_directory);
+      return make_error_code(errc::is_a_directory);
     return EC;
   }
 
@@ -831,7 +809,7 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
     if (LastError != ERROR_ACCESS_DENIED)
       return EC;
     if (is_directory(Name))
-      return std::make_error_code(std::errc::is_a_directory);
+      return make_error_code(errc::is_a_directory);
     return EC;
   }
 
@@ -867,6 +845,51 @@ bool home_directory(SmallVectorImpl<char> &result) {
   return true;
 }
 
+static bool getTempDirEnvVar(const char *Var, SmallVectorImpl<char> &Res) {
+  SmallVector<wchar_t, 128> NameUTF16;
+  if (windows::UTF8ToUTF16(Var, NameUTF16))
+    return false;
+
+  SmallVector<wchar_t, 1024> Buf;
+  size_t Size = 1024;
+  do {
+    Buf.reserve(Size);
+    Size =
+        GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
+    if (Size == 0)
+      return false;
+
+    // Try again with larger buffer.
+  } while (Size > Buf.capacity());
+  Buf.set_size(Size);
+
+  if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
+    return false;
+  return true;
+}
+
+static bool getTempDirEnvVar(SmallVectorImpl<char> &Res) {
+  const char *EnvironmentVariables[] = {"TMP", "TEMP", "USERPROFILE"};
+  for (const char *Env : EnvironmentVariables) {
+    if (getTempDirEnvVar(Env, Res))
+      return true;
+  }
+  return false;
+}
+
+void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
+  (void)ErasedOnReboot;
+  Result.clear();
+
+  // Check whether the temporary directory is specified by an environment
+  // variable.
+  if (getTempDirEnvVar(Result))
+    return;
+
+  // Fall back to a system default.
+  const char *DefaultResult = "C:\\TEMP";
+  Result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
+}
 } // end namespace path
 
 namespace windows {