Changes to mimic those in Unix/Path.inc in support of PR495. This hasn't

been compiled or tested.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2005-07-07 23:35:23 +00:00
parent dd04df0ec3
commit 1cf2d04351

View File

@ -94,7 +94,7 @@ Path::GetTemporaryDirectory() {
throw std::string("Can't determine temporary directory"); throw std::string("Can't determine temporary directory");
Path result; Path result;
result.setDirectory(pathname); result.set(pathname);
// Append a subdirectory passed on our process id so multiple LLVMs don't // Append a subdirectory passed on our process id so multiple LLVMs don't
// step on each other's toes. // step on each other's toes.
@ -128,7 +128,7 @@ Path::Path(const std::string& unverified_path)
Path Path
Path::GetRootDirectory() { Path::GetRootDirectory() {
Path result; Path result;
result.setDirectory("/"); result.set("C:\\");
return result; return result;
} }
@ -138,14 +138,14 @@ static void getPathList(const char*path, std::vector<sys::Path>& Paths) {
Path tmpPath; Path tmpPath;
while( delim != 0 ) { while( delim != 0 ) {
std::string tmp(at, size_t(delim-at)); std::string tmp(at, size_t(delim-at));
if (tmpPath.setDirectory(tmp)) if (tmpPath.set(tmp))
if (tmpPath.canRead()) if (tmpPath.canRead())
Paths.push_back(tmpPath); Paths.push_back(tmpPath);
at = delim + 1; at = delim + 1;
delim = strchr(at, ';'); delim = strchr(at, ';');
} }
if (*at != 0) if (*at != 0)
if (tmpPath.setDirectory(std::string(at))) if (tmpPath.set(std::string(at)))
if (tmpPath.canRead()) if (tmpPath.canRead())
Paths.push_back(tmpPath); Paths.push_back(tmpPath);
@ -166,7 +166,7 @@ Path::GetBytecodeLibraryPaths(std::vector<sys::Path>& Paths) {
#ifdef LLVM_LIBDIR #ifdef LLVM_LIBDIR
{ {
Path tmpPath; Path tmpPath;
if (tmpPath.setDirectory(LLVM_LIBDIR)) if (tmpPath.set(LLVM_LIBDIR))
if (tmpPath.canRead()) if (tmpPath.canRead())
Paths.push_back(tmpPath); Paths.push_back(tmpPath);
} }
@ -186,7 +186,7 @@ Path::GetUserHomeDirectory() {
const char* home = getenv("HOME"); const char* home = getenv("HOME");
if (home) { if (home) {
Path result; Path result;
if (result.setDirectory(home)) if (result.set(home))
return result; return result;
} }
return GetRootDirectory(); return GetRootDirectory();
@ -380,58 +380,40 @@ Path::getDirectoryContents(std::set<Path>& result) const {
} }
bool bool
Path::setDirectory(const std::string& a_path) { Path::set(const std::string& a_path) {
if (a_path.size() == 0) if (a_path.size() == 0)
return false; return false;
Path save(*this); std::string save(path);
path = a_path; path = a_path;
FlipBackSlashes(path); FlipBackSlashes(path);
size_t last = a_path.size() -1; size_t last = a_path.size() -1;
if (a_path[last] != '/')
path += '/';
if (!isValid()) { if (!isValid()) {
path = save.path; path = save;
return false; return false;
} }
return true; return true;
} }
bool bool
Path::setFile(const std::string& a_path) { Path::appendComponent(const std::string& dir) {
if (a_path.size() == 0) if (name.empty())
return false; return false;
Path save(*this); std::string save(path);
path = a_path; if (!path.empty()) {
FlipBackSlashes(path); size_t last = path.size() - 1;
size_t last = a_path.size() - 1; if (path[last] != '/')
while (last > 0 && a_path[last] == '/') path += '/';
last--; }
path.erase(last+1); path += name;
if (!isValid()) { if (!isValid()) {
path = save.path; path = save;
return false; return false;
} }
return true; return true;
} }
bool bool
Path::appendDirectory(const std::string& dir) { Path::eraseComponent() {
if (isFile())
return false;
Path save(*this);
path += dir;
path += "/";
if (!isValid()) {
path = save.path;
return false;
}
return true;
}
bool
Path::elideDirectory() {
if (isFile())
return false;
size_t slashpos = path.rfind('/',path.size()); size_t slashpos = path.rfind('/',path.size());
if (slashpos == 0 || slashpos == std::string::npos) if (slashpos == 0 || slashpos == std::string::npos)
return false; return false;
@ -443,47 +425,20 @@ Path::elideDirectory() {
return true; return true;
} }
bool
Path::appendFile(const std::string& file) {
if (!isDirectory())
return false;
Path save(*this);
path += file;
if (!isValid()) {
path = save.path;
return false;
}
return true;
}
bool
Path::elideFile() {
if (isDirectory())
return false;
size_t slashpos = path.rfind('/',path.size());
if (slashpos == std::string::npos)
return false;
path.erase(slashpos+1);
return true;
}
bool bool
Path::appendSuffix(const std::string& suffix) { Path::appendSuffix(const std::string& suffix) {
if (isDirectory()) std::string save(path);
return false;
Path save(*this);
path.append("."); path.append(".");
path.append(suffix); path.append(suffix);
if (!isValid()) { if (!isValid()) {
path = save.path; path = save;
return false; return false;
} }
return true; return true;
} }
bool bool
Path::elideSuffix() { Path::eraseSuffix() {
if (isDirectory()) return false;
size_t dotpos = path.rfind('.',path.size()); size_t dotpos = path.rfind('.',path.size());
size_t slashpos = path.rfind('/',path.size()); size_t slashpos = path.rfind('/',path.size());
if (slashpos != std::string::npos && dotpos != std::string::npos && if (slashpos != std::string::npos && dotpos != std::string::npos &&
@ -494,12 +449,8 @@ Path::elideSuffix() {
return false; return false;
} }
bool bool
Path::createDirectory( bool create_parents) { Path::createDirectory( bool create_parents) {
// Make sure we're dealing with a directory
if (!isDirectory()) return false;
// Get a writeable copy of the path name // Get a writeable copy of the path name
char *pathname = reinterpret_cast<char *>(_alloca(path.length()+1)); char *pathname = reinterpret_cast<char *>(_alloca(path.length()+1));
path.copy(pathname,path.length()); path.copy(pathname,path.length());
@ -548,9 +499,6 @@ Path::createDirectory( bool create_parents) {
bool bool
Path::createFile() { Path::createFile() {
// Make sure we're dealing with a file
if (!isFile()) return false;
// Create the file // Create the file
HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL); FILE_ATTRIBUTE_NORMAL, NULL);
@ -562,89 +510,83 @@ Path::createFile() {
} }
bool bool
Path::destroyDirectory(bool remove_contents) const { Path::destroy(bool remove_contents) const {
// Make sure we're dealing with a directory if (isFile()) {
if (!isDirectory()) return false; DWORD attr = GetFileAttributes(path.c_str());
// If it doesn't exist, we're done. // If it doesn't exist, we're done.
if (!exists()) return true; if (attr == INVALID_FILE_ATTRIBUTES)
return true;
char *pathname = reinterpret_cast<char *>(_alloca(path.length()+2)); // Read-only files cannot be deleted on Windows. Must remove the read-only
int lastchar = path.length() - 1 ; // attribute first.
path.copy(pathname,lastchar+2); if (attr & FILE_ATTRIBUTE_READONLY) {
if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY))
// Make path end with '/*'. ThrowError(path + ": Can't destroy file: ");
pathname[lastchar+1] = '*';
pathname[lastchar+2] = 0;
if (remove_contents) {
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(pathname, &fd);
// It's a bad idea to alter the contents of a directory while enumerating
// its contents. So build a list of its contents first, then destroy them.
if (h != INVALID_HANDLE_VALUE) {
std::vector<Path> list;
do {
if (strcmp(fd.cFileName, ".") == 0)
continue;
if (strcmp(fd.cFileName, "..") == 0)
continue;
Path aPath(path + &fd.cFileName[0]);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
aPath.path += "/";
list.push_back(aPath);
} while (FindNextFile(h, &fd));
DWORD err = GetLastError();
FindClose(h);
if (err != ERROR_NO_MORE_FILES) {
SetLastError(err);
ThrowError(path + ": Can't read directory: ");
}
for (std::vector<Path>::iterator I = list.begin(); I != list.end(); ++I) {
Path &aPath = *I;
if (aPath.isDirectory())
aPath.destroyDirectory(true);
else
aPath.destroyFile();
}
} else {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
ThrowError(path + ": Can't read directory: ");
} }
}
pathname[lastchar] = 0; if (!DeleteFile(path.c_str()))
if (!RemoveDirectory(pathname))
ThrowError(std::string(pathname) + ": Can't destroy directory: ");
return true;
}
bool
Path::destroyFile() const {
if (!isFile()) return false;
DWORD attr = GetFileAttributes(path.c_str());
// If it doesn't exist, we're done.
if (attr == INVALID_FILE_ATTRIBUTES)
return true;
// 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))
ThrowError(path + ": Can't destroy file: "); ThrowError(path + ": Can't destroy file: ");
} return true;
} else if (isDirectory()) {
if (!DeleteFile(path.c_str())) // If it doesn't exist, we're done.
ThrowError(path + ": Can't destroy file: "); if (!exists())
return true; return true;
char *pathname = reinterpret_cast<char *>(_alloca(path.length()+2));
int lastchar = path.length() - 1 ;
path.copy(pathname,lastchar+2);
// Make path end with '/*'.
pathname[lastchar+1] = '*';
pathname[lastchar+2] = 0;
if (remove_contents) {
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(pathname, &fd);
// It's a bad idea to alter the contents of a directory while enumerating
// its contents. So build a list of its contents first, then destroy them.
if (h != INVALID_HANDLE_VALUE) {
std::vector<Path> list;
do {
if (strcmp(fd.cFileName, ".") == 0)
continue;
if (strcmp(fd.cFileName, "..") == 0)
continue;
Path aPath(path + &fd.cFileName[0]);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
aPath.path += "/";
list.push_back(aPath);
} while (FindNextFile(h, &fd));
DWORD err = GetLastError();
FindClose(h);
if (err != ERROR_NO_MORE_FILES) {
SetLastError(err);
ThrowError(path + ": Can't read directory: ");
}
for (std::vector<Path>::iterator I = list.begin(); I != list.end();
++I) {
Path &aPath = *I;
aPath.destroy(true);
}
} else {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
ThrowError(path + ": Can't read directory: ");
}
}
pathname[lastchar] = 0;
if (!RemoveDirectory(pathname))
ThrowError(std::string(pathname) + ": Can't destroy directory: ");
return true;
}
} }
bool Path::getMagicNumber(std::string& Magic, unsigned len) const { bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
@ -676,7 +618,8 @@ bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
} }
bool bool
Path::renameFile(const Path& newName) { Path::rename(const Path& newName) {
// FIXME: This should rename a directory too.
if (!isFile()) return false; if (!isFile()) return false;
if (!MoveFile(path.c_str(), newName.c_str())) if (!MoveFile(path.c_str(), newName.c_str()))
ThrowError("Can't move '" + path + ThrowError("Can't move '" + path +
@ -766,10 +709,6 @@ Path::makeUnique(bool reuse_current) {
bool bool
Path::createTemporaryFile(bool reuse_current) { Path::createTemporaryFile(bool reuse_current) {
// Make sure we're dealing with a file
if (!isFile())
return false;
// Make this into a unique file name // Make this into a unique file name
makeUnique( reuse_current ); makeUnique( reuse_current );