Replace (Lower|Upper)caseString in favor of StringRef's newest methods.
[oota-llvm.git] / lib / Support / PathV2.cpp
index d86c150c3319f5ae27200df2d27f66ef8dcf349b..bebe442e24786add86f9f589112912bed179c350 100644 (file)
 
 namespace {
   using llvm::StringRef;
-
-  bool is_separator(const char value) {
-    switch(value) {
-#ifdef LLVM_ON_WIN32
-    case '\\': // fall through
-#endif
-    case '/': return true;
-    default: return false;
-    }
-  }
+  using llvm::sys::path::is_separator;
 
 #ifdef LLVM_ON_WIN32
   const StringRef separators = "\\/";
@@ -154,7 +145,7 @@ namespace {
 
     return end_pos;
   }
-}
+} // end unnamed namespace
 
 namespace llvm {
 namespace sys  {
@@ -400,6 +391,12 @@ void append(SmallVectorImpl<char> &path, const Twine &a,
   }
 }
 
+void append(SmallVectorImpl<char> &path,
+            const_iterator begin, const_iterator end) {
+  for (; begin != end; ++begin)
+    path::append(path, *begin);
+}
+
 const StringRef parent_path(StringRef path) {
   size_t end_pos = parent_path_end(path);
   if (end_pos == StringRef::npos)
@@ -483,6 +480,46 @@ const StringRef extension(StringRef path) {
       return fname.substr(pos);
 }
 
+bool is_separator(char value) {
+  switch(value) {
+#ifdef LLVM_ON_WIN32
+    case '\\': // fall through
+#endif
+    case '/': return true;
+    default: return false;
+  }
+}
+
+void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
+  result.clear();
+  
+  // Check whether the temporary directory is specified by an environment
+  // variable.
+  const char *EnvironmentVariable;
+#ifdef LLVM_ON_WIN32
+  EnvironmentVariable = "TEMP";
+#else
+  EnvironmentVariable = "TMPDIR";
+#endif
+  if (char *RequestedDir = getenv(EnvironmentVariable)) {
+    result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+    return;
+  }
+    
+  // Fall back to a system default.
+  const char *DefaultResult;
+#ifdef LLVM_ON_WIN32
+  (void)erasedOnReboot;
+  DefaultResult = "C:\\TEMP";
+#else
+  if (erasedOnReboot)
+    DefaultResult = "/tmp";
+  else
+    DefaultResult = "/var/tmp";
+#endif
+  result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
+}
+  
 bool has_root_name(const Twine &path) {
   SmallString<128> path_storage;
   StringRef p = path.toStringRef(path_storage);
@@ -619,7 +656,7 @@ error_code create_directories(const Twine &path, bool &existed) {
   if (error_code ec = fs::exists(parent, parent_exists)) return ec;
 
   if (!parent_exists)
-    return create_directories(parent, existed);
+    if (error_code ec = create_directories(parent, existed)) return ec;
 
   return create_directory(p, existed);
 }
@@ -636,14 +673,38 @@ bool is_directory(file_status status) {
   return status.type() == file_type::directory_file;
 }
 
+error_code is_directory(const Twine &path, bool &result) {
+  file_status st;
+  if (error_code ec = status(path, st))
+    return ec;
+  result = is_directory(st);
+  return success;
+}
+
 bool is_regular_file(file_status status) {
   return status.type() == file_type::regular_file;
 }
 
+error_code is_regular_file(const Twine &path, bool &result) {
+  file_status st;
+  if (error_code ec = status(path, st))
+    return ec;
+  result = is_regular_file(st);
+  return success;
+}
+
 bool is_symlink(file_status status) {
   return status.type() == file_type::symlink_file;
 }
 
+error_code is_symlink(const Twine &path, bool &result) {
+  file_status st;
+  if (error_code ec = status(path, st))
+    return ec;
+  result = is_symlink(st);
+  return success;
+}
+
 bool is_other(file_status status) {
   return exists(status) &&
          !is_regular_file(status) &&
@@ -651,52 +712,83 @@ bool is_other(file_status status) {
          !is_symlink(status);
 }
 
-void directory_entry::replace_filename(const Twine &filename, file_status st,
-                                       file_status symlink_st) {
+void directory_entry::replace_filename(const Twine &filename, file_status st) {
   SmallString<128> path(Path.begin(), Path.end());
   path::remove_filename(path);
   path::append(path, filename);
   Path = path.str();
   Status = st;
-  SymlinkStatus = symlink_st;
 }
 
 error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
-  SmallString<128> PathStorage;
   SmallString<32>  MagicStorage;
-  StringRef Path  = path.toNullTerminatedStringRef(PathStorage);
-  StringRef Magic = magic.toNullTerminatedStringRef(MagicStorage);
-
-  assert(Magic.size() > 0 && "magic must be non-empty!");
-
-  SmallString<32> BufferStorage;
-  BufferStorage.reserve(Magic.size());
-
-  // Open file.
-  std::FILE *file = std::fopen(Path.data(), "rb");
-  if (file == 0)
-    return error_code(errno, posix_category());
-  size_t size = ::fread(BufferStorage.data(), 1, Magic.size(), file);
-  if (size != Magic.size()) {
-    int error = errno;
-    bool eof = std::feof(file) != 0;
-    std::fclose(file);
-    if (eof) {
-      // EOF, return false.
+  StringRef Magic = magic.toStringRef(MagicStorage);
+  SmallString<32> Buffer;
+
+  if (error_code ec = get_magic(path, Magic.size(), Buffer)) {
+    if (ec == errc::value_too_large) {
+      // Magic.size() > file_size(Path).
       result = false;
       return success;
     }
-    return error_code(error, posix_category());
+    return ec;
   }
-  std::fclose(file);
 
-  if (std::memcmp(BufferStorage.data(), Magic.data(), Magic.size()) != 0)
-    result = false;
-  else
-    result = true;
+  result = Magic == Buffer;
+  return success;
+}
+
+error_code identify_magic(const Twine &path, LLVMFileType &result) {
+  SmallString<32> Magic;
+  error_code ec = get_magic(path, Magic.capacity(), Magic);
+  if (ec && ec != errc::value_too_large)
+    return ec;
+
+  result = IdentifyFileType(Magic.data(), Magic.size());
   return success;
 }
 
+namespace {
+error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) {
+  if (ft == file_type::directory_file) {
+    // This code would be a lot better with exceptions ;/.
+    error_code ec;
+    for (directory_iterator i(path, ec), e; i != e; i.increment(ec)) {
+      if (ec) return ec;
+      file_status st;
+      if (error_code ec = i->status(st)) return ec;
+      if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec;
+    }
+    bool obviously_this_exists;
+    if (error_code ec = remove(path, obviously_this_exists)) return ec;
+    assert(obviously_this_exists);
+    ++count; // Include the directory itself in the items removed.
+  } else {
+    bool obviously_this_exists;
+    if (error_code ec = remove(path, obviously_this_exists)) return ec;
+    assert(obviously_this_exists);
+    ++count;
+  }
+
+  return success;
+}
+} // end unnamed namespace
+
+error_code remove_all(const Twine &path, uint32_t &num_removed) {
+  SmallString<128> path_storage;
+  StringRef p = path.toStringRef(path_storage);
+
+  file_status fs;
+  if (error_code ec = status(path, fs))
+    return ec;
+  num_removed = 0;
+  return remove_all_r(p, fs.type(), num_removed);
+}
+
+error_code directory_entry::status(file_status &result) const {
+  return fs::status(Path, result);
+}
+
 } // end namespace fs
 } // end namespace sys
 } // end namespace llvm