diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 5e3cbe45ef2fe..a8b0c117b8c1a 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -13,8 +13,8 @@ pub enum Either { Right(U) } -pub fn either(f_left: fn((&T)) -> V, - f_right: fn((&U)) -> V, value: &Either) -> V { +pub fn either(f_left: fn(&T) -> V, + f_right: fn(&U) -> V, value: &Either) -> V { /*! * Applies a function based on the given either value * diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index 7ed43f619e13e..be932ce55582e 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -48,6 +48,7 @@ pub use types::common::posix88::*; pub use types::common::posix01::*; pub use types::common::posix08::*; pub use types::common::bsd44::*; +pub use types::os::common::posix01::*; pub use types::os::arch::c95::*; pub use types::os::arch::c99::*; pub use types::os::arch::posix88::*; @@ -69,12 +70,13 @@ pub use funcs::c95::stdio::*; pub use funcs::c95::stdlib::*; pub use funcs::c95::string::*; -pub use funcs::posix88::stat::*; +pub use funcs::posix88::stat_::*; pub use funcs::posix88::stdio::*; pub use funcs::posix88::fcntl::*; pub use funcs::posix88::dirent::*; pub use funcs::posix88::unistd::*; +pub use funcs::posix01::stat_::*; pub use funcs::posix01::unistd::*; pub use funcs::posix08::unistd::*; @@ -122,6 +124,8 @@ pub use open, creat; pub use access, chdir, close, dup, dup2, execv, execve, execvp, getcwd, getpid, isatty, lseek, pipe, read, rmdir, unlink, write; +pub use fstat, lstat, stat; + mod types { @@ -158,6 +162,10 @@ mod types { #[cfg(target_os = "linux")] pub mod os { + pub mod common { + pub mod posix01 {} + } + #[cfg(target_arch = "x86")] pub mod arch { pub mod c95 { @@ -195,7 +203,33 @@ mod types { pub type mode_t = u32; pub type ssize_t = i32; } - pub mod posix01 {} + pub mod posix01 { + pub type nlink_t = u32; + pub type blksize_t = i32; + pub type blkcnt_t = i32; + pub struct stat { + st_dev: dev_t, + __pad1: c_short, + st_ino: ino_t, + st_mode: mode_t, + st_nlink: nlink_t, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: dev_t, + __pad2: c_short, + st_size: off_t, + st_blksize: blksize_t, + st_blocks: blkcnt_t, + st_atime: time_t, + st_atime_nsec: c_long, + st_mtime: time_t, + st_mtime_nsec: c_long, + st_ctime: time_t, + st_ctime_nsec: c_long, + __unused4: c_long, + __unused5: c_long, + } + } pub mod posix08 {} pub mod bsd44 {} pub mod extra {} @@ -239,6 +273,29 @@ mod types { pub type ssize_t = i64; } pub mod posix01 { + pub type nlink_t = u64; + pub type blksize_t = i64; + pub type blkcnt_t = i64; + pub struct stat { + st_dev: dev_t, + st_ino: ino_t, + st_nlink: nlink_t, + st_mode: mode_t, + st_uid: uid_t, + st_gid: gid_t, + __pad0: c_int, + st_rdev: dev_t, + st_size: off_t, + st_blksize: blksize_t, + st_blocks: blkcnt_t, + st_atime: time_t, + st_atime_nsec: c_long, + st_mtime: time_t, + st_mtime_nsec: c_long, + st_ctime: time_t, + st_ctime_nsec: c_long, + __unused: [c_long * 3], + } } pub mod posix08 { } @@ -251,6 +308,10 @@ mod types { #[cfg(target_os = "freebsd")] pub mod os { + pub mod common { + pub mod posix01 {} + } + #[cfg(target_arch = "x86_64")] pub mod arch { pub mod c95 { @@ -289,6 +350,34 @@ mod types { pub type ssize_t = i64; } pub mod posix01 { + pub type nlink_t = u16; + pub type blksize_t = i64; + pub type blkcnt_t = i64; + pub type fflags_t = u32; + pub struct stat { + st_dev: dev_t, + st_ino: ino_t, + st_mode: mode_t, + st_nlink: nlink_t, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: dev_t, + st_atime: time_t, + st_atime_nsec: c_long, + st_mtime: time_t, + st_mtime_nsec: c_long, + st_ctime: time_t, + st_ctime_nsec: c_long, + st_size: off_t, + st_blocks: blkcnt_t, + st_blksize: blksize_t, + st_flags: fflags_t, + st_gen: uint32_t, + st_lspare: int32_t, + st_birthtime: time_t, + st_birthtime_nsec: c_long, + __unused: [uint8_t * 2], + } } pub mod posix08 { } @@ -301,6 +390,24 @@ mod types { #[cfg(target_os = "win32")] pub mod os { + pub mod common { + pub mod posix01 { + pub struct stat { + st_dev: dev_t, + st_ino: ino_t, + st_mode: mode_t, + st_nlink: c_short, + st_uid: c_short, + st_gid: c_short, + st_rdev: dev_t, + st_size: int64_t, + st_atime: time64_t, + st_mtime: time64_t, + st_c_time: time64_t, + } + } + } + #[cfg(target_arch = "x86")] pub mod arch { pub mod c95 { @@ -378,6 +485,38 @@ mod types { #[cfg(target_os = "macos")] pub mod os { + pub mod common { + pub mod posix01 { + pub type nlink_t = u16; + pub type blksize_t = i64; + pub type blkcnt_t = i32; + pub struct stat { + st_dev: dev_t, + st_mode: mode_t, + st_nlink: nlink_t, + st_ino: ino_t, + st_uid: uid_t, + st_gid: gid_t, + st_rdev: dev_t, + st_atime: time_t, + st_atime_nsec: c_long, + st_mtime: time_t, + st_mtime_nsec: c_long, + st_ctime: time_t, + st_ctime_nsec: c_long, + st_birthtime: time_t, + st_birthtime_nsec: c_long, + st_size: off_t, + st_blocks: blkcnt_t, + st_blksize: blksize_t, + st_flags: uint32_t, + st_gen: uint32_t, + st_lspare: int32_t, + st_qspare: [int64_t * 2], + } + } + } + #[cfg(target_arch = "x86")] pub mod arch { pub mod c95 { @@ -880,7 +1019,7 @@ pub mod funcs { pub mod posix88 { #[nolink] #[abi = "cdecl"] - pub extern mod stat { + pub extern mod stat_ { #[link_name = "_chmod"] fn chmod(path: *c_char, mode: c_int) -> c_int; @@ -990,11 +1129,28 @@ pub mod funcs { pub mod posix88 { #[nolink] #[abi = "cdecl"] - pub extern mod stat { + pub extern mod stat_ { fn chmod(path: *c_char, mode: mode_t) -> c_int; fn fchmod(fd: c_int, mode: mode_t) -> c_int; + + #[cfg(target_os = "linux")] + #[cfg(target_os = "freebsd")] + fn fstat(fildes: c_int, buf: *mut stat) -> c_int; + + #[cfg(target_os = "macos")] + #[link_name = "fstat64"] + fn fstat(fildes: c_int, buf: *mut stat) -> c_int; + fn mkdir(path: *c_char, mode: mode_t) -> c_int; - fn mkfifo(ath: *c_char, mode: mode_t) -> c_int; + fn mkfifo(path: *c_char, mode: mode_t) -> c_int; + + #[cfg(target_os = "linux")] + #[cfg(target_os = "freebsd")] + fn stat(path: *c_char, buf: *mut stat) -> c_int; + + #[cfg(target_os = "macos")] + #[link_name = "stat64"] + fn stat(path: *c_char, buf: *mut stat) -> c_int; } #[nolink] @@ -1079,6 +1235,18 @@ pub mod funcs { #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] pub mod posix01 { + #[nolink] + #[abi = "cdecl"] + pub extern mod stat_ { + #[cfg(target_os = "linux")] + #[cfg(target_os = "freebsd")] + fn lstat(path: *c_char, buf: *mut stat) -> c_int; + + #[cfg(target_os = "macos")] + #[link_name = "lstat64"] + fn lstat(path: *c_char, buf: *mut stat) -> c_int; + } + #[nolink] #[abi = "cdecl"] pub extern mod unistd { @@ -1106,6 +1274,10 @@ pub mod funcs { #[cfg(target_os = "win32")] pub mod posix01 { + #[nolink] + pub extern mod stat_ { + } + #[nolink] pub extern mod unistd { } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index a834bb84f8d87..80a9d685f0ec7 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -489,11 +489,11 @@ pub fn tmpdir() -> Path { } } /// Recursively walk a directory structure -pub fn walk_dir(p: &Path, f: fn((&Path)) -> bool) { +pub fn walk_dir(p: &Path, f: fn(&Path) -> bool) { walk_dir_(p, f); - fn walk_dir_(p: &Path, f: fn((&Path)) -> bool) -> bool { + fn walk_dir_(p: &Path, f: fn(&Path) -> bool) -> bool { let mut keepgoing = true; do list_dir(p).each |q| { let path = &p.push(*q); @@ -595,7 +595,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { * This version prepends each entry with the directory. */ pub fn list_dir_path(p: &Path) -> ~[~Path] { - os::list_dir(p).map(|f| ~p.push(*f)) + list_dir(p).map(|f| ~p.push(*f)) } /// Removes a directory at the specified path diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 5f570ed434ec6..a31be1ab15be3 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -17,14 +17,22 @@ pub struct WindowsPath { components: ~[~str], } +pub pure fn WindowsPath(s: &str) -> WindowsPath { + from_str(s) +} + pub struct PosixPath { is_absolute: bool, components: ~[~str], } +pub pure fn PosixPath(s: &str) -> PosixPath { + from_str(s) +} + pub trait GenericPath { - static pure fn from_str((&str)) -> self; + static pure fn from_str(&str) -> self; pure fn dirname() -> ~str; pure fn filename() -> Option<~str>; @@ -49,7 +57,7 @@ pub type Path = WindowsPath; #[cfg(windows)] pub pure fn Path(s: &str) -> Path { - from_str::(s) + WindowsPath(s) } #[cfg(unix)] @@ -57,7 +65,271 @@ pub type Path = PosixPath; #[cfg(unix)] pub pure fn Path(s: &str) -> Path { - from_str::(s) + PosixPath(s) +} + +#[cfg(target_os = "linux")] +mod stat { + #[cfg(target_arch = "x86")] + pub mod arch { + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + __pad1: 0, + st_ino: 0, + st_mode: 0, + st_nlink: 0, + st_uid: 0, + st_gid: 0, + st_rdev: 0, + __pad2: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atime: 0, + st_atime_nsec: 0, + st_mtime: 0, + st_mtime_nsec: 0, + st_ctime: 0, + st_ctime_nsec: 0, + __unused4: 0, + __unused5: 0, + } + } + } + + #[cfg(target_arch = "x86_64")] + pub mod arch { + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + st_ino: 0, + st_nlink: 0, + st_mode: 0, + st_uid: 0, + st_gid: 0, + __pad0: 0, + st_rdev: 0, + st_size: 0, + st_blksize: 0, + st_blocks: 0, + st_atime: 0, + st_atime_nsec: 0, + st_mtime: 0, + st_mtime_nsec: 0, + st_ctime: 0, + st_ctime_nsec: 0, + __unused: [0, 0, 0], + } + } + } +} + +#[cfg(target_os = "freebsd")] +mod stat { + #[cfg(target_arch = "x86_64")] + pub mod arch { + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + st_ino: 0, + st_mode: 0, + st_nlink: 0, + st_uid: 0, + st_gid: 0, + st_rdev: 0, + st_atime: 0, + st_atime_nsec: 0, + st_mtime: 0, + st_mtime_nsec: 0, + st_ctime: 0, + st_ctime_nsec: 0, + st_size: 0, + st_blocks: 0, + st_blksize: 0, + st_flags: 0, + st_gen: 0, + st_lspare: 0, + st_birthtime: 0, + st_birthtime_nsec: 0, + __unused: [0, 0], + } + } + } +} + +#[cfg(target_os = "macos")] +mod stat { + pub mod arch { + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + st_mode: 0, + st_nlink: 0, + st_ino: 0, + st_uid: 0, + st_gid: 0, + st_rdev: 0, + st_atime: 0, + st_atime_nsec: 0, + st_mtime: 0, + st_mtime_nsec: 0, + st_ctime: 0, + st_ctime_nsec: 0, + st_birthtime: 0, + st_birthtime_nsec: 0, + st_size: 0, + st_blocks: 0, + st_blksize: 0, + st_flags: 0, + st_gen: 0, + st_lspare: 0, + st_qspare: [0, 0], + } + } + } +} + +#[cfg(target_os = "windows")] +mod stat { + pub mod arch { + pub fn default_stat() -> libc::stat { + libc::stat { + st_dev: 0, + st_ino: 0, + st_mode: 0, + st_nlink: 0, + st_uid: 0, + st_gid: 0, + st_rdev: 0, + st_size: 0, + st_atime: 0, + st_mtime: 0, + st_ctime: 0, + } + } + } +} + + +impl Path { + fn stat(&self) -> Option { + do str::as_c_str(self.to_str()) |buf| { + let mut st = stat::arch::default_stat(); + let r = libc::stat(buf, ptr::mut_addr_of(&st)); + + if r == 0 { Some(move st) } else { None } + } + } + + fn lstat(&self) -> Option { + do str::as_c_str(self.to_str()) |buf| { + let mut st = stat::arch::default_stat(); + let r = libc::lstat(buf, ptr::mut_addr_of(&st)); + + if r == 0 { Some(move st) } else { None } + } + } + + fn exists(&self) -> bool { + match self.stat() { + None => false, + Some(_) => true, + } + } + + fn get_size(&self) -> Option { + match self.stat() { + None => None, + Some(ref st) => Some(st.st_size as i64), + } + } + + fn get_mode(&self) -> Option { + match self.stat() { + None => None, + Some(ref st) => Some(st.st_mode as uint), + } + } +} + +#[cfg(target_os = "freebsd")] +#[cfg(target_os = "linux")] +#[cfg(target_os = "macos")] +impl Path { + fn get_atime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_atime as i64, + st.st_atime_nsec as int)) + } + } + } + + fn get_mtime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_mtime as i64, + st.st_mtime_nsec as int)) + } + } + } + + fn get_ctime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_ctime as i64, + st.st_ctime_nsec as int)) + } + } + } +} + +#[cfg(target_os = "freebsd")] +#[cfg(target_os = "macos")] +impl Path { + fn get_birthtime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_birthtime as i64, + st.st_birthtime_nsec as int)) + } + } + } +} + +#[cfg(target_os = "win32")] +impl Path { + fn get_atime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_atime as i64, 0)) + } + } + } + + fn get_mtime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_mtime as i64, 0)) + } + } + } + + fn get_ctime(&self) -> Option<(i64, int)> { + match self.stat() { + None => None, + Some(ref st) => { + Some((st.st_ctime as i64, 0)) + } + } + } } impl PosixPath : ToStr { @@ -166,7 +438,7 @@ impl PosixPath : GenericPath { } pure fn with_dirname(d: &str) -> PosixPath { - let dpath = from_str::(d); + let dpath = PosixPath(d); match self.filename() { Some(ref f) => dpath.push(*f), None => move dpath @@ -365,7 +637,7 @@ impl WindowsPath : GenericPath { } pure fn with_dirname(d: &str) -> WindowsPath { - let dpath = from_str::(d); + let dpath = WindowsPath(d); match self.filename() { Some(ref f) => dpath.push(*f), None => move dpath @@ -490,90 +762,132 @@ pub pure fn normalize(components: &[~str]) -> ~[~str] { move cs } -#[test] -fn test_double_slash_collapsing() -{ - let path = from_str::("tmp/"); - let path = path.push("/hmm"); - let path = path.normalize(); - assert ~"tmp/hmm" == path.to_str(); - - let path = from_str::("tmp/"); - let path = path.push("/hmm"); - let path = path.normalize(); - assert ~"tmp\\hmm" == path.to_str(); -} - -mod posix { +// Various windows helpers, and tests for the impl. +mod windows { + #[inline(always)] + pub pure fn is_sep(u: u8) -> bool { + u == '/' as u8 || u == '\\' as u8 + } - #[cfg(test)] - fn mk(s: &str) -> PosixPath { from_str::(s) } + pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { + if (s.len() > 1 && + s[0] == '\\' as u8 && + s[1] == '\\' as u8) { + let mut i = 2; + while i < s.len() { + if s[i] == '\\' as u8 { + let pre = s.slice(2, i); + let rest = s.slice(i, s.len()); + return Some((move pre, move rest)); + } + i += 1; + } + } + None + } - #[cfg(test)] - fn t(wp: &PosixPath, s: &str) { - let ss = wp.to_str(); - let sss = str::from_slice(s); - if (ss != sss) { - debug!("got %s", ss); - debug!("expected %s", sss); - assert ss == sss; + pub pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { + unsafe { + if (s.len() > 1 && + libc::isalpha(s[0] as libc::c_int) != 0 && + s[1] == ':' as u8) { + let rest = if s.len() == 2 { + ~"" + } else { + s.slice(2, s.len()) + }; + return Some((s.slice(0,1), move rest)); + } + None } } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_double_slash_collapsing() { + let path = PosixPath("tmp/"); + let path = path.push("/hmm"); + let path = path.normalize(); + assert ~"tmp/hmm" == path.to_str(); + + let path = WindowsPath("tmp/"); + let path = path.push("/hmm"); + let path = path.normalize(); + assert ~"tmp\\hmm" == path.to_str(); + } #[test] fn test_filetype_foo_bar() { - let wp = mk("foo.bar"); + let wp = PosixPath("foo.bar"); + assert wp.filetype() == Some(~".bar"); + + let wp = WindowsPath("foo.bar"); assert wp.filetype() == Some(~".bar"); } #[test] fn test_filetype_foo() { - let wp = mk("foo"); + let wp = PosixPath("foo"); + assert wp.filetype() == None; + + let wp = WindowsPath("foo"); assert wp.filetype() == None; } #[test] fn test_posix_paths() { - t(&(mk("hi")), "hi"); - t(&(mk("/lib")), "/lib"); - t(&(mk("hi/there")), "hi/there"); - t(&(mk("hi/there.txt")), "hi/there.txt"); + fn t(wp: &PosixPath, s: &str) { + let ss = wp.to_str(); + let sss = str::from_slice(s); + if (ss != sss) { + debug!("got %s", ss); + debug!("expected %s", sss); + assert ss == sss; + } + } + + t(&(PosixPath("hi")), "hi"); + t(&(PosixPath("/lib")), "/lib"); + t(&(PosixPath("hi/there")), "hi/there"); + t(&(PosixPath("hi/there.txt")), "hi/there.txt"); - t(&(mk("hi/there.txt")), "hi/there.txt"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt")), "hi/there.txt"); + t(&(PosixPath("hi/there.txt") .with_filetype("")), "hi/there"); - t(&(mk("/a/b/c/there.txt") + t(&(PosixPath("/a/b/c/there.txt") .with_dirname("hi")), "hi/there.txt"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt") .with_dirname(".")), "./there.txt"); - t(&(mk("a/b/c") + t(&(PosixPath("a/b/c") .push("..")), "a/b/c/.."); - t(&(mk("there.txt") + t(&(PosixPath("there.txt") .with_filetype("o")), "there.o"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt") .with_filetype("o")), "hi/there.o"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt") .with_filetype("o") .with_dirname("/usr/lib")), "/usr/lib/there.o"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt") .with_filetype("o") .with_dirname("/usr/lib/")), "/usr/lib/there.o"); - t(&(mk("hi/there.txt") + t(&(PosixPath("hi/there.txt") .with_filetype("o") .with_dirname("/usr//lib//")), "/usr/lib/there.o"); - t(&(mk("/usr/bin/rust") + t(&(PosixPath("/usr/bin/rust") .push_many([~"lib", ~"thingy.so"]) .with_filestem("librustc")), "/usr/bin/rust/lib/librustc.so"); @@ -582,86 +896,55 @@ mod posix { #[test] fn test_normalize() { - t(&(mk("hi/there.txt") + fn t(wp: &PosixPath, s: &str) { + let ss = wp.to_str(); + let sss = str::from_slice(s); + if (ss != sss) { + debug!("got %s", ss); + debug!("expected %s", sss); + assert ss == sss; + } + } + + t(&(PosixPath("hi/there.txt") .with_dirname(".").normalize()), "there.txt"); - t(&(mk("a/b/../c/././/../foo.txt/").normalize()), + t(&(PosixPath("a/b/../c/././/../foo.txt/").normalize()), "a/foo.txt"); - t(&(mk("a/b/c") + t(&(PosixPath("a/b/c") .push("..").normalize()), "a/b"); } -} - -// Various windows helpers, and tests for the impl. -mod windows { - - #[inline(always)] - pub pure fn is_sep(u: u8) -> bool { - u == '/' as u8 || u == '\\' as u8 - } - - pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { - if (s.len() > 1 && - s[0] == '\\' as u8 && - s[1] == '\\' as u8) { - let mut i = 2; - while i < s.len() { - if s[i] == '\\' as u8 { - let pre = s.slice(2, i); - let rest = s.slice(i, s.len()); - return Some((move pre, move rest)); - } - i += 1; - } - } - None - } - - pub pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { - unsafe { - if (s.len() > 1 && - libc::isalpha(s[0] as libc::c_int) != 0 && - s[1] == ':' as u8) { - let rest = if s.len() == 2 { - ~"" - } else { - s.slice(2, s.len()) - }; - return Some((s.slice(0,1), move rest)); - } - None - } - } #[test] fn test_extract_unc_prefixes() { - assert extract_unc_prefix("\\\\").is_none(); - assert extract_unc_prefix("\\\\hi").is_none(); - assert extract_unc_prefix("\\\\hi\\") == Some((~"hi", ~"\\")); - assert extract_unc_prefix("\\\\hi\\there") == + assert windows::extract_unc_prefix("\\\\").is_none(); + assert windows::extract_unc_prefix("\\\\hi").is_none(); + assert windows::extract_unc_prefix("\\\\hi\\") == + Some((~"hi", ~"\\")); + assert windows::extract_unc_prefix("\\\\hi\\there") == Some((~"hi", ~"\\there")); - assert extract_unc_prefix("\\\\hi\\there\\friends.txt") == + assert windows::extract_unc_prefix("\\\\hi\\there\\friends.txt") == Some((~"hi", ~"\\there\\friends.txt")); } #[test] fn test_extract_drive_prefixes() { - assert extract_drive_prefix("c").is_none(); - assert extract_drive_prefix("c:") == Some((~"c", ~"")); - assert extract_drive_prefix("d:") == Some((~"d", ~"")); - assert extract_drive_prefix("z:") == Some((~"z", ~"")); - assert extract_drive_prefix("c:\\hi") == Some((~"c", ~"\\hi")); - assert extract_drive_prefix("d:hi") == Some((~"d", ~"hi")); - assert extract_drive_prefix("c:hi\\there.txt") == + assert windows::extract_drive_prefix("c").is_none(); + assert windows::extract_drive_prefix("c:") == Some((~"c", ~"")); + assert windows::extract_drive_prefix("d:") == Some((~"d", ~"")); + assert windows::extract_drive_prefix("z:") == Some((~"z", ~"")); + assert windows::extract_drive_prefix("c:\\hi") == + Some((~"c", ~"\\hi")); + assert windows::extract_drive_prefix("d:hi") == Some((~"d", ~"hi")); + assert windows::extract_drive_prefix("c:hi\\there.txt") == Some((~"c", ~"hi\\there.txt")); - assert extract_drive_prefix("c:\\hi\\there.txt") == + assert windows::extract_drive_prefix("c:\\hi\\there.txt") == Some((~"c", ~"\\hi\\there.txt")); } #[test] fn test_windows_paths() { - fn mk(s: &str) -> WindowsPath { from_str::(s) } fn t(wp: &WindowsPath, s: &str) { let ss = wp.to_str(); let sss = str::from_slice(s); @@ -672,51 +955,34 @@ mod windows { } } - t(&(mk("hi")), "hi"); - t(&(mk("hi/there")), "hi\\there"); - t(&(mk("hi/there.txt")), "hi\\there.txt"); + t(&(WindowsPath("hi")), "hi"); + t(&(WindowsPath("hi/there")), "hi\\there"); + t(&(WindowsPath("hi/there.txt")), "hi\\there.txt"); - t(&(mk("there.txt") + t(&(WindowsPath("there.txt") .with_filetype("o")), "there.o"); - t(&(mk("hi/there.txt") + t(&(WindowsPath("hi/there.txt") .with_filetype("o")), "hi\\there.o"); - t(&(mk("hi/there.txt") + t(&(WindowsPath("hi/there.txt") .with_filetype("o") .with_dirname("c:\\program files A")), "c:\\program files A\\there.o"); - t(&(mk("hi/there.txt") + t(&(WindowsPath("hi/there.txt") .with_filetype("o") .with_dirname("c:\\program files B\\")), "c:\\program files B\\there.o"); - t(&(mk("hi/there.txt") + t(&(WindowsPath("hi/there.txt") .with_filetype("o") .with_dirname("c:\\program files C\\/")), "c:\\program files C\\there.o"); - t(&(mk("c:\\program files (x86)\\rust") + t(&(WindowsPath("c:\\program files (x86)\\rust") .push_many([~"lib", ~"thingy.dll"]) .with_filename("librustc.dll")), "c:\\program files (x86)\\rust\\lib\\librustc.dll"); - } - - #[cfg(test)] - fn mk(s: &str) -> PosixPath { from_str::(s) } - - #[test] - fn test_filetype_foo_bar() { - let wp = mk("foo.bar"); - assert wp.filetype() == Some(~".bar"); - } - - #[test] - fn test_filetype_foo() { - let wp = mk("foo"); - assert wp.filetype() == None; - } - } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 6a4923eb0477a..0eee413cdad00 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -140,7 +140,7 @@ impl ReprVisitor { // Various helpers for the TyVisitor impl #[inline(always)] - fn get(f: fn((&T))) -> bool { + fn get(f: fn(&T)) -> bool { unsafe { f(transmute::<*c_void,&T>(copy self.ptr)); } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 31d813dad92c6..5c59f429fd466 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -143,7 +143,7 @@ pub fn chain_err( * print_buf(buf) * } */ -pub fn iter(res: &Result, f: fn((&T))) { +pub fn iter(res: &Result, f: fn(&T)) { match *res { Ok(ref t) => f(t), Err(_) => () @@ -158,7 +158,7 @@ pub fn iter(res: &Result, f: fn((&T))) { * This function can be used to pass through a successful result while * handling an error. */ -pub fn iter_err(res: &Result, f: fn((&E))) { +pub fn iter_err(res: &Result, f: fn(&E)) { match *res { Ok(_) => (), Err(ref e) => f(e) @@ -179,7 +179,7 @@ pub fn iter_err(res: &Result, f: fn((&E))) { * parse_bytes(buf) * } */ -pub fn map(res: &Result, op: fn((&T)) -> U) +pub fn map(res: &Result, op: fn(&T) -> U) -> Result { match *res { Ok(ref t) => Ok(op(t)), @@ -195,7 +195,7 @@ pub fn map(res: &Result, op: fn((&T)) -> U) * is immediately returned. This function can be used to pass through a * successful result while handling an error. */ -pub fn map_err(res: &Result, op: fn((&E)) -> F) +pub fn map_err(res: &Result, op: fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -210,14 +210,14 @@ impl Result { pure fn is_err() -> bool { is_err(&self) } - pure fn iter(f: fn((&T))) { + pure fn iter(f: fn(&T)) { match self { Ok(ref t) => f(t), Err(_) => () } } - fn iter_err(f: fn((&E))) { + fn iter_err(f: fn(&E)) { match self { Ok(_) => (), Err(ref e) => f(e) @@ -228,7 +228,7 @@ impl Result { impl Result { pure fn get() -> T { get(&self) } - fn map_err(op: fn((&E)) -> F) -> Result { + fn map_err(op: fn(&E) -> F) -> Result { match self { Ok(copy t) => Ok(t), Err(ref e) => Err(op(e)) @@ -239,7 +239,7 @@ impl Result { impl Result { pure fn get_err() -> E { get_err(&self) } - fn map(op: fn((&T)) -> U) -> Result { + fn map(op: fn(&T) -> U) -> Result { match self { Ok(ref t) => Ok(op(t)), Err(copy e) => Err(e) @@ -277,7 +277,7 @@ impl Result { * } */ pub fn map_vec( - ts: &[T], op: fn((&T)) -> Result) -> Result<~[V],U> { + ts: &[T], op: fn(&T) -> Result) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(vec::len(ts)); for vec::each(ts) |t| { @@ -290,7 +290,7 @@ pub fn map_vec( } pub fn map_opt( - o_t: &Option, op: fn((&T)) -> Result) -> Result,U> { + o_t: &Option, op: fn(&T) -> Result) -> Result,U> { match *o_t { None => Ok(None), @@ -311,7 +311,7 @@ pub fn map_opt( * to accommodate an error like the vectors being of different lengths. */ pub fn map_vec2(ss: &[S], ts: &[T], - op: fn((&S),(&T)) -> Result) -> Result<~[V],U> { + op: fn(&S,&T) -> Result) -> Result<~[V],U> { assert vec::same_length(ss, ts); let n = vec::len(ts); @@ -333,7 +333,7 @@ pub fn map_vec2(ss: &[S], ts: &[T], * on its own as no result vector is built. */ pub fn iter_vec2(ss: &[S], ts: &[T], - op: fn((&S),(&T)) -> Result<(),U>) -> Result<(),U> { + op: fn(&S,&T) -> Result<(),U>) -> Result<(),U> { assert vec::same_length(ss, ts); let n = vec::len(ts); diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 971eaf5c857eb..2d8d1cd9fd868 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1845,7 +1845,7 @@ const tag_six_b: uint = 252u; * let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) }; * ~~~ */ -pub pure fn as_bytes(s: &const ~str, f: fn((&~[u8])) -> T) -> T { +pub pure fn as_bytes(s: &const ~str, f: fn(&~[u8]) -> T) -> T { unsafe { let v: *~[u8] = cast::transmute(copy s); f(&*v) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index e7821c1246cd6..8e99317468def 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1099,7 +1099,7 @@ pub pure fn reversed(v: &[const T]) -> ~[T] { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn each(v: &r/[T], f: fn((&r/T)) -> bool) { +pub pure fn each(v: &r/[T], f: fn(&r/T) -> bool) { // ^^^^ // NB---this CANNOT be &[const T]! The reason // is that you are passing it to `f()` using diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index a1e29b03b4559..200193a48a8cf 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -53,7 +53,7 @@ pub fn find(m: Treemap, k: K) -> Option { } /// Visit all pairs in the map in order. -pub fn traverse(m: Treemap, f: fn((&K), (&V))) { +pub fn traverse(m: Treemap, f: fn(&K, &V)) { match *m { Empty => (), /* diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 17b487f16dee2..31144740c8ade 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -51,7 +51,7 @@ impl Future { get_ref(self) } - fn with(blk: fn((&A)) -> B) -> B { + fn with(blk: fn(&A) -> B) -> B { //! Work with the value without copying it with(&self, blk) @@ -164,7 +164,7 @@ pub fn get(future: &Future) -> A { *get_ref(future) } -pub fn with(future: &Future, blk: fn((&A)) -> B) -> B { +pub fn with(future: &Future, blk: fn(&A) -> B) -> B { //! Work with the value without copying it blk(get_ref(future)) diff --git a/src/libstd/list.rs b/src/libstd/list.rs index d30bc853f718f..35b9a92f5a816 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -29,7 +29,7 @@ pub fn from_vec(v: &[T]) -> @List { * * z - The initial value * * f - The function to apply */ -pub fn foldl(z: T, ls: @List, f: fn((&T), (&U)) -> T) -> T { +pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { let mut accum: T = z; do iter(ls) |elt| { accum = f(&accum, elt);} accum @@ -42,7 +42,7 @@ pub fn foldl(z: T, ls: @List, f: fn((&T), (&U)) -> T) -> T { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pub fn find(ls: @List, f: fn((&T)) -> bool) -> Option { +pub fn find(ls: @List, f: fn(&T) -> bool) -> Option { let mut ls = ls; loop { ls = match *ls { @@ -120,7 +120,7 @@ pure fn push(ll: &mut @list, vv: T) { */ /// Iterate over a list -pub fn iter(l: @List, f: fn((&T))) { +pub fn iter(l: @List, f: fn(&T)) { let mut cur = l; loop { cur = match *cur { @@ -134,7 +134,7 @@ pub fn iter(l: @List, f: fn((&T))) { } /// Iterate over a list -pub fn each(l: @List, f: fn((&T)) -> bool) { +pub fn each(l: @List, f: fn(&T) -> bool) { let mut cur = l; loop { cur = match *cur { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 1d4476c2a2ae0..73529fd2a93f1 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -45,9 +45,9 @@ pub pure fn merge_sort(v: &[const T], le: Le) -> ~[T] { a_ix += 1; } else { rs.push(b[b_ix]); b_ix += 1; } } - rs = vec::append(rs, vec::slice(a, a_ix, a_len)); - rs = vec::append(rs, vec::slice(b, b_ix, b_len)); - return rs; + rs.push_all(vec::slice(a, a_ix, a_len)); + rs.push_all(vec::slice(b, b_ix, b_len)); + move rs } } @@ -786,11 +786,11 @@ mod test_qsort { let expected = ~[1, 2, 3]; - do sort::quick_sort(names) |x, y| { int::le(*x, *y) }; + do quick_sort(names) |x, y| { int::le(*x, *y) }; let immut_names = vec::from_mut(move names); - let pairs = vec::zip(expected, immut_names); + let pairs = vec::zip_slice(expected, immut_names); for vec::each(pairs) |p| { let (a, b) = *p; debug!("%d %d", a, b); @@ -867,7 +867,7 @@ mod tests { #[cfg(test)] mod test_tim_sort { struct CVal { - val: ~float, + val: float, } impl CVal: Ord { @@ -948,14 +948,14 @@ mod test_tim_sort { let rng = rand::Rng(); let mut arr = do vec::from_fn(1000) |_i| { let randVal = rng.gen_float(); - CVal { val: ~randVal } + CVal { val: randVal } }; tim_sort(arr); fail ~"Guarantee the fail"; } - struct DVal { val: ~uint } + struct DVal { val: uint } #[cfg(stage0)] impl DVal: Ord { @@ -979,7 +979,7 @@ mod test_tim_sort { let rng = rand::Rng(); let mut arr = do vec::from_fn(500) |_i| { let randVal = rng.gen_uint(); - DVal { val: ~randVal } + DVal { val: randVal } }; tim_sort(arr); @@ -1032,7 +1032,7 @@ mod big_tests { for uint::range(lo, hi) |i| { let n = 1 << i; let arr = do vec::from_fn(n) |_i| { - ~rng.gen_float() + rng.gen_float() }; let arr = vec::to_mut(move arr); @@ -1058,7 +1058,7 @@ mod big_tests { let size = arr.len(); let mut idx = 1; while idx <= 10 { - arr[size-idx] = ~rng.gen_float(); + arr[size-idx] = rng.gen_float(); idx += 1; } } @@ -1067,7 +1067,7 @@ mod big_tests { for (n/100).times { let idx = rng.gen_uint_range(0, n); - arr[idx] = ~rng.gen_float(); + arr[idx] = rng.gen_float(); } tim_sort(arr); isSorted(arr); @@ -1079,12 +1079,12 @@ mod big_tests { tim_sort(arr); // ~sort isSorted(arr); - let mut arr = vec::from_elem(n, ~(-0.5)); + let mut arr = vec::from_elem(n, -0.5); tim_sort(arr); // =sort isSorted(arr); let half = n / 2; - let mut arr = makeRange(half).map(|i| ~(*i as float)); + let mut arr = makeRange(half).map(|i| *i as float); tim_sort(arr); // !sort isSorted(arr); } diff --git a/src/test/run-pass/stat.rs b/src/test/run-pass/stat.rs new file mode 100644 index 0000000000000..2036e1bae783a --- /dev/null +++ b/src/test/run-pass/stat.rs @@ -0,0 +1,24 @@ +extern mod std; +use io::WriterUtil; +use std::tempfile; + +fn main() { + let dir = option::unwrap(tempfile::mkdtemp(&Path("."), "")); + let path = dir.with_filename("file"); + + { + match io::file_writer(&path, [io::Create, io::Truncate]) { + Err(e) => fail e, + Ok(f) => { + for uint::range(0, 1000) |_i| { + f.write_u8(0); + } + } + } + } + + assert path.exists(); + assert path.get_size() == Some(1000); + + os::remove_dir(&dir); +}