diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/c_str.rs | 50 | ||||
| -rw-r--r-- | src/libstd/condition.rs | 349 | ||||
| -rw-r--r-- | src/libstd/fmt/parse.rs | 65 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 3 | ||||
| -rw-r--r-- | src/libstd/macros.rs | 44 | ||||
| -rw-r--r-- | src/libstd/path/mod.rs | 85 | ||||
| -rw-r--r-- | src/libstd/path/posix.rs | 86 | ||||
| -rw-r--r-- | src/libstd/path/windows.rs | 88 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 1 |
9 files changed, 78 insertions, 693 deletions
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 7e79ad97df0..6fc31b673ac 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -75,24 +75,11 @@ use ptr::RawPtr; use ptr; use str::StrSlice; use str; -use vec::{CloneableVector, ImmutableVector, MutableVector}; +use vec::{ImmutableVector, MutableVector}; use vec; use unstable::intrinsics; use rt::global_heap::malloc_raw; -/// Resolution options for the `null_byte` condition -pub enum NullByteResolution { - /// Truncate at the null byte - Truncate, - /// Use a replacement byte - ReplaceWith(libc::c_char) -} - -condition! { - // This should be &[u8] but there's a lifetime issue (#5370). - pub null_byte: (~[u8]) -> NullByteResolution; -} - /// The representation of a C String. /// /// This structure wraps a `*libc::c_char`, and will automatically free the @@ -252,7 +239,7 @@ pub trait ToCStr { /// /// # Failure /// - /// Raises the `null_byte` condition if the receiver has an interior null. + /// Fails the task if the receiver has an interior null. fn to_c_str(&self) -> CString; /// Unsafe variant of `to_c_str()` that doesn't check for nulls. @@ -273,7 +260,7 @@ pub trait ToCStr { /// /// # Failure /// - /// Raises the `null_byte` condition if the receiver has an interior null. + /// Fails the task if the receiver has an interior null. #[inline] fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T { self.to_c_str().with_ref(f) @@ -362,12 +349,7 @@ fn check_for_null(v: &[u8], buf: *mut libc::c_char) { for i in range(0, v.len()) { unsafe { let p = buf.offset(i as int); - if *p == 0 { - match null_byte::cond.raise(v.to_owned()) { - Truncate => break, - ReplaceWith(c) => *p = c - } - } + assert!(*p != 0); } } } @@ -541,29 +523,9 @@ mod tests { #[test] fn test_to_c_str_fail() { - use c_str::null_byte::cond; - + use task; let mut error_happened = false; - cond.trap(|err| { - assert_eq!(err, bytes!("he", 0, "llo").to_owned()) - error_happened = true; - Truncate - }).inside(|| "he\x00llo".to_c_str()); - assert!(error_happened); - - cond.trap(|_| { - ReplaceWith('?' as libc::c_char) - }).inside(|| "he\x00llo".to_c_str()).with_ref(|buf| { - unsafe { - assert_eq!(*buf.offset(0), 'h' as libc::c_char); - assert_eq!(*buf.offset(1), 'e' as libc::c_char); - assert_eq!(*buf.offset(2), '?' as libc::c_char); - assert_eq!(*buf.offset(3), 'l' as libc::c_char); - assert_eq!(*buf.offset(4), 'l' as libc::c_char); - assert_eq!(*buf.offset(5), 'o' as libc::c_char); - assert_eq!(*buf.offset(6), 0); - } - }) + assert!(task::try(proc() { "he\x00llo".to_c_str() }).is_err()); } #[test] diff --git a/src/libstd/condition.rs b/src/libstd/condition.rs deleted file mode 100644 index e0dc5c8b65d..00000000000 --- a/src/libstd/condition.rs +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/*! - -Condition handling - -Conditions are a utility used to deal with handling error conditions. The syntax -of a condition handler strikes a resemblance to try/catch blocks in other -languages, but condition handlers are *not* a form of exception handling in the -same manner. - -A condition is declared through the `condition!` macro provided by the compiler: - -```rust -condition! { - pub my_error: int -> ~str; -} -# fn main() {} -``` - -This macro declares an inner module called `my_error` with one static variable, -`cond` that is a static `Condition` instance. To help understand what the other -parameters are used for, an example usage of this condition would be: - -```rust -# condition! { pub my_error: int -> ~str; } -# fn main() { - -my_error::cond.trap(|raised_int| { - - // the condition `my_error` was raised on, and the value it raised is stored - // in `raised_int`. This closure must return a `~str` type (as specified in - // the declaration of the condition - if raised_int == 3 { ~"three" } else { ~"oh well" } - -}).inside(|| { - - // The condition handler above is installed for the duration of this block. - // That handler will override any previous handler, but the previous handler - // is restored when this block returns (handlers nest) - // - // If any code from this block (or code from another block) raises on the - // condition, then the above handler will be invoked (so long as there's no - // other nested handler). - - println!("{}", my_error::cond.raise(3)); // prints "three" - println!("{}", my_error::cond.raise(4)); // prints "oh well" - -}) - -# } - ``` - -Condition handling is useful in cases where propagating errors is either to -cumbersome or just not necessary in the first place. It should also be noted, -though, that if there is not handler installed when a condition is raised, then -the task invokes `fail!()` and will terminate. - -## More Info - -Condition handlers as an error strategy is well explained in the [conditions -tutorial](http://static.rust-lang.org/doc/master/tutorial-conditions.html), -along with comparing and contrasting it with other error handling strategies. - -*/ - -use local_data; -use prelude::*; -use unstable::raw::Closure; - -#[doc(hidden)] -pub struct Handler<T, U> { - priv handle: Closure, - priv prev: Option<@Handler<T, U>>, -} - -/// This struct represents the state of a condition handler. It contains a key -/// into TLS which holds the currently install handler, along with the name of -/// the condition (useful for debugging). -/// -/// This struct should never be created directly, but rather only through the -/// `condition!` macro provided to all libraries using `std`. -pub struct Condition<T, U> { - /// Name of the condition handler - name: &'static str, - /// TLS key used to insert/remove values in TLS. - key: local_data::Key<@Handler<T, U>> -} - -impl<T, U> Condition<T, U> { - /// Creates an object which binds the specified handler. This will also save - /// the current handler *on creation* such that when the `Trap` is consumed, - /// it knows which handler to restore. - /// - /// # Example - /// - /// ```rust - /// condition! { my_error: int -> int; } - /// - /// # fn main() { - /// let trap = my_error::cond.trap(|error| error + 3); - /// - /// // use `trap`'s inside method to register the handler and then run a - /// // block of code with the handler registered - /// # } - /// ``` - pub fn trap<'a>(&'a self, h: 'a |T| -> U) -> Trap<'a, T, U> { - let h: Closure = unsafe { ::cast::transmute(h) }; - let prev = local_data::get(self.key, |k| k.map(|x| *x)); - let h = @Handler { handle: h, prev: prev }; - Trap { cond: self, handler: h } - } - - /// Raises on this condition, invoking any handler if one has been - /// registered, or failing the current task otherwise. - /// - /// While a condition handler is being run, the condition will have no - /// handler listed, so a task failure will occur if the condition is - /// re-raised during the handler. - /// - /// # Arguments - /// - /// * t - The argument to pass along to the condition handler. - /// - /// # Return value - /// - /// If a handler is found, its return value is returned, otherwise this - /// function will not return. - pub fn raise(&self, t: T) -> U { - let msg = format!("Unhandled condition: {}: {:?}", self.name, t); - self.raise_default(t, || fail!("{}", msg.clone())) - } - - /// Performs the same functionality as `raise`, except that when no handler - /// is found the `default` argument is called instead of failing the task. - pub fn raise_default(&self, t: T, default: || -> U) -> U { - match local_data::pop(self.key) { - None => { - debug!("Condition.raise: found no handler"); - default() - } - Some(handler) => { - debug!("Condition.raise: found handler"); - match handler.prev { - None => {} - Some(hp) => local_data::set(self.key, hp) - } - let handle : |T| -> U = unsafe { - ::cast::transmute(handler.handle) - }; - let u = handle(t); - local_data::set(self.key, handler); - u - } - } - } -} - -/// A `Trap` is created when the `trap` method is invoked on a `Condition`, and -/// it is used to actually bind a handler into the TLS slot reserved for this -/// condition. -/// -/// Normally this object is not dealt with directly, but rather it's directly -/// used after being returned from `trap` -pub struct Trap<'a, T, U> { - priv cond: &'a Condition<T, U>, - priv handler: @Handler<T, U> -} - -impl<'a, T, U> Trap<'a, T, U> { - /// Execute a block of code with this trap handler's exception handler - /// registered. - /// - /// # Example - /// - /// ```rust - /// condition! { my_error: int -> int; } - /// - /// # fn main() { - /// let result = my_error::cond.trap(|error| error + 3).inside(|| { - /// my_error::cond.raise(4) - /// }); - /// assert_eq!(result, 7); - /// # } - /// ``` - pub fn inside<V>(&self, inner: 'a || -> V) -> V { - let _g = Guard { cond: self.cond }; - debug!("Trap: pushing handler to TLS"); - local_data::set(self.cond.key, self.handler); - inner() - } - - /// Returns a guard that will automatically reset the condition upon - /// exit of the scope. This is useful if you want to use conditions with - /// an RAII pattern. - pub fn guard(&self) -> Guard<'a,T,U> { - let guard = Guard { - cond: self.cond - }; - debug!("Guard: pushing handler to TLS"); - local_data::set(self.cond.key, self.handler); - guard - } -} - -/// A guard that will automatically reset the condition handler upon exit of -/// the scope. This is useful if you want to use conditions with an RAII -/// pattern. -pub struct Guard<'a, T, U> { - priv cond: &'a Condition<T, U> -} - -#[unsafe_destructor] -impl<'a, T, U> Drop for Guard<'a, T, U> { - fn drop(&mut self) { - debug!("Guard: popping handler from TLS"); - let curr = local_data::pop(self.cond.key); - match curr { - None => {} - Some(h) => match h.prev { - None => {} - Some(hp) => local_data::set(self.cond.key, hp) - } - } - } -} - -#[cfg(test)] -mod test { - condition! { - sadness: int -> int; - } - - fn trouble(i: int) { - debug!("trouble: raising condition"); - let j = sadness::cond.raise(i); - debug!("trouble: handler recovered with {}", j); - } - - fn nested_trap_test_inner() { - let mut inner_trapped = false; - - sadness::cond.trap(|_j| { - debug!("nested_trap_test_inner: in handler"); - inner_trapped = true; - 0 - }).inside(|| { - debug!("nested_trap_test_inner: in protected block"); - trouble(1); - }); - - assert!(inner_trapped); - } - - #[test] - fn nested_trap_test_outer() { - let mut outer_trapped = false; - - sadness::cond.trap(|_j| { - debug!("nested_trap_test_outer: in handler"); - outer_trapped = true; 0 - }).inside(|| { - debug!("nested_guard_test_outer: in protected block"); - nested_trap_test_inner(); - trouble(1); - }); - - assert!(outer_trapped); - } - - fn nested_reraise_trap_test_inner() { - let mut inner_trapped = false; - - sadness::cond.trap(|_j| { - debug!("nested_reraise_trap_test_inner: in handler"); - inner_trapped = true; - let i = 10; - debug!("nested_reraise_trap_test_inner: handler re-raising"); - sadness::cond.raise(i) - }).inside(|| { - debug!("nested_reraise_trap_test_inner: in protected block"); - trouble(1); - }); - - assert!(inner_trapped); - } - - #[test] - fn nested_reraise_trap_test_outer() { - let mut outer_trapped = false; - - sadness::cond.trap(|_j| { - debug!("nested_reraise_trap_test_outer: in handler"); - outer_trapped = true; 0 - }).inside(|| { - debug!("nested_reraise_trap_test_outer: in protected block"); - nested_reraise_trap_test_inner(); - }); - - assert!(outer_trapped); - } - - #[test] - fn test_default() { - let mut trapped = false; - - sadness::cond.trap(|j| { - debug!("test_default: in handler"); - sadness::cond.raise_default(j, || { trapped=true; 5 }) - }).inside(|| { - debug!("test_default: in protected block"); - trouble(1); - }); - - assert!(trapped); - } - - // Issue #6009 - mod m { - condition! { - // #6009, #8215: should this truly need a `pub` for access from n? - pub sadness: int -> int; - } - - mod n { - use super::sadness; - - #[test] - fn test_conditions_are_public() { - let mut trapped = false; - sadness::cond.trap(|_| { - trapped = true; - 0 - }).inside(|| { - sadness::cond.raise(0); - }); - assert!(trapped); - } - } - } -} diff --git a/src/libstd/fmt/parse.rs b/src/libstd/fmt/parse.rs index 6c08eae7474..555fe29bed0 100644 --- a/src/libstd/fmt/parse.rs +++ b/src/libstd/fmt/parse.rs @@ -19,8 +19,6 @@ use prelude::*; use char; use str; -condition! { pub parse_error: ~str -> (); } - /// A piece is a portion of the format string which represents the next part to /// emit. These are emitted as a stream by the `Parser` class. #[deriving(Eq)] @@ -170,6 +168,8 @@ pub struct Parser<'a> { priv input: &'a str, priv cur: str::CharOffsets<'a>, priv depth: uint, + /// Error messages accumulated during parsing + errors: ~[~str], } impl<'a> Iterator<Piece<'a>> for Parser<'a> { @@ -207,14 +207,15 @@ impl<'a> Parser<'a> { input: s, cur: s.char_indices(), depth: 0, + errors: ~[], } } /// Notifies of an error. The message doesn't actually need to be of type /// ~str, but I think it does when this eventually uses conditions so it /// might as well start using it now. - fn err(&self, msg: &str) { - parse_error::cond.raise("invalid format string: " + msg); + fn err(&mut self, msg: &str) { + self.errors.push(msg.to_owned()); } /// Optionally consumes the specified character. If the character is not at @@ -671,7 +672,9 @@ mod tests { } fn musterr(s: &str) { - Parser::new(s).next(); + let mut p = Parser::new(s); + p.next(); + assert!(p.errors.len() != 0); } #[test] @@ -684,12 +687,12 @@ mod tests { same("\\}", ~[String("}")]); } - #[test] #[should_fail] fn invalid01() { musterr("{") } - #[test] #[should_fail] fn invalid02() { musterr("\\") } - #[test] #[should_fail] fn invalid03() { musterr("\\a") } - #[test] #[should_fail] fn invalid04() { musterr("{3a}") } - #[test] #[should_fail] fn invalid05() { musterr("{:|}") } - #[test] #[should_fail] fn invalid06() { musterr("{:>>>}") } + #[test] fn invalid01() { musterr("{") } + #[test] fn invalid02() { musterr("\\") } + #[test] fn invalid03() { musterr("\\a") } + #[test] fn invalid04() { musterr("{3a}") } + #[test] fn invalid05() { musterr("{:|}") } + #[test] fn invalid06() { musterr("{:>>>}") } #[test] fn format_nothing() { @@ -916,36 +919,16 @@ mod tests { })]); } - #[test] #[should_fail] fn badselect01() { - musterr("{select, }") - } - #[test] #[should_fail] fn badselect02() { - musterr("{1, select}") - } - #[test] #[should_fail] fn badselect03() { - musterr("{1, select, }") - } - #[test] #[should_fail] fn badselect04() { - musterr("{1, select, a {}}") - } - #[test] #[should_fail] fn badselect05() { - musterr("{1, select, other }}") - } - #[test] #[should_fail] fn badselect06() { - musterr("{1, select, other {}") - } - #[test] #[should_fail] fn badselect07() { - musterr("{select, other {}") - } - #[test] #[should_fail] fn badselect08() { - musterr("{1 select, other {}") - } - #[test] #[should_fail] fn badselect09() { - musterr("{:d select, other {}") - } - #[test] #[should_fail] fn badselect10() { - musterr("{1:d select, other {}") - } + #[test] fn badselect01() { musterr("{select, }") } + #[test] fn badselect02() { musterr("{1, select}") } + #[test] fn badselect03() { musterr("{1, select, }") } + #[test] fn badselect04() { musterr("{1, select, a {}}") } + #[test] fn badselect05() { musterr("{1, select, other }}") } + #[test] fn badselect06() { musterr("{1, select, other {}") } + #[test] fn badselect07() { musterr("{select, other {}") } + #[test] fn badselect08() { musterr("{1 select, other {}") } + #[test] fn badselect09() { musterr("{:d select, other {}") } + #[test] fn badselect10() { musterr("{1:d select, other {}") } #[test] fn plural_simple() { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index adce11fed2d..0398af9c1c1 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -178,8 +178,6 @@ pub mod run; pub mod cast; pub mod fmt; pub mod cleanup; -#[deprecated] -pub mod condition; pub mod logging; pub mod util; pub mod mem; @@ -216,7 +214,6 @@ mod std { pub use clone; pub use cmp; pub use comm; - pub use condition; pub use fmt; pub use io; pub use kinds; diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index b31ae92d742..cd81d6037e6 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -124,50 +124,6 @@ macro_rules! unreachable (() => ( )) #[macro_export] -macro_rules! condition ( - - { pub $c:ident: $input:ty -> $out:ty; } => { - - pub mod $c { - #[allow(unused_imports)]; - #[allow(non_uppercase_statics)]; - #[allow(missing_doc)]; - - use super::*; - - local_data_key!(key: @::std::condition::Handler<$input, $out>) - - pub static cond : - ::std::condition::Condition<$input,$out> = - ::std::condition::Condition { - name: stringify!($c), - key: key - }; - } - }; - - { $c:ident: $input:ty -> $out:ty; } => { - - mod $c { - #[allow(unused_imports)]; - #[allow(non_uppercase_statics)]; - #[allow(dead_code)]; - - use super::*; - - local_data_key!(key: @::std::condition::Handler<$input, $out>) - - pub static cond : - ::std::condition::Condition<$input,$out> = - ::std::condition::Condition { - name: stringify!($c), - key: key - }; - } - } -) - -#[macro_export] macro_rules! format(($($arg:tt)*) => ( format_args!(::std::fmt::format, $($arg)*) )) diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 4aa4a3feab1..f3f70c263ec 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -147,12 +147,6 @@ pub use is_sep_byte = self::windows::is_sep_byte; pub mod posix; pub mod windows; -// Condition that is raised when a NUL is found in a byte vector given to a Path function -condition! { - // this should be a &[u8] but there's a lifetime issue - null_byte: ~[u8] -> ~[u8]; -} - /// A trait that represents the generic operations available on paths pub trait GenericPath: Clone + GenericPathUnsafe { /// Creates a new Path from a byte vector or string. @@ -160,18 +154,13 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the path contains a NUL. + /// Fails the task if the path contains a NUL. /// /// See individual Path impls for additional restrictions. #[inline] fn new<T: BytesContainer>(path: T) -> Self { - if contains_nul(path.container_as_bytes()) { - let path = self::null_byte::cond.raise(path.container_into_owned_bytes()); - assert!(!contains_nul(path)); - unsafe { GenericPathUnsafe::new_unchecked(path) } - } else { - unsafe { GenericPathUnsafe::new_unchecked(path) } - } + assert!(!contains_nul(path.container_as_bytes())); + unsafe { GenericPathUnsafe::new_unchecked(path) } } /// Creates a new Path from a byte vector or string, if possible. @@ -283,16 +272,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the filename contains a NUL. + /// Fails the task if the filename contains a NUL. #[inline] fn set_filename<T: BytesContainer>(&mut self, filename: T) { - if contains_nul(filename.container_as_bytes()) { - let filename = self::null_byte::cond.raise(filename.container_into_owned_bytes()); - assert!(!contains_nul(filename)); - unsafe { self.set_filename_unchecked(filename) } - } else { - unsafe { self.set_filename_unchecked(filename) } - } + assert!(!contains_nul(filename.container_as_bytes())); + unsafe { self.set_filename_unchecked(filename) } } /// Replaces the extension with the given byte vector or string. /// If there is no extension in `self`, this adds one. @@ -301,8 +285,9 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the extension contains a NUL. + /// Fails the task if the extension contains a NUL. fn set_extension<T: BytesContainer>(&mut self, extension: T) { + assert!(!contains_nul(extension.container_as_bytes())); // borrowck causes problems here too let val = { match self.filename() { @@ -315,21 +300,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe { None } else { 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() + extension.len() + 1); - v.push_all(name); - v.push(dot); - v.push_all(extension); - } else { - let extension = extension.container_as_bytes(); - v = vec::with_capacity(name.len() + extension.len() + 1); - v.push_all(name); - v.push(dot); - v.push_all(extension); - } + let extension = extension.container_as_bytes(); + v = vec::with_capacity(name.len() + extension.len() + 1); + v.push_all(name); + v.push(dot); + v.push_all(extension); Some(v) } } @@ -338,19 +313,10 @@ pub trait GenericPath: Clone + GenericPathUnsafe { Some(name.slice_to(idx).to_owned()) } else { 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(idx + extension.len() + 1); - v.push_all(name.slice_to(idx+1)); - v.push_all(extension); - } else { - let extension = extension.container_as_bytes(); - v = vec::with_capacity(idx + extension.len() + 1); - v.push_all(name.slice_to(idx+1)); - v.push_all(extension); - } + let extension = extension.container_as_bytes(); + v = vec::with_capacity(idx + extension.len() + 1); + v.push_all(name.slice_to(idx+1)); + v.push_all(extension); Some(v) } } @@ -370,7 +336,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the filename contains a NUL. + /// Fails the task if the filename contains a NUL. #[inline] fn with_filename<T: BytesContainer>(&self, filename: T) -> Self { let mut p = self.clone(); @@ -383,7 +349,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the extension contains a NUL. + /// Fails the task if the extension contains a NUL. #[inline] fn with_extension<T: BytesContainer>(&self, extension: T) -> Self { let mut p = self.clone(); @@ -408,16 +374,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the path contains a NUL. + /// Fails the task if the path contains a NUL. #[inline] fn push<T: BytesContainer>(&mut self, path: T) { - if contains_nul(path.container_as_bytes()) { - let path = self::null_byte::cond.raise(path.container_into_owned_bytes()); - assert!(!contains_nul(path)); - unsafe { self.push_unchecked(path) } - } else { - unsafe { self.push_unchecked(path) } - } + assert!(!contains_nul(path.container_as_bytes())); + unsafe { self.push_unchecked(path) } } /// Pushes multiple paths (as byte vectors or strings) onto `self`. /// See `push` for details. @@ -445,7 +406,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// # Failure /// - /// Raises the `null_byte` condition if the path contains a NUL. + /// Fails the task if the path contains a NUL. #[inline] fn join<T: BytesContainer>(&self, path: T) -> Self { let mut p = self.clone(); diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index ba0cd0bb521..6970ebfb15d 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -318,7 +318,7 @@ impl Path { /// /// # Failure /// - /// Raises the `null_byte` condition if the vector contains a NUL. + /// Fails the task if the vector contains a NUL. #[inline] pub fn new<T: BytesContainer>(path: T) -> Path { GenericPath::new(path) @@ -527,83 +527,21 @@ mod tests { #[test] fn test_null_byte() { - use path::null_byte::cond; - - let mut handled = false; - let mut p = cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("foo/bar", 0)); - (b!("/bar").to_owned()) - }).inside(|| { + use task; + let result = task::try(proc() { Path::new(b!("foo/bar", 0)) }); - assert!(handled); - assert_eq!(p.as_vec(), b!("/bar")); - - handled = false; - cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("f", 0, "o")); - (b!("foo").to_owned()) - }).inside(|| { - p.set_filename(b!("f", 0, "o")) - }); - assert!(handled); - assert_eq!(p.as_vec(), b!("/foo")); - - handled = false; - cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("f", 0, "o")); - (b!("foo").to_owned()) - }).inside(|| { - p.push(b!("f", 0, "o")); - }); - assert!(handled); - assert_eq!(p.as_vec(), b!("/foo/foo")); - } - - #[test] - fn test_null_byte_fail() { - use path::null_byte::cond; - use task; + assert!(result.is_err()); - macro_rules! t( - ($name:expr => $code:expr) => ( - { - let mut t = task::task(); - t.name($name); - let res = t.try(proc() $code); - assert!(res.is_err()); - } - ) - ) + let result = task::try(proc() { + Path::new("test").set_filename(b!("f", 0, "o")) + }); + assert!(result.is_err()); - t!(~"new() w/nul" => { - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - Path::new(b!("foo/bar", 0)) - }); - }) - - t!(~"set_filename w/nul" => { - let mut p = Path::new(b!("foo/bar")); - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - p.set_filename(b!("foo", 0)) - }); - }) - - t!(~"push w/nul" => { - let mut p = Path::new(b!("foo/bar")); - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - p.push(b!("foo", 0)) - }); - }) + let result = task::try(proc() { + Path::new("test").push(b!("f", 0, "o")); + }); + assert!(result.is_err()); } #[test] diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index eec6f37b627..90154adb7fe 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -590,7 +590,7 @@ impl Path { /// /// # Failure /// - /// Raises the `null_byte` condition if the vector contains a NUL. + /// Fails the task if the vector contains a NUL. /// Fails if invalid UTF-8. #[inline] pub fn new<T: BytesContainer>(path: T) -> Path { @@ -1248,83 +1248,21 @@ mod tests { #[test] fn test_null_byte() { - use path::null_byte::cond; - - let mut handled = false; - let mut p = cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("foo\\bar", 0)); - (b!("\\bar").to_owned()) - }).inside(|| { - Path::new(b!("foo\\bar", 0)) - }); - assert!(handled); - assert_eq!(p.as_vec(), b!("\\bar")); - - handled = false; - cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("f", 0, "o")); - (b!("foo").to_owned()) - }).inside(|| { - p.set_filename(b!("f", 0, "o")) - }); - assert!(handled); - assert_eq!(p.as_vec(), b!("\\foo")); - - handled = false; - cond.trap(|v| { - handled = true; - assert_eq!(v.as_slice(), b!("f", 0, "o")); - (b!("foo").to_owned()) - }).inside(|| { - p.push(b!("f", 0, "o")); - }); - assert!(handled); - assert_eq!(p.as_vec(), b!("\\foo\\foo")); - } - - #[test] - fn test_null_byte_fail() { - use path::null_byte::cond; use task; + let result = task::try(proc() { + Path::new(b!("foo/bar", 0)) + }); + assert!(result.is_err()); - macro_rules! t( - ($name:expr => $code:expr) => ( - { - let mut t = task::task(); - t.name($name); - let res = t.try(proc() $code); - assert!(res.is_err()); - } - ) - ) - - t!(~"from_vec() w\\nul" => { - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - Path::new(b!("foo\\bar", 0)) - }); - }) - - t!(~"set_filename w\\nul" => { - let mut p = Path::new(b!("foo\\bar")); - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - p.set_filename(b!("foo", 0)) - }); - }) + let result = task::try(proc() { + Path::new("test").set_filename(b!("f", 0, "o")) + }); + assert!(result.is_err()); - t!(~"push w\\nul" => { - let mut p = Path::new(b!("foo\\bar")); - cond.trap(|_| { - (b!("null", 0).to_owned()) - }).inside(|| { - p.push(b!("foo", 0)) - }); - }) + let result = task::try(proc() { + Path::new("test").push(b!("f", 0, "o")); + }); + assert!(result.is_err()); } #[test] diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 55425eb2e72..376d685c8ac 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -44,7 +44,6 @@ Several modules in `core` are clients of `rt`: * `std::local_data` - The interface to local data. * `std::gc` - The garbage collector. * `std::unstable::lang` - Miscellaneous lang items, some of which rely on `std::rt`. -* `std::condition` - Uses local data. * `std::cleanup` - Local heap destruction. * `std::io` - In the future `std::io` will use an `rt` implementation. * `std::logging` |
