<commit_before>
/// A priority queue implemented with a binary heap
use core::cmp::Ord;
use ptr::addr_of;

#[abi = "rust-intrinsic"]
extern "C" mod rusti {
    fn move_val_init<T>(dst: &mut T, -src: T);
}

pub struct PriorityQueue <T: Ord>{
    priv data: ~[T],
}

impl <T: Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftdown(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftup(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    #[cfg(stage0)]
    pure fn to_vec(self) -> ~[T] { fail }
    #[cfg(stage1)]
    #[cfg(stage2)]
    #[cfg(stage3)]
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    #[cfg(stage0)]
    pure fn to_sorted_vec(self) -> ~[T] { fail }
    #[cfg(stage1)]
    #[cfg(stage2)]
    #[cfg(stage3)]
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftdown_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    /// Create a PriorityQueue from a vector (heapify)
    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftdown(n) }; // purity-checking workaround
        }
        q
    }

    // The implementations of siftup and siftdown use unsafe blocks in order to
    // move an element out of the vector (leaving behind a junk element), shift
    // along the others and move it back into the vector over the junk element.
    // This reduces the constant factor compared to using swaps, which involves
    // twice as many moves.

    priv fn siftup(&mut self, start: uint, pos: uint) unsafe {
        let mut pos = pos;
        let new = move *addr_of(&self.data[pos]);

        while pos > start {
            let parent = (pos - 1) >> 1;
            if new > self.data[parent] {
                rusti::move_val_init(&mut self.data[pos],
                                     move *addr_of(&self.data[parent]));
                pos = parent;
                loop
            }
            break
        }
        rusti::move_val_init(&mut self.data[pos], move new);
    }

    priv fn siftdown_range(&mut self, pos: uint, end: uint) unsafe {
        let mut pos = pos;
        let start = pos;
        let new = move *addr_of(&self.data[pos]);

        let mut child = 2 * pos + 1;
        while child < end {
            let right = child + 1;
            if right < end && !(self.data[child] > self.data[right]) {
                child = right;
            }
            rusti::move_val_init(&mut self.data[pos],
                                 move *addr_of(&self.data[child]));
            pos = child;
            child = 2 * pos + 1;
        }
        rusti::move_val_init(&mut self.data[pos], move new);
        self.siftup(start, pos);
    }

    priv fn siftdown(&mut self, pos: uint) {
        self.siftdown_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_unique() {
        let mut heap = from_vec(~[~2, ~4, ~9]);
        assert heap.len() == 3;
        assert *heap.top() == ~9;
        heap.push(~11);
        assert heap.len() == 4;
        assert *heap.top() == ~11;
        heap.push(~5);
        assert heap.len() == 5;
        assert *heap.top() == ~11;
        heap.push(~27);
        assert heap.len() == 6;
        assert *heap.top() == ~27;
        heap.push(~3);
        assert heap.len() == 7;
        assert *heap.top() == ~27;
        heap.push(~103);
        assert heap.len() == 8;
        assert *heap.top() == ~103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<commit_msg>Fix doc comment<commit_after>
//! A priority queue implemented with a binary heap

use core::cmp::Ord;
use ptr::addr_of;

#[abi = "rust-intrinsic"]
extern "C" mod rusti {
    fn move_val_init<T>(dst: &mut T, -src: T);
}

pub struct PriorityQueue <T: Ord>{
    priv data: ~[T],
}

impl <T: Ord> PriorityQueue<T> {
    /// Returns the greatest item in the queue - fails if empty
    pure fn top(&self) -> &self/T { &self.data[0] }

    /// Returns the greatest item in the queue - None if empty
    pure fn maybe_top(&self) -> Option<&self/T> {
        if self.is_empty() { None } else { Some(self.top()) }
    }

    /// Returns the length of the queue
    pure fn len(&self) -> uint { self.data.len() }

    /// Returns true if a queue contains no elements
    pure fn is_empty(&self) -> bool { self.data.is_empty() }

    /// Returns true if a queue contains some elements
    pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }

    /// Returns the number of elements the queue can hold without reallocating
    pure fn capacity(&self) -> uint { vec::capacity(&self.data) }

    fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }

    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.data, n)
    }

    /// Drop all items from the queue
    fn clear(&mut self) { self.data.truncate(0) }

    /// Pop the greatest item from the queue - fails if empty
    fn pop(&mut self) -> T {
        let mut item = self.data.pop();
        if self.is_not_empty() { item <-> self.data[0]; self.siftdown(0); }
        item
    }

    /// Pop the greatest item from the queue - None if empty
    fn maybe_pop(&mut self) -> Option<T> {
        if self.is_empty() { None } else { Some(self.pop()) }
    }

    /// Push an item onto the queue
    fn push(&mut self, item: T) {
        self.data.push(item);
        self.siftup(0, self.len() - 1);
    }

    /// Optimized version of a push followed by a pop
    fn push_pop(&mut self, item: T) -> T {
        let mut item = item;
        if self.is_not_empty() && self.data[0] > item {
            item <-> self.data[0];
            self.siftdown(0);
        }
        item
    }

    /// Optimized version of a pop followed by a push - fails if empty
    fn replace(&mut self, item: T) -> T {
        let mut item = item;
        item <-> self.data[0];
        self.siftdown(0);
        item
    }

    /// Consume the PriorityQueue and return the underlying vector
    #[cfg(stage0)]
    pure fn to_vec(self) -> ~[T] { fail }
    #[cfg(stage1)]
    #[cfg(stage2)]
    #[cfg(stage3)]
    pure fn to_vec(self) -> ~[T] { let PriorityQueue{data: v} = self; v }

    /// Consume the PriorityQueue and return a vector in sorted (ascending) order
    #[cfg(stage0)]
    pure fn to_sorted_vec(self) -> ~[T] { fail }
    #[cfg(stage1)]
    #[cfg(stage2)]
    #[cfg(stage3)]
    pure fn to_sorted_vec(self) -> ~[T] {
        let mut q = self;
        let mut end = q.len();
        while end > 1 {
            end -= 1;
            q.data[end] <-> q.data[0];
            unsafe { q.siftdown_range(0, end) } // purity-checking workaround
        }
        q.to_vec()
    }

    /// Create a PriorityQueue from a vector (heapify)
    static pub pure fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
        let mut q = PriorityQueue{data: xs,};
        let mut n = q.len() / 2;
        while n > 0 {
            n -= 1;
            unsafe { q.siftdown(n) }; // purity-checking workaround
        }
        q
    }

    // The implementations of siftup and siftdown use unsafe blocks in order to
    // move an element out of the vector (leaving behind a junk element), shift
    // along the others and move it back into the vector over the junk element.
    // This reduces the constant factor compared to using swaps, which involves
    // twice as many moves.

    priv fn siftup(&mut self, start: uint, pos: uint) unsafe {
        let mut pos = pos;
        let new = move *addr_of(&self.data[pos]);

        while pos > start {
            let parent = (pos - 1) >> 1;
            if new > self.data[parent] {
                rusti::move_val_init(&mut self.data[pos],
                                     move *addr_of(&self.data[parent]));
                pos = parent;
                loop
            }
            break
        }
        rusti::move_val_init(&mut self.data[pos], move new);
    }

    priv fn siftdown_range(&mut self, pos: uint, end: uint) unsafe {
        let mut pos = pos;
        let start = pos;
        let new = move *addr_of(&self.data[pos]);

        let mut child = 2 * pos + 1;
        while child < end {
            let right = child + 1;
            if right < end && !(self.data[child] > self.data[right]) {
                child = right;
            }
            rusti::move_val_init(&mut self.data[pos],
                                 move *addr_of(&self.data[child]));
            pos = child;
            child = 2 * pos + 1;
        }
        rusti::move_val_init(&mut self.data[pos], move new);
        self.siftup(start, pos);
    }

    priv fn siftdown(&mut self, pos: uint) {
        self.siftdown_range(pos, self.len());
    }
}

#[cfg(test)]
mod tests {
    use sort::merge_sort;
    use core::cmp::le;
    use priority_queue::PriorityQueue::from_vec;

    #[test]
    fn test_top_and_pop() {
        let data = ~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
        let mut sorted = merge_sort(data, le);
        let mut heap = from_vec(data);
        while heap.is_not_empty() {
            assert *heap.top() == sorted.last();
            assert heap.pop() == sorted.pop();
        }
    }

    #[test]
    fn test_push() {
        let mut heap = from_vec(~[2, 4, 9]);
        assert heap.len() == 3;
        assert *heap.top() == 9;
        heap.push(11);
        assert heap.len() == 4;
        assert *heap.top() == 11;
        heap.push(5);
        assert heap.len() == 5;
        assert *heap.top() == 11;
        heap.push(27);
        assert heap.len() == 6;
        assert *heap.top() == 27;
        heap.push(3);
        assert heap.len() == 7;
        assert *heap.top() == 27;
        heap.push(103);
        assert heap.len() == 8;
        assert *heap.top() == 103;
    }

    #[test]
    fn test_push_unique() {
        let mut heap = from_vec(~[~2, ~4, ~9]);
        assert heap.len() == 3;
        assert *heap.top() == ~9;
        heap.push(~11);
        assert heap.len() == 4;
        assert *heap.top() == ~11;
        heap.push(~5);
        assert heap.len() == 5;
        assert *heap.top() == ~11;
        heap.push(~27);
        assert heap.len() == 6;
        assert *heap.top() == ~27;
        heap.push(~3);
        assert heap.len() == 7;
        assert *heap.top() == ~27;
        heap.push(~103);
        assert heap.len() == 8;
        assert *heap.top() == ~103;
    }

    #[test]
    fn test_push_pop() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.push_pop(6) == 6;
        assert heap.len() == 5;
        assert heap.push_pop(0) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(4) == 5;
        assert heap.len() == 5;
        assert heap.push_pop(1) == 4;
        assert heap.len() == 5;
    }

    #[test]
    fn test_replace() {
        let mut heap = from_vec(~[5, 5, 2, 1, 3]);
        assert heap.len() == 5;
        assert heap.replace(6) == 5;
        assert heap.len() == 5;
        assert heap.replace(0) == 6;
        assert heap.len() == 5;
        assert heap.replace(4) == 5;
        assert heap.len() == 5;
        assert heap.replace(1) == 4;
        assert heap.len() == 5;
    }

    fn check_to_vec(data: ~[int]) {
        let heap = from_vec(data);
        assert merge_sort(heap.to_vec(), le) == merge_sort(data, le);
        assert heap.to_sorted_vec() == merge_sort(data, le);
    }

    #[test]
    fn test_to_vec() {
        check_to_vec(~[]);
        check_to_vec(~[5]);
        check_to_vec(~[3, 2]);
        check_to_vec(~[2, 3]);
        check_to_vec(~[5, 1, 2]);
        check_to_vec(~[1, 100, 2, 3]);
        check_to_vec(~[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
        check_to_vec(~[2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
        check_to_vec(~[9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
        check_to_vec(~[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
        check_to_vec(~[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
        check_to_vec(~[5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_pop() { let mut heap = from_vec::<int>(~[]); heap.pop(); }

    #[test]
    fn test_empty_maybe_pop() {
        let mut heap = from_vec::<int>(~[]);
        assert heap.maybe_pop().is_none();
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_top() { let empty = from_vec::<int>(~[]); empty.top(); }

    #[test]
    fn test_empty_maybe_top() {
        let empty = from_vec::<int>(~[]);
        assert empty.maybe_top().is_none();
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_empty_replace() {
        let mut heap = from_vec::<int>(~[]);
        heap.replace(5);
    }
}
<|endoftext|>


<commit_before>use core::{fmt, mem, ptr, slice, str};
use panic::panic_impl;
use env::{args_init, args_destroy};
use system::syscall::sys_exit;
use vec::Vec;

pub fn begin_unwind(string: &'static str, file_line: &(&'static str, u32)) -> ! {
    let &(file, line) = file_line;
    panic_impl(format_args!("{}", string), file, line)
}

pub fn begin_unwind_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
    let &(file, line) = file_line;
    panic_impl(fmt, file, line)
}

#[no_mangle]
#[naked]
#[cfg(target_arch = "x86")]
pub unsafe fn _start() {
    asm!("push esp
        call _start_stack
        pop esp"
        :
        :
        : "memory"
        : "intel", "volatile");
    let _ = sys_exit(0);
}

#[no_mangle]
#[naked]
#[cfg(target_arch = "x86_64")]
pub unsafe fn _start() {
    asm!("push rsp
        call _start_stack
        pop rsp"
        :
        :
        : "memory"
        : "intel", "volatile");
    let _ = sys_exit(0);
}

#[no_mangle]
pub unsafe extern "C" fn _start_stack(sp: usize){
    extern "C" {
        fn main(argc: usize, argv: *const *const u8) -> usize;
    }

    //asm!("xchg bx, bx" : : : "memory" : "intel", "volatile");

    let stack = sp as *const usize;
    let argc = *stack;
    let argv = stack.offset(1) as *const *const u8;
    let _ = sys_exit(main(argc, argv));
}

#[lang = "start"]
fn lang_start(main: *const u8, argc: usize, argv: *const *const u8) -> usize {
    unsafe {
        let mut args: Vec<&'static str> = Vec::new();
        for i in 0..argc as isize {
            let arg = ptr::read(argv.offset(i));
            if arg as usize > 0 {
                let mut len = 0;
                for j in 0..4096 {
                    len = j;
                    if ptr::read(arg.offset(j)) == 0 {
                        break;
                    }
                }
                let utf8: &'static [u8] = slice::from_raw_parts(arg, len as usize);
                args.push(str::from_utf8_unchecked(utf8));
            }
        }

        args_init(args);

        mem::transmute::<_, fn()>(main)();

        args_destroy();
    }

    0
}
<commit_msg>Cleanup start functions<commit_after>use core::{fmt, mem, ptr, slice, str};
use panic::panic_impl;
use env::{args_init, args_destroy};
use system::syscall::sys_exit;
use vec::Vec;

pub fn begin_unwind(string: &'static str, file_line: &(&'static str, u32)) -> ! {
    let &(file, line) = file_line;
    panic_impl(format_args!("{}", string), file, line)
}

pub fn begin_unwind_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
    let &(file, line) = file_line;
    panic_impl(fmt, file, line)
}

#[no_mangle]
#[naked]
#[cfg(target_arch = "x86")]
pub unsafe fn _start() {
    asm!("push esp
        call _start_stack
        pop esp"
        :
        :
        : "memory"
        : "intel", "volatile");
    let _ = sys_exit(0);
}

#[no_mangle]
#[naked]
#[cfg(target_arch = "x86_64")]
pub unsafe fn _start() {
    asm!("push rsp
        call _start_stack
        pop rsp"
        :
        :
        : "memory"
        : "intel", "volatile");
    let _ = sys_exit(0);
}

#[no_mangle]
pub unsafe extern "C" fn _start_stack(stack: *const usize){
    extern "C" {
        fn main(argc: usize, argv: *const *const u8) -> usize;
    }

    //asm!("xchg bx, bx" : : : "memory" : "intel", "volatile");

    let argc = *stack;
    let argv = stack.offset(1) as *const *const u8;
    let _ = sys_exit(main(argc, argv));
}

#[lang = "start"]
fn lang_start(main: *const u8, argc: usize, argv: *const *const u8) -> usize {
    unsafe {
        let mut args: Vec<&'static str> = Vec::new();
        for i in 0..argc as isize {
            let arg = ptr::read(argv.offset(i));
            if arg as usize > 0 {
                let mut len = 0;
                for j in 0..4096 {
                    len = j;
                    if ptr::read(arg.offset(j)) == 0 {
                        break;
                    }
                }
                let utf8: &'static [u8] = slice::from_raw_parts(arg, len as usize);
                args.push(str::from_utf8_unchecked(utf8));
            }
        }

        args_init(args);

        mem::transmute::<_, fn()>(main)();

        args_destroy();
    }

    0
}
<|endoftext|>


<commit_before><commit_msg>No longer pass GLX_ALPHA_SIZE to the framebuffer config attributes<commit_after><|endoftext|>


<commit_before><commit_msg>Remove calls to exit() and replace them with error propagation up to main()<commit_after><|endoftext|>


<commit_before><commit_msg>Add problem #79<commit_after>use core::hashmap::{ HashMap, HashSet };

use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 79,
    answer: "73162890",
    solver: solve
};

struct Relation<T> {
    num_prec: uint,
    succ: HashSet<T>
}

impl<T: Hash + IterBytes + Eq> Relation<T> {
    fn new() -> Relation<T> { Relation { num_prec: 0, succ: HashSet::new() } }
}

struct Relations<T> {
    top: HashMap<T, Relation<T>>
}

impl<T: Hash + IterBytes + Eq + Copy> Relations<T> {
    fn new() -> Relations<T> { Relations { top: HashMap::new() } }

    fn set_dependant(&mut self, prec: T, succ: T) {
        if !self.top.contains_key(&prec) {
            self.top.insert(prec, Relation::new());
        }
        if !self.top.contains_key(&succ) {
            self.top.insert(succ, Relation::new());
        }

        let mut contained = true;
        match self.top.find_mut(&prec) {
            Some(s) => {
                if !s.succ.contains(&succ) {
                    s.succ.insert(succ);
                    contained = false;
                }
            }
            None => { fail!() }
        }
        if !contained {
            match self.top.find_mut(&succ) {
                Some(p) => { p.num_prec += 1; }
                None => { fail!(); }
            }
        }
    }

    fn find_all_not_preceded(&self) -> ~[T] {
        let mut result = ~[];
        for self.top.each |&(k, v)| {
            if v.num_prec == 0 { result.push(*k); }
        }
        return result;
    }

    fn delete_and_find(&mut self, prec: T) -> ~[T] {
        let mut result = ~[];
        do self.top.pop(&prec).map |p| {
            for p.succ.each |&s| {
                do self.top.find_mut(&s).map |y| {
                    y.num_prec -= 1;
                    if y.num_prec == 0 {
                        result.push(s);
                    }
                };
            }
        };
        return result;
    }
}

fn tsort<T: Hash + IterBytes + Eq + Copy>(rels: &mut Relations<T>) -> ~[T] {
    let mut sorted = ~[];
    let mut queue = rels.find_all_not_preceded();
    while !queue.is_empty() {
        let prec = queue.shift();
        sorted.push(prec);
        queue.push_all(rels.delete_and_find(prec));
    }
    return sorted;
}

fn solve() -> ~str {
    let result = io::file_reader(&Path("files/keylog.txt")).map(|file| {
        let mut rels = Relations::new();
        for file.each_line |line| {
            let ds = vec::filter_map(str::to_chars(line), |c| char::to_digit(c, 10));
            for uint::range(1, ds.len()) |i| {
                rels.set_dependant(ds[i - 1], ds[i]);
            }
        }
        tsort(&mut rels)
    });

    match result {
        Err(msg) => fail!(msg),
        Ok(value) => return str::concat(value.map(|d| d.to_str()))
    }
}
<|endoftext|>


<commit_before><commit_msg>add (not yet compiling) mnist example<commit_after>extern crate torchrs;

use torchrs::nn::{Module, Conv2d, Linear};

use torchrs::nn::functional::{max_pool2d, relu, dropout, dropout2d, log_softmax};
#[derive(Serialize, Deserialize, Debug, ModuleParse)]
struct Net<'a> {
    delegate: nn::Module<'a>,
    conv1: Conv2d<'a>,
    conv2: Conv2d<'a>,
    fc1: Linear<'a>,
    fc2: Linear<'a>,
}

impl Net<'a> {
    pub fn new() -> Net<'a> {
        let t = Net {
        delegate: Module::new(),
        conv1: Conv2d::build(1, 10, 5).done(),
        conv2: Conv2d::build(10, 20, 5).done(),
        fc1: Linear::build(320, 50).done(),
        fc2: Linear::build(50, 10).done(),
        };
        t.init_module();
        t
    }
}
// The forward operations could take on one of two implementations.
// The first supporting a near verbatim version of the python
// implementation, and the second supporting a slightly more
// idiomatic to Rust method chaining.

// a) as a near verbatim implementation of the python version
impl <'a>ModIntf<'a> for Net<'a> {
    fn forward(&mut self, args: &[&mut Tensor]) -> [&mut Tensor] {
        let training = self.delegate.training;
        let x = relu(max_pool2d(self.conv1(&args[0]), 2), false);
        let x = relu(max_pool2d(dropout2d(self.conv2(&x), training, 0.5), 2), false);
        let x = x.view(-1, 320);
        let x = relu(self.fc1(&x), false);
        let x = dropout(&x, training, 0.5);
        let x = self.fc2(&x);
        [log_softmax(&x)]
    }
 }

fn main () {

}<|endoftext|>


<commit_before>/*!
Test supports module.

*/

#![allow(dead_code)]

use glutin;
use glium::{self, DisplayBuild};

use std::os;

/// Returns true if we are executing headless tests.
pub fn is_headless() -> bool {
    os::getenv("HEADLESS_TESTS").is_some()
}

/// Builds a headless display for tests.
#[cfg(feature = "headless")]
pub fn build_display() -> glium::Display {
    let display = if is_headless() {
        glutin::HeadlessRendererBuilder::new(1024, 768).build_glium().unwrap()
    } else {
        glutin::WindowBuilder::new().with_visibility(false).build_glium().unwrap()
    };

    display
}

/// Builds a headless display for tests.
#[cfg(not(feature = "headless"))]
pub fn build_display() -> glium::Display {
    assert!(!is_headless());
    glutin::WindowBuilder::new().with_visibility(false).build_glium().unwrap()
}

/// Builds a 2x2 unicolor texture.
pub fn build_unicolor_texture2d(display: &glium::Display, red: f32, green: f32, blue: f32)
    -> glium::Texture2d
{
    let color = ((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8);

    glium::texture::Texture2d::new(display, vec![
        vec![color, color],
        vec![color, color],
    ])
}

/// Builds a vertex buffer, index buffer, and program, to draw red `(1.0, 0.0, 0.0, 1.0)` to the whole screen.
pub fn build_fullscreen_red_pipeline(display: &glium::Display) -> (glium::vertex::VertexBufferAny,
    glium::IndexBuffer, glium::Program)
{
    #[vertex_format]
    #[derive(Copy)]
    struct Vertex {
        position: [f32; 2],
    }

    (
        glium::VertexBuffer::new(display, vec![
            Vertex { position: [-1.0,  1.0] }, Vertex { position: [1.0,  1.0] },
            Vertex { position: [-1.0, -1.0] }, Vertex { position: [1.0, -1.0] },
        ]).into_vertex_buffer_any(),

        glium::IndexBuffer::new(display, glium::index::TriangleStrip(vec![0u8, 1, 2, 3])),

        glium::Program::from_source(display,
            "
                #version 110

                attribute vec2 position;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0);
                }
            ",
            "
                #version 110

                void main() {
                    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                }
            ",
            None).unwrap()
    )
}

/// Builds a vertex buffer and an index buffer corresponding to a rectangle.
///
/// The vertex buffer has the "position" attribute of type "vec2".
pub fn build_rectangle_vb_ib(display: &glium::Display)
    -> (glium::vertex::VertexBufferAny, glium::IndexBuffer)
{
    #[vertex_format]
    #[derive(Copy)]
    struct Vertex {
        position: [f32; 2],
    }

    (
        glium::VertexBuffer::new(display, vec![
            Vertex { position: [-1.0,  1.0] }, Vertex { position: [1.0,  1.0] },
            Vertex { position: [-1.0, -1.0] }, Vertex { position: [1.0, -1.0] },
        ]).into_vertex_buffer_any(),

        glium::IndexBuffer::new(display, glium::index::TriangleStrip(vec![0u8, 1, 2, 3])),
    )
}

/// Builds a texture suitable for rendering.
pub fn build_renderable_texture(display: &glium::Display) -> glium::Texture2d {
    glium::Texture2d::new_empty(display,
                                glium::texture::UncompressedFloatFormat::U8U8U8U8,
                                1024, 1024)
}
<commit_msg>Switch to `Texture2d::empty()` in the tests<commit_after>/*!
Test supports module.

*/

#![allow(dead_code)]

use glutin;
use glium::{self, DisplayBuild};

use std::os;

/// Returns true if we are executing headless tests.
pub fn is_headless() -> bool {
    os::getenv("HEADLESS_TESTS").is_some()
}

/// Builds a headless display for tests.
#[cfg(feature = "headless")]
pub fn build_display() -> glium::Display {
    let display = if is_headless() {
        glutin::HeadlessRendererBuilder::new(1024, 768).build_glium().unwrap()
    } else {
        glutin::WindowBuilder::new().with_visibility(false).build_glium().unwrap()
    };

    display
}

/// Builds a headless display for tests.
#[cfg(not(feature = "headless"))]
pub fn build_display() -> glium::Display {
    assert!(!is_headless());
    glutin::WindowBuilder::new().with_visibility(false).build_glium().unwrap()
}

/// Builds a 2x2 unicolor texture.
pub fn build_unicolor_texture2d(display: &glium::Display, red: f32, green: f32, blue: f32)
    -> glium::Texture2d
{
    let color = ((red * 255.0) as u8, (green * 255.0) as u8, (blue * 255.0) as u8);

    glium::texture::Texture2d::new(display, vec![
        vec![color, color],
        vec![color, color],
    ])
}

/// Builds a vertex buffer, index buffer, and program, to draw red `(1.0, 0.0, 0.0, 1.0)` to the whole screen.
pub fn build_fullscreen_red_pipeline(display: &glium::Display) -> (glium::vertex::VertexBufferAny,
    glium::IndexBuffer, glium::Program)
{
    #[vertex_format]
    #[derive(Copy)]
    struct Vertex {
        position: [f32; 2],
    }

    (
        glium::VertexBuffer::new(display, vec![
            Vertex { position: [-1.0,  1.0] }, Vertex { position: [1.0,  1.0] },
            Vertex { position: [-1.0, -1.0] }, Vertex { position: [1.0, -1.0] },
        ]).into_vertex_buffer_any(),

        glium::IndexBuffer::new(display, glium::index::TriangleStrip(vec![0u8, 1, 2, 3])),

        glium::Program::from_source(display,
            "
                #version 110

                attribute vec2 position;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0);
                }
            ",
            "
                #version 110

                void main() {
                    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                }
            ",
            None).unwrap()
    )
}

/// Builds a vertex buffer and an index buffer corresponding to a rectangle.
///
/// The vertex buffer has the "position" attribute of type "vec2".
pub fn build_rectangle_vb_ib(display: &glium::Display)
    -> (glium::vertex::VertexBufferAny, glium::IndexBuffer)
{
    #[vertex_format]
    #[derive(Copy)]
    struct Vertex {
        position: [f32; 2],
    }

    (
        glium::VertexBuffer::new(display, vec![
            Vertex { position: [-1.0,  1.0] }, Vertex { position: [1.0,  1.0] },
            Vertex { position: [-1.0, -1.0] }, Vertex { position: [1.0, -1.0] },
        ]).into_vertex_buffer_any(),

        glium::IndexBuffer::new(display, glium::index::TriangleStrip(vec![0u8, 1, 2, 3])),
    )
}

/// Builds a texture suitable for rendering.
pub fn build_renderable_texture(display: &glium::Display) -> glium::Texture2d {
    glium::Texture2d::empty(display, 1024, 1024)
}
<|endoftext|>


<commit_before><commit_msg>clean up naming in message handler<commit_after><|endoftext|>


<commit_before>

// xfail-stage0

use std;
import std::task;

fn test_sleep() { task::sleep(1000000u); }

fn test_unsupervise() {
  fn f() {
    task::unsupervise();
    fail;
  }
  spawn f();
}

fn test_join() {
  fn winner() {
  }

  auto wintask = spawn winner();

  assert task::join(wintask) == task::tr_success;

  fn failer() {
    task::unsupervise();
    fail;
  }

  auto failtask = spawn failer();

  assert task::join(failtask) == task::tr_failure;
}

fn main() {
  // FIXME: Why aren't we running this?
  //test_sleep();
  test_unsupervise();
  test_join();
}
<commit_msg>Re-removing a test case that was moved during the big test suite overhaul.<commit_after><|endoftext|>


<commit_before><commit_msg>Rank physical devices and pick the best one<commit_after><|endoftext|>


<commit_before><commit_msg>test: Add an xfailed test for issue #959<commit_after>// xfail-test

fn f() -> float { (fail "boo") as float / 2.0 }

fn main() { }<|endoftext|>


<commit_before><commit_msg>Marginally more useful error handling.<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for allergies case<commit_after>#[derive(Debug, Clone, PartialEq)]
pub enum Allergen {
    Eggs = 0x0000_0001,
    Peanuts = 0x0000_0002,
    Shellfish = 0x0000_0004,
    Strawberries = 0x0000_0008,
    Tomatoes = 0x0000_0010,
    Chocolate = 0x0000_0020,
    Pollen = 0x0000_0040,
    Cats = 0x0000_0080,
}

#[derive(Debug)]
pub struct Allergies {
    result: u32,
}

impl Allergies {
    pub fn new(score: u32) -> Allergies {
        Allergies { result: score }
    }

    pub fn is_allergic_to(&self, item: &Allergen) -> bool {
        self.result & (*item).clone() as u32 != 0
    }

    pub fn allergies(&self) -> Vec<Allergen> {
        let mut result: Vec<Allergen> = Vec::new();

        let value = self.result;

        if value & Allergen::Eggs as u32 == Allergen::Eggs as u32 {
            result.push(Allergen::Eggs);
        }

        if value & Allergen::Peanuts as u32 == Allergen::Peanuts as u32 {
            result.push(Allergen::Peanuts);
        }

        if value & Allergen::Shellfish as u32 == Allergen::Shellfish as u32 {
            result.push(Allergen::Shellfish);
        }

        if value & Allergen::Strawberries as u32 == Allergen::Strawberries as u32 {
            result.push(Allergen::Strawberries);
        }

        if value & Allergen::Tomatoes as u32 == Allergen::Tomatoes as u32 {
            result.push(Allergen::Tomatoes);
        }

        if value & Allergen::Chocolate as u32 == Allergen::Chocolate as u32 {
            result.push(Allergen::Chocolate);
        }

        if value & Allergen::Pollen as u32 == Allergen::Pollen as u32 {
            result.push(Allergen::Pollen);
        }

        if value & Allergen::Cats as u32 == Allergen::Cats as u32 {
            result.push(Allergen::Cats)
        }

        println!("{:?}", result);

        result
    }
}
<|endoftext|>


<commit_before><commit_msg>added key to to do items<commit_after><|endoftext|>


<commit_before><commit_msg>continued cleaning up iterator_provider_tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add security for config<commit_after><|endoftext|>


<commit_before><commit_msg>Add async API example<commit_after>//! IGD async API example.
//!
//! It demonstrates how to:
//! * get external IP
//! * add port mappings
//! * remove port mappings
//!
//! If everything works fine, 2 port mappings are added, 1 removed and we're left with single
//! port mapping: External 1234 ---> 4321 Internal

extern crate igd;
extern crate futures;
extern crate tokio_core;

use igd::tokio::search_gateway;
use igd::PortMappingProtocol;
use futures::future::Future;

fn main() {
    let mut evloop = tokio_core::reactor::Core::new().unwrap();
    let handle = evloop.handle();

    let task = search_gateway(&handle)
        .map_err(|e| panic!("Failed to find IGD: {}", e))
        .and_then(|gateway| gateway.get_external_ip()
            .map_err(|e| panic!("Failed to get external IP: {}", e))
            .and_then(|ip| Ok((gateway, ip)))
        )
        .and_then(|(gateway, pub_ip)| {
            println!("Our public IP: {}", pub_ip);
            Ok(gateway)
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                1234,
                "192.168.1.210:4321".parse().unwrap(),
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| {
            gateway.add_port(
                PortMappingProtocol::TCP,
                2345,
                "192.168.1.210:5432".parse().unwrap(),
                0,
                "rust-igd-async-example",
            )
            .map_err(|e| panic!("Failed to add port mapping: {}", e))
            .and_then(|_| {
                println!("New port mapping was successfully added.");
                Ok(gateway)
            })
        })
        .and_then(|gateway| gateway.remove_port(PortMappingProtocol::TCP, 2345))
        .and_then(|_| {
            println!("Port was removed.");
            Ok(())
        });

    let _ = evloop.run(task).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>test(Rust): Add test for sizeof structs and enums<commit_after>//! Print sizes of structs and enums
//!
//! Run with `cargo test sizes -- --nocapture`
//! to get the printed output.

use stencila_schema::*;

macro_rules! sizeof {
    ($type:ident) => {
        {
            let size = std::mem::size_of::<$type>();
            println!("{}: {}", stringify!($type), size);
            size
        }
    };
}

#[test]
fn sizes() {
    sizeof!(Primitive);

    sizeof!(ArrayValidator);
    sizeof!(Article);
    sizeof!(AudioObject);
    sizeof!(BooleanValidator);
    sizeof!(Brand);
    sizeof!(CitationIntentEnumeration);
    sizeof!(Cite);
    sizeof!(CiteGroup);
    sizeof!(Claim);
    sizeof!(Code);
    sizeof!(CodeBlock);
    sizeof!(CodeChunk);
    sizeof!(CodeError);
    sizeof!(CodeExpression);
    sizeof!(CodeFragment);
    sizeof!(Collection);
    sizeof!(Comment);
    sizeof!(ConstantValidator);
    sizeof!(ContactPoint);
    sizeof!(CreativeWork);
    sizeof!(Datatable);
    sizeof!(DatatableColumn);
    sizeof!(Date);
    sizeof!(DefinedTerm);
    sizeof!(Delete);
    sizeof!(Emphasis);
    sizeof!(EnumValidator);
    sizeof!(Enumeration);
    sizeof!(Figure);
    sizeof!(Function);
    sizeof!(Grant);
    sizeof!(Heading);
    sizeof!(ImageObject);
    sizeof!(Include);
    sizeof!(IntegerValidator);
    sizeof!(Link);
    sizeof!(List);
    sizeof!(ListItem);
    sizeof!(Mark);
    sizeof!(Math);
    sizeof!(MathBlock);
    sizeof!(MathFragment);
    sizeof!(MediaObject);
    sizeof!(MonetaryGrant);
    sizeof!(NontextualAnnotation);
    sizeof!(Note);
    sizeof!(NumberValidator);
    sizeof!(Organization);
    sizeof!(Paragraph);
    sizeof!(Parameter);
    sizeof!(Periodical);
    sizeof!(Person);
    sizeof!(PostalAddress);
    sizeof!(Product);
    sizeof!(PropertyValue);
    sizeof!(PublicationIssue);
    sizeof!(PublicationVolume);
    sizeof!(Quote);
    sizeof!(QuoteBlock);
    sizeof!(Review);
    sizeof!(SoftwareApplication);
    sizeof!(SoftwareEnvironment);
    sizeof!(SoftwareSession);
    sizeof!(SoftwareSourceCode);
    sizeof!(StringValidator);
    sizeof!(Strong);
    sizeof!(Subscript);
    sizeof!(Superscript);
    sizeof!(Table);
    sizeof!(TableCell);
    sizeof!(TableRow);
    sizeof!(ThematicBreak);
    sizeof!(Thing);
    sizeof!(TupleValidator);
    sizeof!(Validator);
    sizeof!(Variable);
    sizeof!(VideoObject);
    sizeof!(VolumeMount);

    sizeof!(InlineContent);
    sizeof!(BlockContent);

    sizeof!(CreativeWork);
    sizeof!(CreativeWorkTypes);
}
<|endoftext|>


<commit_before>use std::i32;
use std::iter::repeat;
use std::cmp::max;
use std::collections::Bitv;

use alignment::{Alignment, AlignmentOperation};

#[derive(Copy)]
enum AlignmentType {
    Global,
    Semiglobal,
    Local
}

/// Calculate alignments.
///
/// # Example
///
/// ```
/// use bio::alignment::pairwise::Aligner;
/// use bio::alignment::AlignmentOperation::{Match, Subst, Ins, Del};
/// let x = b"ACCGTGGAT";
/// let y = b"AAAAACCGTTGAT";
/// let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
/// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
/// let alignment = aligner.semiglobal(x, y);
/// assert_eq!(alignment.i, 4);
/// assert_eq!(alignment.j, 0);
/// assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
/// ```
#[allow(non_snake_case)]
pub struct Aligner<F> where F: Fn(u8, u8) -> i32 {
    S: [Vec<i32>; 2],
    I: [Vec<i32>; 2],
    D: [Vec<i32>; 2],
    traceback: Traceback,
    gap_open: i32,
    gap_extend: i32,
    score: F
}

impl<F> Aligner<F> where F: Fn(u8, u8) -> i32 {
    pub fn with_capacity(m: usize, n: usize, gap_open: i32, gap_extend: i32, score: F) -> Self {
        let get_vec = |&:| Vec::with_capacity(m + 1);
        Aligner {
            S: [get_vec(), get_vec()],
            I: [get_vec(), get_vec()],
            D: [get_vec(), get_vec()],
            traceback: Traceback::with_capacity(m, n),
            gap_open: gap_open,
            gap_extend: gap_extend,
            score: score
        }
    }

    fn init(&mut self, m: usize, alignment_type: AlignmentType) {
        // set minimum score to -inf, and allow to add gap_extend
        // without overflow
        let min_score = i32::MIN - self.gap_extend;
        for k in 0..2us {
            self.S[k].clear();
            self.I[k].clear();
            self.D[k].clear();
            self.I[k].extend(repeat(min_score).take(m + 1));
            self.D[k].extend(repeat(min_score).take(m + 1));
            match alignment_type {
                AlignmentType::Global => {
                    let ref mut s = self.S[k];
                    let mut score = self.gap_open;
                    for _ in 0..m+1 {
                        s.push(score);
                        score += self.gap_extend;
                    }
                },
                _ => self.S[k].extend(repeat(0).take(m + 1))
            }
        }
    }

    pub fn global(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Global)
    }

    pub fn semiglobal(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Semiglobal)
    }

    pub fn local(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Local)
    }

    fn align(&mut self, x: &[u8], y: &[u8], alignment_type: AlignmentType) -> Alignment {
        let (m, n) = (x.len(), y.len());

        self.init(m, alignment_type);
        self.traceback.init(n, alignment_type);

        let (mut best, mut best_i, mut best_j) = (0, 0, 0);
        let mut col = 0;

        for i in 1..n+1 {
            col = i % 2;
            let prev = 1 - col;

            match alignment_type {
                AlignmentType::Global => {
                    self.S[col][0] = self.gap_open + (i as i32 - 1) * self.gap_extend;
                    self.traceback.del(i, 0);
                },
                _ => {
                    // with local and semiglobal, allow to begin anywhere in y
                    self.S[col][0] = 0;
                }
            }

            let b = y[i - 1];
            let mut score = 0i32;
            for j in 1..m+1 {
                let a = x[j - 1];

                let d_score = max(
                    self.S[prev][j] + self.gap_open,
                    self.D[prev][j] + self.gap_extend
                );
                let i_score = max(
                    self.S[col][j-1] + self.gap_open,
                    self.I[col][j-1] + self.gap_extend
                );
                score = self.S[prev][j-1] + (self.score)(a, b);

                if d_score > score {
                    score = d_score;
                    self.traceback.del(i, j);
                }
                else if i_score > score {
                    score = i_score;
                    self.traceback.ins(i, j);
                }
                else {
                    self.traceback.subst(i, j);
                }

                match alignment_type {
                    AlignmentType::Local => {
                        if score < 0 {
                            self.traceback.start(i, j);
                            score = 0;
                        }
                        else if score > best {
                            best = score;
                            best_i = i;
                            best_j = j;
                        }
                    },
                    _ => ()
                }

                self.S[col][j] = score;
                self.D[col][j] = d_score;
                self.I[col][j] = i_score;
            }

            match alignment_type {
                AlignmentType::Semiglobal => {
                    if score > best {
                        best = score;
                        best_i = i;
                        best_j = m;
                    }
                },
                _ => ()
            }
        }
        match alignment_type {
            AlignmentType::Global => {
                let score = self.S[col][m];
                self.traceback.get_alignment(n, m, x, y, score)
            },
            _ => self.traceback.get_alignment(best_i, best_j, x, y, best)
        }

    }
}

struct Traceback {
    subst: Vec<Bitv>,
    del: Vec<Bitv>,
    ins: Vec<Bitv>
}

impl Traceback {
    fn with_capacity(m: usize, n: usize) -> Self {
        let get_vec = |&:| repeat(Bitv::from_elem(m + 1, false)).take(n + 1).collect::<Vec<Bitv>>();
        Traceback {
            subst: get_vec(),
            del: get_vec(),
            ins: get_vec()
        }
    }

    fn init(&mut self, n: usize, alignment_type: AlignmentType) {
        match alignment_type {
            AlignmentType::Global => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
                // set the first cell to start, the rest to deletions
                self.del[0].set(0, false);
            },
            _ => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.del[i].negate();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
            }
        }
    }

    fn start(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, false);
        self.del[i].set(j, false);
        self.ins[i].set(j, false);
    }

    fn subst(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, true);
    }

    fn del(&mut self, i: usize, j: usize) {
        self.del[i].set(j, true);
    }

    fn ins(&mut self, i: usize, j: usize) {
        self.ins[i].set(j, true);
    }

    fn is_subst(&self, i: usize, j: usize) -> bool {
        self.subst[i].get(j).unwrap()
    }

    fn is_del(&self, i: usize, j: usize) -> bool {
        self.del[i].get(j).unwrap()
    }

    fn is_ins(&self, i: usize, j: usize) -> bool {
        self.ins[i].get(j).unwrap()
    }

    fn get_alignment(&self, mut i: usize, mut j: usize, x: &[u8], y: &[u8], score: i32) -> Alignment {
        let mut ops = Vec::with_capacity(x.len());

        loop {
            let (ii, jj, op) = if self.is_subst(i, j) {
                let op = if y[i-1] == x[j-1] {
                    AlignmentOperation::Match
                }
                else {
                    AlignmentOperation::Subst
                };
                (i - 1, j - 1, op)
            }
            else if self.is_del(i, j) {
                (i - 1, j, AlignmentOperation::Del)
            }
            else if self.is_ins(i, j) {
                (i, j - 1, AlignmentOperation::Ins)
            } else {
                // reached alignment start
                break;
            };
            ops.push(op);
            i = ii;
            j = jj;
        }

        ops.reverse();
        Alignment { i: i, j: j, operations: ops, score: score}
    }
}

#[cfg(test)]
mod tests {
    use super::Aligner;
    use alignment::AlignmentOperation::{Match, Subst, Del};

    #[test]
    fn test_semiglobal() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.semiglobal(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_local() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.local(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_global() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.global(x, y);
        assert_eq!(alignment.i, 0);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Del, Del, Del, Del, Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }
}
<commit_msg>Docs.<commit_after>use std::i32;
use std::iter::repeat;
use std::cmp::max;
use std::collections::Bitv;

use alignment::{Alignment, AlignmentOperation};

#[derive(Copy)]
enum AlignmentType {
    Global,
    Semiglobal,
    Local
}

/// Calculate alignments with a generalized variant of the Smith Waterman algorithm.
/// Complexity: O(n * m) for strings of length m and n.
///
/// # Example
///
/// ```
/// use bio::alignment::pairwise::Aligner;
/// use bio::alignment::AlignmentOperation::{Match, Subst, Ins, Del};
/// let x = b"ACCGTGGAT";
/// let y = b"AAAAACCGTTGAT";
/// let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
/// let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
/// let alignment = aligner.semiglobal(x, y);
/// assert_eq!(alignment.i, 4);
/// assert_eq!(alignment.j, 0);
/// assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
/// ```
#[allow(non_snake_case)]
pub struct Aligner<F> where F: Fn(u8, u8) -> i32 {
    S: [Vec<i32>; 2],
    I: [Vec<i32>; 2],
    D: [Vec<i32>; 2],
    traceback: Traceback,
    gap_open: i32,
    gap_extend: i32,
    score: F
}

impl<F> Aligner<F> where F: Fn(u8, u8) -> i32 {
    /// Create new aligner instance. The size hints help to
    /// avoid unnecessary memory allocations.
    ///
    /// # Arguments
    ///
    /// * `m` - the expected size of x
    /// * `n` - the expected size of y
    /// * `gap_open` - the score for opening a gap (should be negative)
    /// * `gap_extend` - the score for extending a gap (should be negative)
    /// * `score` - function that returns the score for substitutions
    ///
    pub fn with_capacity(m: usize, n: usize, gap_open: i32, gap_extend: i32, score: F) -> Self {
        let get_vec = |&:| Vec::with_capacity(m + 1);
        Aligner {
            S: [get_vec(), get_vec()],
            I: [get_vec(), get_vec()],
            D: [get_vec(), get_vec()],
            traceback: Traceback::with_capacity(m, n),
            gap_open: gap_open,
            gap_extend: gap_extend,
            score: score
        }
    }

    fn init(&mut self, m: usize, alignment_type: AlignmentType) {
        // set minimum score to -inf, and allow to add gap_extend
        // without overflow
        let min_score = i32::MIN - self.gap_extend;
        for k in 0..2us {
            self.S[k].clear();
            self.I[k].clear();
            self.D[k].clear();
            self.I[k].extend(repeat(min_score).take(m + 1));
            self.D[k].extend(repeat(min_score).take(m + 1));
            match alignment_type {
                AlignmentType::Global => {
                    let ref mut s = self.S[k];
                    let mut score = self.gap_open;
                    for _ in 0..m+1 {
                        s.push(score);
                        score += self.gap_extend;
                    }
                },
                _ => self.S[k].extend(repeat(0).take(m + 1))
            }
        }
    }

    pub fn global(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Global)
    }

    pub fn semiglobal(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Semiglobal)
    }

    pub fn local(&mut self, x: &[u8], y: &[u8]) -> Alignment {
        self.align(x, y, AlignmentType::Local)
    }

    fn align(&mut self, x: &[u8], y: &[u8], alignment_type: AlignmentType) -> Alignment {
        let (m, n) = (x.len(), y.len());

        self.init(m, alignment_type);
        self.traceback.init(n, alignment_type);

        let (mut best, mut best_i, mut best_j) = (0, 0, 0);
        let mut col = 0;

        for i in 1..n+1 {
            col = i % 2;
            let prev = 1 - col;

            match alignment_type {
                AlignmentType::Global => {
                    self.S[col][0] = self.gap_open + (i as i32 - 1) * self.gap_extend;
                    self.traceback.del(i, 0);
                },
                _ => {
                    // with local and semiglobal, allow to begin anywhere in y
                    self.S[col][0] = 0;
                }
            }

            let b = y[i - 1];
            let mut score = 0i32;
            for j in 1..m+1 {
                let a = x[j - 1];

                let d_score = max(
                    self.S[prev][j] + self.gap_open,
                    self.D[prev][j] + self.gap_extend
                );
                let i_score = max(
                    self.S[col][j-1] + self.gap_open,
                    self.I[col][j-1] + self.gap_extend
                );
                score = self.S[prev][j-1] + (self.score)(a, b);

                if d_score > score {
                    score = d_score;
                    self.traceback.del(i, j);
                }
                else if i_score > score {
                    score = i_score;
                    self.traceback.ins(i, j);
                }
                else {
                    self.traceback.subst(i, j);
                }

                match alignment_type {
                    AlignmentType::Local => {
                        if score < 0 {
                            self.traceback.start(i, j);
                            score = 0;
                        }
                        else if score > best {
                            best = score;
                            best_i = i;
                            best_j = j;
                        }
                    },
                    _ => ()
                }

                self.S[col][j] = score;
                self.D[col][j] = d_score;
                self.I[col][j] = i_score;
            }

            match alignment_type {
                AlignmentType::Semiglobal => {
                    if score > best {
                        best = score;
                        best_i = i;
                        best_j = m;
                    }
                },
                _ => ()
            }
        }
        match alignment_type {
            AlignmentType::Global => {
                let score = self.S[col][m];
                self.traceback.get_alignment(n, m, x, y, score)
            },
            _ => self.traceback.get_alignment(best_i, best_j, x, y, best)
        }

    }
}

struct Traceback {
    subst: Vec<Bitv>,
    del: Vec<Bitv>,
    ins: Vec<Bitv>
}

impl Traceback {
    fn with_capacity(m: usize, n: usize) -> Self {
        let get_vec = |&:| repeat(Bitv::from_elem(m + 1, false)).take(n + 1).collect::<Vec<Bitv>>();
        Traceback {
            subst: get_vec(),
            del: get_vec(),
            ins: get_vec()
        }
    }

    fn init(&mut self, n: usize, alignment_type: AlignmentType) {
        match alignment_type {
            AlignmentType::Global => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
                // set the first cell to start, the rest to deletions
                self.del[0].set(0, false);
            },
            _ => {
                for i in 0..n+1 {
                    self.subst[i].set_all();
                    self.subst[i].negate();
                    self.del[i].set_all();
                    self.del[i].negate();
                    self.ins[i].set_all();
                    self.ins[i].negate();
                }
            }
        }
    }

    fn start(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, false);
        self.del[i].set(j, false);
        self.ins[i].set(j, false);
    }

    fn subst(&mut self, i: usize, j: usize) {
        self.subst[i].set(j, true);
    }

    fn del(&mut self, i: usize, j: usize) {
        self.del[i].set(j, true);
    }

    fn ins(&mut self, i: usize, j: usize) {
        self.ins[i].set(j, true);
    }

    fn is_subst(&self, i: usize, j: usize) -> bool {
        self.subst[i].get(j).unwrap()
    }

    fn is_del(&self, i: usize, j: usize) -> bool {
        self.del[i].get(j).unwrap()
    }

    fn is_ins(&self, i: usize, j: usize) -> bool {
        self.ins[i].get(j).unwrap()
    }

    fn get_alignment(&self, mut i: usize, mut j: usize, x: &[u8], y: &[u8], score: i32) -> Alignment {
        let mut ops = Vec::with_capacity(x.len());

        loop {
            let (ii, jj, op) = if self.is_subst(i, j) {
                let op = if y[i-1] == x[j-1] {
                    AlignmentOperation::Match
                }
                else {
                    AlignmentOperation::Subst
                };
                (i - 1, j - 1, op)
            }
            else if self.is_del(i, j) {
                (i - 1, j, AlignmentOperation::Del)
            }
            else if self.is_ins(i, j) {
                (i, j - 1, AlignmentOperation::Ins)
            } else {
                // reached alignment start
                break;
            };
            ops.push(op);
            i = ii;
            j = jj;
        }

        ops.reverse();
        Alignment { i: i, j: j, operations: ops, score: score}
    }
}

#[cfg(test)]
mod tests {
    use super::Aligner;
    use alignment::AlignmentOperation::{Match, Subst, Del};

    #[test]
    fn test_semiglobal() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.semiglobal(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_local() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.local(x, y);
        assert_eq!(alignment.i, 4);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }

    #[test]
    fn test_global() {
        let x = b"ACCGTGGAT";
        let y = b"AAAAACCGTTGAT";
        let score = |&: a: u8, b: u8| if a == b {1i32} else {-1i32};
        let mut aligner = Aligner::with_capacity(x.len(), y.len(), -5, -1, score);
        let alignment = aligner.global(x, y);
        assert_eq!(alignment.i, 0);
        assert_eq!(alignment.j, 0);
        assert_eq!(alignment.operations, [Del, Del, Del, Del, Match, Match, Match, Match, Match, Subst, Match, Match, Match]);
    }
}
<|endoftext|>


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

// This test case tests the incremental compilation hash (ICH) implementation
// for struct definitions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// We also test the ICH for struct definitions exported in metadata. Same as
// above, we want to make sure that the change between rev1 and rev2 also
// results in a change of the ICH for the struct's metadata, and that it stays
// the same between rev2 and rev3.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Layout ----------------------------------------------------------------------
#[cfg(cfail1)]
pub struct LayoutPacked;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(packed)]
pub struct LayoutPacked;

#[cfg(cfail1)]
struct LayoutC;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
struct LayoutC;

// Tuple Struct Change Field Type ----------------------------------------------

#[cfg(cfail1)]
struct TupleStructFieldType(i32);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructFieldType(u32);

// Tuple Struct Add Field ------------------------------------------------------

#[cfg(cfail1)]
struct TupleStructAddField(i32);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructAddField(i32, u32);

// Tuple Struct Field Visibility -----------------------------------------------

#[cfg(cfail1)]
struct TupleStructFieldVisibility(char);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructFieldVisibility(pub char);

// Record Struct Field Type ----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldType { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldType { x: u64 }

// Record Struct Field Name ----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldName { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldName { y: f32 }

// Record Struct Add Field -----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructAddField { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructAddField { x: f32, y: () }

// Record Struct Field Visibility ----------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldVisibility { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldVisibility { pub x: f32 }

// Add Lifetime Parameter ------------------------------------------------------

#[cfg(cfail1)]
struct AddLifetimeParameter<'a>(&'a f32, &'a f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameter<'a, 'b>(&'a f32, &'b f64);

// Add Lifetime Parameter Bound ------------------------------------------------

#[cfg(cfail1)]
struct AddLifetimeParameterBound<'a, 'b>(&'a f32, &'b f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameterBound<'a, 'b: 'a>(&'a f32, &'b f64);

#[cfg(cfail1)]
struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64)
    where 'b: 'a;

// Add Type Parameter ----------------------------------------------------------

#[cfg(cfail1)]
struct AddTypeParameter<T1>(T1, T1);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameter<T1, T2>(T1, T2);

// Add Type Parameter Bound ----------------------------------------------------

#[cfg(cfail1)]
struct AddTypeParameterBound<T>(T);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameterBound<T: Send>(T);

#[cfg(cfail1)]
struct AddTypeParameterBoundWhereClause<T>(T);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameterBoundWhereClause<T>(T) where T: Sync;

// Empty struct ----------------------------------------------------------------

#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail2")]
pub struct EmptyStruct;

// Visibility ------------------------------------------------------------------

#[cfg(cfail1)]
struct Visibility;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail3")]
pub struct Visibility;
<commit_msg>incr.comp.: Cover indirect changes in struct ICH test case<commit_after>// Copyright 2016 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.

// This test case tests the incremental compilation hash (ICH) implementation
// for struct definitions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// We also test the ICH for struct definitions exported in metadata. Same as
// above, we want to make sure that the change between rev1 and rev2 also
// results in a change of the ICH for the struct's metadata, and that it stays
// the same between rev2 and rev3.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Layout ----------------------------------------------------------------------
#[cfg(cfail1)]
pub struct LayoutPacked;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(packed)]
pub struct LayoutPacked;

#[cfg(cfail1)]
struct LayoutC;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
struct LayoutC;

// Tuple Struct Change Field Type ----------------------------------------------

#[cfg(cfail1)]
struct TupleStructFieldType(i32);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructFieldType(u32);

// Tuple Struct Add Field ------------------------------------------------------

#[cfg(cfail1)]
struct TupleStructAddField(i32);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructAddField(i32, u32);

// Tuple Struct Field Visibility -----------------------------------------------

#[cfg(cfail1)]
struct TupleStructFieldVisibility(char);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct TupleStructFieldVisibility(pub char);

// Record Struct Field Type ----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldType { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldType { x: u64 }

// Record Struct Field Name ----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldName { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldName { y: f32 }

// Record Struct Add Field -----------------------------------------------------

#[cfg(cfail1)]
struct RecordStructAddField { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructAddField { x: f32, y: () }

// Record Struct Field Visibility ----------------------------------------------

#[cfg(cfail1)]
struct RecordStructFieldVisibility { x: f32 }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct RecordStructFieldVisibility { pub x: f32 }

// Add Lifetime Parameter ------------------------------------------------------

#[cfg(cfail1)]
struct AddLifetimeParameter<'a>(&'a f32, &'a f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameter<'a, 'b>(&'a f32, &'b f64);

// Add Lifetime Parameter Bound ------------------------------------------------

#[cfg(cfail1)]
struct AddLifetimeParameterBound<'a, 'b>(&'a f32, &'b f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameterBound<'a, 'b: 'a>(&'a f32, &'b f64);

#[cfg(cfail1)]
struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64)
    where 'b: 'a;

// Add Type Parameter ----------------------------------------------------------

#[cfg(cfail1)]
struct AddTypeParameter<T1>(T1, T1);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameter<T1, T2>(T1, T2);

// Add Type Parameter Bound ----------------------------------------------------

#[cfg(cfail1)]
struct AddTypeParameterBound<T>(T);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameterBound<T: Send>(T);

#[cfg(cfail1)]
struct AddTypeParameterBoundWhereClause<T>(T);

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
struct AddTypeParameterBoundWhereClause<T>(T) where T: Sync;

// Empty struct ----------------------------------------------------------------

#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail2")]
pub struct EmptyStruct;

// Visibility ------------------------------------------------------------------

#[cfg(cfail1)]
struct Visibility;

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail3")]
pub struct Visibility;

struct ReferencedType1;
struct ReferencedType2;

// Tuple Struct Change Field Type Indirectly -----------------------------------
mod tuple_struct_change_field_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as FieldType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as FieldType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    struct TupleStruct(FieldType);
}

// Record Struct Change Field Type Indirectly -----------------------------------
mod record_struct_change_field_type_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedType1 as FieldType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as FieldType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    struct RecordStruct {
        _x: FieldType
    }
}

trait ReferencedTrait1 {}
trait ReferencedTrait2 {}

// Change Trait Bound Indirectly -----------------------------------------------
mod change_trait_bound_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    struct Struct<T: Trait>(T);
}

// Change Trait Bound Indirectly In Where Clause -------------------------------
mod change_trait_bound_indirectly_in_where_clause {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    struct Struct<T>(T) where T : Trait;
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for ZST statics being allowed to "read" from themselves<commit_after>// build-pass

static FOO: () = FOO;

fn main() {
    FOO
}
<|endoftext|>


<commit_before><commit_msg>Fix capitalization of `ResourceDimension` enum.<commit_after><|endoftext|>


<commit_before><commit_msg>`Transaction` sign unittest fails.<commit_after><|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Error};

/// Utility type to specify which kind of store action is running
#[derive(Clone, Debug)]
pub enum StoreAction {
    Create,
    Retrieve,
    Update,
    Delete,
}

impl StoreAction {

    pub fn uppercase(&self) -> &str {
        match *self {
            StoreAction::Create   => "CREATE",
            StoreAction::Retrieve => "RETRIEVE",
            StoreAction::Update   => "UPDATE",
            StoreAction::Delete   => "DELETE",
        }
    }
}

impl Display for StoreAction {

    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        write!(fmt, "StoreAction: {}",
                match *self {
                    StoreAction::Create   => "create",
                    StoreAction::Retrieve => "retrieve",
                    StoreAction::Update   => "update",
                    StoreAction::Delete   => "delete",
                })
    }

}

<commit_msg>Add StoreAction::as_commit_message() utility fn<commit_after>use std::fmt::{Display, Formatter, Error};

/// Utility type to specify which kind of store action is running
#[derive(Clone, Debug)]
pub enum StoreAction {
    Create,
    Retrieve,
    Update,
    Delete,
}

impl StoreAction {

    pub fn uppercase(&self) -> &str {
        match *self {
            StoreAction::Create   => "CREATE",
            StoreAction::Retrieve => "RETRIEVE",
            StoreAction::Update   => "UPDATE",
            StoreAction::Delete   => "DELETE",
        }
    }

    pub fn as_commit_message(&self) -> &str {
        match *self {
            StoreAction::Create   => "Create",
            StoreAction::Retrieve => "Retrieve",
            StoreAction::Update   => "Update",
            StoreAction::Delete   => "Delete",
        }
    }
}

impl Display for StoreAction {

    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        write!(fmt, "StoreAction: {}",
                match *self {
                    StoreAction::Create   => "create",
                    StoreAction::Retrieve => "retrieve",
                    StoreAction::Update   => "update",
                    StoreAction::Delete   => "delete",
                })
    }

}

<|endoftext|>


<commit_before><commit_msg>Code cleaning<commit_after><|endoftext|>


<commit_before><commit_msg>Add trivial benchmarks.<commit_after>#![feature(convert)]
#![feature(plugin,test)]
#![plugin(quickcheck_macros)]

#[macro_use]
extern crate log;
extern crate env_logger;
extern crate yak_client;
extern crate test;

use std::collections::HashMap;
use yak_client::YakError;

use std::env;

use yak_client::Client;
use test::Bencher;

pub fn open_from_env(env_var: &str, name: &str) -> Client {
  let yak_url = env::var(env_var).ok()
    .expect(format!("env var {} not found", env_var).as_str());
  let full_url = format!("{}-{}", yak_url, name);
  Client::connect(&full_url).unwrap()
}

pub fn open_client(name: &str) -> (Client, Client) {
  let head = open_from_env("YAK_HEAD", name);
  let tail = open_from_env("YAK_TAIL", name);
  (head, tail)
}

#[bench]
fn bench_simple_write(b: &mut Bencher) {
  env_logger::init().unwrap_or(());

  let (mut head, mut tail) = open_client("bench_simple_put");
  head.truncate().unwrap();
  let key = "foo";
  let val = "bar";

  b.iter(|| head.write(key.as_bytes(), val.as_bytes()).unwrap());
}

#[bench]
fn bench_simple_read(b: &mut Bencher) {
  env_logger::init().unwrap_or(());

  let (mut head, mut tail) = open_client("bench_simple_put");
  head.truncate().unwrap();
  let key = "foo";
  let val = "bar";
  head.write(key.as_bytes(), val.as_bytes()).unwrap();

  b.iter(|| tail.read(key.as_bytes()).unwrap());
}
<|endoftext|>


<commit_before><commit_msg>Remove panic handler from features.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix typo'd values in blocks() test<commit_after><|endoftext|>


<commit_before><commit_msg>Add a secure_with_ssl method to FtpStream so that users can supply their own SSL configuration (#44)<commit_after><|endoftext|>


<commit_before><commit_msg>Added a polygon point containment check<commit_after><|endoftext|>


<commit_before><commit_msg>New crate alias syntax.<commit_after><|endoftext|>


<commit_before><commit_msg>Change Archive's associated functions to return LibResult<commit_after><|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before><commit_msg>Pull up module decompose<commit_after><|endoftext|>


<commit_before><commit_msg>Remove wrapping; address overflows; fix #7<commit_after><|endoftext|>


<commit_before><commit_msg>Add Apache 2.0 license header to source<commit_after><|endoftext|>


<commit_before><commit_msg>Fix subf.s bug<commit_after><|endoftext|>


<commit_before><commit_msg>Remove pointless <'a><commit_after><|endoftext|>


<commit_before><commit_msg>Add the Fd definition file.<commit_after>/// A file descriptor.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Fd {
    inner: usize,
}
<|endoftext|>


<commit_before><commit_msg>GDT code.<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor imag-edit to new store iterator interface<commit_after><|endoftext|>


<commit_before><commit_msg>Problem 07<commit_after>enum NestedList<T> {
    Nil,
    One(T, ~NestedList<T>),
    Many(~NestedList<T>, ~NestedList<T>)
}

fn rev<T>(list: NestedList<T>) -> NestedList<T> {
    fn rev_aux<T>(list: NestedList<T>, acc: NestedList<T>) -> NestedList<T> {
        match list {
            Nil => acc,
            One(elem, ~rest) => rev_aux(rest, One(elem, ~acc)),
            Many(~node, ~rest) => rev_aux(rest, Many(~rev(node), ~acc))
        }
    }
    rev_aux(list, Nil)
}

fn flatten<T: Clone>(list: &NestedList<T>) -> NestedList<T> {
    fn aux<T: Clone>(list: &NestedList<T>, acc: NestedList<T>) -> NestedList<T> {
        match *list {
            Nil => acc,
            One(ref elem, ~ref rest) => aux(rest, One(elem.clone(), ~acc)),
            Many(~ref node, ~ref rest) => aux(rest, aux(node, acc))
        }
    }

    rev(aux(list, Nil))
}

fn main() {
    let list: NestedList<char> =
        One('a', ~Many(
                ~One('b', ~Many(
                        ~One('c', ~One('d', ~Nil)),
                        ~One('e', ~Nil)
                    )),
            ~Nil));

    println!("{:?}", flatten(&list));
}
<|endoftext|>


<commit_before><commit_msg>Add steal_weak methods to deque<commit_after><|endoftext|>


<commit_before><commit_msg>An error type for wiz<commit_after>use std::io;

/// The error type for the program's every operations, such as TOML Parsing
/// or IO-related errors. Wherever there's an error, it _should_ be wrapped
/// into this type.
pub enum Error {
    Parsing(String),
    IO(String),
}

impl From<io::Error> for Error {
    /// Converts an `io::Error` into this type.
    fn from(err: io::Error) -> Self {
        Error::IO(String::from("An IO error occured:") + err.description())
    }
}<|endoftext|>


<commit_before><commit_msg>Fix Position Y decoding.<commit_after><|endoftext|>


<commit_before><commit_msg>reorder<commit_after><|endoftext|>


<commit_before><commit_msg>Add initial futex wrapper<commit_after>use libc;
use libc::{c_int, c_void, timespec};

use std::mem::transmute;
use std::ptr::null;
use std::result::Result;

pub enum Errors {
    /// No read access to futex memory
    FutexRead,
    /// Futex value does not equal given expected value (e.g. in race condition)
    FutexValue,
    /// Wait was interrupted by a signal
    Signal,
    /// Oops.
    InvalidArg,
    /// Too many open files
    TooManyFiles,
    /// Oops.
    InvalidOp,
    /// Futex hit wait timeout
    WaitTimeout
}

/// Wraps futex(2):
///
/// int futex(int *uaddr, int op, int val, const struct timespec *timeout,
///           int *uaddr2, int val3);
//#[link(name="libc")]
//extern {
unsafe fn futex(addr1:    *mut   c_int,
         op:              c_int,
         val:             c_int,
         timespec: *const timespec,
         addr2:    *mut   c_int,
         val3:            c_int)
         -> c_int {
syscall!(FUTEX, addr1, op, val, timespec, addr2, val3) as c_int
         }
//}

const OP_WAIT        : i32 = 0;
const OP_WAKE        : i32 = 1;
// deprecated: const OP_FD          : i32 = 2;
// deprecated: const OP_REQUEUE     : i32 = 3;
const OP_CMP_REQUEUE : i32 = 4;

#[inline(always)]
fn get_result(retval: i32) -> Result<i32, Errors> {
    use libc::{EACCES, EAGAIN, EINTR, EINVAL, ENOSYS, ETIMEDOUT};

    if retval >= 0 {
        return Ok(retval);
    }

    match retval {
        EACCES => Err(Errors::FutexRead),
        EINTR  => Err(Errors::Signal),
        EINVAL => Err(Errors::InvalidArg),
        ENOSYS => Err(Errors::InvalidOp),
        EAGAIN => Err(Errors::FutexValue),
        ETIMEDOUT => Err(Errors::WaitTimeout),
        _ => panic!("unexpected futex return value: {}", retval)
    }
}

/// Verifies that the futex in `addr` still contains the value `val`, and then
/// sleeps the thread awaiting a FUTEX_WAKE.
pub fn wait(addr: &mut i32, val: i32) -> Result<i32, Errors> {
    unsafe {
        get_result(
            futex(addr as (*mut i32),
                  OP_WAIT,
                  val,
                  null::<timespec>(),
                  transmute(null::<i32>()),
                  0))
    }
}

/// Same as `wait`, except only sleeps for the given number of seconds.
/// If the wait times out, Err(Errors::WaitTimeout) will be returned.
pub fn time_wait(addr: &mut i32, val: i32, wait_secs: u32) -> Result<i32, Errors> {
    let ts = timespec { tv_sec: wait_secs as i64, tv_nsec: 0 };

    let ret = unsafe {
        futex(addr as (*mut i32),
              OP_WAIT,
              val,
              &ts,
              transmute(null::<i32>()),
              0)
    };

    get_result(ret)
}

/// This operation wakes at most `nprocs` processes waiting on this
/// futex address (i.e., inside FUTEX_WAIT).
///
/// Results the number of processes woken up or error
pub fn wake(addr: &mut i32, nprocs: u32) -> Result<i32, Errors> {
    let ret = unsafe {
        futex(addr as (*mut i32),
              OP_WAKE,
              nprocs as i32,
              null::<timespec>(),
              transmute(null::<i32>()),
              0)
    };

    get_result(ret)
}

/// This operation was introduced in order to avoid a "thundering herd" effect
/// when `wake` is used and all processes woken up need to acquire another
/// futex. This call wakes up `nprocs` processes, and requeues all other
/// waiters on the futex at address `requeue_addr`.
///
/// TODO: explain val.
pub fn requeue(addr: &mut i32, requeue_addr: &mut i32, val: i32, nprocs: u32) -> Result<i32, Errors> {
    let ret = unsafe {
        futex(addr as (*mut i32),
              OP_CMP_REQUEUE,
              nprocs as i32,
              null::<timespec>(),
              transmute(requeue_addr),
              val)
    };

    get_result(ret)
}
<|endoftext|>


<commit_before>extern crate libc;

use std::os;
use std::io;
use std::io::fs;
use std::io::File;
use std::path::Path;
use std::collections::HashMap;

use document::Document;

pub struct Runner;

impl Runner {
    pub fn run(path_string: &str) {
        let documents_path = path_string.to_string() + "/_posts";
        let layout_path    = path_string.to_string() + "/_layouts/default.tpl";
        let index_path     = path_string.to_string() + "/index.tpl";
        let build_path     = path_string.to_string() + "/build";
        let post_path      = path_string.to_string() + "/build/posts";

        println!("Generating site in {}\n", path_string);

        let mut documents = Runner::parse_documents(documents_path.as_slice());
        let layout        = Runner::parse_file(layout_path.as_slice());

        let mut index_attr = HashMap::new();
        index_attr.insert("name".to_string(), "index".to_string());

        let index     = Document::new(
            index_attr,
            Runner::parse_file(index_path.as_slice())
        );

        documents.insert(0, index);

        Runner::create_build(build_path.as_slice(), post_path.as_slice(), documents, layout);
    }

    fn parse_documents(documents_path: &str) -> Vec<Document> {
        let path = &Path::new(documents_path);

        let paths = fs::readdir(path);
        let mut documents = vec!();

        if paths.is_ok() {
            for path in paths.unwrap().iter() {
                if path.extension_str().unwrap() != "tpl" {
                    continue;
                }

                let attributes = Runner::extract_attributes(path.as_str().unwrap());
                let content    = Runner::extract_content(path.as_str().unwrap());

                documents.push(Document::new(attributes, content));
            }
        } else {
            println!("Path {} doesn't exist\n", documents_path);
            unsafe { libc::exit(1 as libc::c_int); }
        }

        return documents;
    }

    fn parse_file(file_path: &str) -> String {
        let path = &Path::new(file_path);

        if File::open(path).is_ok() {
            return File::open(path).read_to_string().unwrap();
        } else {
            println!("File {} doesn't exist\n", file_path);
            unsafe { libc::exit(1 as libc::c_int); }
        }
    }

    fn create_build(build_path: &str, post_path: &str, documents: Vec<Document>, layout: String) {
        fs::mkdir(&Path::new(build_path), io::USER_RWX);
        fs::mkdir(&Path::new(post_path), io::USER_RWX);

        for document in documents.iter() {
            document.create_file(build_path, post_path, layout.clone());
        }

        println!("Directory {} created", build_path);
    }

    fn extract_attributes(document_path: &str) -> HashMap<String, String> {
        let path = Path::new(document_path);
        let mut attributes = HashMap::new();
        attributes.insert("name".to_string(), path.filestem_str().unwrap().to_string());

        let content = Runner::parse_file(document_path);

        let mut content_splits = content.as_slice().split_str("---");

        let attribute_string = content_splits.nth(0u).unwrap();

        for attribute_line in attribute_string.split_str("\n") {
            if !attribute_line.contains_char(':') {
                continue;
            }

            let mut attribute_split = attribute_line.split(':');

            let key   = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();
            let value = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();

            attributes.insert(key, value);
        }

        return attributes;
    }

    fn extract_content(document_path: &str) -> String {
        let content = Runner::parse_file(document_path);

        let mut content_splits = content.as_slice().split_str("---");

        content_splits.nth(1u).unwrap().to_string()
    }
}
<commit_msg>extract parsing of index into own function<commit_after>extern crate libc;

use std::os;
use std::io;
use std::io::fs;
use std::io::File;
use std::path::Path;
use std::collections::HashMap;

use document::Document;

pub struct Runner;

impl Runner {
    pub fn run(path_string: &str) {
        let documents_path = path_string.to_string() + "/_posts";
        let layout_path    = path_string.to_string() + "/_layouts/default.tpl";
        let index_path     = path_string.to_string() + "/index.tpl";
        let build_path     = path_string.to_string() + "/build";
        let post_path      = path_string.to_string() + "/build/posts";

        println!("Generating site in {}\n", path_string);

        let mut posts = Runner::parse_documents(documents_path.as_slice());
        let layout    = Runner::parse_file(layout_path.as_slice());

        let mut documents = Runner::parse_index(index_path.as_slice(), posts);
        Runner::create_build(build_path.as_slice(), post_path.as_slice(), documents, layout);
    }

    fn parse_documents(documents_path: &str) -> Vec<Document> {
        let path = &Path::new(documents_path);

        let paths = fs::readdir(path);
        let mut documents = vec!();

        if paths.is_ok() {
            for path in paths.unwrap().iter() {
                if path.extension_str().unwrap() != "tpl" {
                    continue;
                }

                let attributes = Runner::extract_attributes(path.as_str().unwrap());
                let content    = Runner::extract_content(path.as_str().unwrap());

                documents.push(Document::new(attributes, content));
            }
        } else {
            println!("Path {} doesn't exist\n", documents_path);
            unsafe { libc::exit(1 as libc::c_int); }
        }

        return documents;
    }

    fn parse_file(file_path: &str) -> String {
        let path = &Path::new(file_path);

        if File::open(path).is_ok() {
            return File::open(path).read_to_string().unwrap();
        } else {
            println!("File {} doesn't exist\n", file_path);
            unsafe { libc::exit(1 as libc::c_int); }
        }
    }

    fn parse_index(index_path: &str, posts: Vec<Document>) -> Vec<Document> {
        let mut index_attr = HashMap::new();
        index_attr.insert("name".to_string(), "index".to_string());

        let index     = Document::new(
            index_attr,
            Runner::parse_file(index_path)
        );

        let mut documents = posts;
        documents.insert(0, index);

        println!("{}", documents);

        return documents;
    }

    fn create_build(build_path: &str, post_path: &str, documents: Vec<Document>, layout: String) {
        fs::mkdir(&Path::new(build_path), io::USER_RWX);
        fs::mkdir(&Path::new(post_path), io::USER_RWX);

        for document in documents.iter() {
            document.create_file(build_path, post_path, layout.clone());
        }

        println!("Directory {} created", build_path);
    }

    fn extract_attributes(document_path: &str) -> HashMap<String, String> {
        let path = Path::new(document_path);
        let mut attributes = HashMap::new();
        attributes.insert("name".to_string(), path.filestem_str().unwrap().to_string());

        let content = Runner::parse_file(document_path);

        let mut content_splits = content.as_slice().split_str("---");

        let attribute_string = content_splits.nth(0u).unwrap();

        for attribute_line in attribute_string.split_str("\n") {
            if !attribute_line.contains_char(':') {
                continue;
            }

            let mut attribute_split = attribute_line.split(':');

            let key   = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();
            let value = attribute_split.nth(0u).unwrap().trim_chars(' ').to_string().clone();

            attributes.insert(key, value);
        }

        return attributes;
    }

    fn extract_content(document_path: &str) -> String {
        let content = Runner::parse_file(document_path);

        let mut content_splits = content.as_slice().split_str("---");

        content_splits.nth(1u).unwrap().to_string()
    }
}
<|endoftext|>


<commit_before><commit_msg>Added border<commit_after><|endoftext|>


<commit_before><commit_msg>Create (6 kyu) Decode the Morse code.rs<commit_after><|endoftext|>