From 9bf7aa308e4a5cc46e27a8ca9421cc42815c2833 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 5 Sep 2008 20:07:34 +0000 Subject: Moved matchString from util.* to str.*; added new String::matchString method; fixed matchString doxygen comment (it confused pattern & string); added unit tests for matchString svn-id: r34364 --- common/str.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ common/str.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ common/util.cpp | 33 --------------------------------- common/util.h | 22 ---------------------- test/common/str.h | 18 ++++++++++++++++++ 5 files changed, 115 insertions(+), 55 deletions(-) diff --git a/common/str.cpp b/common/str.cpp index f6a2df5b0e..b2c9a7cdbf 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -311,6 +311,14 @@ bool String::contains(char x) const { return strchr(c_str(), x) != NULL; } +bool String::matchString(const char *pat) const { + return Common::matchString(c_str(), pat); +} + +bool String::matchString(const String &pat) const { + return Common::matchString(c_str(), pat.c_str()); +} + void String::deleteLastChar() { deleteChar(_size - 1); } @@ -587,4 +595,40 @@ Common::String normalizePath(const Common::String &path, const char sep) { return result; } +bool matchString(const char *str, const char *pat) { + assert(str); + assert(pat); + + const char *p = 0; + const char *q = 0; + + for (;;) { + switch (*pat) { + case '*': + p = ++pat; + q = str; + break; + + default: + if (*pat != *str) { + if (p) { + pat = p; + str = ++q; + if (!*str) + return !*pat; + break; + } + else + return false; + } + // fallthrough + case '?': + if (!*str) + return !*pat; + pat++; + str++; + } + } +} + } // End of namespace Common diff --git a/common/str.h b/common/str.h index 596bf341f9..20914c1f1f 100644 --- a/common/str.h +++ b/common/str.h @@ -149,6 +149,30 @@ public: bool contains(const char *x) const; bool contains(char x) const; + /** + * Simple DOS-style pattern matching function (understands * and ? like used in DOS). + * Taken from exult/files/listfiles.cc + * + * Token meaning: + * "*": any character, any amount of times. + * "?": any character, only once. + * + * Example strings/patterns: + * String: monkey.s01 Pattern: monkey.s?? => true + * String: monkey.s101 Pattern: monkey.s?? => false + * String: monkey.s99 Pattern: monkey.s?1 => false + * String: monkey.s101 Pattern: monkey.s* => true + * String: monkey.s99 Pattern: monkey.s*1 => false + * + * @param str Text to be matched against the given pattern. + * @param pat Glob pattern. + * + * @return true if str matches the pattern, false otherwise. + */ + bool matchString(const char *pat) const; + bool matchString(const String &pat) const; + + inline const char *c_str() const { return _str; } inline uint size() const { return _size; } @@ -172,11 +196,19 @@ public: /** Set character c at position p. */ void insertChar(char c, uint32 p); + /** Clears the string, making it empty. */ void clear(); + /** Convert all characters in the string to lowercase. */ void toLowercase(); + + /** Convert all characters in the string to uppercase. */ void toUppercase(); + /** + * Removes trailing and leading whitespaces. Uses isspace() to decide + * what is whitespace and what not. + */ void trim(); uint hash() const; @@ -257,6 +289,27 @@ Common::String lastPathComponent(const Common::String &path, const char sep); Common::String normalizePath(const Common::String &path, const char sep); +/** + * Simple DOS-style pattern matching function (understands * and ? like used in DOS). + * Taken from exult/files/listfiles.cc + * + * Token meaning: + * "*": any character, any amount of times. + * "?": any character, only once. + * + * Example strings/patterns: + * String: monkey.s01 Pattern: monkey.s?? => true + * String: monkey.s101 Pattern: monkey.s?? => false + * String: monkey.s99 Pattern: monkey.s?1 => false + * String: monkey.s101 Pattern: monkey.s* => true + * String: monkey.s99 Pattern: monkey.s*1 => false + * + * @param str Text to be matched against the given pattern. + * @param pat Glob pattern. + * + * @return true if str matches the pattern, false otherwise. + */ +bool matchString(const char *str, const char *pat); class StringList : public Array { diff --git a/common/util.cpp b/common/util.cpp index f23a0ee6d6..f68d253ec3 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -63,39 +63,6 @@ extern bool isSmartphone(void); namespace Common { -bool matchString(const char *str, const char *pat) { - const char *p = 0; - const char *q = 0; - - for (;;) { - switch (*pat) { - case '*': - p = ++pat; - q = str; - break; - - default: - if (*pat != *str) { - if (p) { - pat = p; - str = ++q; - if (!*str) - return !*pat; - break; - } - else - return false; - } - // fallthrough - case '?': - if (!*str) - return !*pat; - pat++; - str++; - } - } -} - StringTokenizer::StringTokenizer(const String &str, const String &delimiters) : _str(str), _delimiters(delimiters) { reset(); } diff --git a/common/util.h b/common/util.h index ecfdac33d7..32f07181c4 100644 --- a/common/util.h +++ b/common/util.h @@ -52,28 +52,6 @@ template inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; } namespace Common { -/** - * Simple DOS-style pattern matching function (understands * and ? like used in DOS). - * Taken from exult/files/listfiles.cc - * - * Token meaning: - * "*": any character, any amount of times. - * "?": any character, only once. - * - * Example strings/patterns: - * String: monkey.s?? Pattern: monkey.s01 => true - * String: monkey.s?? Pattern: monkey.s101 => false - * String: monkey.s?1 Pattern: monkey.s99 => false - * String: monkey.s* Pattern: monkey.s101 => true - * String: monkey.s*1 Pattern: monkey.s99 => false - * - * @param str Text to be matched against the given pattern. - * @param pat Glob pattern. - * - * @return true if str matches the pattern, false otherwise. - */ -bool matchString(const char *str, const char *pat); - /** * A simple non-optimized string tokenizer. * diff --git a/test/common/str.h b/test/common/str.h index c4819520d8..921c4614f5 100644 --- a/test/common/str.h +++ b/test/common/str.h @@ -189,4 +189,22 @@ class StringTestSuite : public CxxTest::TestSuite TS_ASSERT(Common::normalizePath("foo//./bar//", '/') == "foo/bar"); TS_ASSERT(Common::normalizePath("foo//.bar//", '/') == "foo/.bar"); } + + void test_matchString(void) { + TS_ASSERT( Common::matchString("monkey.s01", "monkey.s??")); + TS_ASSERT( Common::matchString("monkey.s99", "monkey.s??")); + TS_ASSERT(!Common::matchString("monkey.s101", "monkey.s??")); + + TS_ASSERT( Common::matchString("monkey.s01", "monkey.s?1")); + TS_ASSERT(!Common::matchString("monkey.s99", "monkey.s?1")); + TS_ASSERT(!Common::matchString("monkey.s101", "monkey.s?1")); + + TS_ASSERT( Common::matchString("monkey.s01", "monkey.s*")); + TS_ASSERT( Common::matchString("monkey.s99", "monkey.s*")); + TS_ASSERT( Common::matchString("monkey.s101", "monkey.s*")); + + TS_ASSERT( Common::matchString("monkey.s01", "monkey.s*1")); + TS_ASSERT(!Common::matchString("monkey.s99", "monkey.s*1")); + TS_ASSERT( Common::matchString("monkey.s101", "monkey.s*1")); + } }; -- cgit v1.2.3