diff options
author | Le Philousophe | 2019-10-20 17:37:18 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2019-11-03 00:44:23 +0100 |
commit | d62bb15d718678f64ac3c3a3866e6411eaa7bfec (patch) | |
tree | 023cb0ef9874fd7a82550e1fd9ddfef9273f287a | |
parent | b6132fec03360a53dd8f6dd683d4247958276492 (diff) | |
download | scummvm-rg350-d62bb15d718678f64ac3c3a3866e6411eaa7bfec.tar.gz scummvm-rg350-d62bb15d718678f64ac3c3a3866e6411eaa7bfec.tar.bz2 scummvm-rg350-d62bb15d718678f64ac3c3a3866e6411eaa7bfec.zip |
COMMON: Add ignoreClashes flag to SearchSet and FSDirectory
This lets engine mute warnings about name clashes when there are useless
for its case. This will be used by Versailles as the tree has
directories with the same name at various places.
Files are duplicated too in different directories but are identical.
-rw-r--r-- | common/archive.cpp | 2 | ||||
-rw-r--r-- | common/archive.h | 9 | ||||
-rw-r--r-- | common/fs.cpp | 42 | ||||
-rw-r--r-- | common/fs.h | 29 |
4 files changed, 57 insertions, 25 deletions
diff --git a/common/archive.cpp b/common/archive.cpp index 7e189654a6..586f3c4fd1 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -115,7 +115,7 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority if (!dir.exists() || !dir.isDirectory()) return; - add(name, new FSDirectory(dir, depth, flat), priority); + add(name, new FSDirectory(dir, depth, flat, _ignoreClashes), priority); } void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String origPattern, bool ignoreCase, int priority, int depth, bool flat) { diff --git a/common/archive.h b/common/archive.h index d76d0c4966..2cf7555371 100644 --- a/common/archive.h +++ b/common/archive.h @@ -152,7 +152,10 @@ class SearchSet : public Archive { // Add an archive keeping the list sorted by descending priority. void insert(const Node& node); + bool _ignoreClashes; + public: + SearchSet() : _ignoreClashes(false) { } virtual ~SearchSet() { clear(); } /** @@ -247,6 +250,12 @@ public: * opening the first file encountered that matches the name. */ virtual SeekableReadStream *createReadStreamForMember(const String &name) const; + + /** + * Ignore clashes when adding directories. For more details see the corresponding parameter + * in FSDirectory documentation + */ + void setIgnoreClashes(bool ignoreClashes) { _ignoreClashes = ignoreClashes; } }; diff --git a/common/fs.cpp b/common/fs.cpp index d27de48370..89c19aaaab 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -168,22 +168,24 @@ bool FSNode::createDirectory() const { return _realNode->createDirectory(); } -FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat) - : _node(node), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat, bool ignoreClashes) + : _node(node), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { } -FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat) - : _node(node), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat, + bool ignoreClashes) + : _node(node), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { setPrefix(prefix); } -FSDirectory::FSDirectory(const String &name, int depth, bool flat) - : _node(name), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const String &name, int depth, bool flat, bool ignoreClashes) + : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { } -FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat) - : _node(name), _cached(false), _depth(depth), _flat(flat) { +FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat, + bool ignoreClashes) + : _node(name), _cached(false), _depth(depth), _flat(flat), _ignoreClashes(ignoreClashes) { setPrefix(prefix); } @@ -253,11 +255,12 @@ SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) c return stream; } -FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat) { - return getSubDirectory(String(), name, depth, flat); +FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat, bool ignoreClashes) { + return getSubDirectory(String(), name, depth, flat, ignoreClashes); } -FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth, bool flat) { +FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth, + bool flat, bool ignoreClashes) { if (name.empty() || !_node.isDirectory()) return nullptr; @@ -265,7 +268,7 @@ FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &na if (!node) return nullptr; - return new FSDirectory(prefix, *node, depth, flat); + return new FSDirectory(prefix, *node, depth, flat, ignoreClashes); } void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const { @@ -286,17 +289,26 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& // since the hashmap is case insensitive, we need to check for clashes when caching if (it->isDirectory()) { if (!_flat && _subDirCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str()); + // Always warn in this case as it's when there are 2 directories at the same place with different case + // That means a problem in user installation as lookups are always done case insensitive + warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", + name.c_str()); } else { if (_subDirCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", name.c_str()); + if (!_ignoreClashes) { + warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", + name.c_str()); + } } cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + "/"); _subDirCache[lowercaseName] = *it; } } else { if (_fileCache.contains(lowercaseName)) { - warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", name.c_str()); + if (!_ignoreClashes) { + warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring file '%s'", + name.c_str()); + } } else { _fileCache[lowercaseName] = *it; } diff --git a/common/fs.h b/common/fs.h index 7041428fc8..718f47ff56 100644 --- a/common/fs.h +++ b/common/fs.h @@ -267,6 +267,12 @@ public: * are cached without the relative path, so in the example above * c:\my\data\file.ext would be cached as file.ext. * + * When the 'ignoreClashes' argument to the constructor is true, name clashes are + * expected by the engine. It means that files which clash should be identical and + * getSubDirectory shouldn't be used on clashing directories. This flag is useful + * in flat mode when there are directories with same name at different places in the + * tree whose name isn't relevant for the engine code. + * * Client code can customize cache by using the constructors with the 'prefix' * parameter. In this case, the prefix is prepended to each entry in the cache, * and effectively treated as a 'virtual' parent subdirectory. FSDirectory adds @@ -276,7 +282,10 @@ public: * */ class FSDirectory : public Archive { - FSNode _node; + FSNode _node; + int _depth; + bool _flat; + bool _ignoreClashes; String _prefix; // string that is prepended to each cache item key void setPrefix(const String &prefix); @@ -286,8 +295,6 @@ class FSDirectory : public Archive { typedef HashMap<String, FSNode, IgnoreCase_Hash, IgnoreCase_EqualTo> NodeCache; mutable NodeCache _fileCache, _subDirCache; mutable bool _cached; - mutable int _depth; - mutable bool _flat; // look for a match FSNode *lookupCache(NodeCache &cache, const String &name) const; @@ -304,17 +311,19 @@ public: * unbound FSDirectory if name is not found on the filesystem or if the node is not a * valid directory. */ - FSDirectory(const String &name, int depth = 1, bool flat = false); - FSDirectory(const FSNode &node, int depth = 1, bool flat = false); + FSDirectory(const String &name, int depth = 1, bool flat = false, + bool ignoreClashes = false); + FSDirectory(const FSNode &node, int depth = 1, bool flat = false, + bool ignoreClashes = false); /** * Create a FSDirectory representing a tree with the specified depth. The parameter * prefix is prepended to the keys in the cache. See class comment. */ FSDirectory(const String &prefix, const String &name, int depth = 1, - bool flat = false); + bool flat = false, bool ignoreClashes = false); FSDirectory(const String &prefix, const FSNode &node, int depth = 1, - bool flat = false); + bool flat = false, bool ignoreClashes = false); virtual ~FSDirectory(); @@ -328,8 +337,10 @@ public: * for an explanation of the prefix parameter. * @return a new FSDirectory instance */ - FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false); - FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1, bool flat = false); + FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false, + bool ignoreClashes = false); + FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1, + bool flat = false, bool ignoreClashes = false); /** * Checks for existence in the cache. A full match of relative path and filename is needed |