diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 9cd3d3683cd..efe681ce830 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -164,7 +164,7 @@ fn parse_pp_exact(line: &str, testfile: &Path) -> Option { Some(s) => Some(Path::new(s)), None => { if parse_name_directive(line, "pp-exact") { - testfile.file_path() + testfile.filename().map_move(|s| Path::new(s)) } else { None } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index b1d8d83f9d3..9c6edb8d566 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -662,7 +662,12 @@ fn make_lib_name(config: &config, auxfile: &Path, testfile: &Path) -> Path { fn make_exe_name(config: &config, testfile: &Path) -> Path { let mut f = output_base_name(config, testfile); - f.add_extension(os::EXE_EXTENSION); + if !os::EXE_SUFFIX.is_empty() { + match f.filename().map_move(|s| s + os::EXE_SUFFIX.as_bytes()) { + Some(v) => f.set_filename(v), + None => () + } + } f } @@ -747,7 +752,10 @@ fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path { fn aux_output_dir_name(config: &config, testfile: &Path) -> Path { let mut f = output_base_name(config, testfile); - f.add_extension("libaux"); + match f.filename().map_move(|s| s + bytes!(".libaux")) { + Some(v) => f.set_filename(v), + None => () + } f } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 2274f7d3c69..8f426147078 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -24,7 +24,7 @@ pub enum FileMatch { FileMatches, FileDoesntMatch } pub type pick<'self> = &'self fn(path: &Path) -> FileMatch; pub fn pick_file(file: Path, path: &Path) -> Option { - if path.file_path() == Some(file) { + if path.filename() == Some(file.as_vec()) { Some(path.clone()) } else { None @@ -206,11 +206,10 @@ pub fn rust_path() -> ~[Path] { env_rust_path.push(cwd.clone()); } loop { - let f = cwd.pop(); - if f.is_none() || bytes!("..") == f.unwrap() { - break; + if { let f = cwd.filename(); f.is_none() || f.unwrap() == bytes!("..") } { + break } - cwd.push(".rust"); + cwd.set_filename(".rust"); if !env_rust_path.contains(&cwd) && os::path_exists(&cwd) { env_rust_path.push(cwd.clone()); } diff --git a/src/librustpkg/path_util.rs b/src/librustpkg/path_util.rs index 0fe3abdefa3..69c3f6e0f1c 100644 --- a/src/librustpkg/path_util.rs +++ b/src/librustpkg/path_util.rs @@ -449,8 +449,8 @@ pub fn user_set_rust_path() -> bool { /// Append the version string onto the end of the path's filename pub fn versionize(p: &Path, v: &Version) -> Path { - let q = p.file_path().expect("path is a directory"); - let mut q = q.as_vec().to_owned(); + let q = p.filename().expect("path is a directory"); + let mut q = q.to_owned(); q.push('-' as u8); let vs = v.to_str(); q.push_all(vs.as_bytes()); diff --git a/src/libstd/os.rs b/src/libstd/os.rs index be50f6d1a9f..8701365d321 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -693,8 +693,9 @@ pub fn mkdir_recursive(p: &Path, mode: c_int) -> bool { if path_is_dir(p) { return true; } - let mut p_ = p.clone(); - if p_.pop().is_some() { + if p.filename().is_some() { + let mut p_ = p.clone(); + p_.pop(); if !mkdir_recursive(&p_, mode) { return false; } diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 278a4ab36ff..08a29f6552a 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -268,23 +268,6 @@ pub trait GenericPath: Clone + GenericPathUnsafe { self.extension().and_then(str::from_utf8_slice_opt) } - /// Replaces the directory portion of the path with the given byte vector or string. - /// If `self` represents the root of the filesystem hierarchy, the last path component - /// of the argument becomes the filename. - /// - /// # Failure - /// - /// Raises the `null_byte` condition if the dirname contains a NUL. - #[inline] - fn set_dirname(&mut self, dirname: T) { - if contains_nul(dirname.container_as_bytes()) { - let dirname = self::null_byte::cond.raise(dirname.container_into_owned_bytes()); - assert!(!contains_nul(dirname)); - unsafe { self.set_dirname_unchecked(dirname) } - } else { - unsafe { self.set_dirname_unchecked(dirname) } - } - } /// Replaces the filename portion of the path with the given byte vector or string. /// If the replacement name is [], this is equivalent to popping the path. /// @@ -301,53 +284,6 @@ pub trait GenericPath: Clone + GenericPathUnsafe { unsafe { self.set_filename_unchecked(filename) } } } - /// Replaces the filestem with the given byte vector or string. - /// If there is no extension in `self` (or `self` has no filename), this is equivalent - /// to `set_filename`. Otherwise, if the argument is [] or "", the extension (including - /// the preceding '.') becomes the new filename. - /// - /// # Failure - /// - /// Raises the `null_byte` condition if the filestem contains a NUL. - fn set_filestem(&mut self, filestem: T) { - // borrowck is being a pain here - enum Value { - Checked(T), - Unchecked(~[u8]) - } - let val = { - match self.filename() { - None => Checked(filestem), - Some(name) => { - let dot = '.' as u8; - match name.rposition_elem(&dot) { - None | Some(0) => Checked(filestem), - Some(idx) => { - let mut v; - if contains_nul(filestem.container_as_bytes()) { - let filestem = filestem.container_into_owned_bytes(); - let filestem = self::null_byte::cond.raise(filestem); - assert!(!contains_nul(filestem)); - v = filestem; - let n = v.len(); - v.reserve(n + name.len() - idx); - } else { - let filestem = filestem.container_as_bytes(); - v = vec::with_capacity(filestem.len() + name.len() - idx); - v.push_all(filestem); - } - v.push_all(name.slice_from(idx)); - Unchecked(v) - } - } - } - } - }; - match val { - Checked(v) => self.set_filename(v), - Unchecked(v) => unsafe { self.set_filename_unchecked(v) } - } - } /// Replaces the extension with the given byte vector or string. /// If there is no extension in `self`, this adds one. /// If the argument is [] or "", this removes the extension. @@ -417,61 +353,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { Some(v) => unsafe { self.set_filename_unchecked(v) } } } - /// Adds the given extension (as a byte vector or string) to the file. - /// This does not remove any existing extension. - /// `foo.bar`.add_extension(`baz`) becomes `foo.bar.baz`. - /// If `self` has no filename, this is a no-op. - /// If the argument is [] or "", this is a no-op. - /// - /// # Failure - /// - /// Raises the `null_byte` condition if the extension contains a NUL. - fn add_extension(&mut self, extension: T) { - if extension.container_as_bytes().is_empty() { return; } - // appease borrowck - let val = { - match self.filename() { - None => None, - Some(name) => { - let mut v; - if contains_nul(extension.container_as_bytes()) { - let ext = extension.container_into_owned_bytes(); - let extension = self::null_byte::cond.raise(ext); - assert!(!contains_nul(extension)); - v = vec::with_capacity(name.len() + 1 + extension.len()); - v.push_all(name); - v.push('.' as u8); - v.push_all(extension); - } else { - let extension = extension.container_as_bytes(); - v = vec::with_capacity(name.len() + 1 + extension.len()); - v.push_all(name); - v.push('.' as u8); - v.push_all(extension); - } - Some(v) - } - } - }; - match val { - None => (), - Some(v) => unsafe { self.set_filename_unchecked(v) } - } - } - /// Returns a new Path constructed by replacing the dirname with the given - /// byte vector or string. - /// See `set_dirname` for details. - /// - /// # Failure - /// - /// Raises the `null_byte` condition if the dirname contains a NUL. - #[inline] - fn with_dirname(&self, dirname: T) -> Self { - let mut p = self.clone(); - p.set_dirname(dirname); - p - } /// Returns a new Path constructed by replacing the filename with the given /// byte vector or string. /// See `set_filename` for details. @@ -485,19 +367,6 @@ pub trait GenericPath: Clone + GenericPathUnsafe { p.set_filename(filename); p } - /// Returns a new Path constructed by setting the filestem to the given - /// byte vector or string. - /// See `set_filestem` for details. - /// - /// # Failure - /// - /// Raises the `null_byte` condition if the filestem contains a NUL. - #[inline] - fn with_filestem(&self, filestem: T) -> Self { - let mut p = self.clone(); - p.set_filestem(filestem); - p - } /// Returns a new Path constructed by setting the extension to the given /// byte vector or string. /// See `set_extension` for details. @@ -518,12 +387,6 @@ pub trait GenericPath: Clone + GenericPathUnsafe { // self.dirname() returns a NUL-free vector unsafe { GenericPathUnsafe::new_unchecked(self.dirname()) } } - /// Returns the file component of `self`, as a relative Path. - /// If `self` represents the root of the filesystem hierarchy, returns None. - fn file_path(&self) -> Option { - // self.filename() returns a NUL-free vector - self.filename().map_move(|v| unsafe { GenericPathUnsafe::new_unchecked(v) }) - } /// Returns a Path that represents the filesystem root that `self` is rooted in. /// @@ -561,16 +424,10 @@ pub trait GenericPath: Clone + GenericPathUnsafe { } } } - /// Pops the last path component off of `self` and returns it. - /// If `self` represents the root of the file hierarchy, None is returned. - fn pop(&mut self) -> Option<~[u8]>; - /// Pops the last path component off of `self` and returns it as a string, if possible. - /// `self` will still be modified even if None is returned. - /// See `pop` for details. - #[inline] - fn pop_str(&mut self) -> Option<~str> { - self.pop().and_then(|v| str::from_utf8_owned_opt(v)) - } + /// Removes the last path component from the receiver. + /// Returns `true` if the receiver was modified, or `false` if it already + /// represented the root of the file hierarchy. + fn pop(&mut self) -> bool; /// Returns a new Path constructed by joining `self` with the given path /// (as a byte vector or string). @@ -658,11 +515,6 @@ pub trait GenericPathUnsafe { /// The resulting Path will always be normalized. unsafe fn new_unchecked(path: T) -> Self; - /// Replaces the directory portion of the path without checking for null - /// bytes. - /// See `set_dirname` for details. - unsafe fn set_dirname_unchecked(&mut self, dirname: T); - /// Replaces the filename portion of the path without checking for null /// bytes. /// See `set_filename` for details. diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index fdc943fb882..a7c89cb6029 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -20,7 +20,6 @@ use option::{Option, None, Some}; use str; use str::Str; use to_bytes::IterBytes; -use util; use vec; use vec::{CopyableVector, RSplitIterator, SplitIterator, Vector, VectorVector}; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; @@ -122,39 +121,6 @@ impl GenericPathUnsafe for Path { Path{ repr: path, sepidx: idx } } - unsafe fn set_dirname_unchecked(&mut self, dirname: T) { - let dirname = dirname.container_as_bytes(); - match self.sepidx { - None if bytes!(".") == self.repr || bytes!("..") == self.repr => { - self.repr = Path::normalize(dirname); - } - None => { - let mut v = vec::with_capacity(dirname.len() + self.repr.len() + 1); - v.push_all(dirname); - v.push(sep_byte); - v.push_all(self.repr); - self.repr = Path::normalize(v); - } - Some(0) if self.repr.len() == 1 && self.repr[0] == sep_byte => { - self.repr = Path::normalize(dirname); - } - Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => { - self.repr = Path::normalize(dirname); - } - Some(idx) if dirname.is_empty() => { - let v = Path::normalize(self.repr.slice_from(idx+1)); - self.repr = v; - } - Some(idx) => { - let mut v = vec::with_capacity(dirname.len() + self.repr.len() - idx); - v.push_all(dirname); - v.push_all(self.repr.slice_from(idx)); - self.repr = Path::normalize(v); - } - } - self.sepidx = self.repr.rposition_elem(&sep_byte); - } - unsafe fn set_filename_unchecked(&mut self, filename: T) { let filename = filename.container_as_bytes(); match self.sepidx { @@ -236,25 +202,23 @@ impl GenericPath for Path { } } - fn pop(&mut self) -> Option<~[u8]> { + fn pop(&mut self) -> bool { match self.sepidx { - None if bytes!(".") == self.repr => None, + None if bytes!(".") == self.repr => false, None => { - let mut v = ~['.' as u8]; - util::swap(&mut v, &mut self.repr); + self.repr = ~['.' as u8]; self.sepidx = None; - Some(v) + true } - Some(0) if bytes!("/") == self.repr => None, + Some(0) if bytes!("/") == self.repr => false, Some(idx) => { - let v = self.repr.slice_from(idx+1).to_owned(); if idx == 0 { self.repr.truncate(idx+1); } else { self.repr.truncate(idx); } self.sepidx = self.repr.rposition_elem(&sep_byte); - Some(v) + true } } } @@ -692,17 +656,6 @@ mod tests { assert!(handled); assert_eq!(p.as_vec(), b!("/foo")); - handled = false; - do cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("null/", 0, "/byte")); - (b!("null/byte").to_owned()) - }).inside { - p.set_dirname(b!("null/", 0, "/byte")); - }; - assert!(handled); - assert_eq!(p.as_vec(), b!("null/byte/foo")); - handled = false; do cond.trap(|v| { handled = true; @@ -712,7 +665,7 @@ mod tests { p.push(b!("f", 0, "o")); }; assert!(handled); - assert_eq!(p.as_vec(), b!("null/byte/foo/foo")); + assert_eq!(p.as_vec(), b!("/foo/foo")); } #[test] @@ -749,15 +702,6 @@ mod tests { }; }) - t!(~"set_dirname w/nul" => { - let mut p = Path::new(b!("foo/bar")); - do cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside { - p.set_dirname(b!("foo", 0)) - }; - }) - t!(~"push w/nul" => { let mut p = Path::new(b!("foo/bar")); do cond.trap(|_| { @@ -1006,46 +950,35 @@ mod tests { (s: $path:expr, $left:expr, $right:expr) => ( { let mut p = Path::new($path); - let file = p.pop_str(); + let result = p.pop(); assert_eq!(p.as_str(), Some($left)); - assert_eq!(file.map(|s| s.as_slice()), $right); + assert_eq!(result, $right); } ); - (v: [$($path:expr),+], [$($left:expr),+], Some($($right:expr),+)) => ( + (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => ( { let mut p = Path::new(b!($($path),+)); - let file = p.pop(); + let result = p.pop(); assert_eq!(p.as_vec(), b!($($left),+)); - assert_eq!(file.map(|v| v.as_slice()), Some(b!($($right),+))); - } - ); - (v: [$($path:expr),+], [$($left:expr),+], None) => ( - { - let mut p = Path::new(b!($($path),+)); - let file = p.pop(); - assert_eq!(p.as_vec(), b!($($left),+)); - assert_eq!(file, None); + assert_eq!(result, $right); } ) ) - t!(v: ["a/b/c"], ["a/b"], Some("c")); - t!(v: ["a"], ["."], Some("a")); - t!(v: ["."], ["."], None); - t!(v: ["/a"], ["/"], Some("a")); - t!(v: ["/"], ["/"], None); - t!(v: ["a/b/c", 0x80], ["a/b"], Some("c", 0x80)); - t!(v: ["a/b", 0x80, "/c"], ["a/b", 0x80], Some("c")); - t!(v: [0xff], ["."], Some(0xff)); - t!(v: ["/", 0xff], ["/"], Some(0xff)); - t!(s: "a/b/c", "a/b", Some("c")); - t!(s: "a", ".", Some("a")); - t!(s: ".", ".", None); - t!(s: "/a", "/", Some("a")); - t!(s: "/", "/", None); - - assert_eq!(Path::new(b!("foo/bar", 0x80)).pop_str(), None); - assert_eq!(Path::new(b!("foo", 0x80, "/bar")).pop_str(), Some(~"bar")); + t!(v: ["a/b/c"], ["a/b"], true); + t!(v: ["a"], ["."], true); + t!(v: ["."], ["."], false); + t!(v: ["/a"], ["/"], true); + t!(v: ["/"], ["/"], false); + t!(v: ["a/b/c", 0x80], ["a/b"], true); + t!(v: ["a/b", 0x80, "/c"], ["a/b", 0x80], true); + t!(v: [0xff], ["."], true); + t!(v: ["/", 0xff], ["/"], true); + t!(s: "a/b/c", "a/b", true); + t!(s: "a", ".", true); + t!(s: ".", ".", false); + t!(s: "/a", "/", true); + t!(s: "/", "/", false); } #[test] @@ -1124,27 +1057,6 @@ mod tests { fn test_with_helpers() { let empty: &[u8] = []; - t!(v: Path::new(b!("a/b/c")).with_dirname(b!("d")), b!("d/c")); - t!(v: Path::new(b!("a/b/c")).with_dirname(b!("d/e")), b!("d/e/c")); - t!(v: Path::new(b!("a/", 0x80, "b/c")).with_dirname(b!(0xff)), b!(0xff, "/c")); - t!(v: Path::new(b!("a/b/", 0x80)).with_dirname(b!("/", 0xcd)), - b!("/", 0xcd, "/", 0x80)); - t!(s: Path::new("a/b/c").with_dirname("d"), "d/c"); - t!(s: Path::new("a/b/c").with_dirname("d/e"), "d/e/c"); - t!(s: Path::new("a/b/c").with_dirname(""), "c"); - t!(s: Path::new("a/b/c").with_dirname("/"), "/c"); - t!(s: Path::new("a/b/c").with_dirname("."), "c"); - t!(s: Path::new("a/b/c").with_dirname(".."), "../c"); - t!(s: Path::new("/").with_dirname("foo"), "foo"); - t!(s: Path::new("/").with_dirname(""), "."); - t!(s: Path::new("/foo").with_dirname("bar"), "bar/foo"); - t!(s: Path::new("..").with_dirname("foo"), "foo"); - t!(s: Path::new("../..").with_dirname("foo"), "foo"); - t!(s: Path::new("..").with_dirname(""), "."); - t!(s: Path::new("../..").with_dirname(""), "."); - t!(s: Path::new("foo").with_dirname(".."), "../foo"); - t!(s: Path::new("foo").with_dirname("../.."), "../../foo"); - t!(v: Path::new(b!("a/b/c")).with_filename(b!("d")), b!("a/b/d")); t!(v: Path::new(b!("a/b/c", 0xff)).with_filename(b!(0x80)), b!("a/b/", 0x80)); t!(v: Path::new(b!("/", 0xff, "/foo")).with_filename(b!(0xcd)), @@ -1169,34 +1081,6 @@ mod tests { t!(s: Path::new("..").with_filename(""), ".."); t!(s: Path::new("../..").with_filename(""), "../.."); - t!(v: Path::new(b!("hi/there", 0x80, ".txt")).with_filestem(b!(0xff)), - b!("hi/", 0xff, ".txt")); - t!(v: Path::new(b!("hi/there.txt", 0x80)).with_filestem(b!(0xff)), - b!("hi/", 0xff, ".txt", 0x80)); - t!(v: Path::new(b!("hi/there", 0xff)).with_filestem(b!(0x80)), b!("hi/", 0x80)); - t!(v: Path::new(b!("hi", 0x80, "/there")).with_filestem(empty), b!("hi", 0x80)); - t!(s: Path::new("hi/there.txt").with_filestem("here"), "hi/here.txt"); - t!(s: Path::new("hi/there.txt").with_filestem(""), "hi/.txt"); - t!(s: Path::new("hi/there.txt").with_filestem("."), "hi/..txt"); - t!(s: Path::new("hi/there.txt").with_filestem(".."), "hi/...txt"); - t!(s: Path::new("hi/there.txt").with_filestem("/"), "hi/.txt"); - t!(s: Path::new("hi/there.txt").with_filestem("foo/bar"), "hi/foo/bar.txt"); - t!(s: Path::new("hi/there.foo.txt").with_filestem("here"), "hi/here.txt"); - t!(s: Path::new("hi/there").with_filestem("here"), "hi/here"); - t!(s: Path::new("hi/there").with_filestem(""), "hi"); - t!(s: Path::new("hi").with_filestem(""), "."); - t!(s: Path::new("/hi").with_filestem(""), "/"); - t!(s: Path::new("hi/there").with_filestem(".."), "."); - t!(s: Path::new("hi/there").with_filestem("."), "hi"); - t!(s: Path::new("hi/there.").with_filestem("foo"), "hi/foo."); - t!(s: Path::new("hi/there.").with_filestem(""), "hi"); - t!(s: Path::new("hi/there.").with_filestem("."), "."); - t!(s: Path::new("hi/there.").with_filestem(".."), "hi/..."); - t!(s: Path::new("/").with_filestem("foo"), "/foo"); - t!(s: Path::new(".").with_filestem("foo"), "foo"); - t!(s: Path::new("hi/there..").with_filestem("here"), "hi/here."); - t!(s: Path::new("hi/there..").with_filestem(""), "hi"); - t!(v: Path::new(b!("hi/there", 0x80, ".txt")).with_extension(b!("exe")), b!("hi/there", 0x80, ".exe")); t!(v: Path::new(b!("hi/there.txt", 0x80)).with_extension(b!(0xff)), @@ -1245,17 +1129,6 @@ mod tests { ) ) - t!(v: b!("a/b/c"), set_dirname, with_dirname, b!("d")); - t!(v: b!("a/b/c"), set_dirname, with_dirname, b!("d/e")); - t!(v: b!("a/", 0x80, "/c"), set_dirname, with_dirname, b!(0xff)); - t!(s: "a/b/c", set_dirname, with_dirname, "d"); - t!(s: "a/b/c", set_dirname, with_dirname, "d/e"); - t!(s: "/", set_dirname, with_dirname, "foo"); - t!(s: "/foo", set_dirname, with_dirname, "bar"); - t!(s: "a/b/c", set_dirname, with_dirname, ""); - t!(s: "../..", set_dirname, with_dirname, "x"); - t!(s: "foo", set_dirname, with_dirname, "../.."); - t!(v: b!("a/b/c"), set_filename, with_filename, b!("d")); t!(v: b!("/"), set_filename, with_filename, b!("foo")); t!(v: b!(0x80), set_filename, with_filename, b!(0xff)); @@ -1265,14 +1138,6 @@ mod tests { t!(s: "a/b", set_filename, with_filename, ""); t!(s: "a", set_filename, with_filename, ""); - t!(v: b!("hi/there.txt"), set_filestem, with_filestem, b!("here")); - t!(v: b!("hi/there", 0x80, ".txt"), set_filestem, with_filestem, b!("here", 0xff)); - t!(s: "hi/there.txt", set_filestem, with_filestem, "here"); - t!(s: "hi/there.", set_filestem, with_filestem, "here"); - t!(s: "hi/there", set_filestem, with_filestem, "here"); - t!(s: "hi/there.txt", set_filestem, with_filestem, ""); - t!(s: "hi/there", set_filestem, with_filestem, ""); - t!(v: b!("hi/there.txt"), set_extension, with_extension, b!("exe")); t!(v: b!("hi/there.t", 0x80, "xt"), set_extension, with_extension, b!("exe", 0xff)); t!(s: "hi/there.txt", set_extension, with_extension, "exe"); @@ -1283,36 +1148,6 @@ mod tests { t!(s: ".", set_extension, with_extension, "txt"); } - #[test] - fn test_add_extension() { - macro_rules! t( - (s: $path:expr, $ext:expr, $exp:expr) => ( - { - let mut path = Path::new($path); - path.add_extension($ext); - assert_eq!(path.as_str(), Some($exp)); - } - ); - (v: $path:expr, $ext:expr, $exp:expr) => ( - { - let mut path = Path::new($path); - path.add_extension($ext); - assert_eq!(path.as_vec(), $exp); - } - ) - ) - - t!(s: "hi/there.txt", "foo", "hi/there.txt.foo"); - t!(s: "hi/there.", "foo", "hi/there..foo"); - t!(s: "hi/there", ".foo", "hi/there..foo"); - t!(s: "hi/there.txt", "", "hi/there.txt"); - t!(v: b!("hi/there.txt"), b!("foo"), b!("hi/there.txt.foo")); - t!(v: b!("hi/there"), b!("bar"), b!("hi/there.bar")); - t!(v: b!("/"), b!("foo"), b!("/")); - t!(v: b!("."), b!("foo"), b!(".")); - t!(v: b!("hi/there.", 0x80, "foo"), b!(0xff), b!("hi/there.", 0x80, "foo.", 0xff)); - } - #[test] fn test_getters() { macro_rules! t( @@ -1372,7 +1207,7 @@ mod tests { } #[test] - fn test_dir_file_path() { + fn test_dir_path() { t!(v: Path::new(b!("hi/there", 0x80)).dir_path(), b!("hi")); t!(v: Path::new(b!("hi", 0xff, "/there")).dir_path(), b!("hi", 0xff)); t!(s: Path::new("hi/there").dir_path(), "hi"); @@ -1381,32 +1216,6 @@ mod tests { t!(s: Path::new("/").dir_path(), "/"); t!(s: Path::new("..").dir_path(), ".."); t!(s: Path::new("../..").dir_path(), "../.."); - - macro_rules! t( - (s: $path:expr, $exp:expr) => ( - { - let path = $path; - let left = path.and_then_ref(|p| p.as_str()); - assert_eq!(left, $exp); - } - ); - (v: $path:expr, $exp:expr) => ( - { - let path = $path; - let left = path.map(|p| p.as_vec()); - assert_eq!(left, $exp); - } - ) - ) - - t!(v: Path::new(b!("hi/there", 0x80)).file_path(), Some(b!("there", 0x80))); - t!(v: Path::new(b!("hi", 0xff, "/there")).file_path(), Some(b!("there"))); - t!(s: Path::new("hi/there").file_path(), Some("there")); - t!(s: Path::new("hi").file_path(), Some("hi")); - t!(s: Path::new(".").file_path(), None); - t!(s: Path::new("/").file_path(), None); - t!(s: Path::new("..").file_path(), None); - t!(s: Path::new("../..").file_path(), None); } #[test] diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 5f8e1dc58fa..77232196f78 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -20,7 +20,6 @@ use option::{Option, Some, None}; use str; use str::{CharSplitIterator, OwnedStr, Str, StrVector}; use to_bytes::IterBytes; -use util; use vec::Vector; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; @@ -174,49 +173,6 @@ impl GenericPathUnsafe for Path { ret } - /// See `GenericPathUnsafe::set_dirname_unchecked`. - /// - /// # Failure - /// - /// Raises the `str::not_utf8` condition if not valid UTF-8. - unsafe fn set_dirname_unchecked(&mut self, dirname: T) { - let dirname = dirname.container_as_str(); - match self.sepidx_or_prefix_len() { - None if "." == self.repr || ".." == self.repr => { - self.update_normalized(dirname); - } - None => { - let mut s = str::with_capacity(dirname.len() + self.repr.len() + 1); - s.push_str(dirname); - s.push_char(sep); - s.push_str(self.repr); - self.update_normalized(s); - } - Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => { - self.update_normalized(dirname); - } - Some((_,idxa,end)) if dirname.is_empty() => { - let (prefix, path) = Path::normalize_(self.repr.slice(idxa,end)); - self.repr = path; - self.prefix = prefix; - self.update_sepidx(); - } - Some((idxb,idxa,end)) => { - let idx = if dirname.ends_with("\\") { idxa } - else { - let prefix = parse_prefix(dirname); - if prefix == Some(DiskPrefix) && prefix_len(prefix) == dirname.len() { - idxa - } else { idxb } - }; - let mut s = str::with_capacity(dirname.len() + end - idx); - s.push_str(dirname); - s.push_str(self.repr.slice(idx,end)); - self.update_normalized(s); - } - } - } - /// See `GenericPathUnsafe::set_filename_unchecekd`. /// /// # Failure @@ -452,28 +408,18 @@ impl GenericPath for Path { unsafe { GenericPathUnsafe::new_unchecked(self.dirname_str().unwrap()) } } - fn file_path(&self) -> Option { - self.filename_str().map_move(|s| unsafe { GenericPathUnsafe::new_unchecked(s) }) - } - #[inline] - fn pop(&mut self) -> Option<~[u8]> { - self.pop_str().map_move(|s| s.into_bytes()) - } - - fn pop_str(&mut self) -> Option<~str> { + fn pop(&mut self) -> bool { match self.sepidx_or_prefix_len() { - None if "." == self.repr => None, + None if "." == self.repr => false, None => { - let mut s = ~"."; - util::swap(&mut s, &mut self.repr); + self.repr = ~"."; self.sepidx = None; - Some(s) + true } - Some((idxb,idxa,end)) if idxb == idxa && idxb == end => None, - Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => None, - Some((idxb,idxa,end)) => { - let s = self.repr.slice(idxa, end).to_owned(); + Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false, + Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => false, + Some((idxb,idxa,_)) => { let trunc = match self.prefix { Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => { let plen = self.prefix_len(); @@ -483,7 +429,7 @@ impl GenericPath for Path { }; self.repr.truncate(trunc); self.update_sepidx(); - Some(s) + true } } } @@ -1401,17 +1347,6 @@ mod tests { assert!(handled); assert_eq!(p.as_vec(), b!("\\foo")); - handled = false; - do cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("null\\", 0, "\\byte")); - (b!("null\\byte").to_owned()) - }).inside { - p.set_dirname(b!("null\\", 0, "\\byte")); - }; - assert!(handled); - assert_eq!(p.as_vec(), b!("null\\byte\\foo")); - handled = false; do cond.trap(|v| { handled = true; @@ -1421,7 +1356,7 @@ mod tests { p.push(b!("f", 0, "o")); }; assert!(handled); - assert_eq!(p.as_vec(), b!("null\\byte\\foo\\foo")); + assert_eq!(p.as_vec(), b!("\\foo\\foo")); } #[test] @@ -1458,15 +1393,6 @@ mod tests { }; }) - t!(~"set_dirname w\\nul" => { - let mut p = Path::new(b!("foo\\bar")); - do cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside { - p.set_dirname(b!("foo", 0)) - }; - }) - t!(~"push w\\nul" => { let mut p = Path::new(b!("foo\\bar")); do cond.trap(|_| { @@ -1770,69 +1696,58 @@ mod tests { { let pstr = $path; let mut p = Path::new(pstr); - let file = p.pop_str(); + let result = p.pop(); let left = $left; assert!(p.as_str() == Some(left), "`{}`.pop() failed; expected remainder `{}`, found `{}`", pstr, left, p.as_str().unwrap()); - let right = $right; - let res = file.map(|s| s.as_slice()); - assert!(res == right, "`{}`.pop() failed; expected `{:?}`, found `{:?}`", - pstr, right, res); + assert_eq!(result, $right); } ); - (v: [$($path:expr),+], [$($left:expr),+], Some($($right:expr),+)) => ( + (v: [$($path:expr),+], [$($left:expr),+], $right:expr) => ( { let mut p = Path::new(b!($($path),+)); - let file = p.pop(); + let result = p.pop(); assert_eq!(p.as_vec(), b!($($left),+)); - assert_eq!(file.map(|v| v.as_slice()), Some(b!($($right),+))); - } - ); - (v: [$($path:expr),+], [$($left:expr),+], None) => ( - { - let mut p = Path::new(b!($($path),+)); - let file = p.pop(); - assert_eq!(p.as_vec(), b!($($left),+)); - assert_eq!(file, None); + assert_eq!(result, $right); } ) ) - t!(s: "a\\b\\c", "a\\b", Some("c")); - t!(s: "a", ".", Some("a")); - t!(s: ".", ".", None); - t!(s: "\\a", "\\", Some("a")); - t!(s: "\\", "\\", None); - t!(v: ["a\\b\\c"], ["a\\b"], Some("c")); - t!(v: ["a"], ["."], Some("a")); - t!(v: ["."], ["."], None); - t!(v: ["\\a"], ["\\"], Some("a")); - t!(v: ["\\"], ["\\"], None); + t!(s: "a\\b\\c", "a\\b", true); + t!(s: "a", ".", true); + t!(s: ".", ".", false); + t!(s: "\\a", "\\", true); + t!(s: "\\", "\\", false); + t!(v: ["a\\b\\c"], ["a\\b"], true); + t!(v: ["a"], ["."], true); + t!(v: ["."], ["."], false); + t!(v: ["\\a"], ["\\"], true); + t!(v: ["\\"], ["\\"], false); - t!(s: "C:\\a\\b", "C:\\a", Some("b")); - t!(s: "C:\\a", "C:\\", Some("a")); - t!(s: "C:\\", "C:\\", None); - t!(s: "C:a\\b", "C:a", Some("b")); - t!(s: "C:a", "C:", Some("a")); - t!(s: "C:", "C:", None); - t!(s: "\\\\server\\share\\a\\b", "\\\\server\\share\\a", Some("b")); - t!(s: "\\\\server\\share\\a", "\\\\server\\share", Some("a")); - t!(s: "\\\\server\\share", "\\\\server\\share", None); - t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b", Some("c")); - t!(s: "\\\\?\\a\\b", "\\\\?\\a", Some("b")); - t!(s: "\\\\?\\a", "\\\\?\\a", None); - t!(s: "\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", Some("b")); - t!(s: "\\\\?\\C:\\a", "\\\\?\\C:\\", Some("a")); - t!(s: "\\\\?\\C:\\", "\\\\?\\C:\\", None); - t!(s: "\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", Some("b")); - t!(s: "\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share", Some("a")); - t!(s: "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", None); - t!(s: "\\\\.\\a\\b\\c", "\\\\.\\a\\b", Some("c")); - t!(s: "\\\\.\\a\\b", "\\\\.\\a", Some("b")); - t!(s: "\\\\.\\a", "\\\\.\\a", None); + t!(s: "C:\\a\\b", "C:\\a", true); + t!(s: "C:\\a", "C:\\", true); + t!(s: "C:\\", "C:\\", false); + t!(s: "C:a\\b", "C:a", true); + t!(s: "C:a", "C:", true); + t!(s: "C:", "C:", false); + t!(s: "\\\\server\\share\\a\\b", "\\\\server\\share\\a", true); + t!(s: "\\\\server\\share\\a", "\\\\server\\share", true); + t!(s: "\\\\server\\share", "\\\\server\\share", false); + t!(s: "\\\\?\\a\\b\\c", "\\\\?\\a\\b", true); + t!(s: "\\\\?\\a\\b", "\\\\?\\a", true); + t!(s: "\\\\?\\a", "\\\\?\\a", false); + t!(s: "\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true); + t!(s: "\\\\?\\C:\\a", "\\\\?\\C:\\", true); + t!(s: "\\\\?\\C:\\", "\\\\?\\C:\\", false); + t!(s: "\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true); + t!(s: "\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share", true); + t!(s: "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false); + t!(s: "\\\\.\\a\\b\\c", "\\\\.\\a\\b", true); + t!(s: "\\\\.\\a\\b", "\\\\.\\a", true); + t!(s: "\\\\.\\a", "\\\\.\\a", false); - t!(s: "\\\\?\\a\\b\\", "\\\\?\\a", Some("b")); + t!(s: "\\\\?\\a\\b\\", "\\\\?\\a", true); } #[test] @@ -1934,48 +1849,6 @@ mod tests { } ) ) - t!(s: "a\\b\\c", with_dirname, "d", "d\\c"); - t!(s: "a\\b\\c", with_dirname, "d\\e", "d\\e\\c"); - t!(s: "a\\b\\c", with_dirname, "", "c"); - t!(s: "a\\b\\c", with_dirname, "\\", "\\c"); - t!(s: "a\\b\\c", with_dirname, "/", "\\c"); - t!(s: "a\\b\\c", with_dirname, ".", "c"); - t!(s: "a\\b\\c", with_dirname, "..", "..\\c"); - t!(s: "\\", with_dirname, "foo", "foo"); - t!(s: "\\", with_dirname, "", "."); - t!(s: "\\foo", with_dirname, "bar", "bar\\foo"); - t!(s: "..", with_dirname, "foo", "foo"); - t!(s: "..\\..", with_dirname, "foo", "foo"); - t!(s: "..", with_dirname, "", "."); - t!(s: "..\\..", with_dirname, "", "."); - t!(s: ".", with_dirname, "foo", "foo"); - t!(s: "foo", with_dirname, "..", "..\\foo"); - t!(s: "foo", with_dirname, "..\\..", "..\\..\\foo"); - t!(s: "C:\\a\\b", with_dirname, "foo", "foo\\b"); - t!(s: "foo", with_dirname, "C:\\a\\b", "C:\\a\\b\\foo"); - t!(s: "C:a\\b", with_dirname, "\\\\server\\share", "\\\\server\\share\\b"); - t!(s: "a", with_dirname, "\\\\server\\share", "\\\\server\\share\\a"); - t!(s: "a\\b", with_dirname, "\\\\?\\", "\\\\?\\b"); - t!(s: "a\\b", with_dirname, "C:", "C:b"); - t!(s: "a\\b", with_dirname, "C:\\", "C:\\b"); - t!(s: "a\\b", with_dirname, "C:/", "C:\\b"); - t!(s: "C:\\", with_dirname, "foo", "foo"); - t!(s: "C:", with_dirname, "foo", "foo"); - t!(s: ".", with_dirname, "C:\\", "C:\\"); - t!(s: ".", with_dirname, "C:/", "C:\\"); - t!(s: "\\\\?\\C:\\foo", with_dirname, "C:\\", "C:\\foo"); - t!(s: "\\\\?\\C:\\", with_dirname, "bar", "bar"); - t!(s: "foo\\bar", with_dirname, "\\\\?\\C:\\baz", "\\\\?\\C:\\baz\\bar"); - t!(s: "\\\\?\\foo", with_dirname, "C:\\bar", "C:\\bar"); - t!(s: "\\\\?\\a\\foo", with_dirname, "C:\\bar", "C:\\bar\\foo"); - t!(s: "\\\\?\\a\\foo/bar", with_dirname, "C:\\baz", "C:\\baz\\foo\\bar"); - t!(s: "\\\\?\\UNC\\server\\share\\baz", with_dirname, "a", "a\\baz"); - t!(s: "foo\\bar", with_dirname, "\\\\?\\UNC\\server\\share\\baz", - "\\\\?\\UNC\\server\\share\\baz\\bar"); - t!(s: "\\\\.\\foo", with_dirname, "bar", "bar"); - t!(s: "\\\\.\\foo\\bar", with_dirname, "baz", "baz\\bar"); - t!(s: "\\\\.\\foo\\bar", with_dirname, "baz\\", "baz\\bar"); - t!(s: "\\\\.\\foo\\bar", with_dirname, "baz/", "baz\\bar"); t!(s: "a\\b\\c", with_filename, "d", "a\\b\\d"); t!(s: ".", with_filename, "foo", "foo"); @@ -2028,29 +1901,6 @@ mod tests { t!(s: "\\\\.\\foo", with_filename, "bar", "\\\\.\\foo\\bar"); t!(s: "\\\\.\\foo\\bar", with_filename, "..", "\\\\.\\foo\\.."); - t!(s: "hi\\there.txt", with_filestem, "here", "hi\\here.txt"); - t!(s: "hi\\there.txt", with_filestem, "", "hi\\.txt"); - t!(s: "hi\\there.txt", with_filestem, ".", "hi\\..txt"); - t!(s: "hi\\there.txt", with_filestem, "..", "hi\\...txt"); - t!(s: "hi\\there.txt", with_filestem, "\\", "hi\\.txt"); - t!(s: "hi\\there.txt", with_filestem, "foo\\bar", "hi\\foo\\bar.txt"); - t!(s: "hi\\there.foo.txt", with_filestem, "here", "hi\\here.txt"); - t!(s: "hi\\there", with_filestem, "here", "hi\\here"); - t!(s: "hi\\there", with_filestem, "", "hi"); - t!(s: "hi", with_filestem, "", "."); - t!(s: "\\hi", with_filestem, "", "\\"); - t!(s: "hi\\there", with_filestem, "..", "."); - t!(s: "hi\\there", with_filestem, ".", "hi"); - t!(s: "hi\\there.", with_filestem, "foo", "hi\\foo."); - t!(s: "hi\\there.", with_filestem, "", "hi"); - t!(s: "hi\\there.", with_filestem, ".", "."); - t!(s: "hi\\there.", with_filestem, "..", "hi\\..."); - t!(s: "\\", with_filestem, "foo", "\\foo"); - t!(s: ".", with_filestem, "foo", "foo"); - t!(s: "hi\\there..", with_filestem, "here", "hi\\here."); - t!(s: "hi\\there..", with_filestem, "", "hi"); - // filestem setter calls filename setter internally, no need for extended tests - t!(s: "hi\\there.txt", with_extension, "exe", "hi\\there.exe"); t!(s: "hi\\there.txt", with_extension, "", "hi\\there"); t!(s: "hi\\there.txt", with_extension, ".", "hi\\there.."); @@ -2093,16 +1943,6 @@ mod tests { ) ) - t!(v: b!("a\\b\\c"), set_dirname, with_dirname, b!("d")); - t!(v: b!("a\\b\\c"), set_dirname, with_dirname, b!("d\\e")); - t!(s: "a\\b\\c", set_dirname, with_dirname, "d"); - t!(s: "a\\b\\c", set_dirname, with_dirname, "d\\e"); - t!(s: "\\", set_dirname, with_dirname, "foo"); - t!(s: "\\foo", set_dirname, with_dirname, "bar"); - t!(s: "a\\b\\c", set_dirname, with_dirname, ""); - t!(s: "..\\..", set_dirname, with_dirname, "x"); - t!(s: "foo", set_dirname, with_dirname, "..\\.."); - t!(v: b!("a\\b\\c"), set_filename, with_filename, b!("d")); t!(v: b!("\\"), set_filename, with_filename, b!("foo")); t!(s: "a\\b\\c", set_filename, with_filename, "d"); @@ -2111,13 +1951,6 @@ mod tests { t!(s: "a\\b", set_filename, with_filename, ""); t!(s: "a", set_filename, with_filename, ""); - t!(v: b!("hi\\there.txt"), set_filestem, with_filestem, b!("here")); - t!(s: "hi\\there.txt", set_filestem, with_filestem, "here"); - t!(s: "hi\\there.", set_filestem, with_filestem, "here"); - t!(s: "hi\\there", set_filestem, with_filestem, "here"); - t!(s: "hi\\there.txt", set_filestem, with_filestem, ""); - t!(s: "hi\\there", set_filestem, with_filestem, ""); - t!(v: b!("hi\\there.txt"), set_extension, with_extension, b!("exe")); t!(s: "hi\\there.txt", set_extension, with_extension, "exe"); t!(s: "hi\\there.", set_extension, with_extension, "txt"); @@ -2130,33 +1963,6 @@ mod tests { // will suffice. No need for the full set of prefix tests. } - #[test] - fn test_add_extension() { - macro_rules! t( - (s: $path:expr, $ext:expr, $exp:expr) => ( - { - let mut path = Path::new($path); - path.add_extension($ext); - assert_eq!(path.as_str(), Some($exp)); - } - ); - (v: $path:expr, $ext:expr, $exp:expr) => ( - { - let mut path = Path::new($path); - path.add_extension($ext); - assert_eq!(path.as_vec(), $exp); - } - ) - ) - - t!(v: b!("hi\\there.txt"), b!("foo"), b!("hi\\there.txt.foo")); - t!(v: b!("hi\\there"), b!("bar"), b!("hi\\there.bar")); - t!(v: b!("\\"), b!("foo"), b!("\\")); - t!(v: b!("."), b!("foo"), b!(".")); - t!(s: "hi\\there.", "foo", "hi\\there..foo"); - t!(s: "hi\\there.txt", "", "hi\\there.txt"); - } - #[test] fn test_getters() { macro_rules! t( @@ -2211,7 +2017,7 @@ mod tests { } #[test] - fn test_dir_file_path() { + fn test_dir_path() { t!(s: Path::new("hi\\there").dir_path(), "hi"); t!(s: Path::new("hi").dir_path(), "."); t!(s: Path::new("\\hi").dir_path(), "\\"); @@ -2219,24 +2025,7 @@ mod tests { t!(s: Path::new("..").dir_path(), ".."); t!(s: Path::new("..\\..").dir_path(), "..\\.."); - macro_rules! t( - ($path:expr, $exp:expr) => ( - { - let path = $path; - let left = path.and_then_ref(|p| p.as_str()); - assert_eq!(left, $exp); - } - ); - ) - - t!(Path::new("hi\\there").file_path(), Some("there")); - t!(Path::new("hi").file_path(), Some("hi")); - t!(Path::new(".").file_path(), None); - t!(Path::new("\\").file_path(), None); - t!(Path::new("..").file_path(), None); - t!(Path::new("..\\..").file_path(), None); - - // dir_path and file_path are just dirname and filename interpreted as paths. + // dir_path is just dirname interpreted as a path. // No need for extended tests }