aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/archive.cpp46
-rw-r--r--common/archive.h46
-rw-r--r--common/file.cpp10
-rw-r--r--common/file.h4
4 files changed, 92 insertions, 14 deletions
diff --git a/common/archive.cpp b/common/archive.cpp
index ecc00f4cff..e815b781bf 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -123,6 +123,52 @@ void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority
add(name, new FSDirectory(dir, depth, flat), priority);
}
+void SearchSet::addSubDirectoriesMatching(const FSNode &directory, String pattern, bool ignoreCase, int priority) {
+ FSList subDirs;
+ if (!directory.getChildren(subDirs))
+ return;
+
+ String nextPattern;
+ String::const_iterator sep = Common::find(pattern.begin(), pattern.end(), '/');
+ if (sep != pattern.end()) {
+ pattern = String(pattern.begin(), sep);
+
+ ++sep;
+ if (sep != pattern.end())
+ nextPattern = String(sep, pattern.end());
+ }
+
+ // TODO: The code we have for displaying all matches, which vary only in case, might
+ // be a bit overhead, but as long as we want to display all useful information to the
+ // user we will need to keep track of all directory names added so far. We might
+ // want to reconsider this though.
+ typedef HashMap<String, bool, IgnoreCase_Hash, IgnoreCase_EqualTo> MatchList;
+ MatchList multipleMatches;
+ MatchList::iterator matchIter;
+
+ for (FSList::const_iterator i = subDirs.begin(); i != subDirs.end(); ++i) {
+ String name = i->getName();
+
+ if (Common::matchString(name.c_str(), pattern.c_str(), ignoreCase)) {
+ matchIter = multipleMatches.find(name);
+ if (matchIter == multipleMatches.end()) {
+ multipleMatches[name] = true;
+ } else {
+ if (matchIter->_value) {
+ warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), matchIter->_key.c_str());
+ matchIter->_value = false;
+ }
+
+ warning("Clash in case for match of pattern \"%s\" found in directory \"%s\": \"%s\"", pattern.c_str(), directory.getPath().c_str(), name.c_str());
+ }
+
+ if (nextPattern.empty())
+ addDirectory(name, *i, priority);
+ else
+ addSubDirectoriesMatching(*i, nextPattern, ignoreCase, priority);
+ }
+ }
+}
void SearchSet::remove(const String &name) {
ArchiveNodeList::iterator it = find(name);
diff --git a/common/archive.h b/common/archive.h
index aa13d26d16..39fce497c4 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -169,6 +169,52 @@ public:
void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
/**
+ * Create and add a sub directory by name (caseless).
+ *
+ * It is also possible to add sub directories of sub directories (of any depth) with this function.
+ * The path seperator for this case is SLASH for *all* systems.
+ *
+ * An example would be:
+ *
+ * "game/itedata"
+ *
+ * In this example the code would first try to search for all directories matching
+ * "game" (case insensitive) in the path "directory" first and search through all
+ * of the matches for "itedata" (case insensitive too).
+ *
+ * Note that it will add *all* matches found!
+ *
+ * Even though this method is currently implemented via addSubDirectoriesMatching it is not safe
+ * to assume that this method is using anything other than a simple case insensitive compare.
+ * Thus do not use any tokens like '*' or '?' in the "caselessName" parameter of this function!
+ */
+ void addSubDirectoryMatching(const FSNode &directory, const String &caselessName, int priority = 0) {
+ addSubDirectoriesMatching(directory, caselessName, true, priority);
+ }
+
+ /**
+ * Create and add sub directories by pattern.
+ *
+ * It is also possible to add sub directories of sub directories (of any depth) with this function.
+ * The path seperator for this case is SLASH for *all* systems.
+ *
+ * An example would be:
+ *
+ * "game/itedata"
+ *
+ * In this example the code would first try to search for all directories matching
+ * "game" in the path "directory" first and search through all of the matches for
+ * "itedata". If "ingoreCase" is set to true, the code would do a case insensitive
+ * match, otherwise it is doing a case sensitive match.
+ *
+ * This method works of course also with tokens. For a list of available tokens
+ * see the documentation for Common::matchString.
+ *
+ * @see Common::matchString
+ */
+ void addSubDirectoriesMatching(const FSNode &directory, String pattern, bool ignoreCase, int priority = 0);
+
+ /**
* Remove an archive from the searchable set.
*/
void remove(const String& name);
diff --git a/common/file.cpp b/common/file.cpp
index dd4281bd03..6291aa8855 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -32,16 +32,6 @@
namespace Common {
-void File::addDefaultDirectory(const String &directory) {
- FSNode dir(directory);
- addDefaultDirectory(dir);
-}
-
-void File::addDefaultDirectory(const FSNode &dir) {
- if (dir.exists() && dir.isDirectory())
- SearchMan.addDirectory(dir.getPath(), dir);
-}
-
File::File()
: _handle(0) {
}
diff --git a/common/file.h b/common/file.h
index 6ac633c462..8eb03f1629 100644
--- a/common/file.h
+++ b/common/file.h
@@ -48,10 +48,6 @@ protected:
String _name;
public:
-
- static void addDefaultDirectory(const String &directory);
- static void addDefaultDirectory(const FSNode &directory);
-
File();
virtual ~File();