aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support/Path.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support/Path.cpp')
-rw-r--r--lib/Support/Path.cpp173
1 files changed, 80 insertions, 93 deletions
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index d5a0ec5..a7a9919 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h"
@@ -164,9 +165,6 @@ enum FSEntity {
FS_Name
};
-// Implemented in Unix/Path.inc and Windows/Path.inc.
-static std::error_code TempDir(SmallVectorImpl<char> &result);
-
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
SmallVectorImpl<char> &ResultPath,
bool MakeAbsolute, unsigned Mode,
@@ -178,8 +176,7 @@ static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
// Make model absolute by prepending a temp directory if it's not already.
if (!sys::path::is_absolute(Twine(ModelStorage))) {
SmallString<128> TDir;
- if (std::error_code EC = TempDir(TDir))
- return EC;
+ sys::path::system_temp_directory(true, TDir);
sys::path::append(TDir, Twine(ModelStorage));
ModelStorage.swap(TDir);
}
@@ -214,13 +211,13 @@ retry_random_path:
}
case FS_Name: {
- bool Exists;
- std::error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
+ std::error_code EC =
+ sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
+ if (EC == errc::no_such_file_or_directory)
+ return std::error_code();
if (EC)
return EC;
- if (Exists)
- goto retry_random_path;
- return std::error_code();
+ goto retry_random_path;
}
case FS_Dir: {
@@ -308,7 +305,30 @@ const_iterator &const_iterator::operator++() {
return *this;
}
-const_iterator &const_iterator::operator--() {
+bool const_iterator::operator==(const const_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
+}
+
+ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
+ return Position - RHS.Position;
+}
+
+reverse_iterator rbegin(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Position = Path.size();
+ return ++I;
+}
+
+reverse_iterator rend(StringRef Path) {
+ reverse_iterator I;
+ I.Path = Path;
+ I.Component = Path.substr(0, 0);
+ I.Position = 0;
+ return I;
+}
+
+reverse_iterator &reverse_iterator::operator++() {
// If we're at the end and the previous char was a '/', return '.' unless
// we are the root path.
size_t root_dir_pos = root_dir_start(Path);
@@ -335,20 +355,12 @@ const_iterator &const_iterator::operator--() {
return *this;
}
-bool const_iterator::operator==(const const_iterator &RHS) const {
- return Path.begin() == RHS.Path.begin() &&
+bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
+ return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
Position == RHS.Position;
}
-bool const_iterator::operator!=(const const_iterator &RHS) const {
- return !(*this == RHS);
-}
-
-ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
- return Position - RHS.Position;
-}
-
-const StringRef root_path(StringRef path) {
+StringRef root_path(StringRef path) {
const_iterator b = begin(path),
pos = b,
e = end(path);
@@ -380,7 +392,7 @@ const StringRef root_path(StringRef path) {
return StringRef();
}
-const StringRef root_name(StringRef path) {
+StringRef root_name(StringRef path) {
const_iterator b = begin(path),
e = end(path);
if (b != e) {
@@ -402,7 +414,7 @@ const StringRef root_name(StringRef path) {
return StringRef();
}
-const StringRef root_directory(StringRef path) {
+StringRef root_directory(StringRef path) {
const_iterator b = begin(path),
pos = b,
e = end(path);
@@ -431,7 +443,7 @@ const StringRef root_directory(StringRef path) {
return StringRef();
}
-const StringRef relative_path(StringRef path) {
+StringRef relative_path(StringRef path) {
StringRef root = root_path(path);
return path.substr(root.size());
}
@@ -483,7 +495,7 @@ void append(SmallVectorImpl<char> &path,
path::append(path, *begin);
}
-const StringRef parent_path(StringRef path) {
+StringRef parent_path(StringRef path) {
size_t end_pos = parent_path_end(path);
if (end_pos == StringRef::npos)
return StringRef();
@@ -525,17 +537,27 @@ void native(const Twine &path, SmallVectorImpl<char> &result) {
native(result);
}
-void native(SmallVectorImpl<char> &path) {
+void native(SmallVectorImpl<char> &Path) {
#ifdef LLVM_ON_WIN32
- std::replace(path.begin(), path.end(), '/', '\\');
+ std::replace(Path.begin(), Path.end(), '/', '\\');
+#else
+ for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
+ if (*PI == '\\') {
+ auto PN = PI + 1;
+ if (PN < PE && *PN == '\\')
+ ++PI; // increment once, the for loop will move over the escaped slash
+ else
+ *PI = '/';
+ }
+ }
#endif
}
-const StringRef filename(StringRef path) {
- return *(--end(path));
+StringRef filename(StringRef path) {
+ return *rbegin(path);
}
-const StringRef stem(StringRef path) {
+StringRef stem(StringRef path) {
StringRef fname = filename(path);
size_t pos = fname.find_last_of('.');
if (pos == StringRef::npos)
@@ -548,7 +570,7 @@ const StringRef stem(StringRef path) {
return fname.substr(0, pos);
}
-const StringRef extension(StringRef path) {
+StringRef extension(StringRef path) {
StringRef fname = filename(path);
size_t pos = fname.find_last_of('.');
if (pos == StringRef::npos)
@@ -573,62 +595,10 @@ bool is_separator(char value) {
static const char preferred_separator_string[] = { preferred_separator, '\0' };
-const StringRef get_separator() {
+StringRef get_separator() {
return preferred_separator_string;
}
-void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
- result.clear();
-
-#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
- // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
- // macros defined in <unistd.h> on darwin >= 9
- int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
- : _CS_DARWIN_USER_CACHE_DIR;
- size_t ConfLen = confstr(ConfName, nullptr, 0);
- if (ConfLen > 0) {
- do {
- result.resize(ConfLen);
- ConfLen = confstr(ConfName, result.data(), result.size());
- } while (ConfLen > 0 && ConfLen != result.size());
-
- if (ConfLen > 0) {
- assert(result.back() == 0);
- result.pop_back();
- return;
- }
-
- result.clear();
- }
-#endif
-
- // 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);
@@ -932,10 +902,23 @@ file_magic identify_magic(StringRef Magic) {
return file_magic::unknown;
switch ((unsigned char)Magic[0]) {
case 0x00: {
- // COFF short import library file
+ // COFF bigobj or short import library file
if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
- Magic[3] == (char)0xff)
- return file_magic::coff_import_library;
+ Magic[3] == (char)0xff) {
+ size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
+ if (Magic.size() < MinSize)
+ return file_magic::coff_import_library;
+
+ int BigObjVersion = *reinterpret_cast<const support::ulittle16_t*>(
+ Magic.data() + offsetof(COFF::BigObjHeader, Version));
+ if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion)
+ return file_magic::coff_import_library;
+
+ const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
+ if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0)
+ return file_magic::coff_import_library;
+ return file_magic::coff_object;
+ }
// Windows resource file
const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
if (Magic.size() >= sizeof(Expected) &&
@@ -975,6 +958,9 @@ file_magic identify_magic(StringRef Magic) {
case 3: return file_magic::elf_shared_object;
case 4: return file_magic::elf_core;
}
+ else
+ // It's still some type of ELF file.
+ return file_magic::elf;
}
break;
@@ -1016,7 +1002,7 @@ file_magic identify_magic(StringRef Magic) {
case 6: return file_magic::macho_dynamically_linked_shared_lib;
case 7: return file_magic::macho_dynamic_linker;
case 8: return file_magic::macho_bundle;
- case 9: return file_magic::macho_dynamic_linker;
+ case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
case 10: return file_magic::macho_dsym_companion;
}
break;
@@ -1037,12 +1023,13 @@ file_magic identify_magic(StringRef Magic) {
return file_magic::coff_object;
break;
- case 0x4d: // Possible MS-DOS stub on Windows PE file
- if (Magic[1] == 0x5a) {
+ case 'M': // Possible MS-DOS stub on Windows PE file
+ if (Magic[1] == 'Z') {
uint32_t off =
*reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
// PE/COFF file, either EXE or DLL.
- if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
+ if (off < Magic.size() &&
+ memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
return file_magic::pecoff_executable;
}
break;