<commit_before>//! [Special functions][1].
//!
//! [1]: https://en.wikipedia.org/wiki/Special_functions

#[cfg(test)]
extern crate assert;

extern crate libc;
extern crate num;

pub use beta::{ln_beta, inc_beta, inv_inc_beta};

mod beta;

#[link_name = "m"]
mod m {
    use libc::{c_double, c_int};

    extern {
        pub fn erf(x: c_double) -> c_double;
        pub fn erfc(x: c_double) -> c_double;
        pub fn lgamma_r(x: c_double, sign: &mut c_int) -> c_double;
    }
}

/// Compute the error function.
#[inline]
pub fn erf(x: f64) -> f64 {
    unsafe { m::erf(x) }
}

/// Compute the complementary error function.
#[inline]
pub fn erfc(x: f64) -> f64 {
    unsafe { m::erfc(x) }
}

/// Compute the natural logarithm of the gamma function.
#[inline]
pub fn ln_gamma(x: f64) -> (f64, i32) {
    let mut sign: i32 = 0;
    let value = unsafe { m::lgamma_r(x, &mut sign) };
    (value, sign)
}

// Use Horners method to evaluate polynomials at `x0`
macro_rules! eval_poly {
    ( $x0:expr; $( $p:expr ),* ) => {
        {
            let mut coefs = vec![$($p,)*];
            coefs.reverse();
            let mut sum = 0.0;
            for c in coefs.iter() {
                sum = sum * $x0 + c;
            }
            sum
        }
    }
}

/// Compute the real-valued digamma function.
///
/// The digamma function is defined by
///
/// ```math
///        d ln(Γ(x))
/// ψ(x) = ----------
///            dx
/// ```
///
/// where Γ is the Gamma function. The computation is based on an approximation
/// as described in the reference below.
///
/// * M. J. Beal, “Variational Algorithms for Approximate Bayesian Inference.”
/// The Gatsby Computational Neuroscience Unit, University College London, 2003,
/// pp. 265–266.
///
/// # Examples
///
/// ```
/// use special::digamma;
///
/// let euler_mascheroni = 0.5772156649015325;
/// assert_eq!(-euler_mascheroni, digamma(1.0));
/// ```
#[inline]
pub fn digamma(x: f64)-> f64 {
    if x > 8.0 {
        let inv_x = x.recip();
        let inv_x_e2 = inv_x.powi(2);
        x.ln() - 0.5*inv_x - inv_x_e2 * eval_poly!(
            inv_x_e2;
            // Coefficients are `Bernoulli[2n] / 2n`
            1.0/12.0, -1.0/120.0, 1.0/252.0, -1.0/240.0,
            5.0/660.0, -691.0/32760.0, 1.0/12.0, -3617.0/8160.0
        )
    } else {
        // Shift by recurrence
        digamma(x + 1.0) - x.recip()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_digamma() {
        use std::f64::consts::{ FRAC_PI_2, LN_2 };
        let euler_mascheroni = 0.577215664901533;

        assert_eq!(-FRAC_PI_2 - 3.0 * LN_2 - euler_mascheroni, digamma(0.25));
    }
}
<commit_msg>Clean up a test<commit_after>//! [Special functions][1].
//!
//! [1]: https://en.wikipedia.org/wiki/Special_functions

#[cfg(test)]
extern crate assert;

extern crate libc;
extern crate num;

pub use beta::{ln_beta, inc_beta, inv_inc_beta};

mod beta;

#[link_name = "m"]
mod m {
    use libc::{c_double, c_int};

    extern {
        pub fn erf(x: c_double) -> c_double;
        pub fn erfc(x: c_double) -> c_double;
        pub fn lgamma_r(x: c_double, sign: &mut c_int) -> c_double;
    }
}

/// Compute the error function.
#[inline]
pub fn erf(x: f64) -> f64 {
    unsafe { m::erf(x) }
}

/// Compute the complementary error function.
#[inline]
pub fn erfc(x: f64) -> f64 {
    unsafe { m::erfc(x) }
}

/// Compute the natural logarithm of the gamma function.
#[inline]
pub fn ln_gamma(x: f64) -> (f64, i32) {
    let mut sign: i32 = 0;
    let value = unsafe { m::lgamma_r(x, &mut sign) };
    (value, sign)
}

// Use Horners method to evaluate polynomials at `x0`
macro_rules! eval_poly {
    ( $x0:expr; $( $p:expr ),* ) => {
        {
            let mut coefs = vec![$($p,)*];
            coefs.reverse();
            let mut sum = 0.0;
            for c in coefs.iter() {
                sum = sum * $x0 + c;
            }
            sum
        }
    }
}

/// Compute the real-valued digamma function.
///
/// The digamma function is defined by
///
/// ```math
///        d ln(Γ(x))
/// ψ(x) = ----------
///            dx
/// ```
///
/// where Γ is the Gamma function. The computation is based on an approximation
/// as described in the reference below.
///
/// * M. J. Beal, “Variational Algorithms for Approximate Bayesian Inference.”
/// The Gatsby Computational Neuroscience Unit, University College London, 2003,
/// pp. 265–266.
///
/// # Examples
///
/// ```
/// use special::digamma;
///
/// let euler_mascheroni = 0.5772156649015325;
/// assert_eq!(-euler_mascheroni, digamma(1.0));
/// ```
#[inline]
pub fn digamma(x: f64)-> f64 {
    if x > 8.0 {
        let inv_x = x.recip();
        let inv_x_e2 = inv_x.powi(2);
        x.ln() - 0.5*inv_x - inv_x_e2 * eval_poly!(
            inv_x_e2;
            // Coefficients are `Bernoulli[2n] / 2n`
            1.0/12.0, -1.0/120.0, 1.0/252.0, -1.0/240.0,
            5.0/660.0, -691.0/32760.0, 1.0/12.0, -3617.0/8160.0
        )
    } else {
        // Shift by recurrence
        digamma(x + 1.0) - x.recip()
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn digamma() {
        use std::f64::consts::{FRAC_PI_2, LN_2};
        let euler_mascheroni = 0.577215664901533;

        assert_eq!(-FRAC_PI_2 - 3.0 * LN_2 - euler_mascheroni, super::digamma(0.25));
    }
}
<|endoftext|>


<commit_before>pub mod atkin {
    extern crate std;

    struct Squares {
        count: u64,
        max: u64,
    }

    impl Squares {
        pub fn new(max: u64) -> Squares {
            Squares { count: 0, max: max }
        }
    }

    impl Iterator for Squares {
        type Item = u64;
        fn next(&mut self) -> Option<Self::Item> {
            self.count += 1;
            let square = self.count*self.count;
            if square > self.max {
                None
            } else {
                Some(self.count*self.count)
            }
        }
    }

    #[derive(Copy)]
    #[derive(Eq)]
    struct TestInteger {
        value: u64,
        is_prime: bool
    }

    impl Clone for TestInteger {
        fn clone(&self) -> TestInteger { *self }
    }

    impl Ord for TestInteger {
        fn cmp(&self, other: &TestInteger) -> std::cmp::Ordering {
            self.value.cmp(&other.value)
        }
    }

    impl PartialOrd for TestInteger {
        fn partial_cmp(&self, other: &TestInteger) -> std::option::Option<std::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }

    impl PartialEq for TestInteger {
        fn eq(&self, other: &TestInteger) -> bool {
            (self.value == other.value) && (self.is_prime == other.is_prime)
        }
    }

    impl TestInteger {
        pub fn is_prime(&self) -> bool {
            self.is_prime
        }

        pub fn value(&self) -> u64 {
            self.value
        }

        pub fn set_prime(&mut self, prime: bool) -> bool {
            self.is_prime = prime;
            self.is_prime
        }

        pub fn flip(&mut self) -> bool {
            self.is_prime ^= true;
            self.is_prime
        }
    }

    pub struct SieveOfAtkin {
        results: Vec<u64>,
        tests: Vec<TestInteger>,
    }

    enum AtkinCases {
        C1,
        C2,
        C3,
        C4,
    }

    impl SieveOfAtkin {
        pub fn new(limit: u64) -> SieveOfAtkin {
            let res = vec![2,3,5];
            let mut tests: Vec<TestInteger> = Vec::new();
            if limit < 2 {
                panic!("The limit for the sieve must be above 2. {} was set as limit.", limit);
            } else {

                for i in 2..limit {
                    tests.push(TestInteger{ value: i, is_prime: false });
                }
            }
            SieveOfAtkin { results: res, tests: tests }
        }

        // returns a copy so we don't need to worry about our vector being mutated
        pub fn get_results(&self) -> Vec<u64> {
            self.results.clone()
        }

        fn process_case(&mut self, n : u64, index : usize, case: AtkinCases) {
            //Case 1: flip for each solution to 4x^2 + y^2 = n
            //Case 2: flip for each solution to 3x^2 + y^2 = n
            //Case 3: flip for each solution to 3x^2 - y^2 = n where x > y
            //Case 4: do nothing

            let (co_x,co_y): (u64, u64) = match case {
                AtkinCases::C1  => (4,1),
                AtkinCases::C2  => (3,1),
                AtkinCases::C3  => (3,1),
                _               => { return; },
            };

            let expression: Box<Fn(u64, u64) -> u64> = match case {
                AtkinCases::C3  => Box::new( |x, y| { if x > y { co_x*x - co_y*y } else { 0 } } ),
                _               => Box::new( |x, y| { co_x*x + co_y*y } ),
            };

            for i in Squares::new(n) {
                for j in Squares::new(n) {
                    if expression(i, j) == n {
                        self.tests.get_mut(index)
                            .expect("Index passed in process is invalid. This shouldn't happen.")
                            .flip();
                    }
                }
            }
        }

        pub fn run(&mut self) {
            // process test integers for different cases
            for i in 0..self.tests.len()-1 {
                let val = self.tests.get(i)
                    .expect("Index passed in process is invalid. This shouldn't happen.")
                    .clone();
                let case: AtkinCases = match val.value() % 60 {
                    1  | 13 | 17 | 29 | 37 | 41 | 49 | 53   => AtkinCases::C1,
                    7  | 19 | 31 | 43                       => AtkinCases::C2,
                    11 | 23 | 47 | 59                       => AtkinCases::C3,
                    _                                       => AtkinCases::C4,
                };
                self.process_case(val.value(), i, case);
            }

            // start sieving
            while !self.tests.is_empty() {
                let first = self.tests.first()
                    .expect("Attempted to get item from tests vector while it was empty.")
                    .clone();
                if first.is_prime() {
                    self.results.push(first.value());
                    let square = first.value() * first.value();
                    let naturals = std::ops::RangeFrom{ start: 1 };
                    for i in naturals {
                        let n_square = i*square;
                        if n_square > self.tests.last()
                            .expect("Attempted to get item from tests vector while it was empty.")
                            .value() {
                            break;
                        }

                        match self.tests.binary_search(&TestInteger{ value: n_square, is_prime: true }) {
                            Ok(index)   => {
                                self.tests.get_mut(index)
                                        .expect("Attempted to get known index from tests vector. This shouldn't happen.")
                                        .set_prime(false);
                            },
                            Err(_)      => (),
                        }
                    }
                }
                self.tests.remove(0);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use atkin::*;
    #[test]
    fn atkin_test() {
        let primes_to_50 = [2u64, 3u64, 5u64, 7u64, 11u64, 13u64, 17u64, 19u64, 23u64, 29u64, 31u64, 37u64, 41u64, 43u64, 47u64];
        let mut sieve = SieveOfAtkin::new(50);

        sieve.run();
        assert_eq!(sieve.get_results(), primes_to_50);
    }

    #[test]
    fn atkin_output() {
        let mut sieve = SieveOfAtkin::new(10000);
        sieve.run();
        let results = sieve.get_results();
        for prime in results.iter() {
           assert!(is_n_prime(*prime), "Failed with {}", prime);
        }
    }

    fn is_n_prime(n: u64) -> bool {
        let mut prime: bool = true;
        if n > 2 {
            for i in 2..n/2 {
                if n % i == 0 {
                    prime = false;
                    break;
                }
            }
        }
        prime
    }
}

<commit_msg>attempting to get tests to work<commit_after>pub mod atkin {
    extern crate std;
    use std::sync::{Arc, Mutex};
    use std::thread;
    use std::collections::VecDeque;

    struct Squares {
        count: u64,
        max: u64,
    }

    impl Squares {
        pub fn new(max: u64) -> Squares {
            Squares { count: 0, max: max }
        }
    }

    impl Iterator for Squares {
        type Item = u64;
        fn next(&mut self) -> Option<Self::Item> {
            self.count += 1;
            let square = self.count*self.count;
            if square > self.max {
                None
            } else {
                Some(self.count*self.count)
            }
        }
    }

    #[derive(Copy)]
    #[derive(Eq)]
    struct TestInteger {
        value: u64,
        is_prime: bool
    }

    impl Clone for TestInteger {
        fn clone(&self) -> TestInteger { *self }
    }

    impl Ord for TestInteger {
        fn cmp(&self, other: &TestInteger) -> std::cmp::Ordering {
            self.value.cmp(&other.value)
        }
    }

    impl PartialOrd for TestInteger {
        fn partial_cmp(&self, other: &TestInteger) -> std::option::Option<std::cmp::Ordering> {
            Some(self.cmp(other))
        }
    }

    impl PartialEq for TestInteger {
        fn eq(&self, other: &TestInteger) -> bool {
            (self.value == other.value) && (self.is_prime == other.is_prime)
        }
    }

    impl TestInteger {
        pub fn is_prime(&self) -> bool {
            self.is_prime
        }

        pub fn value(&self) -> u64 {
            self.value
        }

        pub fn set_prime(&mut self, prime: bool) -> bool {
            self.is_prime = prime;
            self.is_prime
        }

        pub fn flip(&mut self) -> bool {
            self.is_prime ^= true;
            self.is_prime
        }
    }

    pub struct SieveOfAtkin {
        results: Vec<u64>,
        tests: Vec<TestInteger>,
    }

    enum AtkinCases {
        C1,
        C2,
        C3,
        C4,
    }

    impl SieveOfAtkin {
        pub fn new(limit: u64) -> SieveOfAtkin {
            let res = vec![2,3,5];
            let mut tests: Vec<TestInteger> = Vec::new();
            if limit < 2 {
                panic!("The limit for the sieve must be above 2. {} was set as limit.", limit);
            } else {

                for i in 2..limit {
                    tests.push(TestInteger{ value: i, is_prime: false });
                }
            }
            SieveOfAtkin { results: res, tests: tests }
        }

        // returns a copy so we don't need to worry about our vector being mutated
        pub fn get_results(&self) -> Vec<u64> {
            self.results.clone()
        }

        fn process_case_static(n : u64, index : usize, case: AtkinCases, mut tests: Vec<TestInteger>) {
            //Case 1: flip for each solution to 4x^2 + y^2 = n
            //Case 2: flip for each solution to 3x^2 + y^2 = n
            //Case 3: flip for each solution to 3x^2 - y^2 = n where x > y
            //Case 4: do nothing

            let (co_x,co_y): (u64, u64) = match case {
                AtkinCases::C1  => (4,1),
                AtkinCases::C2  => (3,1),
                AtkinCases::C3  => (3,1),
                _               => { return; },
            };

            let expression: Box<Fn(u64, u64) -> u64> = match case {
                AtkinCases::C3  => Box::new( |x, y| { if x > y { co_x*x - co_y*y } else { 0 } } ),
                _               => Box::new( |x, y| { co_x*x + co_y*y } ),
            };

            for i in Squares::new(n) {
                for j in Squares::new(n) {
                    if expression(i, j) == n {
                        tests.get_mut(index)
                            .expect("Index passed in process is invalid. This shouldn't happen.")
                            .flip();
                    }
                }
            }
        }

        pub fn run(&mut self) {
            let mut deque: VecDeque<u64> = VecDeque::new();
            for i in 0..self.tests.len()-1 {
                deque.push_back(i as u64);
            }
            let integers = Arc::new(Mutex::new(deque));
            let mut handles = vec![];
            let tests = Arc::new(Mutex::new(self.tests.clone()));
            // process test integers for different cases
            for _ in 0..10 { //spawns 10 threads
                let integers = integers.clone();
                let tests = tests.clone();
                let handle = thread::spawn(move || {
                    loop {
                        let integer = integers.lock().unwrap().pop_front();
                        if integer.is_none() {
                            break;
                        }
                        let integer = integer.unwrap();
                        let test = tests.lock().unwrap();
                        let val = test.get(integer as usize)
                            .expect("Index passed is invalid. This shouldn't happen.")
                            .clone();
                        let case: AtkinCases = match val.value() % 60 {
                            1  | 13 | 17 | 29 | 37 | 41 | 49 | 53   => AtkinCases::C1,
                            7  | 19 | 31 | 43                       => AtkinCases::C2,
                            11 | 23 | 47 | 59                       => AtkinCases::C3,
                            _                                       => AtkinCases::C4,
                        };
                        SieveOfAtkin::process_case_static(val.value(), integer as usize, case, test.to_vec());
                    }
                });
                handles.push(handle);
            }

            for handle in handles {
                handle.join().unwrap();
            }
            self.tests.clear();
            for i in tests.lock().unwrap().to_vec() {
                self.tests.push(i);
            }

            // start sieving
            while !self.tests.is_empty() {
                let first = self.tests.first()
                    .expect("Attempted to get item from tests vector while it was empty.")
                    .clone();
                if first.is_prime() {
                    self.results.push(first.value());
                    let square = first.value() * first.value();
                    let naturals = std::ops::RangeFrom{ start: 1 };
                    for i in naturals {
                        let n_square = i*square;
                        if n_square > self.tests.last()
                            .expect("Attempted to get item from tests vector while it was empty.")
                            .value() {
                            break;
                        }

                        match self.tests.binary_search(&TestInteger{ value: n_square, is_prime: true }) {
                            Ok(index)   => {
                                self.tests.get_mut(index)
                                        .expect("Attempted to get known index from tests vector. This shouldn't happen.")
                                        .set_prime(false);
                            },
                            Err(_)      => (),
                        }
                    }
                }
                self.tests.remove(0);
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use atkin::*;
    #[test]
    fn atkin_test() {
        let primes_to_50 = [2u64, 3u64, 5u64, 7u64, 11u64, 13u64, 17u64, 19u64, 23u64, 29u64, 31u64, 37u64, 41u64, 43u64, 47u64];
        let mut sieve = SieveOfAtkin::new(50);

        sieve.run();
        assert_eq!(sieve.get_results(), primes_to_50);
    }

    #[test]
    fn atkin_output() {
        let mut sieve = SieveOfAtkin::new(10000);
        sieve.run();
        let results = sieve.get_results();
        for prime in results.iter() {
           assert!(is_n_prime(*prime), "Failed with {}", prime);
        }
    }

    fn is_n_prime(n: u64) -> bool {
        let mut prime: bool = true;
        if n > 2 {
            for i in 2..n/2 {
                if n % i == 0 {
                    prime = false;
                    break;
                }
            }
        }
        prime
    }
}

<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "hyperhyper"]
#![feature(std_misc)]
#![feature(lookup_host)]
#![feature(ip_addr)]
extern crate mio;

use mio::*;
use mio::tcp::*;
use std::str::FromStr;
use std::net::SocketAddr;
use std::time::Duration;
use mio::buf::{ByteBuf, MutByteBuf, SliceBuf};
use std::net::Shutdown;
use std::collections::LinkedList;
// Define a handler to process the events
use std::{io, thread};
use std::net;
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Echo {
    non_block_client: NonBlock<TcpStream>,
    token: Option<Token>,
    mut_buf: Option<MutByteBuf>,

    buf: Option<ByteBuf>,
    interest: Interest
}

impl Echo {
    fn new(client: NonBlock<TcpStream>) -> Echo {
        Echo {
            non_block_client: client,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            interest: Interest::hup(),
            buf: None,
            token: None,
        }
    }
}
impl Handler for Echo {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        let mut buf = ByteBuf::mut_with_capacity(2048);
        match self.non_block_client.read(&mut buf) {
            Ok(None) => {
                println!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                println!("CONN : we read {} bytes!", r);
                self.interest.remove(Interest::readable());
                if (r > 0){
                    event_loop.reregister(&self.non_block_client, token, self.interest,
                                          PollOpt::edge() | PollOpt::oneshot());
                } else {
                    event_loop.shutdown();
                }
            }
            Err(e) => {
                println!("not implemented; client err={:?}", e);
                self.interest.remove(Interest::readable());
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let mut buf = ByteBuf::from_slice("GET /\n".as_bytes());

        match self.non_block_client.write(&mut buf) {
            Ok(None) => {
                println!("client flushing buf; WOULDBLOCK");

                self.buf = Some(buf);
                self.interest.insert(Interest::writable());
            }
            Ok(Some(r)) => {
                println!("CONN : we wrote {} bytes!", r);

                self.mut_buf = Some(buf.flip());

                self.interest.insert(Interest::readable());
                self.interest.remove(Interest::writable());
            }
            Err(e) => println!("not implemented; client err={:?}", e),
        }
        event_loop.reregister(&self.non_block_client, token, self.interest,
                              PollOpt::edge() | PollOpt::oneshot());
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Echo>, msg: String) {
        println!("test3");
    }
}

pub fn google() -> SocketAddr {
    let s = format!("216.58.192.4:{}", 80);
    FromStr::from_str(&s).unwrap()
}

fn get_web_page(hostname: String, port: u16, get_resource: String) {
    let mut event_loop = EventLoop::new().unwrap();
    // == Create & setup client socket

    let url = String::new();

    // == Run test
    println!("Connecting");
    let ip = std::net::lookup_host(&hostname).unwrap().next().unwrap().unwrap();
    let address = SocketAddr::new(ip.ip(), port);
    let (mut sock, _) = tcp::v4().unwrap().connect(&address).unwrap();
    event_loop.register_opt(&sock, CLIENT, Interest::writable(),
                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
    event_loop.run(&mut Echo::new(sock));
}

#[test]
fn test() {
    println!("test");
    get_web_page("www.google.com".to_string(), 80, "/".to_string());
}
<commit_msg>Alignment<commit_after>#![crate_type = "lib"]
#![crate_name = "hyperhyper"]
#![feature(std_misc)]
#![feature(lookup_host)]
#![feature(ip_addr)]
extern crate mio;

use mio::*;
use mio::tcp::*;
use std::str::FromStr;
use std::net::SocketAddr;
use std::time::Duration;
use mio::buf::{ByteBuf, MutByteBuf, SliceBuf};
use std::net::Shutdown;
use std::collections::LinkedList;
// Define a handler to process the events
use std::{io, thread};
use std::net;
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Echo {
    non_block_client: NonBlock<TcpStream>,
    token: Option<Token>,
    mut_buf: Option<MutByteBuf>,

    buf: Option<ByteBuf>,
    interest: Interest
}

impl Echo {
    fn new(client: NonBlock<TcpStream>) -> Echo {
        Echo {
            non_block_client: client,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            interest: Interest::hup(),
            buf: None,
            token: None,
        }
    }
}
impl Handler for Echo {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        let mut buf = ByteBuf::mut_with_capacity(2048);
        match self.non_block_client.read(&mut buf) {
            Ok(None) => {
                println!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                println!("CONN : we read {} bytes!", r);
                self.interest.remove(Interest::readable());
                if (r > 0) {
                    event_loop.reregister(&self.non_block_client, token, self.interest,
                                          PollOpt::edge() | PollOpt::oneshot());
                } else {
                    event_loop.shutdown();
                }
            }
            Err(e) => {
                println!("not implemented; client err={:?}", e);
                self.interest.remove(Interest::readable());
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let mut buf = ByteBuf::from_slice("GET /\n".as_bytes());

        match self.non_block_client.write(&mut buf) {
            Ok(None) => {
                println!("client flushing buf; WOULDBLOCK");

                self.buf = Some(buf);
                self.interest.insert(Interest::writable());
            }
            Ok(Some(r)) => {
                println!("CONN : we wrote {} bytes!", r);

                self.mut_buf = Some(buf.flip());

                self.interest.insert(Interest::readable());
                self.interest.remove(Interest::writable());
            }
            Err(e) => println!("not implemented; client err={:?}", e),
        }
        event_loop.reregister(&self.non_block_client, token, self.interest,
                              PollOpt::edge() | PollOpt::oneshot());
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Echo>, msg: String) {
        println!("test3");
    }
}

pub fn google() -> SocketAddr {
    let s = format!("216.58.192.4:{}", 80);
    FromStr::from_str(&s).unwrap()
}

fn get_web_page(hostname: String, port: u16, get_resource: String) {
    let mut event_loop = EventLoop::new().unwrap();
    // == Create & setup client socket

    let url = String::new();

    // == Run test
    println!("Connecting");
    let ip = std::net::lookup_host(&hostname).unwrap().next().unwrap().unwrap();
    let address = SocketAddr::new(ip.ip(), port);
    let (mut sock, _) = tcp::v4().unwrap().connect(&address).unwrap();
    event_loop.register_opt(&sock, CLIENT, Interest::writable(),
                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
    event_loop.run(&mut Echo::new(sock));
}

#[test]
fn test() {
    println!("test");
    get_web_page("www.google.com".to_string(), 80, "/".to_string());
}
<|endoftext|>


<commit_before>mod cell;
mod grid;
mod engine;
<commit_msg>Game of Life. No tests yet.<commit_after>pub mod cell;
pub mod grid;
pub mod engine;

mod test {
    use std::ops::Add;

    use super::cell::Cell;

    #[derive(Copy, Clone)]
    enum LifeState {
        Dead,
        Alive
    }

    /// Implementation of Conway's Game of Life.
    #[derive(Copy, Clone)]
    struct Life {
        state: LifeState
    }

    impl Life {

        fn alive_count<'a, I>(&self, neighbors: I) -> i32
            where I: Iterator<Item=Option<&'a Self>> {
            neighbors.map(
                |n| {
                    match n {
                        Some(ref cell) => match cell.state {
                            LifeState::Alive => 1,
                            LifeState::Dead => 0
                        },
                        None => 0,
                    }
                }
            ).fold(0, Add::add)
        }

        #[inline]
        fn dead_state(&self, alive: i32) -> LifeState {
            match alive {
                3 => LifeState::Alive,
                _ => LifeState::Dead
            }
        }

        #[inline]
        fn alive_state(&self, alive: i32) -> LifeState {
            match alive {
                2 | 3 => LifeState::Alive,
                _ => LifeState::Dead
            }
        }
    }

    impl Cell for Life {

        fn step<'a, I>(&self, neighbors: I) -> Self
            where I: Iterator<Item=Option<&'a Self>> {

            let alive = self.alive_count(neighbors);

            let new_state = match self.state {
                LifeState::Alive => self.alive_state(alive),
                LifeState::Dead => self.dead_state(alive)
            };

            let mut new_cell = self.clone();
            new_cell.state = new_state;

            new_cell
        }
    }
}<|endoftext|>


<commit_before>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fs::File;
use std::io::Read;

extern crate rustc_serialize;

pub type ERes<T> = Result<T, String>;

pub fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

macro_rules! fail {
    ($expr:expr) => (
        return Err(::std::error::FromError::from_error($expr));
    )
}

macro_rules! println_err(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

pub fn read_file(name: &str) -> ERes<String> {
    let mut f = try!(match File::open(name) {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("open error in file '{}': {}", name, err))
    });
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(format!("read error in file '{}': {}", name, err))
    }
}

pub mod footprint;
pub mod schematic;
<commit_msg>write_file<commit_after>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use std::fs::File;
use std::io::Read;
use std::io::Write;

extern crate rustc_serialize;

pub type ERes<T> = Result<T, String>;

pub fn err<T>(msg: &str) -> ERes<T> {
    Err(String::from(msg))
}

macro_rules! fail {
    ($expr:expr) => (
        return Err(::std::error::FromError::from_error($expr));
    )
}

macro_rules! println_err(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

pub fn read_file(name: &str) -> ERes<String> {
    let mut f = try!(match File::open(name) {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("open error in file '{}': {}", name, err))
    });
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(format!("read error in file '{}': {}", name, err))
    }
}

pub fn write_file(name:&str, data:&String) -> ERes<()> {
    let mut f = try!(match File::create("foo.txt") {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("create error in file '{}': {}", name, err))
    });
    try!(match write!(&mut f, "{}", data) {
        Ok(f) => Ok(f),
        Err(err) => Err(format!("write error in file '{}': {}", name, err))
    });

    Ok(())

}

pub mod footprint;
pub mod schematic;
<|endoftext|>


<commit_before>#![feature(io)]
#![feature(core)]

use std::old_io::IoResult;

struct Triangle {
    normal: [f32; 3],
    v1: [f32; 3],
    v2: [f32; 3],
    v3: [f32; 3],
    attr_byte_count: u16
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal)
            && point_eq(self.v1, rhs.v1)
            && point_eq(self.v2, rhs.v2)
            && point_eq(self.v3, rhs.v3)
            && self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

struct BinaryStlHeader {
    header: [u8; 80],
    num_triangles: u32
}

pub struct BinaryStlFile {
    header: BinaryStlHeader,
    triangles: Vec<Triangle>
}

fn read_point<T: Reader>(input: &mut T) -> IoResult<[f32; 3]> {
    let x1 = try!(input.read_le_f32());
    let x2 = try!(input.read_le_f32());
    let x3 = try!(input.read_le_f32());

    Ok([x1, x2, x3])
}

fn read_triangle<T: Reader>(input: &mut T) -> IoResult<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_le_u16());

    Ok(Triangle { normal: normal,
                  v1: v1, v2: v2, v3: v3,
                  attr_byte_count: attr_count })
}

pub fn read_stl<T: Reader>(input: &mut T) -> IoResult<BinaryStlFile> {
    let mut header = BinaryStlHeader { header: [0u8; 80],
                                       num_triangles: 0 };

    // read the header
    try!(input.read_at_least(header.header.len(), &mut header.header));

    // TODO: check the header to make sure whether this is a binary
    // STL file.

    header.num_triangles = try!(input.read_le_u32());

    let mut triangles = Vec::new();
    for _ in 0..header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
        header: header,
        triangles: triangles
    })
}

fn write_point<T: Writer>(out: &mut T, p: [f32; 3]) -> IoResult<()> {
    for x in p.iter() {
        try!(out.write_le_f32(*x));
    }
    Ok(())
}

pub fn write_stl<T: Writer>(out: &mut T, stl: &BinaryStlFile) -> IoResult<()> {
    assert!(stl.header.num_triangles as usize == stl.triangles.len());

    //write the header.
    try!(out.write_all(&stl.header.header));
    try!(out.write_le_u32(stl.header.num_triangles));

    // write all the triangles
    for t in stl.triangles.iter() {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_le_u16(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use std::old_io::BufReader;
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader { header: [0u8; 80],
                                      num_triangles: 1 },
            triangles: vec![Triangle { normal: [0f32, 1f32, 0f32],
                                       v1: [0f32, 0f32, 0f32],
                                       v2: [0f32, 0f32, 1f32],
                                       v3: [1f32, 0f32, 1f32],
                                       attr_byte_count: 0 }]
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!()
        }

        match read_stl(&mut BufReader::new(buffer.as_slice())) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            },
            Err(_) => panic!()
        }
    }
}
<commit_msg>expose structs as public to be able to use API<commit_after>#![feature(io)]
#![feature(core)]

use std::old_io::IoResult;

pub struct Triangle {
    pub normal: [f32; 3],
    pub v1: [f32; 3],
    pub v2: [f32; 3],
    pub v3: [f32; 3],
    pub attr_byte_count: u16
}

fn point_eq(lhs: [f32; 3], rhs: [f32; 3]) -> bool {
    lhs[0] == rhs[0] && lhs[1] == rhs[1] && lhs[2] == rhs[2]
}

impl PartialEq for Triangle {
    fn eq(&self, rhs: &Triangle) -> bool {
        point_eq(self.normal, rhs.normal)
            && point_eq(self.v1, rhs.v1)
            && point_eq(self.v2, rhs.v2)
            && point_eq(self.v3, rhs.v3)
            && self.attr_byte_count == rhs.attr_byte_count
    }
}

impl Eq for Triangle {}

pub struct BinaryStlHeader {
    pub header: [u8; 80],
    pub num_triangles: u32
}

pub struct BinaryStlFile {
    pub header: BinaryStlHeader,
    pub triangles: Vec<Triangle>
}

fn read_point<T: Reader>(input: &mut T) -> IoResult<[f32; 3]> {
    let x1 = try!(input.read_le_f32());
    let x2 = try!(input.read_le_f32());
    let x3 = try!(input.read_le_f32());

    Ok([x1, x2, x3])
}

fn read_triangle<T: Reader>(input: &mut T) -> IoResult<Triangle> {
    let normal = try!(read_point(input));
    let v1 = try!(read_point(input));
    let v2 = try!(read_point(input));
    let v3 = try!(read_point(input));
    let attr_count = try!(input.read_le_u16());

    Ok(Triangle { normal: normal,
                  v1: v1, v2: v2, v3: v3,
                  attr_byte_count: attr_count })
}

pub fn read_stl<T: Reader>(input: &mut T) -> IoResult<BinaryStlFile> {
    let mut header = BinaryStlHeader { header: [0u8; 80],
                                       num_triangles: 0 };

    // read the header
    try!(input.read_at_least(header.header.len(), &mut header.header));

    // TODO: check the header to make sure whether this is a binary
    // STL file.

    header.num_triangles = try!(input.read_le_u32());

    let mut triangles = Vec::new();
    for _ in 0..header.num_triangles {
        triangles.push(try!(read_triangle(input)));
    }

    Ok(BinaryStlFile {
        header: header,
        triangles: triangles
    })
}

fn write_point<T: Writer>(out: &mut T, p: [f32; 3]) -> IoResult<()> {
    for x in p.iter() {
        try!(out.write_le_f32(*x));
    }
    Ok(())
}

pub fn write_stl<T: Writer>(out: &mut T, stl: &BinaryStlFile) -> IoResult<()> {
    assert!(stl.header.num_triangles as usize == stl.triangles.len());

    //write the header.
    try!(out.write_all(&stl.header.header));
    try!(out.write_le_u32(stl.header.num_triangles));

    // write all the triangles
    for t in stl.triangles.iter() {
        try!(write_point(out, t.normal));
        try!(write_point(out, t.v1));
        try!(write_point(out, t.v2));
        try!(write_point(out, t.v3));
        try!(out.write_le_u16(t.attr_byte_count));
    }

    Ok(())
}

#[cfg(test)]
mod test {
    use std::old_io::BufReader;
    use super::{BinaryStlFile, BinaryStlHeader, write_stl, read_stl, Triangle};
    #[test]
    fn write_read() {
        // Make sure we can write and read a simple file.
        let file = BinaryStlFile {
            header: BinaryStlHeader { header: [0u8; 80],
                                      num_triangles: 1 },
            triangles: vec![Triangle { normal: [0f32, 1f32, 0f32],
                                       v1: [0f32, 0f32, 0f32],
                                       v2: [0f32, 0f32, 1f32],
                                       v3: [1f32, 0f32, 1f32],
                                       attr_byte_count: 0 }]
        };

        let mut buffer = Vec::new();

        match write_stl(&mut buffer, &file) {
            Ok(_) => (),
            Err(_) => panic!()
        }

        match read_stl(&mut BufReader::new(buffer.as_slice())) {
            Ok(stl) => {
                assert!(stl.header.num_triangles == file.header.num_triangles);
                assert!(stl.triangles.len() == 1);
                assert!(stl.triangles[0] == file.triangles[0])
            },
            Err(_) => panic!()
        }
    }
}
<|endoftext|>


<commit_before>extern crate blas;
#[macro_use(s)]
extern crate ndarray;

use ndarray::{Data,DataMut,LinalgScalar};
use ndarray::prelude::*;

pub trait GramSchmidt: Sized + Clone + Default {
    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>;

    fn compute<S>(a: &ArrayBase<S, Ix2>) -> (Array<Self, Ix2>, Array<Self, Ix1>)
        where S: Data<Elem = Self>
    {
        let mut o = a.to_owned();
        let mut n = Array1::default(a.dim().1);

        Self::compute_into(a, &mut o, &mut n);
        (o, n)
    }
}

pub trait ModifiedGramSchmidt: Sized + Clone + Default {
    fn compute_inplace<S1,S2>(orth: &mut ArrayBase<S1, Ix2>, norm: &mut ArrayBase<S2, Ix1>)
        where S1: DataMut<Elem = Self>,
              S2: DataMut<Elem = Self>;

    fn compute_inplace_no_norm<S1>(a: &mut ArrayBase<S1, Ix2>)
        where S1: DataMut<Elem = Self>;

    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>,
    {
        orth.assign(&a);
        Self::compute_inplace(orth, norm);
    }

    fn compute<S>(a: &ArrayBase<S, Ix2>) -> (Array<Self, Ix2>, Array<Self, Ix1>)
        where S: Data<Elem = Self>
    {
        let mut o = a.to_owned();
        let mut n = Array1::default(a.dim().1);

        Self::compute_into(a, &mut o, &mut n);
        (o, n)
    }
}

impl GramSchmidt for f64 {
    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>
    {
        let n_rows = orth.shape()[0];

        orth.row_mut(0).assign(&a.row(0));

        for i in 0..n_rows {
            let (done, mut todo) = orth.view_mut().split_at(Axis(0), i);
            let ref_vec = a.row(i);

            let mut v = todo.row_mut(0);

            for w in done.inner_iter() {
                let projection_factor = project(&ref_vec, &w);
                v.zip_mut_with(&w, |ev,ew| { *ev -= projection_factor * ew; });
            }

            norm[i] = normalization(v.as_slice().unwrap());
            v /= norm[i];
        }
    }
}

impl ModifiedGramSchmidt for f64 {
    fn compute_inplace<S1,S2>(orth: &mut ArrayBase<S1, Ix2>, norm: &mut ArrayBase<S2, Ix1>)
        where S1: DataMut<Elem = Self>,
              S2: DataMut<Elem = Self>,
    {
        let n_rows = orth.shape()[0];

        for i in 0..n_rows {
            let (done, mut todo) = orth.view_mut().split_at(Axis(0), i);

            let mut v = todo.row_mut(0);

            for w in done.inner_iter() {
                // w is already normalized
                // let projection_factor = project(&v, &w);
                let projection_factor = v.dot(&w);
                v.zip_mut_with(&w, |ev,ew| { *ev -= projection_factor * ew; });
            }

            norm[i] = normalization(v.as_slice().unwrap());
            v /= norm[i];
        }
    }

    fn compute_inplace_no_norm<S1>(orth: &mut ArrayBase<S1, Ix2>)
        where S1: DataMut<Elem = Self>,
    {
        let n_rows = orth.shape()[0];

        for i in 0..n_rows {
            let (done, mut todo) = orth.view_mut().split_at(Axis(0), i);

            let mut v = todo.row_mut(0);

            for w in done.inner_iter() {
                // let projection_factor = project(&v, &w);
                let projection_factor = v.dot(&w);
                v.zip_mut_with(&w, |ev,ew| { *ev -= projection_factor * ew; });
            }

            v /= normalization(v.as_slice().unwrap());
        }
    }
}

pub fn orthogonal<S>(a: &ArrayBase<S,Ix2>, tol: f64) -> bool
    where S: Data<Elem=f64>
{
    let b = a.dot(&a.t());
    b.all_close(&Array2::eye(b.shape()[0]), tol)
}

pub fn normalization(v: &[f64]) -> f64 {
    blas::c::dnrm2(v.len() as i32, v, 1)
}

pub fn project<A,S1,S2>(vector: &ArrayBase<S1,Ix1>, onto: &ArrayBase<S2,Ix1>) -> A
    where S1: Data<Elem=A>,
          S2: Data<Elem=A>,
          A: LinalgScalar
{
    vector.dot(onto) / onto.dot(onto)
}

#[cfg(test)]
mod tests {
    use ndarray::{arr1,arr2,Array1,Array2};
    use super::{GramSchmidt,ModifiedGramSchmidt};

    #[test]
    fn normalization() {
        let a = &[1.0,2.0,3.0,4.0,5.0];

        let n_manual = f64::sqrt(1.0 + 4.0 + 9.0 + 16.0 + 25.0);
        let n_calculated = super::normalization(a);

        println!("Norm, manual: {}", n_manual);
        println!("Norm, function: {}", n_calculated);

        assert_eq!(n_manual, n_calculated);
    }

    #[test]
    fn projection() {
        let a = arr1(&[1.0,2.0,3.0,4.0,5.0]);
        let p = super::project(&a,&a);

        println!("Projection: {}", p);
        assert_eq!(p, 1.0);
    }

    #[test]
    fn gram_schmidt() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let (a_orth, a_norm) = GramSchmidt::compute(&a);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let (b_orth, b_norm) = GramSchmidt::compute(&b);

        println!("{:?}", b_orth);
        println!("{:?}", b_norm);

        assert!(super::orthogonal(&a_orth, 1e-14));
        assert!(a_norm.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_orth, 1e-14));
        assert!(b_norm.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));
    }

    #[test]
    fn modified_gram_schmidt() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let (a_orth, a_norm) = ModifiedGramSchmidt::compute(&a);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let (b_orth, b_norm) = ModifiedGramSchmidt::compute(&b);

        assert!(super::orthogonal(&a_orth,1e-14));
        assert!(a_norm.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_orth,1e-14));
        assert!(b_norm.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));
    }

    #[test]
    fn modified_gram_schmidt_into() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let mut a_o = Array2::default((4,4));
        let mut a_n = Array1::default(4);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let mut b_o = Array2::default((4,4));
        let mut b_n = Array1::default(4);

        let c = arr2(&[[-4.079764601288893, 4.831491499921403, -2.9560001027996132, -0.02239325297550033, -0.2672544204261703, -0.07718850306444144],
                       [1.2917480323712418, 0.030479388871438983, 0.604549448561548, 0.013409783846041783, 0.037439247530467186, 0.03153579130305008],
                       [-47.584641085515464, 5.501371846864031, 41.39822251681311, -33.69079455346558, 43.13388644338738, 68.7695035292409],
                       [2.5268795799504997, 25.418530275775225, 33.473125141381374, 77.3391516894698, -44.091836957161426, 45.10932299622911],
                       [-20.383209804181938, -19.163209972229616, 0.09795435026201423, -53.296988576627484, -88.482334971421, 16.757575995918756],
                       [62.270964677492124, -75.82678462673792, -0.6889077708993588, 2.2569901796884064, 9.21906803233946, 44.891962279862234]]);

        let mut c_o = Array2::default((6,6));
        let mut c_n = Array1::default(6);

        ModifiedGramSchmidt::compute_into(&a, &mut a_o, &mut a_n);
        ModifiedGramSchmidt::compute_into(&b, &mut b_o, &mut b_n);
        ModifiedGramSchmidt::compute_into(&c, &mut c_o, &mut c_n);

        assert!(super::orthogonal(&a_o,1e-14));
        assert!(a_n.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_o,1e-14));
        assert!(b_n.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));

        assert!(super::orthogonal(&c_o,1e-14));
    }
}
<commit_msg>Remove projections of current vector immediately<commit_after>extern crate blas;
extern crate ndarray;

use ndarray::{Data,DataMut,LinalgScalar};
use ndarray::prelude::*;

pub trait GramSchmidt: Sized + Clone + Default {
    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>;

    fn compute<S>(a: &ArrayBase<S, Ix2>) -> (Array<Self, Ix2>, Array<Self, Ix1>)
        where S: Data<Elem = Self>
    {
        let mut o = a.to_owned();
        let mut n = Array1::default(a.dim().1);

        Self::compute_into(a, &mut o, &mut n);
        (o, n)
    }
}

pub trait ModifiedGramSchmidt: Sized + Clone + Default {
    fn compute_inplace<S1,S2>(orth: &mut ArrayBase<S1, Ix2>, norm: &mut ArrayBase<S2, Ix1>)
        where S1: DataMut<Elem = Self>,
              S2: DataMut<Elem = Self>;

    fn compute_inplace_no_norm<S1>(a: &mut ArrayBase<S1, Ix2>)
        where S1: DataMut<Elem = Self>;

    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>,
    {
        orth.assign(&a);
        Self::compute_inplace(orth, norm);
    }

    fn compute<S>(a: &ArrayBase<S, Ix2>) -> (Array<Self, Ix2>, Array<Self, Ix1>)
        where S: Data<Elem = Self>
    {
        let mut o = a.to_owned();
        let mut n = Array1::default(a.dim().1);

        Self::compute_into(a, &mut o, &mut n);
        (o, n)
    }
}

impl GramSchmidt for f64 {
    fn compute_into<S1,S2,S3>(a: &ArrayBase<S1, Ix2>, orth: &mut ArrayBase<S2, Ix2>, norm: &mut ArrayBase<S3, Ix1>)
        where S1: Data<Elem = Self>,
              S2: DataMut<Elem = Self>,
              S3: DataMut<Elem = Self>
    {
        let n_rows = orth.shape()[0];

        orth.row_mut(0).assign(&a.row(0));

        for i in 0..n_rows {
            let (done, mut todo) = orth.view_mut().split_at(Axis(0), i);
            let ref_vec = a.row(i);

            let mut v = todo.row_mut(0);

            for w in done.inner_iter() {
                let projection_factor = project(&ref_vec, &w);
                v.zip_mut_with(&w, |ev,ew| { *ev -= projection_factor * ew; });
            }

            norm[i] = normalization(v.as_slice().unwrap());
            v /= norm[i];
        }
    }
}

impl ModifiedGramSchmidt for f64 {
    fn compute_inplace<S1,S2>(orth: &mut ArrayBase<S1, Ix2>, norm: &mut ArrayBase<S2, Ix1>)
        where S1: DataMut<Elem = Self>,
              S2: DataMut<Elem = Self>,
    {
        let n_rows = orth.shape()[0];

        let mut todo = orth.view_mut();

        for i in 0..n_rows {
            let (mut v, rest) = todo.split_at(Axis(0), 1);
            let mut v = v.row_mut(0);
            todo = rest;

            // Normalize the current row and remove its projection from the remaining rows. This
            // partially orthogonalizes the outstanding rows with respect to each current row.
            //
            // Another strategy would have been to use the already orthogonalized rows to
            // orthogonalize the current row in one go and then normalize it.
            //
            // However, the current strategy should be better for cache locality as we will not
            // need to reload the finished rows into cache all the time.
            norm[i] = normalization(v.as_slice().unwrap());
            v /= norm[i];

            for mut w in todo.inner_iter_mut() {
                // w is already normalized
                // let projection_factor = project(&v, &w);
                let projection_factor = v.dot(&w);
                w.zip_mut_with(&v, |ew,ev| { *ew -= projection_factor * ev; });
            }
        }
    }

    fn compute_inplace_no_norm<S1>(orth: &mut ArrayBase<S1, Ix2>)
        where S1: DataMut<Elem = Self>,
    {
        let n_rows = orth.shape()[0];

        let mut todo = orth.view_mut();

        for _i in 0..n_rows {
            let (mut v, rest) = todo.split_at(Axis(0), 1);
            let mut v = v.row_mut(0);
            todo = rest;

            // Same normalization strategy as with compute_inplace; see there for more comments.
            v /= normalization(v.as_slice().unwrap());

            for mut w in todo.inner_iter_mut() {
                // w is already normalized
                // let projection_factor = project(&v, &w);
                let projection_factor = v.dot(&w);
                w.zip_mut_with(&v, |ew,ev| { *ew -= projection_factor * ev; });
            }
        }
    }
}

pub fn orthogonal<S>(a: &ArrayBase<S,Ix2>, tol: f64) -> bool
    where S: Data<Elem=f64>
{
    let b = a.dot(&a.t());
    b.all_close(&Array2::eye(b.shape()[0]), tol)
}

pub fn normalization(v: &[f64]) -> f64 {
    blas::c::dnrm2(v.len() as i32, v, 1)
}

pub fn project<A,S1,S2>(vector: &ArrayBase<S1,Ix1>, onto: &ArrayBase<S2,Ix1>) -> A
    where S1: Data<Elem=A>,
          S2: Data<Elem=A>,
          A: LinalgScalar
{
    vector.dot(onto) / onto.dot(onto)
}

#[cfg(test)]
mod tests {
    use ndarray::{arr1,arr2,Array1,Array2};
    use super::{GramSchmidt,ModifiedGramSchmidt};

    #[test]
    fn normalization() {
        let a = &[1.0,2.0,3.0,4.0,5.0];

        let n_manual = f64::sqrt(1.0 + 4.0 + 9.0 + 16.0 + 25.0);
        let n_calculated = super::normalization(a);

        println!("Norm, manual: {}", n_manual);
        println!("Norm, function: {}", n_calculated);

        assert_eq!(n_manual, n_calculated);
    }

    #[test]
    fn projection() {
        let a = arr1(&[1.0,2.0,3.0,4.0,5.0]);
        let p = super::project(&a,&a);

        println!("Projection: {}", p);
        assert_eq!(p, 1.0);
    }

    #[test]
    fn gram_schmidt() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let (a_orth, a_norm) = GramSchmidt::compute(&a);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let (b_orth, b_norm) = GramSchmidt::compute(&b);

        println!("{:?}", b_orth);
        println!("{:?}", b_norm);

        assert!(super::orthogonal(&a_orth, 1e-14));
        assert!(a_norm.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_orth, 1e-14));
        assert!(b_norm.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));
    }

    #[test]
    fn modified_gram_schmidt() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let (a_orth, a_norm) = ModifiedGramSchmidt::compute(&a);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let (b_orth, b_norm) = ModifiedGramSchmidt::compute(&b);

        assert!(super::orthogonal(&a_orth,1e-14));
        assert!(a_norm.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_orth,1e-14));
        assert!(b_norm.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));
    }

    #[test]
    fn modified_gram_schmidt_into() {
        let a = arr2(&[[1.0, 0.0, 0.0, 0.0],
                       [0.0, 1.0, 0.0, 0.0],
                       [0.0, 0.0, 1.0, 0.0],
                       [0.0, 0.0, 0.0, 1.0]]);

        let mut a_o = Array2::default((4,4));
        let mut a_n = Array1::default(4);

        let b = arr2(&[[2.0, 0.5, 0.0, 0.0],
                       [0.0, 0.3, 0.0, 0.0],
                       [0.0, 1.0, 0.7, 0.0],
                       [0.0, 0.0, 0.0, 3.0]]);

        let mut b_o = Array2::default((4,4));
        let mut b_n = Array1::default(4);

        let c = arr2(&[[-4.079764601288893, 4.831491499921403, -2.9560001027996132, -0.02239325297550033, -0.2672544204261703, -0.07718850306444144],
                       [1.2917480323712418, 0.030479388871438983, 0.604549448561548, 0.013409783846041783, 0.037439247530467186, 0.03153579130305008],
                       [-47.584641085515464, 5.501371846864031, 41.39822251681311, -33.69079455346558, 43.13388644338738, 68.7695035292409],
                       [2.5268795799504997, 25.418530275775225, 33.473125141381374, 77.3391516894698, -44.091836957161426, 45.10932299622911],
                       [-20.383209804181938, -19.163209972229616, 0.09795435026201423, -53.296988576627484, -88.482334971421, 16.757575995918756],
                       [62.270964677492124, -75.82678462673792, -0.6889077708993588, 2.2569901796884064, 9.21906803233946, 44.891962279862234]]);

        let mut c_o = Array2::default((6,6));
        let mut c_n = Array1::default(6);

        ModifiedGramSchmidt::compute_into(&a, &mut a_o, &mut a_n);
        ModifiedGramSchmidt::compute_into(&b, &mut b_o, &mut b_n);
        ModifiedGramSchmidt::compute_into(&c, &mut c_o, &mut c_n);

        assert!(super::orthogonal(&a_o,1e-14));
        assert!(a_n.all_close(&Array1::from_elem(4, 1.0), 1e-16));

        assert!(super::orthogonal(&b_o,1e-14));
        assert!(b_n.all_close(&arr1(&[2.0615528128088303, 0.2910427500435996, 0.7, 3.0]), 1e-16));

        assert!(super::orthogonal(&c_o,1e-14));
    }
}
<|endoftext|>


<commit_before>#![crate_name = "nickel"]
#![crate_type = "rlib"]
#![feature(plugin, core, collections, io, net, os, path, fs, std_misc, old_path)]
#![plugin(regex_macros)]

//!Nickel is supposed to be a simple and lightweight foundation for web applications written in Rust. Its API is inspired by the popular express framework for JavaScript.
//!
//!Some of the features are:
//!
//!* Easy handlers: A handler is just a function that takes a `Request` and `ResponseWriter`
//!* Variables in routes. Just write `my/route/:someid`
//!* Easy parameter access: `request.params.get(&"someid")`
//!* simple wildcard routes: `/some/*/route`
//!* double wildcard routes: `/a/**/route`
//!* middleware

extern crate time;
extern crate "rustc-serialize" as serialize;
extern crate hyper;
extern crate regex;
extern crate typemap;
extern crate plugin;
extern crate url;
extern crate mustache;
extern crate groupable;

#[macro_use] extern crate log;
#[macro_use] extern crate nickel_macros;

pub use nickel::Nickel;
pub use request::Request;
pub use response::Response;
pub use middleware::{Action, Continue, Halt, Middleware, ErrorHandler, MiddlewareResult};
pub use static_files_handler::StaticFilesHandler;
pub use favicon_handler::FaviconHandler;
pub use default_error_handler::DefaultErrorHandler;
pub use json_body_parser::JsonBody;
pub use query_string::QueryString;
pub use router::{Router, Route, RouteResult, HttpRouter};
pub use nickel_error::{ NickelError, NickelErrorKind, ErrorWithStatusCode, UserDefinedError, Other };
pub use mimes::get_media_type;
pub use middleware_handler::ResponseFinalizer;

pub mod router;
mod server;
mod nickel;
mod request;
mod response;
mod middleware;
mod middleware_handler;
mod favicon_handler;
mod static_files_handler;
mod json_body_parser;
pub mod mimes;
mod query_string;
mod urlencoded;
mod nickel_error;
mod default_error_handler;

pub mod status {
    pub use hyper::status::StatusCode;
}
<commit_msg>chore(*): remove build warnings<commit_after>#![crate_name = "nickel"]
#![crate_type = "rlib"]
#![feature(plugin, core, collections, io, net, path, path_ext, std_misc, old_path)]
#![plugin(regex_macros)]

//!Nickel is supposed to be a simple and lightweight foundation for web applications written in Rust. Its API is inspired by the popular express framework for JavaScript.
//!
//!Some of the features are:
//!
//!* Easy handlers: A handler is just a function that takes a `Request` and `ResponseWriter`
//!* Variables in routes. Just write `my/route/:someid`
//!* Easy parameter access: `request.params.get(&"someid")`
//!* simple wildcard routes: `/some/*/route`
//!* double wildcard routes: `/a/**/route`
//!* middleware

extern crate time;
extern crate "rustc-serialize" as serialize;
extern crate hyper;
extern crate regex;
extern crate typemap;
extern crate plugin;
extern crate url;
extern crate mustache;
extern crate groupable;

#[macro_use] extern crate log;
#[macro_use] extern crate nickel_macros;

pub use nickel::Nickel;
pub use request::Request;
pub use response::Response;
pub use middleware::{Action, Continue, Halt, Middleware, ErrorHandler, MiddlewareResult};
pub use static_files_handler::StaticFilesHandler;
pub use favicon_handler::FaviconHandler;
pub use default_error_handler::DefaultErrorHandler;
pub use json_body_parser::JsonBody;
pub use query_string::QueryString;
pub use router::{Router, Route, RouteResult, HttpRouter};
pub use nickel_error::{ NickelError, NickelErrorKind, ErrorWithStatusCode, UserDefinedError, Other };
pub use mimes::get_media_type;
pub use middleware_handler::ResponseFinalizer;

pub mod router;
mod server;
mod nickel;
mod request;
mod response;
mod middleware;
mod middleware_handler;
mod favicon_handler;
mod static_files_handler;
mod json_body_parser;
pub mod mimes;
mod query_string;
mod urlencoded;
mod nickel_error;
mod default_error_handler;

pub mod status {
    pub use hyper::status::StatusCode;
}
<|endoftext|>


<commit_before>extern crate nix;
extern crate cargo;
extern crate gimli;
extern crate object;
extern crate memmap;
extern crate coveralls_api;
extern crate fallible_iterator;
extern crate rustc_demangle;
extern crate syn;
extern crate proc_macro2;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;
extern crate serde;
extern crate serde_json;
extern crate quick_xml;
extern crate regex;
extern crate walkdir;

use std::env;
use std::io;
use std::ffi::CString;
use std::path::Path;
use nix::unistd::*;
use cargo::util::Config as CargoConfig;
use cargo::core::{Workspace, Package};
use cargo::ops;

pub mod config;
pub mod test_loader;
pub mod breakpoint;
pub mod report;
pub mod traces;
mod statemachine;
mod source_analysis;

/// Should be unnecessary with a future nix crate release.
mod personality;
mod ptrace_control;

use config::*;
use test_loader::*;
use ptrace_control::*;
use statemachine::*;
use traces::*;

pub fn run(config: &Config) -> Result<(), i32> {
    let (result, tp) = launch_tarpaulin(&config)?;
    report_coverage(&config, &result);
    if tp {
        Ok(())
    } else {
        println!("Tarpaulin ran successfully. Failure in tests.");
        Err(-1)
    }
}

/// Launches tarpaulin with the given configuration.
pub fn launch_tarpaulin(config: &Config) -> Result<(TraceMap, bool), i32> {
    let mut cargo_config = CargoConfig::default().unwrap();
    let flag_quiet = if config.verbose {
        None
    } else {
        Some(true)
    };
    // This shouldn't fail so no checking the error.
    let _ = cargo_config.configure(0u32, flag_quiet, &None, false, false, &[]);

    let workspace = Workspace::new(config.manifest.as_path(), &cargo_config).map_err(|_| 1i32)?;

    setup_environment();

    let mut copt = ops::CompileOptions::default(&cargo_config, ops::CompileMode::Test);
    if let ops::CompileFilter::Default{ref mut required_features_filterable} = copt.filter {
        *required_features_filterable = true;
    }
    copt.features = config.features.as_slice();
    copt.all_features = config.all_features;
    copt.spec = match ops::Packages::from_flags(workspace.is_virtual(), config.all, &config.exclude, &config.packages) {
        Ok(spec) => spec,
        Err(e) => {
            println!("Error getting Packages from workspace {}", e);
            return Err(-1)
        }
    };
    if config.verbose {
        println!("Running Tarpaulin");
    }
    if !config.skip_clean {
        if config.verbose {
            println!("Cleaning project");
        }
        // Clean isn't expected to fail and if it does it likely won't have an effect
        let clean_opt = ops::CleanOptions {
            config: &cargo_config,
            spec: &[],
            target: None,
            release: false,
        };
        let _ = ops::clean(&workspace, &clean_opt);
    }
    let mut result = TraceMap::new();
    println!("Building project");
    let compilation = ops::compile(&workspace, &copt);
    let mut test_passed = true;
    match compilation {
        Ok(comp) => {
            for &(ref package, ref _target_kind, ref name, ref path) in &comp.tests {
                if config.verbose {
                    println!("Processing {}", name);
                }
                if let Some((res, tp)) = get_test_coverage(&workspace, package, path.as_path(), &config, false) {
                    result.merge(&res);
                    test_passed &= tp;
                }
                if config.run_ignored {
                    if let Some((res, tp)) = get_test_coverage(&workspace, package, path.as_path(),
                                                         &config, true) {
                        result.merge(&res);
                        test_passed &= tp;
                    }
                }
            }
            result.dedup();
            Ok((result, test_passed))
        },
        Err(e) => {
            if config.verbose{
                println!("Error: failed to compile: {}", e);
            }
            Err(-1)
        },
    }
}

fn setup_environment() {
    let rustflags = "RUSTFLAGS";
    let mut value = " -C relocation-model=dynamic-no-pic -C link-dead-code -C opt-level=0 ".to_string();
    if let Ok(vtemp) = env::var(rustflags) {
        value.push_str(vtemp.as_ref());
    }
    env::set_var(rustflags, value);
}

fn accumulate_lines((mut acc, mut group): (Vec<String>, Vec<u64>), next: u64) -> (Vec<String>, Vec<u64>) {
    if let Some(last) = group.last().cloned() {
        if next == last + 1 {
            group.push(next);
            (acc, group)
        } else {
            match (group.first(), group.last()) {
                (Some(first), Some(last)) if first == last => {
                    acc.push(format!("{}", first));
                },
                (Some(first), Some(last)) => {
                    acc.push(format!("{}-{}", first, last));
                },
                (Some(_), None) |
                (None, _) => (),
            };
            (acc, vec![next])
        }
    } else {
        group.push(next);
        (acc, group)
    }
}

/// Reports the test coverage using the users preferred method. See config.rs
/// or help text for details.
pub fn report_coverage(config: &Config, result: &TraceMap) {
    if !result.is_empty() {
        println!("Coverage Results");
        if config.verbose {

            println!();
            println!("Uncovered Lines:");
            for (ref key, ref value) in result.iter() {
                let path = config.strip_project_path(key);
                let mut uncovered_lines = vec![];
                for v in value.iter() {
                    match v.stats {
                        traces::CoverageStat::Line(count) if count == 0 => {
                            uncovered_lines.push(v.line);
                        },
                        _ => (),
                    }
                }
                uncovered_lines.sort();
                let (groups, last_group) =
                    uncovered_lines.into_iter()
                    .fold((vec![], vec![]), accumulate_lines);
                let (groups, _) = accumulate_lines((groups, last_group), u64::max_value());
                println!("{}: {}", path.display(), groups.join(", "));
            }
            println!();
        }
        println!("Tested/Total Lines:");
        for file in result.files() {
            let path = config.strip_project_path(file);
            println!("{}: {}/{}", path.display(), result.covered_in_path(&file), result.coverable_in_path(&file));
        }
        let percent = result.coverage_percentage() * 100.0f64;
        // Put file filtering here
        println!("\n{:.2}% coverage, {}/{} lines covered", percent,
                 result.total_covered(), result.total_coverable());
        if config.is_coveralls() {
            report::coveralls::export(result, config);
            println!("Coverage data sent");
        }

        for g in &config.generate {
            match *g {
                OutputFile::Xml => {
                    report::cobertura::export(result, config);
                },
                _ => {
                    println!("Format currently unsupported");
                },
            }
        }
    } else {
        println!("No coverage results collected.");
    }

}

/// Returns the coverage statistics for a test executable in the given workspace
pub fn get_test_coverage(project: &Workspace,
                         package: &Package,
                         test: &Path,
                         config: &Config,
                         ignored: bool) -> Option<(TraceMap, bool)> {
    if !test.exists() {
        return None;
    }
    match fork() {
        Ok(ForkResult::Parent{ child }) => {
            match collect_coverage(project, test, child, config) {
                Ok(t) => {
                    Some(t)
                },
                Err(e) => {
                    println!("Error occurred: {}", e);
                    None
                },
            }
        }
        Ok(ForkResult::Child) => {
            println!("Launching test");
            execute_test(test, package, ignored, config);
            None
        }
        Err(err) => {
            println!("Failed to run {}", test.display());
            println!("Error {}", err);
            None
        }
    }

}

/// Collects the coverage data from the launched test
fn collect_coverage(project: &Workspace,
                    test_path: &Path,
                    test: Pid,
                    config: &Config) -> io::Result<(TraceMap, bool)> {
    let mut test_passed = false;
    let mut traces = generate_tracemap(project, test_path, config)?;
    {
        let (mut state, mut data) = create_state_machine(test, &mut traces, config);
        loop {
            state = state.step(&mut data, config);
            if state.is_finished() {
                if let TestState::End(i) = state {
                    test_passed = i==0;
                }
                break;
            }
        }
        if let Some(m) = data.error_message {
            println!("{}", m);
        }
        if state == TestState::Abort  {
            println!("Can't collect coverage data. Exiting");
            std::process::exit(1);
        }
    }
    Ok((traces, test_passed))
}

/// Launches the test executable
fn execute_test(test: &Path, package: &Package, ignored: bool, config: &Config) {
    let exec_path = CString::new(test.to_str().unwrap()).unwrap();
    match personality::disable_aslr() {
        Ok(_) => {},
        Err(e) => println!("ASLR disable failed: {}", e),
    }
    request_trace().expect("Failed to trace");
    println!("running {}", test.display());
    if let Some(parent) = package.manifest_path().parent() {
        let _ = env::set_current_dir(parent);
    }

    let mut envars: Vec<CString> = vec![CString::new("RUST_TEST_THREADS=1").unwrap()];
    for (key, value) in env::vars() {
        let mut temp = String::new();
        temp.push_str(key.as_str());
        temp.push('=');
        temp.push_str(value.as_str());
        envars.push(CString::new(temp).unwrap());
    }
    let mut argv = if ignored {
        vec![exec_path.clone(), CString::new("--ignored").unwrap()]
    } else {
        vec![exec_path.clone()]
    };
    if config.verbose {
        envars.push(CString::new("RUST_BACKTRACE=1").unwrap());
    } else {
        argv.push(CString::new("--quiet").unwrap());
    }
    for s in &config.varargs {
        argv.push(CString::new(s.as_bytes()).unwrap_or_default());
    }
    execve(&exec_path, &argv, envars.as_slice())
        .unwrap();
}

<commit_msg>Don't print a line for files that have no uncovered lines<commit_after>extern crate nix;
extern crate cargo;
extern crate gimli;
extern crate object;
extern crate memmap;
extern crate coveralls_api;
extern crate fallible_iterator;
extern crate rustc_demangle;
extern crate syn;
extern crate proc_macro2;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;
extern crate serde;
extern crate serde_json;
extern crate quick_xml;
extern crate regex;
extern crate walkdir;

use std::env;
use std::io;
use std::ffi::CString;
use std::path::Path;
use nix::unistd::*;
use cargo::util::Config as CargoConfig;
use cargo::core::{Workspace, Package};
use cargo::ops;

pub mod config;
pub mod test_loader;
pub mod breakpoint;
pub mod report;
pub mod traces;
mod statemachine;
mod source_analysis;

/// Should be unnecessary with a future nix crate release.
mod personality;
mod ptrace_control;

use config::*;
use test_loader::*;
use ptrace_control::*;
use statemachine::*;
use traces::*;

pub fn run(config: &Config) -> Result<(), i32> {
    let (result, tp) = launch_tarpaulin(&config)?;
    report_coverage(&config, &result);
    if tp {
        Ok(())
    } else {
        println!("Tarpaulin ran successfully. Failure in tests.");
        Err(-1)
    }
}

/// Launches tarpaulin with the given configuration.
pub fn launch_tarpaulin(config: &Config) -> Result<(TraceMap, bool), i32> {
    let mut cargo_config = CargoConfig::default().unwrap();
    let flag_quiet = if config.verbose {
        None
    } else {
        Some(true)
    };
    // This shouldn't fail so no checking the error.
    let _ = cargo_config.configure(0u32, flag_quiet, &None, false, false, &[]);

    let workspace = Workspace::new(config.manifest.as_path(), &cargo_config).map_err(|_| 1i32)?;

    setup_environment();

    let mut copt = ops::CompileOptions::default(&cargo_config, ops::CompileMode::Test);
    if let ops::CompileFilter::Default{ref mut required_features_filterable} = copt.filter {
        *required_features_filterable = true;
    }
    copt.features = config.features.as_slice();
    copt.all_features = config.all_features;
    copt.spec = match ops::Packages::from_flags(workspace.is_virtual(), config.all, &config.exclude, &config.packages) {
        Ok(spec) => spec,
        Err(e) => {
            println!("Error getting Packages from workspace {}", e);
            return Err(-1)
        }
    };
    if config.verbose {
        println!("Running Tarpaulin");
    }
    if !config.skip_clean {
        if config.verbose {
            println!("Cleaning project");
        }
        // Clean isn't expected to fail and if it does it likely won't have an effect
        let clean_opt = ops::CleanOptions {
            config: &cargo_config,
            spec: &[],
            target: None,
            release: false,
        };
        let _ = ops::clean(&workspace, &clean_opt);
    }
    let mut result = TraceMap::new();
    println!("Building project");
    let compilation = ops::compile(&workspace, &copt);
    let mut test_passed = true;
    match compilation {
        Ok(comp) => {
            for &(ref package, ref _target_kind, ref name, ref path) in &comp.tests {
                if config.verbose {
                    println!("Processing {}", name);
                }
                if let Some((res, tp)) = get_test_coverage(&workspace, package, path.as_path(), &config, false) {
                    result.merge(&res);
                    test_passed &= tp;
                }
                if config.run_ignored {
                    if let Some((res, tp)) = get_test_coverage(&workspace, package, path.as_path(),
                                                         &config, true) {
                        result.merge(&res);
                        test_passed &= tp;
                    }
                }
            }
            result.dedup();
            Ok((result, test_passed))
        },
        Err(e) => {
            if config.verbose{
                println!("Error: failed to compile: {}", e);
            }
            Err(-1)
        },
    }
}

fn setup_environment() {
    let rustflags = "RUSTFLAGS";
    let mut value = " -C relocation-model=dynamic-no-pic -C link-dead-code -C opt-level=0 ".to_string();
    if let Ok(vtemp) = env::var(rustflags) {
        value.push_str(vtemp.as_ref());
    }
    env::set_var(rustflags, value);
}

fn accumulate_lines((mut acc, mut group): (Vec<String>, Vec<u64>), next: u64) -> (Vec<String>, Vec<u64>) {
    if let Some(last) = group.last().cloned() {
        if next == last + 1 {
            group.push(next);
            (acc, group)
        } else {
            match (group.first(), group.last()) {
                (Some(first), Some(last)) if first == last => {
                    acc.push(format!("{}", first));
                },
                (Some(first), Some(last)) => {
                    acc.push(format!("{}-{}", first, last));
                },
                (Some(_), None) |
                (None, _) => (),
            };
            (acc, vec![next])
        }
    } else {
        group.push(next);
        (acc, group)
    }
}

/// Reports the test coverage using the users preferred method. See config.rs
/// or help text for details.
pub fn report_coverage(config: &Config, result: &TraceMap) {
    if !result.is_empty() {
        println!("Coverage Results");
        if config.verbose {

            println!();
            println!("Uncovered Lines:");
            for (ref key, ref value) in result.iter() {
                let path = config.strip_project_path(key);
                let mut uncovered_lines = vec![];
                for v in value.iter() {
                    match v.stats {
                        traces::CoverageStat::Line(count) if count == 0 => {
                            uncovered_lines.push(v.line);
                        },
                        _ => (),
                    }
                }
                uncovered_lines.sort();
                let (groups, last_group) =
                    uncovered_lines.into_iter()
                    .fold((vec![], vec![]), accumulate_lines);
                let (groups, _) = accumulate_lines((groups, last_group), u64::max_value());
                if ! groups.is_empty() {
                    println!("{}: {}", path.display(), groups.join(", "));
                }
            }
            println!();
        }
        println!("Tested/Total Lines:");
        for file in result.files() {
            let path = config.strip_project_path(file);
            println!("{}: {}/{}", path.display(), result.covered_in_path(&file), result.coverable_in_path(&file));
        }
        let percent = result.coverage_percentage() * 100.0f64;
        // Put file filtering here
        println!("\n{:.2}% coverage, {}/{} lines covered", percent,
                 result.total_covered(), result.total_coverable());
        if config.is_coveralls() {
            report::coveralls::export(result, config);
            println!("Coverage data sent");
        }

        for g in &config.generate {
            match *g {
                OutputFile::Xml => {
                    report::cobertura::export(result, config);
                },
                _ => {
                    println!("Format currently unsupported");
                },
            }
        }
    } else {
        println!("No coverage results collected.");
    }

}

/// Returns the coverage statistics for a test executable in the given workspace
pub fn get_test_coverage(project: &Workspace,
                         package: &Package,
                         test: &Path,
                         config: &Config,
                         ignored: bool) -> Option<(TraceMap, bool)> {
    if !test.exists() {
        return None;
    }
    match fork() {
        Ok(ForkResult::Parent{ child }) => {
            match collect_coverage(project, test, child, config) {
                Ok(t) => {
                    Some(t)
                },
                Err(e) => {
                    println!("Error occurred: {}", e);
                    None
                },
            }
        }
        Ok(ForkResult::Child) => {
            println!("Launching test");
            execute_test(test, package, ignored, config);
            None
        }
        Err(err) => {
            println!("Failed to run {}", test.display());
            println!("Error {}", err);
            None
        }
    }

}

/// Collects the coverage data from the launched test
fn collect_coverage(project: &Workspace,
                    test_path: &Path,
                    test: Pid,
                    config: &Config) -> io::Result<(TraceMap, bool)> {
    let mut test_passed = false;
    let mut traces = generate_tracemap(project, test_path, config)?;
    {
        let (mut state, mut data) = create_state_machine(test, &mut traces, config);
        loop {
            state = state.step(&mut data, config);
            if state.is_finished() {
                if let TestState::End(i) = state {
                    test_passed = i==0;
                }
                break;
            }
        }
        if let Some(m) = data.error_message {
            println!("{}", m);
        }
        if state == TestState::Abort  {
            println!("Can't collect coverage data. Exiting");
            std::process::exit(1);
        }
    }
    Ok((traces, test_passed))
}

/// Launches the test executable
fn execute_test(test: &Path, package: &Package, ignored: bool, config: &Config) {
    let exec_path = CString::new(test.to_str().unwrap()).unwrap();
    match personality::disable_aslr() {
        Ok(_) => {},
        Err(e) => println!("ASLR disable failed: {}", e),
    }
    request_trace().expect("Failed to trace");
    println!("running {}", test.display());
    if let Some(parent) = package.manifest_path().parent() {
        let _ = env::set_current_dir(parent);
    }

    let mut envars: Vec<CString> = vec![CString::new("RUST_TEST_THREADS=1").unwrap()];
    for (key, value) in env::vars() {
        let mut temp = String::new();
        temp.push_str(key.as_str());
        temp.push('=');
        temp.push_str(value.as_str());
        envars.push(CString::new(temp).unwrap());
    }
    let mut argv = if ignored {
        vec![exec_path.clone(), CString::new("--ignored").unwrap()]
    } else {
        vec![exec_path.clone()]
    };
    if config.verbose {
        envars.push(CString::new("RUST_BACKTRACE=1").unwrap());
    } else {
        argv.push(CString::new("--quiet").unwrap());
    }
    for s in &config.varargs {
        argv.push(CString::new(s.as_bytes()).unwrap_or_default());
    }
    execve(&exec_path, &argv, envars.as_slice())
        .unwrap();
}

<|endoftext|>