diff options
author | Max Horn | 2008-09-02 15:19:31 +0000 |
---|---|---|
committer | Max Horn | 2008-09-02 15:19:31 +0000 |
commit | c752e5fcfa0cd087184062b784c8361fa6c345c9 (patch) | |
tree | b54c3d7c57e8b0685a2d8154ade9c11cd44e9b2b /backends | |
parent | ced14e186eaf41a78b5390645b1043b9fcea9cbe (diff) | |
download | scummvm-rg350-c752e5fcfa0cd087184062b784c8361fa6c345c9.tar.gz scummvm-rg350-c752e5fcfa0cd087184062b784c8361fa6c345c9.tar.bz2 scummvm-rg350-c752e5fcfa0cd087184062b784c8361fa6c345c9.zip |
Modified POSIX FSNode implementation to use Common::normalizePath & Common::lastPathComponent; added a TODO regarding relative paths
svn-id: r34283
Diffstat (limited to 'backends')
-rw-r--r-- | backends/fs/posix/posix-fs.cpp | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index 5cd6a909d6..44723c8e6e 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -25,6 +25,7 @@ #if defined(UNIX) #include "backends/fs/posix/posix-fs.h" +#include "common/algorithm.h" #include <sys/param.h> #include <sys/stat.h> @@ -46,8 +47,7 @@ void POSIXFilesystemNode::setFlags() { POSIXFilesystemNode::POSIXFilesystemNode() { // The root dir. - _path = "/"; - _displayName = _path; + _displayName = _path = "/"; _isValid = true; _isDirectory = true; } @@ -67,8 +67,28 @@ POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p, bool verify) { } else { _path = p; } - - _displayName = lastPathComponent(_path, '/'); + + // Normalize the path (that is, remove unneeded slashes etc.) + _path = Common::normalizePath(_path, '/'); + _displayName = Common::lastPathComponent(_path, '/'); + + // TODO: should we turn relative paths into absolut ones? + // Pro: Ensures the "getParent" works correctly even for relative dirs. + // Contra: The user may wish to use (and keep!) relative paths in his + // config file, and converting relative to absolute paths may hurt him... + // + // An alternative approach would be to change getParent() to work correctly + // if "_path" is the empty string. +#if 0 + if (!_path.hasPrefix("/")) { + char buf[MAXPATHLEN+1]; + getcwd(buf, MAXPATHLEN); + strcat(buf, "/"); + _path = buf + _path; + } +#endif + // TODO: Should we enforce that the path is absolute at this point? + //assert(_path.hasPrefix("/")); if (verify) { setFlags(); @@ -76,13 +96,15 @@ POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p, bool verify) { } AbstractFilesystemNode *POSIXFilesystemNode::getChild(const Common::String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. assert(_isDirectory); + + // Make sure the string contains no slashes + assert(Common::find(n.begin(), n.end(), '/') == n.end()); + // We assume here that _path is already normalized (hence don't bother to call + // Common::normalizePath on the final path Common::String newPath(_path); - if (_path.lastChar() != '/') - newPath += '/'; + newPath += '/'; newPath += n; return new POSIXFilesystemNode(newPath, true); @@ -92,35 +114,36 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo assert(_isDirectory); #ifdef __OS2__ - if (_path == "/") { - ULONG ulDrvNum; - ULONG ulDrvMap; - - DosQueryCurrentDisk(&ulDrvNum, &ulDrvMap); - - for (int i = 0; i < 26; i++) { - if (ulDrvMap & 1) { - char drive_root[4]; - - drive_root[0] = i + 'A'; - drive_root[1] = ':'; - drive_root[2] = '/'; - drive_root[3] = 0; - - POSIXFilesystemNode entry; - - entry._isDirectory = true; - entry._isValid = true; - entry._path = drive_root; - entry._displayName = "[" + Common::String(drive_root, 2) + "]"; - myList.push_back(new POSIXFilesystemNode(entry)); - } - - ulDrvMap >>= 1; - } - - return true; - } + if (_path == "/") { + // Special case for the root dir: List all DOS drives + ULONG ulDrvNum; + ULONG ulDrvMap; + + DosQueryCurrentDisk(&ulDrvNum, &ulDrvMap); + + for (int i = 0; i < 26; i++) { + if (ulDrvMap & 1) { + char drive_root[4]; + + drive_root[0] = i + 'A'; + drive_root[1] = ':'; + drive_root[2] = '/'; + drive_root[3] = 0; + + POSIXFilesystemNode entry; + + entry._isDirectory = true; + entry._isValid = true; + entry._path = drive_root; + entry._displayName = "[" + Common::String(drive_root, 2) + "]"; + myList.push_back(new POSIXFilesystemNode(entry)); + } + + ulDrvMap >>= 1; + } + + return true; + } #endif DIR *dirp = opendir(_path.c_str()); @@ -141,8 +164,7 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo } Common::String newPath(_path); - if (newPath.lastChar() != '/') - newPath += '/'; + newPath += '/'; newPath += dp->d_name; POSIXFilesystemNode entry(newPath, false); @@ -184,9 +206,6 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo (mode == FilesystemNode::kListDirectoriesOnly && !entry._isDirectory)) continue; - if (entry._isDirectory) - entry._path += "/"; - myList.push_back(new POSIXFilesystemNode(entry)); } closedir(dirp); @@ -196,17 +215,20 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo AbstractFilesystemNode *POSIXFilesystemNode::getParent() const { if (_path == "/") - return 0; + return 0; // The filesystem root has no parent const char *start = _path.c_str(); - const char *end = lastPathComponent(_path, '/'); - -#ifdef __OS2__ - if (end == start) - return new POSIXFilesystemNode(); -#endif - - return new POSIXFilesystemNode(Common::String(start, end), true); + const char *end = start + _path.size(); + + // Strip of the last component. We make use of the fact that at this + // point, _path is guaranteed to be normalized + while (end > start && *end != '/') + end--; + + if (end == start) + return new POSIXFilesystemNode(); + else + return new POSIXFilesystemNode(Common::String(start, end), true); } #endif //#if defined(UNIX) |