diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 46f8743ff15fd..96a921cf20bfb 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"); } }