[Scummvm-cvs-logs] SF.net SVN: scummvm:[34272] scummvm/trunk

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Tue Sep 2 13:32:39 CEST 2008


Revision: 34272
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34272&view=rev
Author:   fingolfin
Date:     2008-09-02 11:32:38 +0000 (Tue, 02 Sep 2008)

Log Message:
-----------
Added two new global funcs which ease proper handling of 'path' strings: Common::lastPathComponent() and Common::normalizePath()

Modified Paths:
--------------
    scummvm/trunk/common/str.cpp
    scummvm/trunk/common/str.h
    scummvm/trunk/test/common/str.h

Modified: scummvm/trunk/common/str.cpp
===================================================================
--- scummvm/trunk/common/str.cpp	2008-09-02 08:02:40 UTC (rev 34271)
+++ scummvm/trunk/common/str.cpp	2008-09-02 11:32:38 UTC (rev 34272)
@@ -524,4 +524,71 @@
 	return rtrim(ltrim(t));
 }
 
+Common::String lastPathComponent(const Common::String &path, const char sep) {
+	const char *str = path.c_str();
+	const char *last = str + path.size();
+
+	// Skip over trailing slashes
+	while (last > str && *(last-1) == sep)
+		--last;
+
+	// Path consisted of only slashes -> return empty string
+	if (last == str)
+		return Common::String();
+	
+	// Now scan the whole component
+	const char *first = last - 1;
+	while (first >= str && *first != sep)
+		--first;
+	
+	if (*first == sep)
+		first++;
+
+	return Common::String(first, last);
+}
+
+Common::String normalizePath(const Common::String &path, const char sep) {
+	if (path.empty())
+		return path;
+
+	const char *cur = path.c_str();
+	Common::String result;
+
+	// If there is a leading slash, preserve that:
+	if (*cur == sep) {
+		result += sep;
+		while (*cur == sep)
+			++cur;
+	}
+	
+	// Scan till the end of the String
+	while (*cur != 0) {
+		const char *start = cur;
+		
+		// Scan till the next path separator resp. the end of the string
+		while (*cur != sep && *cur != 0)
+			cur++;
+		
+		const Common::String component(start, cur);
+
+		// Skip empty components and dot components, add all others
+		if (!component.empty() && component != ".") {
+			// Add a separator before the component, unless the result
+			// string already ends with one (which happens only if the
+			// path *starts* with a separator).
+			if (!result.empty() && result.lastChar() != sep)
+				result += sep;
+
+			// Add the component
+			result += component;
+		}
+
+		// Skip over separator chars
+		while (*cur == sep)
+			cur++;
+	}
+
+	return result;
+}
+
 }	// End of namespace Common

Modified: scummvm/trunk/common/str.h
===================================================================
--- scummvm/trunk/common/str.h	2008-09-02 08:02:40 UTC (rev 34271)
+++ scummvm/trunk/common/str.h	2008-09-02 11:32:38 UTC (rev 34272)
@@ -227,6 +227,38 @@
 extern char *rtrim(char *t);
 extern char *trim(char *t);
 
+
+/**
+ * Returns the last component of a given path.
+ *
+ * Examples:
+ *			/foo/bar.txt would return 'bar.txt'
+ *			/foo/bar/    would return 'bar'
+ *			/foo/./bar//    would return 'bar'
+ *
+ * @param path the path of which we want to know the last component
+ * @param sep character used to separate path components
+ * @return The last component of the path.
+ */
+Common::String lastPathComponent(const Common::String &path, const char sep);
+
+/**
+ * Normalize a gien path to a canonical form. In particular:
+ * - trailing separators are removed:  /foo/bar/ -> /foo/bar
+ * - double separators (= empty components) are removed:   /foo//bar -> /foo/bar
+ * - dot components are removed:  /foo/./bar -> /foo/bar
+ *
+ * @todo remove double dot components:  /foo/baz/../bar -> /foo/bar
+ *
+ * @param path	the path to normalize
+ * @param sep	the separator token (usually '/' on Unix-style systems, or '\\' on Windows based stuff)
+ * @return	the normalized path
+ */
+Common::String normalizePath(const Common::String &path, const char sep);
+
+
+
+
 class StringList : public Array<String> {
 public:
 	void push_back(const char *str) {

Modified: scummvm/trunk/test/common/str.h
===================================================================
--- scummvm/trunk/test/common/str.h	2008-09-02 08:02:40 UTC (rev 34271)
+++ scummvm/trunk/test/common/str.h	2008-09-02 11:32:38 UTC (rev 34272)
@@ -157,4 +157,36 @@
 		TS_ASSERT_EQUALS(str, "TEST IT, NOW! 42");
 		TS_ASSERT_EQUALS(str2, "Test it, NOW! 42");
 	}
+
+	void test_lastPathComponent(void) {
+		TS_ASSERT(Common::lastPathComponent("/", '/') == "");
+		TS_ASSERT(Common::lastPathComponent("/foo/bar", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("/foo//bar/", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("/foo/./bar", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("/foo//./bar//", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("/foo//.bar//", '/') == ".bar");
+
+		TS_ASSERT(Common::lastPathComponent("", '/') == "");
+		TS_ASSERT(Common::lastPathComponent("foo/bar", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("foo//bar/", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("foo/./bar", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("foo//./bar//", '/') == "bar");
+		TS_ASSERT(Common::lastPathComponent("foo//.bar//", '/') == ".bar");
+	}
+
+	void test_normalizePath(void) {
+		TS_ASSERT(Common::normalizePath("/", '/') == "/");
+		TS_ASSERT(Common::normalizePath("/foo/bar", '/') == "/foo/bar");
+		TS_ASSERT(Common::normalizePath("/foo//bar/", '/') == "/foo/bar");
+		TS_ASSERT(Common::normalizePath("/foo/./bar", '/') == "/foo/bar");
+		TS_ASSERT(Common::normalizePath("/foo//./bar//", '/') == "/foo/bar");
+		TS_ASSERT(Common::normalizePath("/foo//.bar//", '/') == "/foo/.bar");
+
+		TS_ASSERT(Common::normalizePath("", '/') == "");
+		TS_ASSERT(Common::normalizePath("foo/bar", '/') == "foo/bar");
+		TS_ASSERT(Common::normalizePath("foo//bar/", '/') == "foo/bar");
+		TS_ASSERT(Common::normalizePath("foo/./bar", '/') == "foo/bar");
+		TS_ASSERT(Common::normalizePath("foo//./bar//", '/') == "foo/bar");
+		TS_ASSERT(Common::normalizePath("foo//.bar//", '/') == "foo/.bar");
+	}
 };


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list