about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2013-02-19 01:34:48 +0000
committerArmin Ronacher <armin.ronacher@active-4.com>2013-02-19 01:34:48 +0000
commitb07eab5faab16a975df89eae8ea5d7276bc44507 (patch)
treebd5fc46f9b298ebea03ff8c506488648989b7ed9
parentc8d8f6cfec50cad6b35e3b5fc604abc01a26143e (diff)
downloadrust-b07eab5faab16a975df89eae8ea5d7276bc44507.tar.gz
rust-b07eab5faab16a975df89eae8ea5d7276bc44507.zip
Improved windows path handling support
-rw-r--r--src/libcore/path.rs118
1 files changed, 100 insertions, 18 deletions
diff --git a/src/libcore/path.rs b/src/libcore/path.rs
index 46f8743ff15..96a921cf20b 100644
--- a/src/libcore/path.rs
+++ b/src/libcore/path.rs
@@ -697,21 +697,44 @@ impl GenericPath for WindowsPath {
     }
 
     pure fn unsafe_join(other: &WindowsPath) -> WindowsPath {
+        /* rhs not absolute is simple push */
         if !other.is_absolute {
-            self.push_rel(other)
-        } else {
-            WindowsPath {
-                host: match other.host {
-                    None => copy self.host,
-                    Some(copy x) => Some(x)
-                },
-                device: match other.device {
-                    None => copy self.device,
-                    Some(copy x) => Some(x)
-                },
-                is_absolute: true,
-                components: copy other.components
+            return self.push_many(other.components);
+        }
+
+        /* if rhs has a host set, then the whole thing wins */
+        match other.host {
+            Some(copy host) => {
+                return WindowsPath {
+                    host: Some(host),
+                    device: copy other.device,
+                    is_absolute: true,
+                    components: copy other.components
+                };
+            }
+            _ => {}
+        }
+
+        /* if rhs has a device set, then a part wins */
+        match other.device {
+            Some(copy device) => {
+                return WindowsPath {
+                    host: None,
+                    device: Some(device),
+                    is_absolute: true,
+                    components: copy other.components
+                };
             }
+            _ => {}
+        }
+
+        /* fallback: host and device of lhs win, but the
+           whole path of the right */
+        WindowsPath {
+            host: copy self.host,
+            device: copy self.device,
+            is_absolute: self.is_absolute || other.is_absolute,
+            components: copy other.components
         }
     }
 
@@ -755,7 +778,10 @@ impl GenericPath for WindowsPath {
     pure fn normalize() -> WindowsPath {
         return WindowsPath {
             host: copy self.host,
-            device: copy self.device,
+            device: match self.device {
+                None => None,
+                Some(ref device) => Some(device.to_upper())
+            },
             is_absolute: self.is_absolute,
             components: normalize(self.components)
         }
@@ -794,13 +820,13 @@ pub mod windows {
 
     pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
         if (s.len() > 1 &&
-            s[0] == '\\' as u8 &&
-            s[1] == '\\' as u8) {
+            (s[0] == '\\' as u8 || s[0] == '/' as u8) &&
+            s[0] == s[1]) {
             let mut i = 2;
             while i < s.len() {
-                if s[i] == '\\' as u8 {
+                if is_sep(s[i]) {
                     let pre = s.slice(2, i);
-                    let rest = s.slice(i, s.len());
+                    let mut rest = s.slice(i, s.len());
                     return Some((pre, rest));
                 }
                 i += 1;
@@ -946,13 +972,21 @@ mod tests {
     #[test]
     fn test_extract_unc_prefixes() {
         assert windows::extract_unc_prefix("\\\\").is_none();
+        assert windows::extract_unc_prefix("//").is_none();
         assert windows::extract_unc_prefix("\\\\hi").is_none();
+        assert windows::extract_unc_prefix("//hi").is_none();
         assert windows::extract_unc_prefix("\\\\hi\\") ==
             Some((~"hi", ~"\\"));
+        assert windows::extract_unc_prefix("//hi\\") ==
+            Some((~"hi", ~"\\"));
         assert windows::extract_unc_prefix("\\\\hi\\there") ==
             Some((~"hi", ~"\\there"));
+        assert windows::extract_unc_prefix("//hi/there") ==
+            Some((~"hi", ~"/there"));
         assert windows::extract_unc_prefix("\\\\hi\\there\\friends.txt") ==
             Some((~"hi", ~"\\there\\friends.txt"));
+        assert windows::extract_unc_prefix("//hi\\there\\friends.txt") ==
+            Some((~"hi", ~"\\there\\friends.txt"));
     }
 
     #[test]
@@ -1011,5 +1045,53 @@ mod tests {
             .push_many([~"lib", ~"thingy.dll"])
             .with_filename("librustc.dll")),
           "c:\\program files (x86)\\rust\\lib\\librustc.dll");
+
+        t(&(WindowsPath("\\\\computer\\share")
+            .unsafe_join(&WindowsPath("\\a"))),
+          "\\\\computer\\a");
+
+        t(&(WindowsPath("//computer/share")
+            .unsafe_join(&WindowsPath("\\a"))),
+          "\\\\computer\\a");
+
+        t(&(WindowsPath("//computer/share")
+            .unsafe_join(&WindowsPath("\\\\computer\\share"))),
+          "\\\\computer\\share");
+
+        t(&(WindowsPath("C:/whatever")
+            .unsafe_join(&WindowsPath("//computer/share/a/b"))),
+          "\\\\computer\\share\\a\\b");
+
+        t(&(WindowsPath("C:")
+            .unsafe_join(&WindowsPath("D:/foo"))),
+          "D:\\foo");
+
+        t(&(WindowsPath("C:")
+            .unsafe_join(&WindowsPath("B"))),
+          "C:B");
+
+        t(&(WindowsPath("C:")
+            .unsafe_join(&WindowsPath("/foo"))),
+          "C:\\foo");
+
+        t(&(WindowsPath("C:\\")
+            .unsafe_join(&WindowsPath("\\bar"))),
+          "C:\\bar");
+
+        t(&(WindowsPath("")
+            .unsafe_join(&WindowsPath(""))),
+          "");
+
+        t(&(WindowsPath("")
+            .unsafe_join(&WindowsPath("a"))),
+          "a");
+
+        t(&(WindowsPath("")
+            .unsafe_join(&WindowsPath("C:\\a"))),
+          "C:\\a");
+
+        t(&(WindowsPath("c:\\foo")
+            .normalize()),
+          "C:\\foo");
     }
 }