//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Reid Spencer and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
// Modified by Henrik Bach to comply with at least MinGW.
// Ported to Win32 by Jeff Cohen.
// We need to undo a macro defined in Windows.h, otherwise we won't compile:
#undef CopyFile
+#undef GetCurrentDirectory
// Windows happily accepts either forward or backward slashes, though any path
// returned by a Win32 API will have backward slashes. As LLVM code basically
namespace llvm {
namespace sys {
+const char PathSeparator = ';';
+
+Path::Path(const std::string& p)
+ : path(p) {
+ FlipBackSlashes(path);
+}
+
+Path::Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrLen) {
+ FlipBackSlashes(path);
+}
bool
Path::isValid() const {
return true;
}
+bool
+Path::isAbsolute() const {
+ switch (path.length()) {
+ case 0:
+ return false;
+ case 1:
+ case 2:
+ return path[0] == '/';
+ default:
+ return path[0] == '/' || (path[1] == ':' && path[2] == '/');
+ }
+}
+
static Path *TempDirectory = NULL;
Path
// Append a subdirectory passed on our process id so multiple LLVMs don't
// step on each other's toes.
+#ifdef __MINGW32__
+ // Mingw's Win32 header files are broken.
sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId()));
+#else
+ sprintf(pathname, "LLVM_%u", GetCurrentProcessId());
+#endif
result.appendComponent(pathname);
// If there's a directory left over from a previous LLVM execution that
return result;
}
-static void getPathList(const char*path, std::vector<sys::Path>& Paths) {
- const char* at = path;
- const char* delim = strchr(at, ';');
- Path tmpPath;
- while (delim != 0) {
- std::string tmp(at, size_t(delim-at));
- if (tmpPath.set(tmp))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
- at = delim + 1;
- delim = strchr(at, ';');
- }
-
- if (*at != 0)
- if (tmpPath.set(std::string(at)))
- if (tmpPath.canRead())
- Paths.push_back(tmpPath);
-}
-
void
Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
Paths.push_back(sys::Path("C:/WINDOWS/SYSTEM32"));
}
void
-Path::GetBytecodeLibraryPaths(std::vector<sys::Path>& Paths) {
+Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
if (env_var != 0) {
getPathList(env_var,Paths);
}
return GetRootDirectory();
}
+
+Path
+Path::GetCurrentDirectory() {
+ char pathname[MAX_PATH];
+ ::GetCurrentDirectoryA(MAX_PATH,pathname);
+ return Path(pathname);
+}
+
+/// GetMainExecutable - Return the path to the main executable, given the
+/// value of argv[0] from program startup.
+Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
+ return Path();
+}
+
+
// FIXME: the above set of functions don't map to Windows very well.
return len > 0 && path[len-1] == '/';
}
+std::string Path::getDirname() const {
+ return getDirnameCharSep(path, '/');
+}
+
std::string
Path::getBasename() const {
// Find the last slash
return path.substr(slash, dot - slash);
}
-bool Path::hasMagicNumber(const std::string &Magic) const {
- std::string actualMagic;
- if (getMagicNumber(actualMagic, Magic.size()))
- return Magic == actualMagic;
- return false;
-}
-
bool
-Path::isBytecodeFile() const {
- std::string actualMagic;
- if (!getMagicNumber(actualMagic, 4))
- return false;
- return actualMagic == "llvc" || actualMagic == "llvm";
+Path::exists() const {
+ DWORD attr = GetFileAttributes(path.c_str());
+ return attr != INVALID_FILE_ATTRIBUTES;
}
bool
-Path::exists() const {
+Path::isDirectory() const {
DWORD attr = GetFileAttributes(path.c_str());
- return attr != INVALID_FILE_ATTRIBUTES;
+ return (attr != INVALID_FILE_ATTRIBUTES) &&
+ (attr & FILE_ATTRIBUTE_DIRECTORY);
}
bool
return path.substr(pos+1);
}
-bool
-Path::getFileStatus(FileStatus &info, std::string *ErrStr) const {
- WIN32_FILE_ATTRIBUTE_DATA fi;
- if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
- return MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
- ": Can't get status: ");
+const FileStatus *
+PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
+ if (!fsIsValid || update) {
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
+ ": Can't get status: ");
+ return 0;
+ }
- info.fileSize = fi.nFileSizeHigh;
- info.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
- info.fileSize += fi.nFileSizeLow;
+ status.fileSize = fi.nFileSizeHigh;
+ status.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
+ status.fileSize += fi.nFileSizeLow;
- info.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
- info.user = 9999; // Not applicable to Windows, so...
- info.group = 9999; // Not applicable to Windows, so...
+ status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
+ status.user = 9999; // Not applicable to Windows, so...
+ status.group = 9999; // Not applicable to Windows, so...
- __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
- info.modTime.fromWin32Time(ft);
+ // FIXME: this is only unique if the file is accessed by the same file path.
+ // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode
+ // numbers, but the concept doesn't exist in Windows.
+ status.uniqueID = 0;
+ for (unsigned i = 0; i < path.length(); ++i)
+ status.uniqueID += path[i];
- info.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- return false;
+ __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
+ status.modTime.fromWin32Time(ft);
+
+ status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ fsIsValid = true;
+ }
+ return &status;
}
bool Path::makeReadableOnDisk(std::string* ErrMsg) {
bool
Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
- FileStatus Status;
- if (getFileStatus(Status, ErrMsg))
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
+ MakeErrMsg(ErrMsg, path + ": can't get status of file");
return true;
-
- if (!Status.isDir) {
- MakeErrMsg(ErrMsg, path + ": not a directory");
+ }
+
+ if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (ErrMsg)
+ *ErrMsg = path + ": not a directory";
return true;
}
bool
Path::set(const std::string& a_path) {
- if (a_path.size() == 0)
+ if (a_path.empty())
return false;
std::string save(path);
path = a_path;
bool
Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
- FileStatus Status;
- if (getFileStatus(Status, ErrStr))
- return false;
+ WIN32_FILE_ATTRIBUTE_DATA fi;
+ if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
+ return true;
- if (Status.isFile) {
- DWORD attr = GetFileAttributes(path.c_str());
-
- // If it doesn't exist, we're done.
- if (attr == INVALID_FILE_ATTRIBUTES)
- return false;
-
- // Read-only files cannot be deleted on Windows. Must remove the read-only
- // attribute first.
- if (attr & FILE_ATTRIBUTE_READONLY) {
- if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY))
- return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
- }
-
- if (!DeleteFile(path.c_str()))
- return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
- return false;
- } else if (Status.isDir) {
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// If it doesn't exist, we're done.
if (!exists())
return false;
return MakeErrMsg(ErrStr,
std::string(pathname) + ": Can't destroy directory: ");
return false;
- }
- // It appears the path doesn't exist.
- return true;
+ } else {
+ // Read-only files cannot be deleted on Windows. Must remove the read-only
+ // attribute first.
+ if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ if (!SetFileAttributes(path.c_str(),
+ fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ }
+
+ if (!DeleteFile(path.c_str()))
+ return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
+ return false;
+ }
}
bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path
+ "': ");
- return true;
+ return false;
}
bool
return false;
}
+/// MapInFilePages - Not yet implemented on win32.
+const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+ return 0;
+}
+
+/// MapInFilePages - Not yet implemented on win32.
+void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
+ assert(0 && "NOT IMPLEMENTED");
+}
+
}
}