Skip to content

Commit b07eab5

Browse files
committed
Improved windows path handling support
1 parent c8d8f6c commit b07eab5

File tree

1 file changed

+100
-18
lines changed

1 file changed

+100
-18
lines changed

src/libcore/path.rs

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -697,21 +697,44 @@ impl GenericPath for WindowsPath {
697697
}
698698

699699
pure fn unsafe_join(other: &WindowsPath) -> WindowsPath {
700+
/* rhs not absolute is simple push */
700701
if !other.is_absolute {
701-
self.push_rel(other)
702-
} else {
703-
WindowsPath {
704-
host: match other.host {
705-
None => copy self.host,
706-
Some(copy x) => Some(x)
707-
},
708-
device: match other.device {
709-
None => copy self.device,
710-
Some(copy x) => Some(x)
711-
},
712-
is_absolute: true,
713-
components: copy other.components
702+
return self.push_many(other.components);
703+
}
704+
705+
/* if rhs has a host set, then the whole thing wins */
706+
match other.host {
707+
Some(copy host) => {
708+
return WindowsPath {
709+
host: Some(host),
710+
device: copy other.device,
711+
is_absolute: true,
712+
components: copy other.components
713+
};
714+
}
715+
_ => {}
716+
}
717+
718+
/* if rhs has a device set, then a part wins */
719+
match other.device {
720+
Some(copy device) => {
721+
return WindowsPath {
722+
host: None,
723+
device: Some(device),
724+
is_absolute: true,
725+
components: copy other.components
726+
};
714727
}
728+
_ => {}
729+
}
730+
731+
/* fallback: host and device of lhs win, but the
732+
whole path of the right */
733+
WindowsPath {
734+
host: copy self.host,
735+
device: copy self.device,
736+
is_absolute: self.is_absolute || other.is_absolute,
737+
components: copy other.components
715738
}
716739
}
717740

@@ -755,7 +778,10 @@ impl GenericPath for WindowsPath {
755778
pure fn normalize() -> WindowsPath {
756779
return WindowsPath {
757780
host: copy self.host,
758-
device: copy self.device,
781+
device: match self.device {
782+
None => None,
783+
Some(ref device) => Some(device.to_upper())
784+
},
759785
is_absolute: self.is_absolute,
760786
components: normalize(self.components)
761787
}
@@ -794,13 +820,13 @@ pub mod windows {
794820
795821
pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> {
796822
if (s.len() > 1 &&
797-
s[0] == '\\' as u8 &&
798-
s[1] == '\\' as u8) {
823+
(s[0] == '\\' as u8 || s[0] == '/' as u8) &&
824+
s[0] == s[1]) {
799825
let mut i = 2;
800826
while i < s.len() {
801-
if s[i] == '\\' as u8 {
827+
if is_sep(s[i]) {
802828
let pre = s.slice(2, i);
803-
let rest = s.slice(i, s.len());
829+
let mut rest = s.slice(i, s.len());
804830
return Some((pre, rest));
805831
}
806832
i += 1;
@@ -946,13 +972,21 @@ mod tests {
946972
#[test]
947973
fn test_extract_unc_prefixes() {
948974
assert windows::extract_unc_prefix("\\\\").is_none();
975+
assert windows::extract_unc_prefix("//").is_none();
949976
assert windows::extract_unc_prefix("\\\\hi").is_none();
977+
assert windows::extract_unc_prefix("//hi").is_none();
950978
assert windows::extract_unc_prefix("\\\\hi\\") ==
951979
Some((~"hi", ~"\\"));
980+
assert windows::extract_unc_prefix("//hi\\") ==
981+
Some((~"hi", ~"\\"));
952982
assert windows::extract_unc_prefix("\\\\hi\\there") ==
953983
Some((~"hi", ~"\\there"));
984+
assert windows::extract_unc_prefix("//hi/there") ==
985+
Some((~"hi", ~"/there"));
954986
assert windows::extract_unc_prefix("\\\\hi\\there\\friends.txt") ==
955987
Some((~"hi", ~"\\there\\friends.txt"));
988+
assert windows::extract_unc_prefix("//hi\\there\\friends.txt") ==
989+
Some((~"hi", ~"\\there\\friends.txt"));
956990
}
957991

958992
#[test]
@@ -1011,5 +1045,53 @@ mod tests {
10111045
.push_many([~"lib", ~"thingy.dll"])
10121046
.with_filename("librustc.dll")),
10131047
"c:\\program files (x86)\\rust\\lib\\librustc.dll");
1048+
1049+
t(&(WindowsPath("\\\\computer\\share")
1050+
.unsafe_join(&WindowsPath("\\a"))),
1051+
"\\\\computer\\a");
1052+
1053+
t(&(WindowsPath("//computer/share")
1054+
.unsafe_join(&WindowsPath("\\a"))),
1055+
"\\\\computer\\a");
1056+
1057+
t(&(WindowsPath("//computer/share")
1058+
.unsafe_join(&WindowsPath("\\\\computer\\share"))),
1059+
"\\\\computer\\share");
1060+
1061+
t(&(WindowsPath("C:/whatever")
1062+
.unsafe_join(&WindowsPath("//computer/share/a/b"))),
1063+
"\\\\computer\\share\\a\\b");
1064+
1065+
t(&(WindowsPath("C:")
1066+
.unsafe_join(&WindowsPath("D:/foo"))),
1067+
"D:\\foo");
1068+
1069+
t(&(WindowsPath("C:")
1070+
.unsafe_join(&WindowsPath("B"))),
1071+
"C:B");
1072+
1073+
t(&(WindowsPath("C:")
1074+
.unsafe_join(&WindowsPath("/foo"))),
1075+
"C:\\foo");
1076+
1077+
t(&(WindowsPath("C:\\")
1078+
.unsafe_join(&WindowsPath("\\bar"))),
1079+
"C:\\bar");
1080+
1081+
t(&(WindowsPath("")
1082+
.unsafe_join(&WindowsPath(""))),
1083+
"");
1084+
1085+
t(&(WindowsPath("")
1086+
.unsafe_join(&WindowsPath("a"))),
1087+
"a");
1088+
1089+
t(&(WindowsPath("")
1090+
.unsafe_join(&WindowsPath("C:\\a"))),
1091+
"C:\\a");
1092+
1093+
t(&(WindowsPath("c:\\foo")
1094+
.normalize()),
1095+
"C:\\foo");
10141096
}
10151097
}

0 commit comments

Comments
 (0)