]> git.cworth.org Git - apitrace/blobdiff - common/os_string.hpp
Tweak path splitting.
[apitrace] / common / os_string.hpp
index c92e6a88a7ede3fb58b4f39e08e1bae1f7b377ea..c3fcf83396c405595c33e9cec55b69569bf10622 100644 (file)
@@ -110,6 +110,39 @@ protected:
         return &buffer[0];
     }
 
+    inline bool
+    isSep(char c) {
+        if (c == '/') {
+            return true;
+        }
+#ifdef _WIN32
+        if (c == '\\') {
+            return true;
+        }
+#endif
+        return false;
+    }
+
+    Buffer::iterator rfindSep(void) {
+        Buffer::iterator it = buffer.end();
+
+        // Skip trailing separators
+        while (it != buffer.begin() && isSep(*it)) {
+            --it;
+        }
+
+        // Advance to the last separator
+        while (it != buffer.begin()) {
+            if (isSep(*it)) {
+                return it;
+            }
+            --it;
+        }
+
+        return buffer.end();
+    }
+
+
 public:
 
     /*
@@ -280,14 +313,16 @@ public:
 
 
     /*
-     * String manipulation
+     * Path manipulation
      */
 
     bool
     exists(void) const;
 
+    /* Trim directory (leaving base filename).
+     */
     void trimDirectory(void) {
-        iterator sep = rfind(OS_DIR_SEP);
+        iterator sep = rfindSep();
         if (sep != buffer.end()) {
             buffer.erase(buffer.begin(), sep + 1);
         }
@@ -295,27 +330,28 @@ public:
 
     /* Trim filename component (leaving containing directory).
      *
-     * This function removes everything after the final path
-     * separator, as well as that separator itself if it is not the
-     * only remaining separator.
-     *
-     * Some specific consequences of the above:
-     *
-     * 1. A path with no separator at all is unchanged.
-     * 2. A path with a trailing separator has only that separator removed
-     * 3. A path of just the root directory is unchaged.
+     * - trailing separators are ignored
+     * - a path with no separator at all yields "."
+     * - a path consisting of just the root directory is left unchanged
      */
     void trimFilename(void) {
-        iterator first = find(OS_DIR_SEP);
-        iterator last = rfind(OS_DIR_SEP);
-        if (last == buffer.end()) {
+        iterator sep = rfindSep();
+
+        // No separator found, so return '.'
+        if (sep == buffer.end()) {
+            buffer.resize(2);
+            buffer[0] = '.';
+            buffer[1] = 0;
             return;
         }
-        if (last == first) {
-            buffer.erase(first + 1, end());
-        } else {
-            buffer.erase(last, end());
+
+        // Root. Nothing to do.
+        if (sep == buffer.begin()) {
+            return;
         }
+
+        // Trim filename
+        buffer.erase(sep, end());
     }
 
     void trimExtension(void) {