<commit_before>//! Unsafe pointer utility functions

export addr_of;
export to_unsafe_ptr;
export to_mut_unsafe_ptr;
export mut_addr_of;
export offset;
export const_offset;
export mut_offset;
export null;
export is_null;
export is_not_null;
export memcpy;
export memmove;
export memset;
export to_uint;
export ref_eq;
export buf_len;
export position;
export Ptr;

import cmp::{Eq, Ord};
import libc::{c_void, size_t};

#[nolink]
#[abi = "cdecl"]
extern mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

/// Get an unsafe pointer to a value
#[inline(always)]
pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }

/// Get an unsafe mut pointer to a value
#[inline(always)]
pure fn mut_addr_of<T>(val: T) -> *mut T {
    unsafe {
        unsafe::reinterpret_cast(&rusti::addr_of(val))
    }
}

/// Calculate the offset from a pointer
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a const pointer
#[inline(always)]
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a mut pointer
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

/// Return the offset of the first null pointer in `buf`.
#[inline(always)]
unsafe fn buf_len<T>(buf: **T) -> uint {
    position(buf, |i| i == null())
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline(always)]
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
    let mut i = 0u;
    loop {
        if f(*offset(buf, i)) { return i; }
        else { i += 1u; }
    }
}

/// Create an unsafe null pointer
#[inline(always)]
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(&0u) } }

/// Returns true if the pointer is equal to the null pointer.
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }

/// Returns true if the pointer is not equal to the null pointer.
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may not overlap.
 */
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
}

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may overlap.
 */
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n as size_t);
}

#[inline(always)]
unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
}

/**
  Transform a region pointer - &T - to an unsafe pointer - *T.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.
*/
#[inline(always)]
fn to_unsafe_ptr<T>(thing: &T) -> *T unsafe {
    unsafe::reinterpret_cast(&thing)
}

/**
  Transform a mutable region pointer - &mut T - to a mutable unsafe pointer -
  *mut T. This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.
*/
#[inline(always)]
fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T unsafe {
    unsafe::reinterpret_cast(thing)
}

/**
  Cast a region pointer - &T - to a uint.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  (I couldn't think of a cutesy name for this one.)
*/
#[inline(always)]
fn to_uint<T>(thing: &T) -> uint unsafe {
    unsafe::reinterpret_cast(&thing)
}

/// Determine if two borrowed pointers point to the same thing.
#[inline(always)]
fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
    to_uint(thing) == to_uint(other)
}

trait Ptr {
    pure fn is_null() -> bool;
    pure fn is_not_null() -> bool;
}

/// Extension methods for pointers
impl<T> *T: Ptr {
    /// Returns true if the pointer is equal to the null pointer.
    pure fn is_null() -> bool { is_null(self) }

    /// Returns true if the pointer is not equal to the null pointer.
    pure fn is_not_null() -> bool { is_not_null(self) }
}

// Equality for pointers
impl<T> *const T : Eq {
    pure fn eq(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a == b;
    }
}

// Comparison for pointers
impl<T> *const T : Ord {
    pure fn lt(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a < b;
    }
    pure fn le(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a <= b;
    }
    pure fn ge(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a >= b;
    }
    pure fn gt(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a > b;
    }
}

// Equality for region pointers
impl<T:Eq> &const T : Eq {
    pure fn eq(&&other: &const T) -> bool {
        return *self == *other;
    }
}

// Comparison for region pointers
impl<T:Ord> &const T : Ord {
    pure fn lt(&&other: &const T) -> bool { *self < *other }
    pure fn le(&&other: &const T) -> bool { *self <= *other }
    pure fn ge(&&other: &const T) -> bool { *self >= *other }
    pure fn gt(&&other: &const T) -> bool { *self > *other }
}

#[test]
fn test() {
    unsafe {
        type Pair = {mut fst: int, mut snd: int};
        let p = {mut fst: 10, mut snd: 20};
        let pptr: *mut Pair = mut_addr_of(p);
        let iptr: *mut int = unsafe::reinterpret_cast(&pptr);
        assert (*iptr == 10);;
        *iptr = 30;
        assert (*iptr == 30);
        assert (p.fst == 30);;

        *pptr = {mut fst: 50, mut snd: 60};
        assert (*iptr == 50);
        assert (p.fst == 50);
        assert (p.snd == 60);

        let v0 = ~[32000u16, 32001u16, 32002u16];
        let v1 = ~[0u16, 0u16, 0u16];

        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                    ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
        assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(vec::unsafe::to_ptr(v1),
                    ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                    vec::unsafe::to_ptr(v0), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
    }
}

#[test]
fn test_position() {
    import str::as_c_str;
    import libc::c_char;

    let s = ~"hello";
    unsafe {
        assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char));
        assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char));
        assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char));
    }
}

#[test]
fn test_buf_len() {
    let s0 = ~"hello";
    let s1 = ~"there";
    let s2 = ~"thing";
    do str::as_c_str(s0) |p0| {
        do str::as_c_str(s1) |p1| {
            do str::as_c_str(s2) |p2| {
                let v = ~[p0, p1, p2, null()];
                do vec::as_buf(v) |vp, len| {
                    assert unsafe { buf_len(vp) } == 3u;
                    assert len == 4u;
                }
            }
        }
    }
}

#[test]
fn test_is_null() {
   let p: *int = ptr::null();
   assert p.is_null();
   assert !p.is_not_null();

   let q = ptr::offset(p, 1u);
   assert !q.is_null();
   assert q.is_not_null();
}
<commit_msg>Fix use of reinterpret_cast in to_mut_unsafe_ptr<commit_after>//! Unsafe pointer utility functions

export addr_of;
export to_unsafe_ptr;
export to_mut_unsafe_ptr;
export mut_addr_of;
export offset;
export const_offset;
export mut_offset;
export null;
export is_null;
export is_not_null;
export memcpy;
export memmove;
export memset;
export to_uint;
export ref_eq;
export buf_len;
export position;
export Ptr;

import cmp::{Eq, Ord};
import libc::{c_void, size_t};

#[nolink]
#[abi = "cdecl"]
extern mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

/// Get an unsafe pointer to a value
#[inline(always)]
pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }

/// Get an unsafe mut pointer to a value
#[inline(always)]
pure fn mut_addr_of<T>(val: T) -> *mut T {
    unsafe {
        unsafe::reinterpret_cast(&rusti::addr_of(val))
    }
}

/// Calculate the offset from a pointer
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a const pointer
#[inline(always)]
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a mut pointer
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

/// Return the offset of the first null pointer in `buf`.
#[inline(always)]
unsafe fn buf_len<T>(buf: **T) -> uint {
    position(buf, |i| i == null())
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline(always)]
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
    let mut i = 0u;
    loop {
        if f(*offset(buf, i)) { return i; }
        else { i += 1u; }
    }
}

/// Create an unsafe null pointer
#[inline(always)]
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(&0u) } }

/// Returns true if the pointer is equal to the null pointer.
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }

/// Returns true if the pointer is not equal to the null pointer.
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may not overlap.
 */
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
}

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may overlap.
 */
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n as size_t);
}

#[inline(always)]
unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
}

/**
  Transform a region pointer - &T - to an unsafe pointer - *T.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.
*/
#[inline(always)]
fn to_unsafe_ptr<T>(thing: &T) -> *T unsafe {
    unsafe::reinterpret_cast(&thing)
}

/**
  Transform a mutable region pointer - &mut T - to a mutable unsafe pointer -
  *mut T. This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.
*/
#[inline(always)]
fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T unsafe {
    unsafe::reinterpret_cast(&thing)
}

/**
  Cast a region pointer - &T - to a uint.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  (I couldn't think of a cutesy name for this one.)
*/
#[inline(always)]
fn to_uint<T>(thing: &T) -> uint unsafe {
    unsafe::reinterpret_cast(&thing)
}

/// Determine if two borrowed pointers point to the same thing.
#[inline(always)]
fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
    to_uint(thing) == to_uint(other)
}

trait Ptr {
    pure fn is_null() -> bool;
    pure fn is_not_null() -> bool;
}

/// Extension methods for pointers
impl<T> *T: Ptr {
    /// Returns true if the pointer is equal to the null pointer.
    pure fn is_null() -> bool { is_null(self) }

    /// Returns true if the pointer is not equal to the null pointer.
    pure fn is_not_null() -> bool { is_not_null(self) }
}

// Equality for pointers
impl<T> *const T : Eq {
    pure fn eq(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a == b;
    }
}

// Comparison for pointers
impl<T> *const T : Ord {
    pure fn lt(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a < b;
    }
    pure fn le(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a <= b;
    }
    pure fn ge(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a >= b;
    }
    pure fn gt(&&other: *const T) -> bool unsafe {
        let a: uint = unsafe::reinterpret_cast(&self);
        let b: uint = unsafe::reinterpret_cast(&other);
        return a > b;
    }
}

// Equality for region pointers
impl<T:Eq> &const T : Eq {
    pure fn eq(&&other: &const T) -> bool {
        return *self == *other;
    }
}

// Comparison for region pointers
impl<T:Ord> &const T : Ord {
    pure fn lt(&&other: &const T) -> bool { *self < *other }
    pure fn le(&&other: &const T) -> bool { *self <= *other }
    pure fn ge(&&other: &const T) -> bool { *self >= *other }
    pure fn gt(&&other: &const T) -> bool { *self > *other }
}

#[test]
fn test() {
    unsafe {
        type Pair = {mut fst: int, mut snd: int};
        let p = {mut fst: 10, mut snd: 20};
        let pptr: *mut Pair = mut_addr_of(p);
        let iptr: *mut int = unsafe::reinterpret_cast(&pptr);
        assert (*iptr == 10);;
        *iptr = 30;
        assert (*iptr == 30);
        assert (p.fst == 30);;

        *pptr = {mut fst: 50, mut snd: 60};
        assert (*iptr == 50);
        assert (p.fst == 50);
        assert (p.snd == 60);

        let v0 = ~[32000u16, 32001u16, 32002u16];
        let v1 = ~[0u16, 0u16, 0u16];

        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                    ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
        assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(vec::unsafe::to_ptr(v1),
                    ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                    vec::unsafe::to_ptr(v0), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
    }
}

#[test]
fn test_position() {
    import str::as_c_str;
    import libc::c_char;

    let s = ~"hello";
    unsafe {
        assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char));
        assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char));
        assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char));
    }
}

#[test]
fn test_buf_len() {
    let s0 = ~"hello";
    let s1 = ~"there";
    let s2 = ~"thing";
    do str::as_c_str(s0) |p0| {
        do str::as_c_str(s1) |p1| {
            do str::as_c_str(s2) |p2| {
                let v = ~[p0, p1, p2, null()];
                do vec::as_buf(v) |vp, len| {
                    assert unsafe { buf_len(vp) } == 3u;
                    assert len == 4u;
                }
            }
        }
    }
}

#[test]
fn test_is_null() {
   let p: *int = ptr::null();
   assert p.is_null();
   assert !p.is_not_null();

   let q = ptr::offset(p, 1u);
   assert !q.is_null();
   assert q.is_not_null();
}
<|endoftext|>


<commit_before>#[doc = "Unsafe pointer utility functions"];

export addr_of;
export mut_addr_of;
export offset;
export mut_offset;
export null;
export memcpy;
export memmove;

import libc::c_void;

#[nolink]
#[abi = "cdecl"]
native mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

#[doc = "Get an unsafe pointer to a value"]
#[inline(always)]
fn addr_of<T>(val: T) -> *T { rusti::addr_of(val) }

#[doc = "Get an unsafe mut pointer to a value"]
#[inline(always)]
fn mut_addr_of<T>(val: T) -> *mut T unsafe {
    unsafe::reinterpret_cast(rusti::addr_of(val))
}

#[doc = "Calculate the offset from a pointer"]
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T unsafe {
    (ptr as uint + count * sys::size_of::<T>()) as *T
}

#[doc = "Calculate the offset from a mut pointer"]
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

#[doc = "Create an unsafe null pointer"]
#[inline(always)]
fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

#[doc = "
Copies data from one location to another

Copies `count` elements (not bytes) from `src` to `dst`. The source
and destination may not overlap.
"]
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n);
}

#[doc = "
Copies data from one location to another

Copies `count` elements (not bytes) from `src` to `dst`. The source
and destination may overlap.
"]
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n);
}

#[test]
fn test() unsafe {
    type pair = {mut fst: int, mut snd: int};
    let p = {mut fst: 10, mut snd: 20};
    let pptr: *mut pair = mut_addr_of(p);
    let iptr: *mut int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mut fst: 50, mut snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1),
                ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<commit_msg>core: Add ptr::is_null/is_not_null<commit_after>#[doc = "Unsafe pointer utility functions"];

export addr_of;
export mut_addr_of;
export offset;
export mut_offset;
export null;
export memcpy;
export memmove;

import libc::c_void;

#[nolink]
#[abi = "cdecl"]
native mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
native mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

#[doc = "Get an unsafe pointer to a value"]
#[inline(always)]
fn addr_of<T>(val: T) -> *T { rusti::addr_of(val) }

#[doc = "Get an unsafe mut pointer to a value"]
#[inline(always)]
fn mut_addr_of<T>(val: T) -> *mut T unsafe {
    unsafe::reinterpret_cast(rusti::addr_of(val))
}

#[doc = "Calculate the offset from a pointer"]
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T unsafe {
    (ptr as uint + count * sys::size_of::<T>()) as *T
}

#[doc = "Calculate the offset from a mut pointer"]
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

#[doc = "Create an unsafe null pointer"]
#[inline(always)]
pure fn null<T>() -> *T unsafe { ret unsafe::reinterpret_cast(0u); }

#[doc = "Returns true if the pointer is equal to the null pointer"]
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }

#[doc = "Returns true if the pointer is not equal to the null pointer"]
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }

#[doc = "
Copies data from one location to another

Copies `count` elements (not bytes) from `src` to `dst`. The source
and destination may not overlap.
"]
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n);
}

#[doc = "
Copies data from one location to another

Copies `count` elements (not bytes) from `src` to `dst`. The source
and destination may overlap.
"]
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n);
}

#[test]
fn test() unsafe {
    type pair = {mut fst: int, mut snd: int};
    let p = {mut fst: 10, mut snd: 20};
    let pptr: *mut pair = mut_addr_of(p);
    let iptr: *mut int = unsafe::reinterpret_cast(pptr);
    assert (*iptr == 10);;
    *iptr = 30;
    assert (*iptr == 30);
    assert (p.fst == 30);;

    *pptr = {mut fst: 50, mut snd: 60};
    assert (*iptr == 50);
    assert (p.fst == 50);
    assert (p.snd == 60);

    let v0 = [32000u16, 32001u16, 32002u16];
    let v1 = [0u16, 0u16, 0u16];

    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
    assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(vec::unsafe::to_ptr(v1),
                ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
    ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                vec::unsafe::to_ptr(v0), 1u);
    assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
}<|endoftext|>


<commit_before>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

import result::{ok, err};
import io::writer_util;
import core::ctypes;

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_tests_console;
export configure_test_task;

#[abi = "cdecl"]
native mod rustrt {
    fn sched_threads() -> ctypes::size_t;
}

// The name of a test. By convention this follows the rules for rust
// paths; i.e. it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// hierarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn~();

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = {
    name: test_name,
    fn: test_fn,
    ignore: bool,
    should_fail: bool
};

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(args: [str], tests: [test_desc]) {
    check (vec::is_not_empty(args));
    let opts =
        alt parse_opts(args) {
          either::left(o) { o }
          either::right(m) { fail m }
        };
    if !run_tests_console(opts, tests) { fail "Some tests failed"; }
}

type test_opts = {filter: option::t<str>, run_ignored: bool};

type opt_res = either::t<test_opts, str>;

// Parses command line arguments into test options
fn parse_opts(args: [str]) : vec::is_not_empty(args) -> opt_res {

    let args_ = vec::tail(args);
    let opts = [getopts::optflag("ignored")];
    let match =
        alt getopts::getopts(args_, opts) {
          ok(m) { m }
          err(f) { ret either::right(getopts::fail_str(f)) }
        };

    let filter =
        if vec::len(match.free) > 0u {
            option::some(match.free[0])
        } else { option::none };

    let run_ignored = getopts::opt_present(match, "ignored");

    let test_opts = {filter: filter, run_ignored: run_ignored};

    ret either::left(test_opts);
}

enum test_result { tr_ok; tr_failed; tr_ignored; }

// A simple console test runner
fn run_tests_console(opts: test_opts,
                     tests: [test_desc]) -> bool {

    type test_state =
        @{out: io::writer,
          use_color: bool,
          mutable total: uint,
          mutable passed: uint,
          mutable failed: uint,
          mutable ignored: uint,
          mutable failures: [test_desc]};

    fn callback(event: testevent, st: test_state) {
        alt event {
          te_filtered(filtered_tests) {
            st.total = vec::len(filtered_tests);
            st.out.write_line(#fmt["\nrunning %u tests", st.total]);
          }
          te_wait(test) { st.out.write_str(#fmt["test %s ... ", test.name]); }
          te_result(test, result) {
            alt result {
              tr_ok {
                st.passed += 1u;
                write_ok(st.out, st.use_color);
                st.out.write_line("");
              }
              tr_failed {
                st.failed += 1u;
                write_failed(st.out, st.use_color);
                st.out.write_line("");
                st.failures += [test];
              }
              tr_ignored {
                st.ignored += 1u;
                write_ignored(st.out, st.use_color);
                st.out.write_line("");
              }
            }
          }
        }
    }

    let st =
        @{out: io::stdout(),
          use_color: use_color(),
          mutable total: 0u,
          mutable passed: 0u,
          mutable failed: 0u,
          mutable ignored: 0u,
          mutable failures: []};

    run_tests(opts, tests, bind callback(_, st));

    assert (st.passed + st.failed + st.ignored == st.total);
    let success = st.failed == 0u;

    if !success {
        st.out.write_line("\nfailures:");
        for test: test_desc in st.failures {
            let testname = test.name; // Satisfy alias analysis
            st.out.write_line(#fmt["    %s", testname]);
        }
    }

    st.out.write_str(#fmt["\nresult: "]);
    if success {
        // There's no parallelism at this point so it's safe to use color
        write_ok(st.out, true);
    } else { write_failed(st.out, true); }
    st.out.write_str(#fmt[". %u passed; %u failed; %u ignored\n\n", st.passed,
                          st.failed, st.ignored]);

    ret success;

    fn write_ok(out: io::writer, use_color: bool) {
        write_pretty(out, "ok", term::color_green, use_color);
    }

    fn write_failed(out: io::writer, use_color: bool) {
        write_pretty(out, "FAILED", term::color_red, use_color);
    }

    fn write_ignored(out: io::writer, use_color: bool) {
        write_pretty(out, "ignored", term::color_yellow, use_color);
    }

    fn write_pretty(out: io::writer, word: str, color: u8, use_color: bool) {
        if use_color && term::color_supported() {
            term::fg(out, color);
        }
        out.write_str(word);
        if use_color && term::color_supported() {
            term::reset(out);
        }
    }
}

fn use_color() -> bool { ret get_concurrency() == 1u; }

enum testevent {
    te_filtered([test_desc]);
    te_wait(test_desc);
    te_result(test_desc, test_result);
}

fn run_tests(opts: test_opts, tests: [test_desc],
             callback: fn@(testevent)) {

    let filtered_tests = filter_tests(opts, tests);
    callback(te_filtered(filtered_tests));

    // It's tempting to just spawn all the tests at once, but since we have
    // many tests that run in other processes we would be making a big mess.
    let concurrency = get_concurrency();
    #debug("using %u test tasks", concurrency);
    let total = vec::len(filtered_tests);
    let run_idx = 0u;
    let wait_idx = 0u;
    let futures = [];

    while wait_idx < total {
        while vec::len(futures) < concurrency && run_idx < total {
            futures += [run_test(filtered_tests[run_idx])];
            run_idx += 1u;
        }

        let future = futures[0];
        callback(te_wait(future.test));
        let result = future.wait();
        callback(te_result(future.test, result));
        futures = vec::slice(futures, 1u, vec::len(futures));
        wait_idx += 1u;
    }
}

fn get_concurrency() -> uint { rustrt::sched_threads() }

fn filter_tests(opts: test_opts,
                tests: [test_desc]) -> [test_desc] {
    let filtered = tests;

    // Remove tests that don't match the test filter
    filtered = if option::is_none(opts.filter) {
        filtered
    } else {
        let filter_str =
            alt opts.filter {
          option::some(f) { f }
          option::none { "" }
        };

        fn filter_fn(test: test_desc, filter_str: str) ->
            option::t<test_desc> {
            if str::find(test.name, filter_str) >= 0 {
                ret option::some(test);
            } else { ret option::none; }
        }

        let filter = bind filter_fn(_, filter_str);

        vec::filter_map(filtered, filter)
    };

    // Maybe pull out the ignored test and unignore them
    filtered = if !opts.run_ignored {
        filtered
    } else {
        fn filter(test: test_desc) -> option::t<test_desc> {
            if test.ignore {
                ret option::some({name: test.name,
                                  fn: test.fn,
                                  ignore: false,
                                  should_fail: test.should_fail});
            } else { ret option::none; }
        };

        vec::filter_map(filtered, bind filter(_))
    };

    // Sort the tests alphabetically
    filtered =
        {
            fn lteq(t1: test_desc, t2: test_desc) -> bool {
                str::lteq(t1.name, t2.name)
            }
            sort::merge_sort(bind lteq(_, _), filtered)
        };

    ret filtered;
}

type test_future = {test: test_desc, wait: fn@() -> test_result};

fn run_test(test: test_desc) -> test_future {
    if test.ignore {
        ret {test: test, wait: fn@() -> test_result { tr_ignored }};
    }

    let test_task = test_to_task(test.fn);
    ret {test: test,
         wait: fn@() -> test_result {
             alt task::join(test_task) {
               task::tr_success {
                 if test.should_fail { tr_failed }
                 else { tr_ok }
               }
               task::tr_failure {
                 if test.should_fail { tr_ok }
                 else { tr_failed }
               }
             }
         }
        };
}

// We need to run our tests in another task in order to trap test failures.
// This function only works with functions that don't contain closures.
fn test_to_task(&&f: test_fn) -> task::joinable_task {
    ret task::spawn_joinable(fn~[copy f]() {
        configure_test_task();
        f();
    });
}

// Call from within a test task to make sure it's set up correctly
fn configure_test_task() {
    // If this task fails we don't want that failure to propagate to the
    // test runner or else we couldn't keep running tests
    task::unsupervise();
}

#[cfg(test)]
mod tests {

    #[test]
    fn do_not_run_ignored_tests() {
        fn f() { fail; }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: true,
            should_fail: false
        };
        let future = run_test(desc);
        let result = future.wait();
        assert result != tr_ok;
    }

    #[test]
    fn ignored_tests_result_in_ignored() {
        fn f() { }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: true,
            should_fail: false
        };
        let res = run_test(desc).wait();
        assert (res == tr_ignored);
    }

    #[test]
    #[ignore(cfg(target_os = "win32"))]
    fn test_should_fail() {
        fn f() { fail; }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: false,
            should_fail: true
        };
        let res = run_test(desc).wait();
        assert res == tr_ok;
    }

    #[test]
    fn test_should_fail_but_succeeds() {
        fn f() { }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: false,
            should_fail: true
        };
        let res = run_test(desc).wait();
        assert res == tr_failed;
    }

    #[test]
    fn first_free_arg_should_be_a_filter() {
        let args = ["progname", "filter"];
        check (vec::is_not_empty(args));
        let opts = alt parse_opts(args) { either::left(o) { o } };
        assert (str::eq("filter", option::get(opts.filter)));
    }

    #[test]
    fn parse_ignored_flag() {
        let args = ["progname", "filter", "--ignored"];
        check (vec::is_not_empty(args));
        let opts = alt parse_opts(args) { either::left(o) { o } };
        assert (opts.run_ignored);
    }

    #[test]
    fn filter_for_ignored_option() {
        // When we run ignored tests the test filter should filter out all the
        // unignored tests and flip the ignore flag on the rest to false

        let opts = {filter: option::none, run_ignored: true};
        let tests =
            [{name: "1", fn: fn~() { }, ignore: true, should_fail: false},
             {name: "2", fn: fn~() { }, ignore: false, should_fail: false}];
        let filtered = filter_tests(opts, tests);

        assert (vec::len(filtered) == 1u);
        assert (filtered[0].name == "1");
        assert (filtered[0].ignore == false);
    }

    #[test]
    fn sort_tests() {
        let opts = {filter: option::none, run_ignored: false};

        let names =
            ["sha1::test", "int::test_to_str", "int::test_pow",
             "test::do_not_run_ignored_tests",
             "test::ignored_tests_result_in_ignored",
             "test::first_free_arg_should_be_a_filter",
             "test::parse_ignored_flag", "test::filter_for_ignored_option",
             "test::sort_tests"];
        let tests =
        {
        let testfn = fn~() { };
        let tests = [];
        for name: str in names {
            let test = {name: name, fn: testfn, ignore: false,
                        should_fail: false};
            tests += [test];
        }
        tests
    };
    let filtered = filter_tests(opts, tests);

    let expected =
        ["int::test_pow", "int::test_to_str", "sha1::test",
         "test::do_not_run_ignored_tests", "test::filter_for_ignored_option",
         "test::first_free_arg_should_be_a_filter",
         "test::ignored_tests_result_in_ignored", "test::parse_ignored_flag",
         "test::sort_tests"];

    check (vec::same_length(expected, filtered));
    let pairs = vec::zip(expected, filtered);

    for (a, b) in pairs { assert (a == b.name); }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>libcore: Do less blocking in the test runner<commit_after>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

import result::{ok, err};
import io::writer_util;
import core::ctypes;

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_tests_console;

#[abi = "cdecl"]
native mod rustrt {
    fn sched_threads() -> ctypes::size_t;
}

// The name of a test. By convention this follows the rules for rust
// paths; i.e. it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// hierarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn~();

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = {
    name: test_name,
    fn: test_fn,
    ignore: bool,
    should_fail: bool
};

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(args: [str], tests: [test_desc]) {
    check (vec::is_not_empty(args));
    let opts =
        alt parse_opts(args) {
          either::left(o) { o }
          either::right(m) { fail m }
        };
    if !run_tests_console(opts, tests) { fail "Some tests failed"; }
}

type test_opts = {filter: option::t<str>, run_ignored: bool};

type opt_res = either::t<test_opts, str>;

// Parses command line arguments into test options
fn parse_opts(args: [str]) : vec::is_not_empty(args) -> opt_res {

    let args_ = vec::tail(args);
    let opts = [getopts::optflag("ignored")];
    let match =
        alt getopts::getopts(args_, opts) {
          ok(m) { m }
          err(f) { ret either::right(getopts::fail_str(f)) }
        };

    let filter =
        if vec::len(match.free) > 0u {
            option::some(match.free[0])
        } else { option::none };

    let run_ignored = getopts::opt_present(match, "ignored");

    let test_opts = {filter: filter, run_ignored: run_ignored};

    ret either::left(test_opts);
}

enum test_result { tr_ok; tr_failed; tr_ignored; }

// A simple console test runner
fn run_tests_console(opts: test_opts,
                     tests: [test_desc]) -> bool {

    type test_state =
        @{out: io::writer,
          use_color: bool,
          mutable total: uint,
          mutable passed: uint,
          mutable failed: uint,
          mutable ignored: uint,
          mutable failures: [test_desc]};

    fn callback(event: testevent, st: test_state) {
        alt event {
          te_filtered(filtered_tests) {
            st.total = vec::len(filtered_tests);
            st.out.write_line(#fmt["\nrunning %u tests", st.total]);
          }
          te_wait(test) { st.out.write_str(#fmt["test %s ... ", test.name]); }
          te_result(test, result) {
            alt result {
              tr_ok {
                st.passed += 1u;
                write_ok(st.out, st.use_color);
                st.out.write_line("");
              }
              tr_failed {
                st.failed += 1u;
                write_failed(st.out, st.use_color);
                st.out.write_line("");
                st.failures += [test];
              }
              tr_ignored {
                st.ignored += 1u;
                write_ignored(st.out, st.use_color);
                st.out.write_line("");
              }
            }
          }
        }
    }

    let st =
        @{out: io::stdout(),
          use_color: use_color(),
          mutable total: 0u,
          mutable passed: 0u,
          mutable failed: 0u,
          mutable ignored: 0u,
          mutable failures: []};

    run_tests(opts, tests, bind callback(_, st));

    assert (st.passed + st.failed + st.ignored == st.total);
    let success = st.failed == 0u;

    if !success {
        st.out.write_line("\nfailures:");
        for test: test_desc in st.failures {
            let testname = test.name; // Satisfy alias analysis
            st.out.write_line(#fmt["    %s", testname]);
        }
    }

    st.out.write_str(#fmt["\nresult: "]);
    if success {
        // There's no parallelism at this point so it's safe to use color
        write_ok(st.out, true);
    } else { write_failed(st.out, true); }
    st.out.write_str(#fmt[". %u passed; %u failed; %u ignored\n\n", st.passed,
                          st.failed, st.ignored]);

    ret success;

    fn write_ok(out: io::writer, use_color: bool) {
        write_pretty(out, "ok", term::color_green, use_color);
    }

    fn write_failed(out: io::writer, use_color: bool) {
        write_pretty(out, "FAILED", term::color_red, use_color);
    }

    fn write_ignored(out: io::writer, use_color: bool) {
        write_pretty(out, "ignored", term::color_yellow, use_color);
    }

    fn write_pretty(out: io::writer, word: str, color: u8, use_color: bool) {
        if use_color && term::color_supported() {
            term::fg(out, color);
        }
        out.write_str(word);
        if use_color && term::color_supported() {
            term::reset(out);
        }
    }
}

fn use_color() -> bool { ret get_concurrency() == 1u; }

enum testevent {
    te_filtered([test_desc]);
    te_wait(test_desc);
    te_result(test_desc, test_result);
}

type monitor_msg = (test_desc, test_result);

fn run_tests(opts: test_opts, tests: [test_desc],
             callback: fn@(testevent)) {

    let filtered_tests = filter_tests(opts, tests);
    callback(te_filtered(filtered_tests));

    // It's tempting to just spawn all the tests at once, but since we have
    // many tests that run in other processes we would be making a big mess.
    let concurrency = get_concurrency();
    #debug("using %u test tasks", concurrency);

    let total = vec::len(filtered_tests);
    let run_idx = 0u;
    let wait_idx = 0u;
    let done_idx = 0u;

    let p = comm::port();
    let ch = comm::chan(p);

    while done_idx < total {
        while wait_idx < concurrency && run_idx < total {
            run_test(vec::shift(filtered_tests), ch);
            wait_idx += 1u;
            run_idx += 1u;
        }

        let (test, result) = comm::recv(p);
        callback(te_wait(test));
        callback(te_result(test, result));
        wait_idx -= 1u;
        done_idx += 1u;
    }
}

fn get_concurrency() -> uint { rustrt::sched_threads() }

fn filter_tests(opts: test_opts,
                tests: [test_desc]) -> [test_desc] {
    let filtered = tests;

    // Remove tests that don't match the test filter
    filtered = if option::is_none(opts.filter) {
        filtered
    } else {
        let filter_str =
            alt opts.filter {
          option::some(f) { f }
          option::none { "" }
        };

        fn filter_fn(test: test_desc, filter_str: str) ->
            option::t<test_desc> {
            if str::find(test.name, filter_str) >= 0 {
                ret option::some(test);
            } else { ret option::none; }
        }

        let filter = bind filter_fn(_, filter_str);

        vec::filter_map(filtered, filter)
    };

    // Maybe pull out the ignored test and unignore them
    filtered = if !opts.run_ignored {
        filtered
    } else {
        fn filter(test: test_desc) -> option::t<test_desc> {
            if test.ignore {
                ret option::some({name: test.name,
                                  fn: test.fn,
                                  ignore: false,
                                  should_fail: test.should_fail});
            } else { ret option::none; }
        };

        vec::filter_map(filtered, bind filter(_))
    };

    // Sort the tests alphabetically
    filtered =
        {
            fn lteq(t1: test_desc, t2: test_desc) -> bool {
                str::lteq(t1.name, t2.name)
            }
            sort::merge_sort(bind lteq(_, _), filtered)
        };

    ret filtered;
}

type test_future = {test: test_desc, wait: fn@() -> test_result};

fn run_test(+test: test_desc, monitor_ch: comm::chan<monitor_msg>) {
    if test.ignore {
        comm::send(monitor_ch, (test, tr_ignored));
        ret;
    }

    task::spawn {||

        let testfn = test.fn;
        let test_task = task::spawn_joinable {||
            configure_test_task();
            testfn();
        };

        let task_result = task::join(test_task);
        let test_result = calc_result(test, task_result == task::tr_success);
        comm::send(monitor_ch, (test, test_result));
    };
}

fn calc_result(test: test_desc, task_succeeded: bool) -> test_result {
    if task_succeeded {
        if test.should_fail { tr_failed }
        else { tr_ok }
    } else {
        if test.should_fail { tr_ok }
        else { tr_failed }
    }
}

// Call from within a test task to make sure it's set up correctly
fn configure_test_task() {
    // If this task fails we don't want that failure to propagate to the
    // test runner or else we couldn't keep running tests
    task::unsupervise();
}

#[cfg(test)]
mod tests {

    #[test]
    fn do_not_run_ignored_tests() {
        fn f() { fail; }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: true,
            should_fail: false
        };
        let p = comm::port();
        let ch = comm::chan(p);
        run_test(desc, ch);
        let (_, res) = comm::recv(p);
        assert res != tr_ok;
    }

    #[test]
    fn ignored_tests_result_in_ignored() {
        fn f() { }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: true,
            should_fail: false
        };
        let p = comm::port();
        let ch = comm::chan(p);
        run_test(desc, ch);
        let (_, res) = comm::recv(p);
        assert res == tr_ignored;
    }

    #[test]
    #[ignore(cfg(target_os = "win32"))]
    fn test_should_fail() {
        fn f() { fail; }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: false,
            should_fail: true
        };
        let p = comm::port();
        let ch = comm::chan(p);
        run_test(desc, ch);
        let (_, res) = comm::recv(p);
        assert res == tr_ok;
    }

    #[test]
    fn test_should_fail_but_succeeds() {
        fn f() { }
        let desc = {
            name: "whatever",
            fn: f,
            ignore: false,
            should_fail: true
        };
        let p = comm::port();
        let ch = comm::chan(p);
        run_test(desc, ch);
        let (_, res) = comm::recv(p);
        assert res == tr_failed;
    }

    #[test]
    fn first_free_arg_should_be_a_filter() {
        let args = ["progname", "filter"];
        check (vec::is_not_empty(args));
        let opts = alt parse_opts(args) { either::left(o) { o } };
        assert (str::eq("filter", option::get(opts.filter)));
    }

    #[test]
    fn parse_ignored_flag() {
        let args = ["progname", "filter", "--ignored"];
        check (vec::is_not_empty(args));
        let opts = alt parse_opts(args) { either::left(o) { o } };
        assert (opts.run_ignored);
    }

    #[test]
    fn filter_for_ignored_option() {
        // When we run ignored tests the test filter should filter out all the
        // unignored tests and flip the ignore flag on the rest to false

        let opts = {filter: option::none, run_ignored: true};
        let tests =
            [{name: "1", fn: fn~() { }, ignore: true, should_fail: false},
             {name: "2", fn: fn~() { }, ignore: false, should_fail: false}];
        let filtered = filter_tests(opts, tests);

        assert (vec::len(filtered) == 1u);
        assert (filtered[0].name == "1");
        assert (filtered[0].ignore == false);
    }

    #[test]
    fn sort_tests() {
        let opts = {filter: option::none, run_ignored: false};

        let names =
            ["sha1::test", "int::test_to_str", "int::test_pow",
             "test::do_not_run_ignored_tests",
             "test::ignored_tests_result_in_ignored",
             "test::first_free_arg_should_be_a_filter",
             "test::parse_ignored_flag", "test::filter_for_ignored_option",
             "test::sort_tests"];
        let tests =
        {
        let testfn = fn~() { };
        let tests = [];
        for name: str in names {
            let test = {name: name, fn: testfn, ignore: false,
                        should_fail: false};
            tests += [test];
        }
        tests
    };
    let filtered = filter_tests(opts, tests);

    let expected =
        ["int::test_pow", "int::test_to_str", "sha1::test",
         "test::do_not_run_ignored_tests", "test::filter_for_ignored_option",
         "test::first_free_arg_should_be_a_filter",
         "test::ignored_tests_result_in_ignored", "test::parse_ignored_flag",
         "test::sort_tests"];

    check (vec::same_length(expected, filtered));
    let pairs = vec::zip(expected, filtered);

    for (a, b) in pairs { assert (a == b.name); }
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>new version of Dijkstra<commit_after>/// DA.rs is not good, let me rewrite it
use std::cmp::Eq;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::ops::Add;

#[derive(Debug)]
struct Graph<T, P>
where
    T: Eq + Hash,
    P: PartialOrd,
{
    form: HashMap<T, HashMap<T, P>>,
}

impl<T, P> Graph<T, P>
where
    T: Eq + Hash + Clone + Copy,
    P: PartialOrd + Clone + Copy + Add<Output = P>,
{
    fn new() -> Self {
        Graph {
            form: HashMap::new(),
        }
    }

    // don't forget insert node itself
    fn insert(&mut self, data: &(T, T, P)) {
        self.form
            .entry(data.0)
            .or_insert(HashMap::new())
            .insert(data.1, data.2);

        self.form
            .entry(data.1)
            .or_insert(HashMap::new())
            .insert(data.0, data.2);
    }

    fn distance_between(&self, x: &T, y: &T) -> Result<P, String> {
        match self.form.get(x) {
            Some(x) => match x.get(y) {
                Some(x) => Ok(*x),
                None => Err(String::from("Not Found")),
            },
            None => Err(String::from("Not Found")),
        }
    }

    // update all distance from start
    fn dijkstra(&mut self, start: &T) {
        let mut rest_set = self.form.keys().cloned().collect::<HashSet<T>>();
        rest_set.remove(start);

        let mut last = *start;
        while !rest_set.is_empty() {
            // find all nodes connected with last in rest_set
            let rest_nodes = {
                rest_set
                    .iter()
                    .map(|x| (*x, self.distance_between(&last, x)))
                    .filter(|x| x.1.is_ok())
                    .map(|x| (x.0, x.1.unwrap()))
                    .collect::<Vec<(T, P)>>()
            };

            // update start to node value
            for node in rest_nodes {
                match self.distance_between(start, &node.0) {
                    Ok(d) => {
                        if self.distance_between(start, &last).unwrap() + node.1 < d {
                            self.insert(&(
                                *start,
                                node.0,
                                self.distance_between(start, &last).unwrap() + node.1,
                            ));
                        }
                    }
                    Err(_) => self.insert(&(
                        *start,
                        node.0,
                        self.distance_between(start, &last).unwrap() + node.1,
                    )),
                }
            }

            // search from rest_set again because value maybe changed
            let next = {
                let mut cache = rest_set
                    .iter()
                    .map(|x| (x, self.distance_between(start, x)))
                    .filter(|x| x.1.is_ok())
                    .map(|x| (x.0, x.1.unwrap()))
                    .collect::<Vec<(&T, P)>>();

                // find nearest one
                cache.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap());
                *cache.first().unwrap().0
            };

            // next loop start from next
            rest_set.remove(&next);
            last = next;
        }
    }
}

fn main() {
    let mut testcase0: Graph<i32, i32> = Graph::new();
    let set = vec![
        (1, 1, 0),
        (2, 2, 0),
        (3, 3, 0),
        (4, 4, 0),
        (5, 5, 0),
        (6, 6, 0),
        (1, 2, 7),
        (1, 3, 9),
        (1, 6, 14),
        (2, 3, 10),
        (2, 4, 15),
        (3, 6, 2),
        (3, 4, 11),
        (4, 5, 6),
        (5, 6, 9),
    ];

    for s in set {
        testcase0.insert(&s);
    }

    testcase0.dijkstra(&1);
    println!("{:?}", testcase0.form.get(&1));

    //////
    let mut testcase1: Graph<char, i32> = Graph::new();
    let set = vec![
        ('A', 'A', 0),
        ('B', 'B', 0),
        ('C', 'C', 0),
        ('D', 'D', 0),
        ('E', 'E', 0),
        ('F', 'F', 0),
        //
        ('A', 'B', 6),
        ('A', 'C', 3),
        ('B', 'C', 2),
        ('B', 'D', 5),
        ('C', 'D', 3),
        ('C', 'E', 4),
        ('D', 'E', 2),
        ('D', 'F', 3),
        ('E', 'F', 5),
    ];

    for s in set {
        testcase1.insert(&s);
    }
    testcase1.dijkstra(&'A');
    println!("{:?}", testcase1.form.get(&'A'));
}
<|endoftext|>


<commit_before><commit_msg>Add test for E0152 error message improvement<commit_after>// Copyright 2015 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.

// Test for issue #31788

// error-pattern: duplicate entry for `panic_fmt`, first definition found in `std`

#![feature(lang_items)]

#[lang = "panic_fmt"]
fn panic_fmt() -> ! {
    loop {}
}

fn main() {}<|endoftext|>


<commit_before><commit_msg>Daemon finally working for sure<commit_after><|endoftext|>


<commit_before>use errors::crypto::CryptoError;
use services::crypto::anoncreds::constants::{
    LARGE_PRIME
};
use services::crypto::anoncreds::types::{
    PublicKey,
    SecretKey,
    Schema
};
use services::crypto::helpers::{
    random_qr,
    random_in_range
};
use services::crypto::wrappers::bn::BigNumber;

use std::collections::HashMap;

pub struct Issuer {

}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }
    pub fn generate_keys(&self, schema: &Schema) {
//        let bn = BigNumber::new();
//        //    let p_prime = generate_prime_2p_plus_1(LARGE_PRIME);
//        //    let q_prime = generate_prime_2p_plus_1(LARGE_PRIME);
//        let p_prime = FF::from_hex("d1a2a65b9b574dd3e8416aa93f6d570adc2b5fc26925f78216225de6c882ebf431c5fec9d5fab19237092699f3e1b31c94912926b5e7dd03983328465dffa76a6a227d6518632ac99ebf103e84f8e492e8e2ec37395f2f50b38753f3f3a529f80944cf84c2cc5534dae121bb1c65f62705882d279d18ff9d76a7f8d2546a3407", BIG_SIZE);
//        let q_prime = FF::from_hex("c15bb30a08c65b35f17f52c28c86f89f67e786cd87c57792c6dbddd5b9fb83cc38d56bed6b7f67f36e7f1f5df80b93d47be95ca3e11d79038cb23b8ce9809f3ecb79be259e5b65fb4d9317743f724a2c20673300baeb1bdaa532f3a2fe9c65f70e3834b3a51db5b6a0ed590ef52b86b4fd4db72ea9c439b2825003d33a49068b", BIG_SIZE);
//        let mut p = &p_prime * &FF::from_hex("2", BIG_SIZE);
//        p.inc(1);
//        let mut q = &q_prime * &FF::from_hex("2", BIG_SIZE);
//        q.inc(1);
//        let n = &p * &q;
//        //let s = random_qr(&n); //TODO random_qr works incorrectly now.
//        let xz = issuer.gen_x(&p_prime, &q_prime);
    }

    fn _generate_keys(schema: &Schema) -> Result<(PublicKey, SecretKey), CryptoError> {
        let bn = try!(BigNumber::new());
        let p = try!(bn.safe_prime(LARGE_PRIME));
        let q = try!(bn.safe_prime(LARGE_PRIME));

        let mut p_prime = try!(p.sub(&try!(BigNumber::from_u32(1))));
        try!(p_prime.div_word(2));

        let mut q_prime = try!(q.sub(&try!(BigNumber::from_u32(1))));
        try!(q_prime.div_word(2));

        let n = try!(p.mul(&q, None));
        let s = try!(random_qr(&n));
        let xz = try!(Issuer::_gen_x(&p_prime, &q_prime));
        let mut r: HashMap<String, BigNumber> = HashMap::new();

        for attribute in &schema.attribute_names {
            let random = try!(Issuer::_gen_x(&p_prime, &q_prime));
            r.insert(attribute.to_string(), try!(s.mod_exp(&random, &n, None)));
        }

        let z = try!(s.mod_exp(&xz, &n, None));

        let rms = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        let rctxt = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        Ok((
            PublicKey {
                n: n,
                rms: rms,
                rctxt: rctxt,
                r: r,
                s: s,
                z: z
            },
            SecretKey {
                p: p_prime,
                q: q_prime
            }
        ))
    }

    fn _generate_revocation_keys() {

    }

    pub fn issuer_primary_claim(&self) {

    }

    fn _gen_x(p: &BigNumber, q: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut value = try!(p.mul(&q, None));
        try!(value.sub_word(3));

        let mut result = try!(value.rand_range());
        try!(result.add_word(2));
        Ok(result)
    }
}<commit_msg>removed unnecessary code<commit_after>use errors::crypto::CryptoError;
use services::crypto::anoncreds::constants::{
    LARGE_PRIME
};
use services::crypto::anoncreds::types::{
    PublicKey,
    SecretKey,
    Schema
};
use services::crypto::helpers::{
    random_qr,
    random_in_range
};
use services::crypto::wrappers::bn::BigNumber;

use std::collections::HashMap;

pub struct Issuer {

}

impl Issuer {
    pub fn new() -> Issuer {
        Issuer {}
    }
    pub fn generate_keys(&self, schema: &Schema) -> Result<((PublicKey, SecretKey)), CryptoError> {
        (Issuer::_generate_keys(&schema));
        unimplemented!();
    }

    fn _generate_keys(schema: &Schema) -> Result<(PublicKey, SecretKey), CryptoError> {
        let bn = try!(BigNumber::new());
        let p = try!(bn.safe_prime(LARGE_PRIME));
        let q = try!(bn.safe_prime(LARGE_PRIME));

        let mut p_prime = try!(p.sub(&try!(BigNumber::from_u32(1))));
        try!(p_prime.div_word(2));

        let mut q_prime = try!(q.sub(&try!(BigNumber::from_u32(1))));
        try!(q_prime.div_word(2));

        let n = try!(p.mul(&q, None));
        let s = try!(random_qr(&n));
        let xz = try!(Issuer::_gen_x(&p_prime, &q_prime));
        let mut r: HashMap<String, BigNumber> = HashMap::new();

        for attribute in &schema.attribute_names {
            let random = try!(Issuer::_gen_x(&p_prime, &q_prime));
            r.insert(attribute.to_string(), try!(s.mod_exp(&random, &n, None)));
        }

        let z = try!(s.mod_exp(&xz, &n, None));

        let rms = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        let rctxt = try!(s.mod_exp(&try!(Issuer::_gen_x(&p_prime, &q_prime)), &n, None));
        Ok((
            PublicKey {
                n: n,
                rms: rms,
                rctxt: rctxt,
                r: r,
                s: s,
                z: z
            },
            SecretKey {
                p: p_prime,
                q: q_prime
            }
        ))
    }

    fn _generate_revocation_keys() {

    }

    pub fn issuer_primary_claim(&self) {

    }

    fn _gen_x(p: &BigNumber, q: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut value = try!(p.mul(&q, None));
        try!(value.sub_word(3));

        let mut result = try!(value.rand_range());
        try!(result.add_word(2));
        Ok(result)
    }
}<|endoftext|>


<commit_before>// Copyright 2015 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.

// compile-flags: -Z parse-only

fn that_odd_parse() {
    // see assoc-oddities-1 for explanation
    x + if c { a } else { b }[n]; //~ ERROR expected one of
}
<commit_msg>Removed test case.  This now test successfully parses with the modification to parsing of binary operators.  This is consistent with the behavior of grammar/parser-lalr.<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for ICE 6793<commit_after>//! This is a reproducer for the ICE 6793: https://github.com/rust-lang/rust-clippy/issues/6793.
//! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`, which is the same as the ICE 6792.

trait Trait {
    type Ty: 'static + Clone;

    fn broken() -> Self::Ty;
}

#[derive(Clone)]
struct MyType {
    x: i32,
}

impl Trait for MyType {
    type Ty = MyType;

    fn broken() -> Self::Ty {
        Self::Ty { x: 1 }
    }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add node network config.<commit_after><|endoftext|>


<commit_before>#![feature(phase)]
#![crate_name = "triangle"]

extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate glfw;
extern crate native;

use gfx::{DeviceHelper, ToSlice};
use glfw::Context;

#[vertex_format]
struct Vertex {
    #[name = "a_Pos"]
    pos: [f32, ..2],

    #[name = "a_Color"]
    color: [f32, ..3],
}

static VERTEX_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120

    attribute vec2 a_Pos;
    attribute vec3 a_Color;
    varying vec4 v_Color;

    void main() {
        v_Color = vec4(a_Color, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec2 a_Pos;
    in vec3 a_Color;
    out vec4 v_Color;

    void main() {
        v_Color = vec4(a_Color, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120

    varying vec4 v_Color;

    void main() {
        gl_FragColor = v_Color;
    }
"
GLSL_150: b"
    #version 150 core

    in vec4 v_Color;
    out vec4 o_Color;

    void main() {
        o_Color = v_Color;
    }
"
};

// We need to run on the main thread for GLFW, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(glfw::ContextVersion(3, 2));
    glfw.window_hint(glfw::OpenglForwardCompat(true));
    glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));

    let (window, events) = glfw
        .create_window(640, 480, "Triangle example.", glfw::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let (w, h) = window.get_framebuffer_size();
    let frame = gfx::Frame::new(w as u16, h as u16);

    let mut device = gfx::GlDevice::new(|s| glfw.get_proc_address(s));

    let vertex_data = vec![
        Vertex { pos: [ -0.5, -0.5 ], color: [1.0, 0.0, 0.0] },
        Vertex { pos: [  0.5, -0.5 ], color: [0.0, 1.0, 0.0] },
        Vertex { pos: [  0.0,  0.5 ], color: [0.0, 0.0, 1.0] },
    ];
    let mesh = device.create_mesh(vertex_data);
    let slice = mesh.to_slice(gfx::TriangleList);

    let program = device.link_program(VERTEX_SRC.clone(), FRAGMENT_SRC.clone())
                        .unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: gfx::batch::RefBatch<(), ()> = graphics.make_batch(
        &program, &mesh, slice, &gfx::DrawState::new()).unwrap();

    graphics.clear(
        gfx::ClearData {
            color: Some([0.3, 0.3, 0.3, 1.0]),
            depth: None,
            stencil: None,
        },
        &frame
    );

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }

        graphics.draw(&batch, &(), &frame);
        graphics.end_frame();

        window.swap_buffers();
    }
}
<commit_msg>Update triangle example to clear every frame<commit_after>#![feature(phase)]
#![crate_name = "triangle"]

extern crate gfx;
#[phase(plugin)]
extern crate gfx_macros;
extern crate glfw;
extern crate native;

use gfx::{DeviceHelper, ToSlice};
use glfw::Context;

#[vertex_format]
struct Vertex {
    #[name = "a_Pos"]
    pos: [f32, ..2],

    #[name = "a_Color"]
    color: [f32, ..3],
}

static VERTEX_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120

    attribute vec2 a_Pos;
    attribute vec3 a_Color;
    varying vec4 v_Color;

    void main() {
        v_Color = vec4(a_Color, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
GLSL_150: b"
    #version 150 core

    in vec2 a_Pos;
    in vec3 a_Color;
    out vec4 v_Color;

    void main() {
        v_Color = vec4(a_Color, 1.0);
        gl_Position = vec4(a_Pos, 0.0, 1.0);
    }
"
};

static FRAGMENT_SRC: gfx::ShaderSource = shaders! {
GLSL_120: b"
    #version 120

    varying vec4 v_Color;

    void main() {
        gl_FragColor = v_Color;
    }
"
GLSL_150: b"
    #version 150 core

    in vec4 v_Color;
    out vec4 o_Color;

    void main() {
        o_Color = v_Color;
    }
"
};

// We need to run on the main thread for GLFW, so ensure we are using the `native` runtime. This is
// technically not needed, since this is the default, but it's not guaranteed.
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
     native::start(argc, argv, main)
}

fn main() {
    let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(glfw::ContextVersion(3, 2));
    glfw.window_hint(glfw::OpenglForwardCompat(true));
    glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));

    let (window, events) = glfw
        .create_window(640, 480, "Triangle example.", glfw::Windowed)
        .expect("Failed to create GLFW window.");

    window.make_current();
    glfw.set_error_callback(glfw::FAIL_ON_ERRORS);
    window.set_key_polling(true);

    let (w, h) = window.get_framebuffer_size();
    let frame = gfx::Frame::new(w as u16, h as u16);

    let mut device = gfx::GlDevice::new(|s| glfw.get_proc_address(s));

    let vertex_data = vec![
        Vertex { pos: [ -0.5, -0.5 ], color: [1.0, 0.0, 0.0] },
        Vertex { pos: [  0.5, -0.5 ], color: [0.0, 1.0, 0.0] },
        Vertex { pos: [  0.0,  0.5 ], color: [0.0, 0.0, 1.0] },
    ];
    let mesh = device.create_mesh(vertex_data);
    let slice = mesh.to_slice(gfx::TriangleList);

    let program = device.link_program(VERTEX_SRC.clone(), FRAGMENT_SRC.clone())
                        .unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: gfx::batch::RefBatch<(), ()> = graphics.make_batch(
        &program, &mesh, slice, &gfx::DrawState::new()).unwrap();

    let clear_data = gfx::ClearData {
        color: Some([0.3, 0.3, 0.3, 1.0]),
        depth: None,
        stencil: None,
    };

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _) =>
                    window.set_should_close(true),
                _ => {},
            }
        }

        graphics.clear(clear_data, &frame);
        graphics.draw(&batch, &(), &frame);
        graphics.end_frame();

        window.swap_buffers();
    }
}
<|endoftext|>


<commit_before><commit_msg>Keep polling in Buffered if there's more futures<commit_after>extern crate futures;
extern crate futures_io;
extern crate futures_mio;
extern crate env_logger;

use std::net::TcpStream;
use std::thread;
use std::io::{Read, Write};

use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
    })
}

#[test]
fn echo_server() {
    drop(env_logger::init());

    let mut l = t!(futures_mio::Loop::new());
    let srv = l.handle().tcp_listen(&"127.0.0.1:0".parse().unwrap());
    let srv = t!(l.run(srv));
    let addr = t!(srv.local_addr());

    let t = thread::spawn(move || {
        let mut s1 = t!(TcpStream::connect(&addr));
        let mut s2 = t!(TcpStream::connect(&addr));

        let msg = b"foo";
        assert_eq!(t!(s1.write(msg)), msg.len());
        assert_eq!(t!(s2.write(msg)), msg.len());
        let mut buf = [0; 1024];
        assert_eq!(t!(s1.read(&mut buf)), msg.len());
        assert_eq!(&buf[..msg.len()], msg);
        assert_eq!(t!(s2.read(&mut buf)), msg.len());
        assert_eq!(&buf[..msg.len()], msg);
    });

    let future = srv.incoming()
                    .and_then(|s| TaskIo::new(s.0))
                    .map(|i| i.split())
                    .map(|(a,b)| copy(a,b).map(|_| ()))
                    .buffered(10)
                    .take(2)
                    .collect();

    t!(l.run(future));

    t.join().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Fix error message in systemd_gui.rs<commit_after><|endoftext|>


<commit_before><commit_msg>ext: fix `strip_parent` test<commit_after><|endoftext|>


<commit_before><commit_msg>Add Index trait to Polynomial<commit_after><|endoftext|>


<commit_before><commit_msg>using ZipCode API GUI Application!<commit_after><|endoftext|>


<commit_before>// Copyright 2013 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.

use std::iter::range_step;
use std::io::{stdin, stdout, File};

static LINE_LEN: uint = 60;

fn make_complements() -> [u8, ..256] {
    let transforms = [
        ('A', 'T'), ('C', 'G'), ('G', 'C'), ('T', 'A'),
        ('U', 'A'), ('M', 'K'), ('R', 'Y'), ('W', 'W'),
        ('S', 'S'), ('Y', 'R'), ('K', 'M'), ('V', 'B'),
        ('H', 'D'), ('D', 'H'), ('B', 'V'), ('N', 'N'),
        ('\n', '\n')];
    let mut complements: [u8, ..256] = [0, ..256];
    for (i, c) in complements.mut_iter().enumerate() {
        *c = i as u8;
    }
    let lower = 'A' as u8 - 'a' as u8;
    for &(from, to) in transforms.iter() {
        complements[from as u8] = to as u8;
        complements[from as u8 - lower] = to as u8;
    }
    complements
}

fn main() {
    let complements = make_complements();
    let mut data = if std::os::getenv("RUST_BENCH").is_some() {
        File::open(&Path::new("shootout-k-nucleotide.data")).read_to_end()
    } else {
        stdin().read_to_end()
    };

    for seq in data.mut_split(|c| *c == '>' as u8) {
        // skip header and last \n
        let begin = match seq.iter().position(|c| *c == '\n' as u8) {
            None => continue,
            Some(c) => c
        };
        let len = seq.len();
        let seq = seq.mut_slice(begin + 1, len - 1);

        // arrange line breaks
        let len = seq.len();
        let off = LINE_LEN - len % (LINE_LEN + 1);
        for i in range_step(LINE_LEN, len, LINE_LEN + 1) {
            for j in std::iter::count(i, -1).take(off) {
                seq[j] = seq[j - 1];
            }
            seq[i - off] = '\n' as u8;
        }

        // reverse complement, as
        //    seq.reverse(); for c in seq.mut_iter() {*c = complements[*c]}
        // but faster:
        let mut it = seq.mut_iter();
        loop {
            match (it.next(), it.next_back()) {
                (Some(front), Some(back)) => {
                    let tmp = complements[*front];
                    *front = complements[*back];
                    *back = tmp;
                }
                _ => break // vector exhausted.
            }
        }
    }

    stdout().write(data);
}
<commit_msg>xfail shootout-reverse-complement on android<commit_after>// Copyright 2013 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.

// xfail-android doesn't terminate?

use std::iter::range_step;
use std::io::{stdin, stdout, File};

static LINE_LEN: uint = 60;

fn make_complements() -> [u8, ..256] {
    let transforms = [
        ('A', 'T'), ('C', 'G'), ('G', 'C'), ('T', 'A'),
        ('U', 'A'), ('M', 'K'), ('R', 'Y'), ('W', 'W'),
        ('S', 'S'), ('Y', 'R'), ('K', 'M'), ('V', 'B'),
        ('H', 'D'), ('D', 'H'), ('B', 'V'), ('N', 'N'),
        ('\n', '\n')];
    let mut complements: [u8, ..256] = [0, ..256];
    for (i, c) in complements.mut_iter().enumerate() {
        *c = i as u8;
    }
    let lower = 'A' as u8 - 'a' as u8;
    for &(from, to) in transforms.iter() {
        complements[from as u8] = to as u8;
        complements[from as u8 - lower] = to as u8;
    }
    complements
}

fn main() {
    let complements = make_complements();
    let mut data = if std::os::getenv("RUST_BENCH").is_some() {
        File::open(&Path::new("shootout-k-nucleotide.data")).read_to_end()
    } else {
        stdin().read_to_end()
    };

    for seq in data.mut_split(|c| *c == '>' as u8) {
        // skip header and last \n
        let begin = match seq.iter().position(|c| *c == '\n' as u8) {
            None => continue,
            Some(c) => c
        };
        let len = seq.len();
        let seq = seq.mut_slice(begin + 1, len - 1);

        // arrange line breaks
        let len = seq.len();
        let off = LINE_LEN - len % (LINE_LEN + 1);
        for i in range_step(LINE_LEN, len, LINE_LEN + 1) {
            for j in std::iter::count(i, -1).take(off) {
                seq[j] = seq[j - 1];
            }
            seq[i - off] = '\n' as u8;
        }

        // reverse complement, as
        //    seq.reverse(); for c in seq.mut_iter() {*c = complements[*c]}
        // but faster:
        let mut it = seq.mut_iter();
        loop {
            match (it.next(), it.next_back()) {
                (Some(front), Some(back)) => {
                    let tmp = complements[*front];
                    *front = complements[*back];
                    *back = tmp;
                }
                _ => break // vector exhausted.
            }
        }
    }

    stdout().write(data);
}
<|endoftext|>


<commit_before>use rustc::hir::def_id::DefId;
use rustc::traits::{self, Reveal, SelectionContext};
use rustc::ty::subst::{Substs, Subst};
use rustc::ty;

use super::EvalContext;
use error::EvalResult;
use memory::Pointer;
use super::terminator::{get_impl_method, ImplMethod};

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    /// Creates a returns a dynamic vtable for the given type and vtable origin.
    /// This is used only for objects.
    ///
    /// The `trait_ref` encodes the erased self type. Hence if we are
    /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
    /// `trait_ref` would map `T:Trait`.
    pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'tcx, Pointer> {
        let tcx = self.tcx;

        debug!("get_vtable(trait_ref={:?})", trait_ref);

        let methods: Vec<_> = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
            match self.fulfill_obligation(trait_ref.clone()) {
                // Should default trait error here?
                traits::VtableDefaultImpl(_) |
                traits::VtableBuiltin(_) => {
                    Vec::new().into_iter()
                }
                traits::VtableImpl(
                    traits::VtableImplData {
                        impl_def_id: id,
                        substs,
                        nested: _ }) => {
                    self.get_vtable_methods(id, substs)
                        .into_iter()
                        .map(|opt_mth| opt_mth.map(|mth| {
                            self.memory.create_fn_ptr(mth.method.def_id, mth.substs, mth.method.fty)
                        }))
                        .collect::<Vec<_>>()
                        .into_iter()
                }
                traits::VtableClosure(
                    traits::VtableClosureData {
                        closure_def_id,
                        substs,
                        nested: _ }) => {
                    let closure_type = self.tcx.closure_type(closure_def_id, substs);
                    let fn_ty = ty::BareFnTy {
                        unsafety: closure_type.unsafety,
                        abi: closure_type.abi,
                        sig: closure_type.sig,
                    };
                    let _fn_ty = self.tcx.mk_bare_fn(fn_ty);
                    unimplemented!()
                    //vec![Some(self.memory.create_fn_ptr(closure_def_id, substs.func_substs, fn_ty))].into_iter()
                }
                traits::VtableFnPointer(
                    traits::VtableFnPointerData {
                        fn_ty: _bare_fn_ty,
                        nested: _ }) => {
                    let _trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                    //vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
                    unimplemented!()
                }
                traits::VtableObject(ref data) => {
                    // this would imply that the Self type being erased is
                    // an object type; this cannot happen because we
                    // cannot cast an unsized type into a trait object
                    bug!("cannot get vtable for an object type: {:?}",
                         data);
                }
                vtable @ traits::VtableParam(..) => {
                    bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                         trait_ref,
                         vtable);
                }
            }
        }).collect();

        let size = self.type_size(trait_ref.self_ty());
        let align = self.type_align(trait_ref.self_ty());

        let ptr_size = self.memory.pointer_size();
        let vtable = self.memory.allocate(ptr_size * (3 + methods.len()), ptr_size)?;

        // FIXME: generate a destructor for the vtable.
        // trans does this with glue::get_drop_glue(ccx, trait_ref.self_ty())

        self.memory.write_usize(vtable.offset(ptr_size as isize), size as u64)?;
        self.memory.write_usize(vtable.offset((ptr_size * 2) as isize), align as u64)?;

        for (i, method) in methods.into_iter().enumerate() {
            if let Some(method) = method {
                self.memory.write_ptr(vtable.offset(ptr_size as isize * (3 + i as isize)), method)?;
            }
        }

        Ok(vtable)
    }

    fn get_vtable_methods(&mut self, impl_id: DefId, substs: &'tcx Substs<'tcx>) -> Vec<Option<ImplMethod<'tcx>>> {
        debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

        let trait_id = match self.tcx.impl_trait_ref(impl_id) {
            Some(t_id) => t_id.def_id,
            None       => bug!("make_impl_vtable: don't know how to \
                                make a vtable for a type impl!")
        };

        self.tcx.populate_implementations_for_trait_if_necessary(trait_id);

        let trait_item_def_ids = self.tcx.trait_item_def_ids(trait_id);
        trait_item_def_ids
            .iter()

            // Filter out non-method items.
            .filter_map(|item_def_id| {
                match *item_def_id {
                    ty::MethodTraitItemId(def_id) => Some(def_id),
                    _ => None,
                }
            })

            // Now produce pointers for each remaining method. If the
            // method could never be called from this object, just supply
            // null.
            .map(|trait_method_def_id| {
                debug!("get_vtable_methods: trait_method_def_id={:?}",
                       trait_method_def_id);

                let trait_method_type = match self.tcx.impl_or_trait_item(trait_method_def_id) {
                    ty::MethodTraitItem(m) => m,
                    _ => bug!("should be a method, not other assoc item"),
                };
                let name = trait_method_type.name;

                // Some methods cannot be called on an object; skip those.
                if !self.tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                    debug!("get_vtable_methods: not vtable safe");
                    return None;
                }

                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                // the method may have some early-bound lifetimes, add
                // regions for those
                let method_substs = Substs::for_item(self.tcx, trait_method_def_id,
                                                     |_, _| self.tcx.mk_region(ty::ReErased),
                                                     |_, _| self.tcx.types.err);

                // The substitutions we have are on the impl, so we grab
                // the method type from the impl to substitute into.
                let mth = get_impl_method(self.tcx, method_substs, impl_id, substs, name);

                debug!("get_vtable_methods: mth={:?}", mth);

                // If this is a default method, it's possible that it
                // relies on where clauses that do not hold for this
                // particular set of type parameters. Note that this
                // method could then never be called, so we do not want to
                // try and trans it, in that case. Issue #23435.
                if mth.is_provided {
                    let predicates = mth.method.predicates.predicates.subst(self.tcx, &mth.substs);
                    if !self.normalize_and_test_predicates(predicates) {
                        debug!("get_vtable_methods: predicates do not hold");
                        return None;
                    }
                }

                Some(mth)
            })
            .collect()
    }

    /// Normalizes the predicates and checks whether they hold.  If this
    /// returns false, then either normalize encountered an error or one
    /// of the predicates did not hold. Used when creating vtables to
    /// check for unsatisfiable methods.
    fn normalize_and_test_predicates(&mut self, predicates: Vec<ty::Predicate<'tcx>>) -> bool {
        debug!("normalize_and_test_predicates(predicates={:?})",
               predicates);

        self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
            let mut selcx = SelectionContext::new(&infcx);
            let mut fulfill_cx = traits::FulfillmentContext::new();
            let cause = traits::ObligationCause::dummy();
            let traits::Normalized { value: predicates, obligations } =
                traits::normalize(&mut selcx, cause.clone(), &predicates);
            for obligation in obligations {
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }
            for predicate in predicates {
                let obligation = traits::Obligation::new(cause.clone(), predicate);
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }

            fulfill_cx.select_all_or_error(&infcx).is_ok()
        })
    }
}
<commit_msg>prevent the modification of vtables<commit_after>use rustc::hir::def_id::DefId;
use rustc::traits::{self, Reveal, SelectionContext};
use rustc::ty::subst::{Substs, Subst};
use rustc::ty;

use super::EvalContext;
use error::EvalResult;
use memory::Pointer;
use super::terminator::{get_impl_method, ImplMethod};

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    /// Creates a returns a dynamic vtable for the given type and vtable origin.
    /// This is used only for objects.
    ///
    /// The `trait_ref` encodes the erased self type. Hence if we are
    /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
    /// `trait_ref` would map `T:Trait`.
    pub fn get_vtable(&mut self, trait_ref: ty::PolyTraitRef<'tcx>) -> EvalResult<'tcx, Pointer> {
        let tcx = self.tcx;

        debug!("get_vtable(trait_ref={:?})", trait_ref);

        let methods: Vec<_> = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
            match self.fulfill_obligation(trait_ref.clone()) {
                // Should default trait error here?
                traits::VtableDefaultImpl(_) |
                traits::VtableBuiltin(_) => {
                    Vec::new().into_iter()
                }
                traits::VtableImpl(
                    traits::VtableImplData {
                        impl_def_id: id,
                        substs,
                        nested: _ }) => {
                    self.get_vtable_methods(id, substs)
                        .into_iter()
                        .map(|opt_mth| opt_mth.map(|mth| {
                            self.memory.create_fn_ptr(mth.method.def_id, mth.substs, mth.method.fty)
                        }))
                        .collect::<Vec<_>>()
                        .into_iter()
                }
                traits::VtableClosure(
                    traits::VtableClosureData {
                        closure_def_id,
                        substs,
                        nested: _ }) => {
                    let closure_type = self.tcx.closure_type(closure_def_id, substs);
                    let fn_ty = ty::BareFnTy {
                        unsafety: closure_type.unsafety,
                        abi: closure_type.abi,
                        sig: closure_type.sig,
                    };
                    let _fn_ty = self.tcx.mk_bare_fn(fn_ty);
                    unimplemented!()
                    //vec![Some(self.memory.create_fn_ptr(closure_def_id, substs.func_substs, fn_ty))].into_iter()
                }
                traits::VtableFnPointer(
                    traits::VtableFnPointerData {
                        fn_ty: _bare_fn_ty,
                        nested: _ }) => {
                    let _trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
                    //vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
                    unimplemented!()
                }
                traits::VtableObject(ref data) => {
                    // this would imply that the Self type being erased is
                    // an object type; this cannot happen because we
                    // cannot cast an unsized type into a trait object
                    bug!("cannot get vtable for an object type: {:?}",
                         data);
                }
                vtable @ traits::VtableParam(..) => {
                    bug!("resolved vtable for {:?} to bad vtable {:?} in trans",
                         trait_ref,
                         vtable);
                }
            }
        }).collect();

        let size = self.type_size(trait_ref.self_ty());
        let align = self.type_align(trait_ref.self_ty());

        let ptr_size = self.memory.pointer_size();
        let vtable = self.memory.allocate(ptr_size * (3 + methods.len()), ptr_size)?;

        // FIXME: generate a destructor for the vtable.
        // trans does this with glue::get_drop_glue(ccx, trait_ref.self_ty())

        self.memory.write_usize(vtable.offset(ptr_size as isize), size as u64)?;
        self.memory.write_usize(vtable.offset((ptr_size * 2) as isize), align as u64)?;

        for (i, method) in methods.into_iter().enumerate() {
            if let Some(method) = method {
                self.memory.write_ptr(vtable.offset(ptr_size as isize * (3 + i as isize)), method)?;
            }
        }

        self.memory.freeze(vtable.alloc_id)?;

        Ok(vtable)
    }

    fn get_vtable_methods(&mut self, impl_id: DefId, substs: &'tcx Substs<'tcx>) -> Vec<Option<ImplMethod<'tcx>>> {
        debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);

        let trait_id = match self.tcx.impl_trait_ref(impl_id) {
            Some(t_id) => t_id.def_id,
            None       => bug!("make_impl_vtable: don't know how to \
                                make a vtable for a type impl!")
        };

        self.tcx.populate_implementations_for_trait_if_necessary(trait_id);

        let trait_item_def_ids = self.tcx.trait_item_def_ids(trait_id);
        trait_item_def_ids
            .iter()

            // Filter out non-method items.
            .filter_map(|item_def_id| {
                match *item_def_id {
                    ty::MethodTraitItemId(def_id) => Some(def_id),
                    _ => None,
                }
            })

            // Now produce pointers for each remaining method. If the
            // method could never be called from this object, just supply
            // null.
            .map(|trait_method_def_id| {
                debug!("get_vtable_methods: trait_method_def_id={:?}",
                       trait_method_def_id);

                let trait_method_type = match self.tcx.impl_or_trait_item(trait_method_def_id) {
                    ty::MethodTraitItem(m) => m,
                    _ => bug!("should be a method, not other assoc item"),
                };
                let name = trait_method_type.name;

                // Some methods cannot be called on an object; skip those.
                if !self.tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
                    debug!("get_vtable_methods: not vtable safe");
                    return None;
                }

                debug!("get_vtable_methods: trait_method_type={:?}",
                       trait_method_type);

                // the method may have some early-bound lifetimes, add
                // regions for those
                let method_substs = Substs::for_item(self.tcx, trait_method_def_id,
                                                     |_, _| self.tcx.mk_region(ty::ReErased),
                                                     |_, _| self.tcx.types.err);

                // The substitutions we have are on the impl, so we grab
                // the method type from the impl to substitute into.
                let mth = get_impl_method(self.tcx, method_substs, impl_id, substs, name);

                debug!("get_vtable_methods: mth={:?}", mth);

                // If this is a default method, it's possible that it
                // relies on where clauses that do not hold for this
                // particular set of type parameters. Note that this
                // method could then never be called, so we do not want to
                // try and trans it, in that case. Issue #23435.
                if mth.is_provided {
                    let predicates = mth.method.predicates.predicates.subst(self.tcx, &mth.substs);
                    if !self.normalize_and_test_predicates(predicates) {
                        debug!("get_vtable_methods: predicates do not hold");
                        return None;
                    }
                }

                Some(mth)
            })
            .collect()
    }

    /// Normalizes the predicates and checks whether they hold.  If this
    /// returns false, then either normalize encountered an error or one
    /// of the predicates did not hold. Used when creating vtables to
    /// check for unsatisfiable methods.
    fn normalize_and_test_predicates(&mut self, predicates: Vec<ty::Predicate<'tcx>>) -> bool {
        debug!("normalize_and_test_predicates(predicates={:?})",
               predicates);

        self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
            let mut selcx = SelectionContext::new(&infcx);
            let mut fulfill_cx = traits::FulfillmentContext::new();
            let cause = traits::ObligationCause::dummy();
            let traits::Normalized { value: predicates, obligations } =
                traits::normalize(&mut selcx, cause.clone(), &predicates);
            for obligation in obligations {
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }
            for predicate in predicates {
                let obligation = traits::Obligation::new(cause.clone(), predicate);
                fulfill_cx.register_predicate_obligation(&infcx, obligation);
            }

            fulfill_cx.select_all_or_error(&infcx).is_ok()
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>GUIアプリケーションっぽさ<commit_after><|endoftext|>


<commit_before><commit_msg>Fix ignored tests<commit_after><|endoftext|>


<commit_before><commit_msg>Update message_builder.rs<commit_after><|endoftext|>


<commit_before><commit_msg>autocommit 2015-04-25 14:30:38 CEST<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#[allow(unused_imports)] #[prelude_import] use base::prelude::*;
use core::{mem};
use base::{error};
use syscall::{execveat};
use cty::{AT_FDCWD, PATH_MAX, c_char};
use str_one::{AsMutCStr, CStr};
use str_two::{NoNullString};
use str_three::{ToCString};
use rt::{raw_env};
use rmo::{Rmo};
use alloc::{Allocator, FbHeap};
use {env, file};

/// Executes the program at `path` with arguments `args`.
///
/// The `args` argument can be built with the `CPtrPtr` structure. If `path` is relative,
/// then the `PATH` will be searched for a matching file.
pub fn exec<P>(path: P, args: &[*const c_char]) -> Result
    where P: ToCString,
{
    let mut buf: [u8; PATH_MAX] = unsafe { mem::uninit() };
    let file: Rmo<_, FbHeap> = try!(path.rmo_cstr(&mut buf));
    if file.len() == 0 {
        return Err(error::InvalidArgument);
    } else if file[0] == b'/' {
        return rv!(execveat(-1, &file, args.as_ptr(), raw_env(), 0));
    }

    // Try first without allocating

    let mut abs_buf: [u8; PATH_MAX] = unsafe { mem::uninit() };
    let abs_file = NoNullString::buffered(&mut abs_buf);
    match exec_rel(&file, abs_file, args) {
        Err(error::NoMemory) => { },
        x => return x,
    }

    // NoMemory can come from our stuff or execve but we can't distinguish at this point.
    // Let's just try again with dynamic allocations.

    let abs_file: NoNullString<FbHeap> = NoNullString::new();
    exec_rel(&file, abs_file, args)
}

fn exec_rel<'a, H>(rel: &CStr, mut buf: NoNullString<'a, H>,
                   args: &[*const c_char]) -> Result
    where H: Allocator,
{
    for path in try!(env::path()) {
        try!(buf.set_path(path));
        try!(buf.push_file(rel));
        let cstr: &_ = try!(buf.as_mut_cstr());
        if file::exists(cstr) == Ok(true) {
            // Paths in PATH don't have to start with a /. We pass AT_FDCWD so that such
            // paths are interpreted relative to the cwd.
            return rv!(execveat(AT_FDCWD, cstr, args.as_ptr(), raw_env(), 0));
        }
    }
    Err(error::DoesNotExist)
}
<|endoftext|>


<commit_before><commit_msg>feat: add tests<commit_after>use zip::result::ZipError;

const BUF: &[u8] = &[
    0, 80, 75, 1, 2, 127, 120, 0, 3, 3, 75, 80, 232, 3, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 7, 0, 0, 0,
    0, 65, 0, 1, 0, 0, 0, 4, 0, 0, 224, 255, 0, 255, 255, 255, 255, 255, 255, 20, 39, 221, 221,
    221, 221, 221, 221, 205, 221, 221, 221, 42, 221, 221, 221, 221, 221, 221, 221, 221, 38, 34, 34,
    219, 80, 75, 5, 6, 0, 0, 0, 0, 5, 96, 0, 1, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 234, 236, 124,
    221, 221, 37, 221, 221, 221, 221, 221, 129, 4, 0, 0, 221, 221, 80, 75, 1, 2, 127, 120, 0, 4, 0,
    0, 2, 127, 120, 0, 79, 75, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0,
    234, 0, 0, 0, 3, 8, 4, 232, 3, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 3, 0,
    221, 209, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 58, 58, 42, 75, 9, 2, 127,
    120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213, 213, 213, 213, 213, 213, 213,
    213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213, 213,
    213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 234, 0, 0, 0, 3, 8,
    0, 0, 0, 12, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 58, 58, 58, 42, 175, 221, 253, 221,
    221, 221, 221, 221, 80, 75, 9, 2, 127, 120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0,
    213, 213, 213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236, 221, 221,
    221, 221, 221, 80, 75, 9, 2, 127, 120, 0, 99, 99, 99, 99, 99, 99, 94, 7, 0, 0, 0, 0, 0, 0, 213,
    213, 213, 213, 213, 213, 213, 213, 213, 7, 0, 0, 211, 211, 211, 211, 124, 236,
];

#[test]
fn invalid_header() {
    let reader = std::io::Cursor::new(&BUF);
    let archive = zip::ZipArchive::new(reader);
    match archive {
        Err(ZipError::InvalidArchive(_)) => {}
        value => panic!("Unexpected value: {:?}", value),
    }
}
<|endoftext|>