aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/archive.cpp2
-rw-r--r--common/archive.h9
-rw-r--r--common/fs.cpp42
-rw-r--r--common/fs.h29
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