diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2005-07-07 23:21:43 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2005-07-07 23:21:43 +0000 |
commit | dd04df0ec33a903ee7fc747701bafde622f77d8b (patch) | |
tree | 341d4fd4ba6e81cb79966ef2c379ccbb2d8b5100 /lib | |
parent | b3d59701c89a6e03a0e0909543f3e7bd9140900f (diff) |
For PR495:
Get rid of the difference between file paths and directory paths. The Path
class now simply stores a path that can refer to either a file or a
directory. This required various changes in the implementation and interface
of the class with the corresponding impact to its users. Doxygen comments were
also updated to reflect these changes. Interface changes are:
appendDirectory -> appendComponent
appendFile -> appendComponent
elideDirectory -> eraseComponent
elideFile -> eraseComponent
elideSuffix -> eraseSuffix
renameFile -> rename
setDirectory -> set
setFile -> set
Changes pass Dejagnu and llvm-test/SingleSource tests.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22349 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Archive/ArchiveReader.cpp | 2 | ||||
-rw-r--r-- | lib/Archive/ArchiveWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Bytecode/Archive/ArchiveReader.cpp | 2 | ||||
-rw-r--r-- | lib/Bytecode/Archive/ArchiveWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Debugger/ProgramInfo.cpp | 4 | ||||
-rw-r--r-- | lib/Linker/LinkModules.cpp | 2 | ||||
-rw-r--r-- | lib/Linker/Linker.cpp | 42 | ||||
-rw-r--r-- | lib/Support/SystemUtils.cpp | 4 | ||||
-rw-r--r-- | lib/Support/ToolRunner.cpp | 6 | ||||
-rw-r--r-- | lib/System/Path.cpp | 6 | ||||
-rw-r--r-- | lib/System/Unix/Path.inc | 209 | ||||
-rw-r--r-- | lib/System/Unix/Program.inc | 6 | ||||
-rw-r--r-- | lib/System/Unix/Signals.inc | 2 | ||||
-rw-r--r-- | lib/System/Win32/Path.inc | 10 |
14 files changed, 135 insertions, 172 deletions
diff --git a/lib/Archive/ArchiveReader.cpp b/lib/Archive/ArchiveReader.cpp index 262f170c07..8d87a6777e 100644 --- a/lib/Archive/ArchiveReader.cpp +++ b/lib/Archive/ArchiveReader.cpp @@ -187,7 +187,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { member->next = 0; member->prev = 0; member->parent = this; - member->path.setFile(pathname); + member->path.set(pathname); member->info.fileSize = MemberSize; member->info.modTime.fromEpochTime(atoi(Hdr->date)); unsigned int mode; diff --git a/lib/Archive/ArchiveWriter.cpp b/lib/Archive/ArchiveWriter.cpp index be80b973c7..1318471530 100644 --- a/lib/Archive/ArchiveWriter.cpp +++ b/lib/Archive/ArchiveWriter.cpp @@ -450,17 +450,17 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress){ // Close up shop FinalFile.close(); arch.close(); - TmpArchive.destroyFile(); + TmpArchive.destroy(); } else { // We don't have to insert the symbol table, so just renaming the temp // file to the correct name will suffice. - TmpArchive.renameFile(archPath); + TmpArchive.rename(archPath); } } catch (...) { // Make sure we clean up. if (TmpArchive.exists()) - TmpArchive.destroyFile(); + TmpArchive.destroy(); throw; } } diff --git a/lib/Bytecode/Archive/ArchiveReader.cpp b/lib/Bytecode/Archive/ArchiveReader.cpp index 262f170c07..8d87a6777e 100644 --- a/lib/Bytecode/Archive/ArchiveReader.cpp +++ b/lib/Bytecode/Archive/ArchiveReader.cpp @@ -187,7 +187,7 @@ Archive::parseMemberHeader(const char*& At, const char* End) { member->next = 0; member->prev = 0; member->parent = this; - member->path.setFile(pathname); + member->path.set(pathname); member->info.fileSize = MemberSize; member->info.modTime.fromEpochTime(atoi(Hdr->date)); unsigned int mode; diff --git a/lib/Bytecode/Archive/ArchiveWriter.cpp b/lib/Bytecode/Archive/ArchiveWriter.cpp index be80b973c7..1318471530 100644 --- a/lib/Bytecode/Archive/ArchiveWriter.cpp +++ b/lib/Bytecode/Archive/ArchiveWriter.cpp @@ -450,17 +450,17 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress){ // Close up shop FinalFile.close(); arch.close(); - TmpArchive.destroyFile(); + TmpArchive.destroy(); } else { // We don't have to insert the symbol table, so just renaming the temp // file to the correct name will suffice. - TmpArchive.renameFile(archPath); + TmpArchive.rename(archPath); } } catch (...) { // Make sure we clean up. if (TmpArchive.exists()) - TmpArchive.destroyFile(); + TmpArchive.destroy(); throw; } } diff --git a/lib/Debugger/ProgramInfo.cpp b/lib/Debugger/ProgramInfo.cpp index 144cfeb2b3..b55606bd64 100644 --- a/lib/Debugger/ProgramInfo.cpp +++ b/lib/Debugger/ProgramInfo.cpp @@ -172,8 +172,8 @@ SourceFile &SourceFileInfo::getSourceText() const { if (SourceText == 0) { // Read the file in if we haven't already. sys::Path tmpPath; if (!Directory.empty()) - tmpPath.setDirectory(Directory); - tmpPath.appendFile(BaseName); + tmpPath.set(Directory); + tmpPath.appendComponent(BaseName); if (tmpPath.canRead()) SourceText = new SourceFile(tmpPath.toString(), Descriptor); else diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 23ba6ebf58..d20044fa3c 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -899,7 +899,7 @@ Linker::LinkModules(Module *Dest, Module *Src, std::string *ErrorMsg) { // If the source library's module id is in the dependent library list of the // destination library, remove it since that module is now linked in. sys::Path modId; - modId.setFile(Src->getModuleIdentifier()); + modId.set(Src->getModuleIdentifier()); if (!modId.isEmpty()) Dest->removeLibrary(modId.getBasename()); diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index 3371740393..c72f1b5aca 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -69,7 +69,6 @@ Linker::verbose(const std::string& message) { void Linker::addPath(const sys::Path& path) { - assert(path.isDirectory() && "Can only insert directories into the path"); LibPaths.push_back(path); } @@ -77,7 +76,7 @@ void Linker::addPaths(const std::vector<std::string>& paths) { for (unsigned i = 0; i != paths.size(); ++i) { sys::Path aPath; - aPath.setDirectory(paths[i]); + aPath.set(paths[i]); LibPaths.push_back(aPath); } } @@ -118,26 +117,35 @@ Linker::LoadObject(const sys::Path &FN) { static inline sys::Path IsLibrary(const std::string& Name, const sys::Path& Directory) { - assert(Directory.isDirectory() && "Need to specify a directory"); sys::Path FullPath(Directory); - FullPath.appendFile("lib" + Name); - FullPath.appendSuffix("a"); - if (FullPath.isArchive()) - return FullPath; + // Make sure the directory actually is a directory in the file system. + if (FullPath.isDirectory()) + { + // Try the libX.a form + FullPath.appendComponent("lib" + Name); + FullPath.appendSuffix("a"); + if (FullPath.isArchive()) + return FullPath; + + // Try the libX.bca form + FullPath.eraseSuffix(); + FullPath.appendSuffix("bca"); + if (FullPath.isArchive()) + return FullPath; - FullPath.elideSuffix(); - FullPath.appendSuffix("bca"); - if (FullPath.isArchive()) - return FullPath; + // Try the libX.so form + FullPath.eraseSuffix(); + FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1])); + if (FullPath.isDynamicLibrary()) // Native shared library? + return FullPath; + if (FullPath.isBytecodeFile()) // .so file containing bytecode? + return FullPath; - FullPath.elideSuffix(); - FullPath.appendSuffix(&(LTDL_SHLIB_EXT[1])); - if (FullPath.isDynamicLibrary()) // Native shared library? - return FullPath; - if (FullPath.isBytecodeFile()) // .so file containing bytecode? - return FullPath; + // Not found .. fall through + } + // Indicate that the library was not found in the directory. FullPath.clear(); return FullPath; } diff --git a/lib/Support/SystemUtils.cpp b/lib/Support/SystemUtils.cpp index 77c97f3111..88c3515920 100644 --- a/lib/Support/SystemUtils.cpp +++ b/lib/Support/SystemUtils.cpp @@ -45,9 +45,9 @@ sys::Path llvm::FindExecutable(const std::string &ExeName, // if ProgramPath contains at least one / character, indicating that it is a // relative path to bugpoint itself. sys::Path Result ( ProgramPath ); - Result.elideFile(); + Result.eraseComponent(); if (!Result.isEmpty()) { - Result.appendFile(ExeName); + Result.appendComponent(ExeName); if (Result.canExecute()) return Result; } diff --git a/lib/Support/ToolRunner.cpp b/lib/Support/ToolRunner.cpp index 9ef14c5677..4a08e1adc7 100644 --- a/lib/Support/ToolRunner.cpp +++ b/lib/Support/ToolRunner.cpp @@ -65,7 +65,7 @@ static void ProcessFailure(sys::Path ProgPath, const char** Args) { ErrorFile.close(); } - ErrorFilename.destroyFile(); + ErrorFilename.destroy(); throw ToolExecutionError(OS.str()); } @@ -176,7 +176,7 @@ void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) { void LLC::compileProgram(const std::string &Bytecode) { sys::Path OutputAsmFile; OutputAsm(Bytecode, OutputAsmFile); - OutputAsmFile.destroyFile(); + OutputAsmFile.destroy(); } int LLC::ExecuteProgram(const std::string &Bytecode, @@ -321,7 +321,7 @@ void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) { void CBE::compileProgram(const std::string &Bytecode) { sys::Path OutputCFile; OutputC(Bytecode, OutputCFile); - OutputCFile.destroyFile(); + OutputCFile.destroy(); } int CBE::ExecuteProgram(const std::string &Bytecode, diff --git a/lib/System/Path.cpp b/lib/System/Path.cpp index d2566fd06a..9ee0a3e852 100644 --- a/lib/System/Path.cpp +++ b/lib/System/Path.cpp @@ -27,7 +27,7 @@ Path Path::GetLLVMConfigDir() { Path result; #ifdef LLVM_ETCDIR - if (result.setDirectory(LLVM_ETCDIR)) + if (result.set(LLVM_ETCDIR)) return result; #endif return GetLLVMDefaultConfigDir(); @@ -80,10 +80,10 @@ Path::FindLibrary(std::string& name) { GetSystemLibraryPaths(LibPaths); for (unsigned i = 0; i < LibPaths.size(); ++i) { sys::Path FullPath(LibPaths[i]); - FullPath.appendFile("lib" + name + LTDL_SHLIB_EXT); + FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT); if (FullPath.isDynamicLibrary()) return FullPath; - FullPath.elideSuffix(); + FullPath.eraseSuffix(); FullPath.appendSuffix("a"); if (FullPath.isArchive()) return FullPath; diff --git a/lib/System/Unix/Path.inc b/lib/System/Unix/Path.inc index f871adb2c7..ffcd6949b5 100644 --- a/lib/System/Unix/Path.inc +++ b/lib/System/Unix/Path.inc @@ -84,7 +84,7 @@ Path::isValid() const { Path Path::GetRootDirectory() { Path result; - result.setDirectory("/"); + result.set("/"); return result; } @@ -98,7 +98,7 @@ Path::GetTemporaryDirectory() { if (0 == mkdtemp(pathname)) ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkdtemp didn't create a valid pathname!"); return result; #elif defined(HAVE_MKSTEMP) @@ -117,7 +117,7 @@ Path::GetTemporaryDirectory() { if (-1 == ::mkdir(pathname, S_IRWXU)) // end race condition ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkstemp didn't create a valid pathname!"); return result; #elif defined(HAVE_MKTEMP) @@ -134,7 +134,7 @@ Path::GetTemporaryDirectory() { if (-1 == ::mkdir(TmpName, S_IRWXU)) ThrowErrno(std::string(TmpName) + ": can't create temporary directory"); Path result; - result.setDirectory(TmpName); + result.set(TmpName); assert(result.isValid() && "mktemp didn't create a valid pathname!"); return result; #else @@ -155,7 +155,7 @@ Path::GetTemporaryDirectory() { if (-1 == ::mkdir(pathname, S_IRWXU)) ThrowErrno(std::string(pathname) + ": can't create temporary directory"); Path result; - result.setDirectory(pathname); + result.set(pathname); assert(result.isValid() && "mkstemp didn't create a valid pathname!"); return result; #endif @@ -167,14 +167,14 @@ static void getPathList(const char*path, std::vector<sys::Path>& Paths) { Path tmpPath; while( delim != 0 ) { std::string tmp(at, size_t(delim-at)); - if (tmpPath.setDirectory(tmp)) + if (tmpPath.set(tmp)) if (tmpPath.canRead()) Paths.push_back(tmpPath); at = delim + 1; delim = strchr(at, ':'); } if (*at != 0) - if (tmpPath.setDirectory(std::string(at))) + if (tmpPath.set(std::string(at))) if (tmpPath.canRead()) Paths.push_back(tmpPath); @@ -204,7 +204,7 @@ Path::GetBytecodeLibraryPaths(std::vector<sys::Path>& Paths) { #ifdef LLVM_LIBDIR { Path tmpPath; - if (tmpPath.setDirectory(LLVM_LIBDIR)) + if (tmpPath.set(LLVM_LIBDIR)) if (tmpPath.canRead()) Paths.push_back(tmpPath); } @@ -222,7 +222,7 @@ Path::GetUserHomeDirectory() { const char* home = getenv("HOME"); if (home) { Path result; - if (result.setDirectory(home)) + if (result.set(home)) return result; } return GetRootDirectory(); @@ -230,12 +230,20 @@ Path::GetUserHomeDirectory() { bool Path::isFile() const { - return (isValid() && path[path.length()-1] != '/'); + struct stat buf; + if (0 != stat(path.c_str(), &buf)) { + ThrowErrno(path + ": can't determine type of path object: "); + } + return S_ISREG(buf.st_mode); } bool Path::isDirectory() const { - return (isValid() && path[path.length()-1] == '/'); + struct stat buf; + if (0 != stat(path.c_str(), &buf)) { + ThrowErrno(path + ": can't determine type of path object: "); + } + return S_ISDIR(buf.st_mode); } std::string @@ -357,8 +365,6 @@ Path::getStatusInfo(StatusInfo& info) const { info.user = buf.st_uid; info.group = buf.st_gid; info.isDir = S_ISDIR(buf.st_mode); - if (info.isDir && path[path.length()-1] != '/') - path += '/'; } static bool AddPermissionBits(const std::string& Filename, int bits) { @@ -419,8 +425,6 @@ Path::getDirectoryContents(std::set<Path>& result) const { ThrowErrno(aPath.path + ": can't determine file object type", stat_errno); } - if (S_ISDIR(buf.st_mode)) - aPath.path += "/"; result.insert(aPath); } } @@ -430,124 +434,84 @@ Path::getDirectoryContents(std::set<Path>& result) const { } bool -Path::setDirectory(const std::string& a_path) { - if (a_path.size() == 0) +Path::set(const std::string& a_path) { + if (a_path.empty()) return false; - Path save(*this); + std::string save(path); path = a_path; - size_t last = a_path.size() -1; - if (a_path[last] != '/') - path += '/'; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::setFile(const std::string& a_path) { - if (a_path.size() == 0) - return false; - Path save(*this); - path = a_path; - size_t last = a_path.size() - 1; - while (last > 0 && a_path[last] == '/') - last--; - path.erase(last+1); - if (!isValid()) { - path = save.path; +Path::appendComponent(const std::string& name) { + if (name.empty()) return false; + std::string save(path); + if (!path.empty()) { + size_t last = path.size() - 1; + if (path[last] != '/') + path += '/'; } - return true; -} - -bool -Path::appendDirectory(const std::string& dir) { - if (isFile()) - return false; - Path save(*this); - path += dir; - path += "/"; + path += name; if (!isValid()) { - path = save.path; + path = save; return false; } return true; } bool -Path::elideDirectory() { - if (isFile()) - return false; +Path::eraseComponent() { size_t slashpos = path.rfind('/',path.size()); - if (slashpos == 0 || slashpos == std::string::npos) - return false; + if (slashpos == 0 || slashpos == std::string::npos) { + path.erase(); + return true; + } if (slashpos == path.size() - 1) slashpos = path.rfind('/',slashpos-1); - if (slashpos == std::string::npos) - return false; - path.erase(slashpos); - 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; + if (slashpos == std::string::npos) { + path.erase(); + return true; } - 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); + path.erase(slashpos); return true; } bool Path::appendSuffix(const std::string& suffix) { - if (isDirectory()) - return false; - Path save(*this); + std::string save(path); path.append("."); path.append(suffix); if (!isValid()) { - path = save.path; + path = save; return false; } return true; } -bool -Path::elideSuffix() { - if (isDirectory()) return false; +bool +Path::eraseSuffix() { + std::string save(path); size_t dotpos = 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 && dotpos > slashpos) { path.erase(dotpos, path.size()-dotpos); - return true; } - return false; + if (!isValid()) { + path = save; + return false; + } + return true; } - bool 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 char pathname[MAXPATHLEN]; path.copy(pathname,MAXPATHLEN); @@ -586,9 +550,6 @@ Path::createDirectory( bool create_parents) { bool Path::createFile() { - // Make sure we're dealing with a file - if (!isFile()) return false; - // Create the file int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR); if (fd < 0) @@ -600,10 +561,6 @@ Path::createFile() { bool Path::createTemporaryFile(bool reuse_current) { - // Make sure we're dealing with a file - if (!isFile()) - return false; - // Make this into a unique file name makeUnique( reuse_current ); @@ -617,45 +574,38 @@ Path::createTemporaryFile(bool reuse_current) { } bool -Path::destroyDirectory(bool remove_contents) const { +Path::destroy(bool remove_contents) const { // Make sure we're dealing with a directory - if (!isDirectory()) return false; - - // If it doesn't exist, we're done. - if (!exists()) return true; - - if (remove_contents) { - // Recursively descend the directory to remove its content - std::string cmd("/bin/rm -rf "); - cmd += path; - system(cmd.c_str()); - } else { - // Otherwise, try to just remove the one directory - char pathname[MAXPATHLEN]; - path.copy(pathname,MAXPATHLEN); - int lastchar = path.length() - 1 ; - if (pathname[lastchar] == '/') - pathname[lastchar] = 0; - else - pathname[lastchar+1] = 0; - if ( 0 != rmdir(pathname)) - ThrowErrno(std::string(pathname) + ": can't destroy directory"); + if (isFile()) { + if (0 != unlink(path.c_str())) + ThrowErrno(path + ": can't destroy file"); + } else if (isDirectory()) { + if (remove_contents) { + // Recursively descend the directory to remove its content + std::string cmd("/bin/rm -rf "); + cmd += path; + system(cmd.c_str()); + } else { + // Otherwise, try to just remove the one directory + char pathname[MAXPATHLEN]; + path.copy(pathname,MAXPATHLEN); + int lastchar = path.length() - 1 ; + if (pathname[lastchar] == '/') + pathname[lastchar] = 0; + else + pathname[lastchar+1] = 0; + if ( 0 != rmdir(pathname)) + ThrowErrno(std::string(pathname) + ": can't destroy directory"); + } } + else + return false; return true; } bool -Path::destroyFile() const { - if (!isFile()) return false; - if (0 != unlink(path.c_str())) - ThrowErrno(path + ": can't destroy file"); - return true; -} - -bool -Path::renameFile(const Path& newName) { - if (!isFile()) return false; - if (0 != rename(path.c_str(), newName.c_str())) +Path::rename(const Path& newName) { + if (0 != ::rename(path.c_str(), newName.c_str())) ThrowErrno(std::string("can't rename '") + path + "' as '" + newName.toString() + "' "); return true; @@ -663,7 +613,6 @@ Path::renameFile(const Path& newName) { bool Path::setStatusInfo(const StatusInfo& si) const { - if (!isFile()) return false; struct utimbuf utb; utb.actime = si.modTime.toPosixTime(); utb.modtime = utb.actime; diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc index 774bd02e88..8aa0705726 100644 --- a/lib/System/Unix/Program.inc +++ b/lib/System/Unix/Program.inc @@ -42,7 +42,7 @@ Program::FindProgramByName(const std::string& progName) { if (progName.length() == 0) // no program return Path(); Path temp; - if (!temp.setFile(progName)) // invalid name + if (!temp.set(progName)) // invalid name return Path(); // FIXME: have to check for absolute filename - we cannot assume anything // about "." being in $PATH @@ -64,8 +64,8 @@ Program::FindProgramByName(const std::string& progName) { // Check to see if this first directory contains the executable... Path FilePath; - if (FilePath.setDirectory(std::string(PathStr,Colon))) { - FilePath.appendFile(progName); + if (FilePath.set(std::string(PathStr,Colon))) { + FilePath.appendComponent(progName); if (FilePath.canExecute()) return FilePath; // Found the executable! } diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc index d02d2007c5..ce5b94b947 100644 --- a/lib/System/Unix/Signals.inc +++ b/lib/System/Unix/Signals.inc @@ -112,7 +112,7 @@ RETSIGTYPE SignalHandler(int Sig) { if (DirectoriesToRemove != 0) while (!DirectoriesToRemove->empty()) { - DirectoriesToRemove->back().destroyDirectory(true); + DirectoriesToRemove->back().destroy(true); DirectoriesToRemove->pop_back(); } diff --git a/lib/System/Win32/Path.inc b/lib/System/Win32/Path.inc index b9132da7f7..6c80834ad7 100644 --- a/lib/System/Win32/Path.inc +++ b/lib/System/Win32/Path.inc @@ -195,12 +195,18 @@ Path::GetUserHomeDirectory() { bool Path::isFile() const { - return (isValid() && path[path.length()-1] != '/'); + WIN32_FILE_ATTRIBUTE_DATA fi; + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + ThrowError(std::string(path) + ": Can't get status: "); + return fi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL; } bool Path::isDirectory() const { - return (isValid() && path[path.length()-1] == '/'); + WIN32_FILE_ATTRIBUTE_DATA fi; + if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) + ThrowError(std::string(path) + ": Can't get status: "); + return fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; } std::string |