<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::DOMExceptionBinding;
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants;
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use util::str::DOMString;

use std::borrow::ToOwned;

#[repr(u16)]
#[derive(Copy, Debug)]
#[jstraceable]
pub enum DOMErrorName {
    IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR,
    HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR,
    WrongDocumentError = DOMExceptionConstants::WRONG_DOCUMENT_ERR,
    InvalidCharacterError = DOMExceptionConstants::INVALID_CHARACTER_ERR,
    NoModificationAllowedError = DOMExceptionConstants::NO_MODIFICATION_ALLOWED_ERR,
    NotFoundError = DOMExceptionConstants::NOT_FOUND_ERR,
    NotSupportedError = DOMExceptionConstants::NOT_SUPPORTED_ERR,
    InvalidStateError = DOMExceptionConstants::INVALID_STATE_ERR,
    SyntaxError = DOMExceptionConstants::SYNTAX_ERR,
    InvalidModificationError = DOMExceptionConstants::INVALID_MODIFICATION_ERR,
    NamespaceError = DOMExceptionConstants::NAMESPACE_ERR,
    InvalidAccessError = DOMExceptionConstants::INVALID_ACCESS_ERR,
    SecurityError = DOMExceptionConstants::SECURITY_ERR,
    NetworkError = DOMExceptionConstants::NETWORK_ERR,
    AbortError = DOMExceptionConstants::ABORT_ERR,
    URLMismatchError = DOMExceptionConstants::URL_MISMATCH_ERR,
    QuotaExceededError = DOMExceptionConstants::QUOTA_EXCEEDED_ERR,
    TimeoutError = DOMExceptionConstants::TIMEOUT_ERR,
    InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR,
    DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR,
    EncodingError
}

#[dom_struct]
pub struct DOMException {
    reflector_: Reflector,
    code: DOMErrorName,
}

impl DOMException {
    fn new_inherited(code: DOMErrorName) -> DOMException {
        DOMException {
            reflector_: Reflector::new(),
            code: code,
        }
    }

    pub fn new(global: GlobalRef, code: DOMErrorName) -> Temporary<DOMException> {
        reflect_dom_object(box DOMException::new_inherited(code), global, DOMExceptionBinding::Wrap)
    }
}

impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> {
    // http://dom.spec.whatwg.org/#dom-domexception-code
    fn Code(self) -> u16 {
        match self.code {
            // http://dom.spec.whatwg.org/#concept-throw
            DOMErrorName::EncodingError => 0,
            code => code as u16
        }
    }

    // http://dom.spec.whatwg.org/#error-names-0
    fn Name(self) -> DOMString {
        format!("{:?}", self.code)
    }

    // http://dom.spec.whatwg.org/#error-names-0
    fn Message(self) -> DOMString {
        let message = match self.code {
            DOMErrorName::IndexSizeError => "The index is not in the allowed range.",
            DOMErrorName::HierarchyRequestError => "The operation would yield an incorrect node tree.",
            DOMErrorName::WrongDocumentError => "The object is in the wrong document.",
            DOMErrorName::InvalidCharacterError => "The string contains invalid characters.",
            DOMErrorName::NoModificationAllowedError => "The object can not be modified.",
            DOMErrorName::NotFoundError => "The object can not be found here.",
            DOMErrorName::NotSupportedError => "The operation is not supported.",
            DOMErrorName::InvalidStateError => "The object is in an invalid state.",
            DOMErrorName::SyntaxError => "The string did not match the expected pattern.",
            DOMErrorName::InvalidModificationError => "The object can not be modified in this way.",
            DOMErrorName::NamespaceError => "The operation is not allowed by Namespaces in XML.",
            DOMErrorName::InvalidAccessError => "The object does not support the operation or argument.",
            DOMErrorName::SecurityError => "The operation is insecure.",
            DOMErrorName::NetworkError => "A network error occurred.",
            DOMErrorName::AbortError => "The operation was aborted.",
            DOMErrorName::URLMismatchError => "The given URL does not match another URL.",
            DOMErrorName::QuotaExceededError => "The quota has been exceeded.",
            DOMErrorName::TimeoutError => "The operation timed out.",
            DOMErrorName::InvalidNodeTypeError => "The supplied node is incorrect or has an incorrect ancestor for this operation.",
            DOMErrorName::DataCloneError => "The object can not be cloned.",
            DOMErrorName::EncodingError => "The encoding operation (either encoded or decoding) failed."
        };

        message.to_owned()
    }
}
<commit_msg>Update the spec links in domexception.rs (fixes #5528)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::Bindings::DOMExceptionBinding;
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants;
use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use util::str::DOMString;

use std::borrow::ToOwned;

#[repr(u16)]
#[derive(Copy, Debug)]
#[jstraceable]
pub enum DOMErrorName {
    IndexSizeError = DOMExceptionConstants::INDEX_SIZE_ERR,
    HierarchyRequestError = DOMExceptionConstants::HIERARCHY_REQUEST_ERR,
    WrongDocumentError = DOMExceptionConstants::WRONG_DOCUMENT_ERR,
    InvalidCharacterError = DOMExceptionConstants::INVALID_CHARACTER_ERR,
    NoModificationAllowedError = DOMExceptionConstants::NO_MODIFICATION_ALLOWED_ERR,
    NotFoundError = DOMExceptionConstants::NOT_FOUND_ERR,
    NotSupportedError = DOMExceptionConstants::NOT_SUPPORTED_ERR,
    InvalidStateError = DOMExceptionConstants::INVALID_STATE_ERR,
    SyntaxError = DOMExceptionConstants::SYNTAX_ERR,
    InvalidModificationError = DOMExceptionConstants::INVALID_MODIFICATION_ERR,
    NamespaceError = DOMExceptionConstants::NAMESPACE_ERR,
    InvalidAccessError = DOMExceptionConstants::INVALID_ACCESS_ERR,
    SecurityError = DOMExceptionConstants::SECURITY_ERR,
    NetworkError = DOMExceptionConstants::NETWORK_ERR,
    AbortError = DOMExceptionConstants::ABORT_ERR,
    URLMismatchError = DOMExceptionConstants::URL_MISMATCH_ERR,
    QuotaExceededError = DOMExceptionConstants::QUOTA_EXCEEDED_ERR,
    TimeoutError = DOMExceptionConstants::TIMEOUT_ERR,
    InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR,
    DataCloneError = DOMExceptionConstants::DATA_CLONE_ERR,
    EncodingError
}

#[dom_struct]
pub struct DOMException {
    reflector_: Reflector,
    code: DOMErrorName,
}

impl DOMException {
    fn new_inherited(code: DOMErrorName) -> DOMException {
        DOMException {
            reflector_: Reflector::new(),
            code: code,
        }
    }

    pub fn new(global: GlobalRef, code: DOMErrorName) -> Temporary<DOMException> {
        reflect_dom_object(box DOMException::new_inherited(code), global, DOMExceptionBinding::Wrap)
    }
}

impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> {
    // http://heycam.github.io/webidl/#dfn-DOMException
    fn Code(self) -> u16 {
        match self.code {
            // http://heycam.github.io/webidl/#dfn-throw
            DOMErrorName::EncodingError => 0,
            code => code as u16
        }
    }

    // http://heycam.github.io/webidl/#idl-DOMException-error-names
    fn Name(self) -> DOMString {
        format!("{:?}", self.code)
    }

    // http://heycam.github.io/webidl/#error-names
    fn Message(self) -> DOMString {
        let message = match self.code {
            DOMErrorName::IndexSizeError => "The index is not in the allowed range.",
            DOMErrorName::HierarchyRequestError => "The operation would yield an incorrect node tree.",
            DOMErrorName::WrongDocumentError => "The object is in the wrong document.",
            DOMErrorName::InvalidCharacterError => "The string contains invalid characters.",
            DOMErrorName::NoModificationAllowedError => "The object can not be modified.",
            DOMErrorName::NotFoundError => "The object can not be found here.",
            DOMErrorName::NotSupportedError => "The operation is not supported.",
            DOMErrorName::InvalidStateError => "The object is in an invalid state.",
            DOMErrorName::SyntaxError => "The string did not match the expected pattern.",
            DOMErrorName::InvalidModificationError => "The object can not be modified in this way.",
            DOMErrorName::NamespaceError => "The operation is not allowed by Namespaces in XML.",
            DOMErrorName::InvalidAccessError => "The object does not support the operation or argument.",
            DOMErrorName::SecurityError => "The operation is insecure.",
            DOMErrorName::NetworkError => "A network error occurred.",
            DOMErrorName::AbortError => "The operation was aborted.",
            DOMErrorName::URLMismatchError => "The given URL does not match another URL.",
            DOMErrorName::QuotaExceededError => "The quota has been exceeded.",
            DOMErrorName::TimeoutError => "The operation timed out.",
            DOMErrorName::InvalidNodeTypeError => "The supplied node is incorrect or has an incorrect ancestor for this operation.",
            DOMErrorName::DataCloneError => "The object can not be cloned.",
            DOMErrorName::EncodingError => "The encoding operation (either encoded or decoding) failed."
        };

        message.to_owned()
    }
}
<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};
use std::io::buffered::BufferedReader;

static IP: &'static str  = "127.0.0.1";
static PORT:        int  = 4414;
static mut visitor_count: uint = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;
            match stream {
                Some(ref mut s) => {
                    match s.peer_name() {
                        Some(pn) => {
                            println!("Received connection from: [{:s}]",
                                    pn.to_str());
                            },
                        None => ()
                    }
                },
                None => ()
            }
            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            let filename = get_requested_filename(request_str);
            println!("filename: {:s}", filename);
            println!("Received request :\n{:s}", request_str);
            unsafe {
                atomic_add(&mut visitor_count, 1);
                println!("Visitor count: {:u}", visitor_count);
            }
            let contents = read_filename(filename);
            let response = format_response(contents);
            stream.write(response.as_bytes());
            println("Connection terminates.");
        }
    }
}

fn get_requested_filename(request: &str) -> &str {
    let lines: ~[&str] = request.split('\n').collect();
    let firstline      = lines[0];
    let after          = firstline.slice_from(4).to_owned();
    let then: ~[&str]  = after.split(' ').collect();
    let filename       = then[0].slice_from(1);

    filename
}

fn read_filename(filename : &str) -> ~str {
    let mut contents = ~"";
    let filepath = Path::new(filename);
    match File::open(&filepath) {
        Some (file) => {
            contents = get_file_contents(file);
        },
        None => {
            println!("Error opening file: {:s}", filename);
        }
    }

    contents
}

fn get_file_contents(file: File) -> ~str {
    let mut filereader = ~BufferedReader::new(file);
    let mut contents : ~str = ~"";
    println("Reading file ...");
    for line in filereader.lines() {
        contents = contents + "
" + line;
    }

    contents
}

fn format_response(file_contents : &str) -> ~str {
    let response = ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
    <doctype !html><title>Hello, Rust!</title>
    "
    + file_contents
        + unsafe{
            visitor_count.to_str()
        } + "

    \r\n";
    response
}

fn atomic_add(var: &mut uint, count: uint) -> uint {
    let oldval = var.clone();
    *var = *var + count;
    return oldval;
}
<commit_msg>serve files as text/plain mimetype<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};
use std::io::buffered::BufferedReader;

static IP: &'static str  = "127.0.0.1";
static PORT:        int  = 4414;
static mut visitor_count: uint = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;
            match stream {
                Some(ref mut s) => {
                    match s.peer_name() {
                        Some(pn) => {
                            println!("Received connection from: [{:s}]",
                                    pn.to_str());
                            unsafe {
                                atomic_add(&mut visitor_count, 1);
                                println!("Visitor count: {:u}", visitor_count);
                            }
                            },
                        None => ()
                    }
                },
                None => ()
            }
            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            let filename = get_requested_filename(request_str);
            if (filename == "") {
let response: ~str = ~"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
<doctype !html><title>Hello, Rust!</title>

Greetings, Krusty!

Visitor count: "
+ unsafe{
    visitor_count.to_str()
} + "

\r\n";
            stream.write(response.as_bytes());
            }
            else {
                println!("filename: {:s}", filename);
                println!("Received request :\n{:s}", request_str);
                let contents = read_filename(filename);
                let response = format_response(contents);
                stream.write(response.as_bytes());
            }
            println!("Connection terminates.");
        }
    }
}

fn get_requested_filename(request: &str) -> &str {
    let lines: ~[&str] = request.split('\n').collect();
    let firstline      = lines[0];
    let after          = firstline.slice_from(4).to_owned();
    let then: ~[&str]  = after.split(' ').collect();
    let filename       = then[0].slice_from(1);

    filename
}

fn read_filename(filename : &str) -> ~str {
    let mut contents = ~"";
    let filepath= Path::new(filename.clone());
    match File::open_mode(&filepath, Open, Read) {
        Some (file) => {
            println("File opened for reading ...");
            contents = get_file_contents(file);
        },
        _ => {
            println!("Error opening file: {:s}", filename);
        }
    }
    contents
}

fn get_file_contents(file: File) -> ~str {
    let mut filereader = ~BufferedReader::new(file);
    println("Reading file ...");
    let contents: ~[u8] = filereader.read_to_end();
    str::from_utf8(contents).to_owned()
}

fn format_response(file_contents : &str) -> ~str {
    let response = ~"HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n"
    + file_contents;
    response
}

fn atomic_add(var: &mut uint, count: uint) -> uint {
    let oldval = var.clone();
    *var = *var + count;
    return oldval;
}
<|endoftext|>


<commit_before>#![cfg(feature = "rblas")]

extern crate rblas;
#[macro_use] extern crate ndarray;

use rblas::Gemm;
use rblas::attribute::Transpose;

use ndarray::{
    OwnedArray,
};

use ndarray::blas::AsBlas;

#[test]
fn strided_matrix() {
    // smoke test, a matrix multiplication of uneven size
    let (n, m) = (45, 33);
    let mut a = OwnedArray::linspace(0., ((n * m) - 1) as f32, n as usize * m as usize ).into_shape((n, m)).unwrap();
    let mut b = ndarray::linalg::eye(m);
    let mut res = OwnedArray::zeros(a.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &a.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    assert_eq!(res, a);

    // matrix multiplication, strided
    let mut aprim = a.to_shared().slice(s![0..12, 0..11]);
    println!("{:?}", aprim.shape());
    println!("{:?}", aprim.strides());
    let mut b = ndarray::linalg::eye(aprim.shape()[1]);
    let mut res = OwnedArray::zeros(aprim.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &aprim.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    println!("{:?}", aprim);
    println!("{:?}", b);
    println!("{:?}", res);
    println!("{:?}", &res - &aprim);
    assert_eq!(res, aprim);

    // Transposed matrix multiply
    let (np, mp) = aprim.dim();
    let mut res = OwnedArray::zeros((mp, np));
    let mut b = ndarray::linalg::eye(np);
    Gemm::gemm(&1., Transpose::Trans, &aprim.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    let mut at = aprim.clone();
    at.swap_axes(0, 1);
    assert_eq!(at, res);

    // strided, needs copy
    let mut abis = a.to_shared().slice(s![0..12, ..;2]);
    println!("{:?}", abis.shape());
    println!("{:?}", abis.strides());
    let mut b = ndarray::linalg::eye(abis.shape()[1]);
    let mut res = OwnedArray::zeros(abis.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &abis.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    println!("{:?}", abis);
    println!("{:?}", b);
    println!("{:?}", res);
    println!("{:?}", &res - &abis);
    assert_eq!(res, abis);
}
<commit_msg>Fix blas tests<commit_after>#![cfg(feature = "rblas")]

extern crate rblas;
#[macro_use] extern crate ndarray;

use rblas::Gemm;
use rblas::attribute::Transpose;

use ndarray::{
    OwnedArray,
};

use ndarray::blas::AsBlas;

#[test]
fn strided_matrix() {
    // smoke test, a matrix multiplication of uneven size
    let (n, m) = (45, 33);
    let mut a = OwnedArray::linspace(0., ((n * m) - 1) as f32, n as usize * m as usize ).into_shape((n, m)).unwrap();
    let mut b = ndarray::linalg::eye(m);
    let mut res = OwnedArray::zeros(a.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &a.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    assert_eq!(res, a);

    // matrix multiplication, strided
    let mut aprim = a.to_shared();
    aprim.islice(s![0..12, 0..11]);
    println!("{:?}", aprim.shape());
    println!("{:?}", aprim.strides());
    let mut b = ndarray::linalg::eye(aprim.shape()[1]);
    let mut res = OwnedArray::zeros(aprim.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &aprim.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    println!("{:?}", aprim);
    println!("{:?}", b);
    println!("{:?}", res);
    println!("{:?}", &res - &aprim);
    assert_eq!(res, aprim);

    // Transposed matrix multiply
    let (np, mp) = aprim.dim();
    let mut res = OwnedArray::zeros((mp, np));
    let mut b = ndarray::linalg::eye(np);
    Gemm::gemm(&1., Transpose::Trans, &aprim.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    let mut at = aprim.clone();
    at.swap_axes(0, 1);
    assert_eq!(at, res);

    // strided, needs copy
    let mut abis = a.to_shared();
    abis.islice(s![0..12, ..;2]);
    println!("{:?}", abis.shape());
    println!("{:?}", abis.strides());
    let mut b = ndarray::linalg::eye(abis.shape()[1]);
    let mut res = OwnedArray::zeros(abis.dim());
    Gemm::gemm(&1., Transpose::NoTrans, &abis.blas(), Transpose::NoTrans, &b.blas(),
               &0., &mut res.blas());
    println!("{:?}", abis);
    println!("{:?}", b);
    println!("{:?}", res);
    println!("{:?}", &res - &abis);
    assert_eq!(res, abis);
}
<|endoftext|>


<commit_before>extern crate compiletest_rs as compiletest;

use std::env::{current_dir, set_current_dir, set_var, var};
use std::fs::{copy, read_dir, remove_file};
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

fn run_mode(mode: &'static str, dir: PathBuf, target_dir: &Path) {
    let mut config = compiletest::default_config();

    config.target_rustcflags = Some(format!("-L {}", target_dir.to_str().unwrap()));

    if let Ok(name) = var::<&str>("TESTNAME") {
        config.filter = Some(name.to_owned())
    }

    let cfg_mode = mode.parse().ok().expect("Invalid mode");
    config.mode = cfg_mode;

    set_current_dir(&dir).unwrap();
    config.src_base = current_dir().unwrap();

    let db_orig = Path::new("Herbie.orig.db");
    let has_db_orig = db_orig.exists();

    if has_db_orig {
        copy(db_orig, "Herbie.db").is_ok();
    }

    set_var("PATH", format!("{}:.", var("PATH").unwrap()));

    compiletest::run_tests(&config);

    if has_db_orig {
        let Output { status, stdout, stderr } =
            Command::new("sqldiff")
            .arg("Herbie.dest.db").arg("Herbie.db")
            .output()
            .unwrap()
        ;

        assert!(status.success());
        assert!(stdout.is_empty(), "DB have diff:\n>>>\n{}<<<", String::from_utf8_lossy(&stdout));
        assert!(stderr.is_empty(), "{}", String::from_utf8_lossy(&stderr));

        remove_file("Herbie.db").unwrap();
    }
}

#[test]
fn compile_test() {
    let cwd = current_dir().unwrap();
    let target_dir = cwd.join("target/debug/");

    for dir in read_dir("tests/compile-fail").unwrap() {
        let dir = cwd.join(dir.unwrap().path());
        run_mode("compile-fail", dir, &target_dir);
    }
}
<commit_msg>Fix tests on ubuntu/travis<commit_after>extern crate compiletest_rs as compiletest;

use std::env::{current_dir, set_current_dir, set_var, var};
use std::fs::{copy, read_dir, remove_file};
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

fn run_mode(mode: &'static str, dir: PathBuf, target_dir: &Path) {
    let mut config = compiletest::default_config();

    config.target_rustcflags = Some(format!("-L {}", target_dir.to_str().unwrap()));

    if let Ok(name) = var::<&str>("TESTNAME") {
        config.filter = Some(name.to_owned())
    }

    let cfg_mode = mode.parse().ok().expect("Invalid mode");
    config.mode = cfg_mode;

    set_current_dir(&dir).unwrap();
    config.src_base = current_dir().unwrap();

    let db_orig = Path::new("Herbie.orig.db");
    let has_db_orig = db_orig.exists();

    if has_db_orig {
        copy(db_orig, "Herbie.db").is_ok();
    }

    set_var("PATH", format!("{}:.", var("PATH").unwrap()));

    compiletest::run_tests(&config);

    if has_db_orig {
        let Output { status: status_dest, stdout: stdout_dest, stderr: stderr_dest } =
            Command::new("sqlite3")
            .arg("Herbie.dest.db").arg("select * from HerbieResults;")
            .output()
            .unwrap()
        ;

        let Output { status, stdout, stderr } =
            Command::new("sqlite3")
            .arg("Herbie.db").arg("select * from HerbieResults;")
            .output()
            .unwrap()
        ;

        assert_eq!(stdout_dest, stdout);

        assert!(stderr.is_empty(), "{}", String::from_utf8_lossy(&stderr));
        assert!(stderr_dest.is_empty(), "{}", String::from_utf8_lossy(&stderr));

        assert!(status_dest.success());
        assert!(status.success());

        remove_file("Herbie.db").unwrap();
    }
}

#[test]
fn compile_test() {
    let cwd = current_dir().unwrap();
    let target_dir = cwd.join("target/debug/");

    for dir in read_dir("tests/compile-fail").unwrap() {
        let dir = cwd.join(dir.unwrap().path());
        run_mode("compile-fail", dir, &target_dir);
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Xorshift generators

use core::num::Wrapping as w;
use core::{fmt, slice};
use rand_core::{RngCore, SeedableRng, Error, impls, le};

/// An Xorshift random number generator.
///
/// The Xorshift[^1] algorithm is not suitable for cryptographic purposes
/// but is very fast. If you do not know for sure that it fits your
/// requirements, use a more secure one such as `StdRng` or `OsRng`.
///
/// [^1]: Marsaglia, George (July 2003).
///       ["Xorshift RNGs"](https://www.jstatsoft.org/v08/i14/paper).
///       *Journal of Statistical Software*. Vol. 8 (Issue 14).
#[derive(Clone)]
#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))]
pub struct XorShiftRng {
    x: w<u32>,
    y: w<u32>,
    z: w<u32>,
    w: w<u32>,
}

// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for XorShiftRng {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "XorShiftRng {{}}")
    }
}

impl RngCore for XorShiftRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        let x = self.x;
        let t = x ^ (x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        let w_ = self.w;
        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
        self.w.0
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        impls::next_u64_via_u32(self)
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        impls::fill_bytes_via_next(self, dest)
    }

    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        Ok(self.fill_bytes(dest))
    }
}

impl SeedableRng for XorShiftRng {
    type Seed = [u8; 16];

    fn from_seed(seed: Self::Seed) -> Self {
        let mut seed_u32 = [0u32; 4];
        le::read_u32_into(&seed, &mut seed_u32);

        // Xorshift cannot be seeded with 0 and we cannot return an Error, but
        // also do not wish to panic (because a random seed can legitimately be
        // 0); our only option is therefore to use a preset value.
        if seed_u32.iter().all(|&x| x == 0) {
            seed_u32 = [0xBAD_5EED, 0xBAD_5EED, 0xBAD_5EED, 0xBAD_5EED];
        }

        XorShiftRng {
            x: w(seed_u32[0]),
            y: w(seed_u32[1]),
            z: w(seed_u32[2]),
            w: w(seed_u32[3]),
        }
    }

    fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
        let mut seed_u32 = [0u32; 4];
        loop {
            unsafe {
                let ptr = seed_u32.as_mut_ptr() as *mut u8;

                let slice = slice::from_raw_parts_mut(ptr, 4 * 4);
                rng.try_fill_bytes(slice)?;
            }
            if !seed_u32.iter().all(|&x| x == 0) { break; }
        }

        Ok(XorShiftRng {
            x: w(seed_u32[0]),
            y: w(seed_u32[1]),
            z: w(seed_u32[2]),
            w: w(seed_u32[3]),
        })
    }
}

#[cfg(test)]
mod tests {
    use {RngCore, SeedableRng};
    use super::XorShiftRng;

    #[test]
    fn test_xorshift_construction() {
        // Test that various construction techniques produce a working RNG.
        let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
        let mut rng1 = XorShiftRng::from_seed(seed);
        assert_eq!(rng1.next_u64(), 4325440999699518727);

        let _rng2 = XorShiftRng::from_rng(rng1).unwrap();
        // Note: we cannot test the state of _rng2 because from_rng does not
        // fix Endianness. This is allowed in the trait specification.
    }

    #[test]
    fn test_xorshift_true_values() {
        let seed = [16,15,14,13, 12,11,10,9, 8,7,6,5, 4,3,2,1];
        let mut rng = XorShiftRng::from_seed(seed);

        let mut results = [0u32; 9];
        for i in results.iter_mut() { *i = rng.next_u32(); }
        let expected: [u32; 9] = [
            2081028795, 620940381, 269070770, 16943764, 854422573, 29242889,
            1550291885, 1227154591, 271695242];
        assert_eq!(results, expected);

        let mut results = [0u64; 9];
        for i in results.iter_mut() { *i = rng.next_u64(); }
        let expected: [u64; 9] = [
            9247529084182843387, 8321512596129439293, 14104136531997710878,
            6848554330849612046, 343577296533772213, 17828467390962600268,
            9847333257685787782, 7717352744383350108, 1133407547287910111];
        assert_eq!(results, expected);

        let mut results = [0u8; 32];
        rng.fill_bytes(&mut results);
        let expected = [102, 57, 212, 16, 233, 130, 49, 183,
                        158, 187, 44, 203, 63, 149, 45, 17,
                        117, 129, 131, 160, 70, 121, 158, 155,
                        224, 209, 192, 53, 10, 62, 57, 72];
        assert_eq!(results, expected);
    }

    #[test]
    fn test_xorshift_zero_seed() {
        // Xorshift does not work with an all zero seed.
        // Assert it does not panic.
        let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
        let mut rng = XorShiftRng::from_seed(seed);
        let a = rng.next_u64();
        let b = rng.next_u64();
        assert!(a != 0);
        assert!(b != a);
    }

    #[test]
    fn test_xorshift_clone() {
        let seed = [1,2,3,4, 5,5,7,8, 8,7,6,5, 4,3,2,1];
        let mut rng1 = XorShiftRng::from_seed(seed);
        let mut rng2 = rng1.clone();
        for _ in 0..16 {
            assert_eq!(rng1.next_u64(), rng2.next_u64());
        }
    }

    #[cfg(all(feature="serde1", feature="std"))]
    #[test]
    fn test_xorshift_serde() {
        use bincode;
        use std::io::{BufWriter, BufReader};

        let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
        let mut rng = XorShiftRng::from_seed(seed);

        let buf: Vec<u8> = Vec::new();
        let mut buf = BufWriter::new(buf);
        bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");

        let buf = buf.into_inner().unwrap();
        let mut read = BufReader::new(&buf[..]);
        let mut deserialized: XorShiftRng = bincode::deserialize_from(&mut read).expect("Could not deserialize");

        assert_eq!(rng.x, deserialized.x);
        assert_eq!(rng.y, deserialized.y);
        assert_eq!(rng.z, deserialized.z);
        assert_eq!(rng.w, deserialized.w);

        for _ in 0..16 {
            assert_eq!(rng.next_u64(), deserialized.next_u64());
        }
    }
}
<commit_msg>Fix benchmarks<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Xorshift generators

use core::num::Wrapping as w;
use core::{fmt, slice};
use rand_core::{RngCore, SeedableRng, Error, impls, le};

/// An Xorshift random number generator.
///
/// The Xorshift[^1] algorithm is not suitable for cryptographic purposes
/// but is very fast. If you do not know for sure that it fits your
/// requirements, use a more secure one such as `StdRng` or `OsRng`.
///
/// [^1]: Marsaglia, George (July 2003).
///       ["Xorshift RNGs"](https://www.jstatsoft.org/v08/i14/paper).
///       *Journal of Statistical Software*. Vol. 8 (Issue 14).
#[derive(Clone)]
#[cfg_attr(feature="serde1", derive(Serialize,Deserialize))]
pub struct XorShiftRng {
    x: w<u32>,
    y: w<u32>,
    z: w<u32>,
    w: w<u32>,
}

// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for XorShiftRng {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "XorShiftRng {{}}")
    }
}

impl RngCore for XorShiftRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        let x = self.x;
        let t = x ^ (x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        let w_ = self.w;
        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
        self.w.0
    }

    #[inline]
    fn next_u64(&mut self) -> u64 {
        impls::next_u64_via_u32(self)
    }

    #[inline]
    fn fill_bytes(&mut self, dest: &mut [u8]) {
        impls::fill_bytes_via_next(self, dest)
    }

    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
        Ok(self.fill_bytes(dest))
    }
}

impl SeedableRng for XorShiftRng {
    type Seed = [u8; 16];

    fn from_seed(seed: Self::Seed) -> Self {
        let mut seed_u32 = [0u32; 4];
        le::read_u32_into(&seed, &mut seed_u32);

        // Xorshift cannot be seeded with 0 and we cannot return an Error, but
        // also do not wish to panic (because a random seed can legitimately be
        // 0); our only option is therefore to use a preset value.
        if seed_u32.iter().all(|&x| x == 0) {
            seed_u32 = [0xBAD_5EED, 0xBAD_5EED, 0xBAD_5EED, 0xBAD_5EED];
        }

        XorShiftRng {
            x: w(seed_u32[0]),
            y: w(seed_u32[1]),
            z: w(seed_u32[2]),
            w: w(seed_u32[3]),
        }
    }

    fn from_rng<R: RngCore>(mut rng: R) -> Result<Self, Error> {
        let mut seed_u32 = [0u32; 4];
        loop {
            unsafe {
                let ptr = seed_u32.as_mut_ptr() as *mut u8;

                let slice = slice::from_raw_parts_mut(ptr, 4 * 4);
                rng.try_fill_bytes(slice)?;
            }
            if !seed_u32.iter().all(|&x| x == 0) { break; }
        }

        Ok(XorShiftRng {
            x: w(seed_u32[0]),
            y: w(seed_u32[1]),
            z: w(seed_u32[2]),
            w: w(seed_u32[3]),
        })
    }
}

#[cfg(test)]
mod tests {
    use ::rand_core::{RngCore, SeedableRng};
    use super::XorShiftRng;

    #[test]
    fn test_xorshift_construction() {
        // Test that various construction techniques produce a working RNG.
        let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
        let mut rng1 = XorShiftRng::from_seed(seed);
        assert_eq!(rng1.next_u64(), 4325440999699518727);

        let _rng2 = XorShiftRng::from_rng(rng1).unwrap();
        // Note: we cannot test the state of _rng2 because from_rng does not
        // fix Endianness. This is allowed in the trait specification.
    }

    #[test]
    fn test_xorshift_true_values() {
        let seed = [16,15,14,13, 12,11,10,9, 8,7,6,5, 4,3,2,1];
        let mut rng = XorShiftRng::from_seed(seed);

        let mut results = [0u32; 9];
        for i in results.iter_mut() { *i = rng.next_u32(); }
        let expected: [u32; 9] = [
            2081028795, 620940381, 269070770, 16943764, 854422573, 29242889,
            1550291885, 1227154591, 271695242];
        assert_eq!(results, expected);

        let mut results = [0u64; 9];
        for i in results.iter_mut() { *i = rng.next_u64(); }
        let expected: [u64; 9] = [
            9247529084182843387, 8321512596129439293, 14104136531997710878,
            6848554330849612046, 343577296533772213, 17828467390962600268,
            9847333257685787782, 7717352744383350108, 1133407547287910111];
        assert_eq!(results, expected);

        let mut results = [0u8; 32];
        rng.fill_bytes(&mut results);
        let expected = [102, 57, 212, 16, 233, 130, 49, 183,
                        158, 187, 44, 203, 63, 149, 45, 17,
                        117, 129, 131, 160, 70, 121, 158, 155,
                        224, 209, 192, 53, 10, 62, 57, 72];
        assert_eq!(results, expected);
    }

    #[test]
    fn test_xorshift_zero_seed() {
        // Xorshift does not work with an all zero seed.
        // Assert it does not panic.
        let seed = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
        let mut rng = XorShiftRng::from_seed(seed);
        let a = rng.next_u64();
        let b = rng.next_u64();
        assert!(a != 0);
        assert!(b != a);
    }

    #[test]
    fn test_xorshift_clone() {
        let seed = [1,2,3,4, 5,5,7,8, 8,7,6,5, 4,3,2,1];
        let mut rng1 = XorShiftRng::from_seed(seed);
        let mut rng2 = rng1.clone();
        for _ in 0..16 {
            assert_eq!(rng1.next_u64(), rng2.next_u64());
        }
    }

    #[cfg(all(feature="serde1", feature="std"))]
    #[test]
    fn test_xorshift_serde() {
        use bincode;
        use std::io::{BufWriter, BufReader};

        let seed = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16];
        let mut rng = XorShiftRng::from_seed(seed);

        let buf: Vec<u8> = Vec::new();
        let mut buf = BufWriter::new(buf);
        bincode::serialize_into(&mut buf, &rng).expect("Could not serialize");

        let buf = buf.into_inner().unwrap();
        let mut read = BufReader::new(&buf[..]);
        let mut deserialized: XorShiftRng = bincode::deserialize_from(&mut read).expect("Could not deserialize");

        assert_eq!(rng.x, deserialized.x);
        assert_eq!(rng.y, deserialized.y);
        assert_eq!(rng.z, deserialized.z);
        assert_eq!(rng.w, deserialized.w);

        for _ in 0..16 {
            assert_eq!(rng.next_u64(), deserialized.next_u64());
        }
    }
}
<|endoftext|>


<commit_before>use std::ffi::{OsString, OsStr};
use std::path::Path;

use core::Source;
use sources::PathSource;
use ops::{self, ExecEngine, ProcessEngine, Compilation};
use util::{self, CargoResult, ProcessError};

pub struct TestOptions<'a, 'b: 'a> {
    pub compile_opts: ops::CompileOptions<'a, 'b>,
    pub no_run: bool,
}

pub fn run_tests(manifest_path: &Path,
                 options: &TestOptions,
                 test_args: &[String]) -> CargoResult<Option<ProcessError>> {
    let config = options.compile_opts.config;
    let compile = match try!(build_and_run(manifest_path, options, test_args)) {
        Ok(compile) => compile,
        Err(e) => return Ok(Some(e)),
    };

    // If a specific test was requested or we're not running any tests at all,
    // don't run any doc tests.
    if let ops::CompileFilter::Only { .. } = options.compile_opts.filter {
        return Ok(None)
    }
    if options.no_run {
        return Ok(None)
    }

    let libs = compile.package.targets().iter()
                      .filter(|t| t.doctested())
                      .map(|t| (t.src_path(), t.name(), t.crate_name()));

    for (lib, name, crate_name) in libs {
        try!(config.shell().status("Doc-tests", name));
        let mut p = try!(compile.rustdoc_process(&compile.package));
        p.arg("--test").arg(lib)
         .arg("--crate-name").arg(&crate_name)
         .arg("-L").arg(&{
             let mut arg = OsString::from("dependency=");
             arg.push(&compile.deps_output);
             arg
         })
         .cwd(compile.package.root());

        if test_args.len() > 0 {
            p.arg("--test-args").arg(&test_args.connect(" "));
        }

        for feat in compile.features.iter() {
            p.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
        }

        for (_, libs) in compile.libraries.iter() {
            for &(ref target, ref lib) in libs.iter() {
                // Note that we can *only* doctest rlib outputs here.  A
                // staticlib output cannot be linked by the compiler (it just
                // doesn't do that). A dylib output, however, can be linked by
                // the compiler, but will always fail. Currently all dylibs are
                // built as "static dylibs" where the standard library is
                // statically linked into the dylib. The doc tests fail,
                // however, for now as they try to link the standard library
                // dynamically as well, causing problems. As a result we only
                // pass `--extern` for rlib deps and skip out on all other
                // artifacts.
                if lib.extension() != Some(OsStr::new("rlib")) &&
                   !target.for_host() {
                    continue
                }
                let mut arg = OsString::from(target.crate_name());
                arg.push("=");
                arg.push(lib);
                p.arg("--extern").arg(&arg);
            }
        }

        try!(config.shell().verbose(|shell| {
            shell.status("Running", p.to_string())
        }));
        match ExecEngine::exec(&mut ProcessEngine, p) {
            Ok(()) => {}
            Err(e) => return Ok(Some(e)),
        }
    }

    Ok(None)
}

pub fn run_benches(manifest_path: &Path,
                   options: &TestOptions,
                   args: &[String]) -> CargoResult<Option<ProcessError>> {
    let mut args = args.to_vec();
    args.push("--bench".to_string());

    Ok(try!(build_and_run(manifest_path, options, &args)).err())
}

fn build_and_run(manifest_path: &Path,
                 options: &TestOptions,
                 test_args: &[String])
                 -> CargoResult<Result<Compilation, ProcessError>> {
    let config = options.compile_opts.config;
    let mut source = try!(PathSource::for_path(&manifest_path.parent().unwrap(),
                                               config));
    try!(source.update());

    let mut compile = try!(ops::compile(manifest_path, &options.compile_opts));
    if options.no_run { return Ok(Ok(compile)) }
    compile.tests.sort();

    let cwd = config.cwd();
    for &(_, ref exe) in &compile.tests {
        let to_display = match util::without_prefix(exe, &cwd) {
            Some(path) => path,
            None => &**exe,
        };
        let mut cmd = try!(compile.target_process(exe, &compile.package));
        cmd.args(test_args);
        try!(config.shell().concise(|shell| {
            shell.status("Running", to_display.display().to_string())
        }));
        try!(config.shell().verbose(|shell| {
            shell.status("Running", cmd.to_string())
        }));
        match ExecEngine::exec(&mut ProcessEngine, cmd) {
            Ok(()) => {}
            Err(e) => return Ok(Err(e))
        }
    }

    Ok(Ok(compile))
}
<commit_msg>Add native dependencies to doctest<commit_after>use std::ffi::{OsString, OsStr};
use std::path::Path;

use core::Source;
use sources::PathSource;
use ops::{self, ExecEngine, ProcessEngine, Compilation};
use util::{self, CargoResult, ProcessError};

pub struct TestOptions<'a, 'b: 'a> {
    pub compile_opts: ops::CompileOptions<'a, 'b>,
    pub no_run: bool,
}

pub fn run_tests(manifest_path: &Path,
                 options: &TestOptions,
                 test_args: &[String]) -> CargoResult<Option<ProcessError>> {
    let config = options.compile_opts.config;
    let compile = match try!(build_and_run(manifest_path, options, test_args)) {
        Ok(compile) => compile,
        Err(e) => return Ok(Some(e)),
    };

    // If a specific test was requested or we're not running any tests at all,
    // don't run any doc tests.
    if let ops::CompileFilter::Only { .. } = options.compile_opts.filter {
        return Ok(None)
    }
    if options.no_run {
        return Ok(None)
    }

    let libs = compile.package.targets().iter()
                      .filter(|t| t.doctested())
                      .map(|t| (t.src_path(), t.name(), t.crate_name()));

    for (lib, name, crate_name) in libs {
        try!(config.shell().status("Doc-tests", name));
        let mut p = try!(compile.rustdoc_process(&compile.package));
        p.arg("--test").arg(lib)
         .arg("--crate-name").arg(&crate_name)
         .arg("-L").arg(&{
             let mut arg = OsString::from("dependency=");
             arg.push(&compile.deps_output);
             arg
         })
         .cwd(compile.package.root());

        for native_dep in compile.native_dirs.values() {
            p.arg("-L").arg(native_dep);
        }

        if test_args.len() > 0 {
            p.arg("--test-args").arg(&test_args.connect(" "));
        }

        for feat in compile.features.iter() {
            p.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
        }

        for (_, libs) in compile.libraries.iter() {
            for &(ref target, ref lib) in libs.iter() {
                // Note that we can *only* doctest rlib outputs here.  A
                // staticlib output cannot be linked by the compiler (it just
                // doesn't do that). A dylib output, however, can be linked by
                // the compiler, but will always fail. Currently all dylibs are
                // built as "static dylibs" where the standard library is
                // statically linked into the dylib. The doc tests fail,
                // however, for now as they try to link the standard library
                // dynamically as well, causing problems. As a result we only
                // pass `--extern` for rlib deps and skip out on all other
                // artifacts.
                if lib.extension() != Some(OsStr::new("rlib")) &&
                   !target.for_host() {
                    continue
                }
                let mut arg = OsString::from(target.crate_name());
                arg.push("=");
                arg.push(lib);
                p.arg("--extern").arg(&arg);
            }
        }

        try!(config.shell().verbose(|shell| {
            shell.status("Running", p.to_string())
        }));
        match ExecEngine::exec(&mut ProcessEngine, p) {
            Ok(()) => {}
            Err(e) => return Ok(Some(e)),
        }
    }

    Ok(None)
}

pub fn run_benches(manifest_path: &Path,
                   options: &TestOptions,
                   args: &[String]) -> CargoResult<Option<ProcessError>> {
    let mut args = args.to_vec();
    args.push("--bench".to_string());

    Ok(try!(build_and_run(manifest_path, options, &args)).err())
}

fn build_and_run(manifest_path: &Path,
                 options: &TestOptions,
                 test_args: &[String])
                 -> CargoResult<Result<Compilation, ProcessError>> {
    let config = options.compile_opts.config;
    let mut source = try!(PathSource::for_path(&manifest_path.parent().unwrap(),
                                               config));
    try!(source.update());

    let mut compile = try!(ops::compile(manifest_path, &options.compile_opts));
    if options.no_run { return Ok(Ok(compile)) }
    compile.tests.sort();

    let cwd = config.cwd();
    for &(_, ref exe) in &compile.tests {
        let to_display = match util::without_prefix(exe, &cwd) {
            Some(path) => path,
            None => &**exe,
        };
        let mut cmd = try!(compile.target_process(exe, &compile.package));
        cmd.args(test_args);
        try!(config.shell().concise(|shell| {
            shell.status("Running", to_display.display().to_string())
        }));
        try!(config.shell().verbose(|shell| {
            shell.status("Running", cmd.to_string())
        }));
        match ExecEngine::exec(&mut ProcessEngine, cmd) {
            Ok(()) => {}
            Err(e) => return Ok(Err(e))
        }
    }

    Ok(Ok(compile))
}
<|endoftext|>


<commit_before>//! The Ref object is a helper over the link functionality, so one is able to create references to
//! files outside of the imag store.

use std::path::PathBuf;
use std::ops::Deref;
use std::ops::DerefMut;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use toml::Value;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

use error::RefErrorKind as REK;
use flags::RefFlags;
use result::Result;
use module_path::ModuleEntryPath;

pub struct Ref<'a>(FileLockEntry<'a>);

impl<'a> Ref<'a> {

    /// Try to get `si` as Ref object from the store
    pub fn get(store: &'a Store, si: StoreId) -> Result<Ref<'a>> {
        match store.get(si) {
            Err(e) => return Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
            Ok(None) => return Err(REK::RefNotInStore.into_error()),
            Ok(Some(fle)) => Ref::read_reference(&fle).map(|_| Ref(fle)),
        }
    }

    fn read_reference(fle: &FileLockEntry<'a>) -> Result<PathBuf> {
        match fle.get_header().read("ref.reference") {
            Ok(Some(Value::String(s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Create a Ref object which refers to `pb`
    pub fn create(store: &'a Store, pb: PathBuf, flags: RefFlags) -> Result<Ref<'a>> {
        if !pb.exists() {
            return Err(REK::RefTargetDoesNotExist.into_error());
        }
        if flags.get_content_hashing() && pb.is_dir() {
            return Err(REK::RefTargetCannotBeHashed.into_error());
        }

        let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
            try!(File::open(pb.clone())
                .map_err(Box::new)
                .map_err(|e| REK::RefTargetFileCannotBeOpened.into_error_with_cause(e))

                // If we were able to open this file,
                // we hash the contents of the file and return (file, hash)
                .and_then(|mut file| {
                    let opt_contenthash = if flags.get_content_hashing() {
                        Some(hash_file_contents(&mut file))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash))
                })

                // and then we get the permissions if we have to
                // and return (file, content hash, permissions)
                .and_then(|(file, opt_contenthash)| {
                    let opt_permissions = if flags.get_permission_tracking() {
                        Some(try!(file
                                  .metadata()
                                  .map(|md| md.permissions())
                                  .map_err(Box::new)
                                  .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
                        ))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash, opt_permissions))
                })

                // and then we try to canonicalize the PathBuf, because we want to store a
                // canonicalized path
                // and return (file, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_contenthash, opt_permissions)| {
                    pb.canonicalize()
                        .map(|can| (file, opt_contenthash, opt_permissions, can))
                        // if PathBuf::canonicalize() failed, build an error from the return value
                        .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(Box::new(e)))
                })

                // and then we hash the canonicalized path
                // and return (file, content hash, permissions, canonicalized path, path hash)
                .and_then(|(file, opt_contenthash, opt_permissions, can)| {
                    let path_hash = try!(Ref::hash_path(&can)
                        .map_err(Box::new)
                        .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
                    );

                    Ok((file, opt_contenthash, opt_permissions, can, path_hash))
                })

                // and then we convert the PathBuf of the canonicalized path to a String to be able
                // to save it in the Ref FileLockEntry obj
                // and return
                // (file, content hash, permissions, canonicalized path as String, path hash)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    match can.to_str().map(String::from) {
                        // UTF convert error in PathBuf::to_str(),
                        None      => Err(REK::PathUTF8Error.into_error()),
                        Some(can) => Ok((file, opt_conhash, opt_perm, can, path_hash))
                    }
                })

                // and then we create the FileLockEntry in the Store
                // and return (filelockentry, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    let fle = try!(store
                                   .create(ModuleEntryPath::new(path_hash))
                                   .map_err(Box::new)
                                   .map_err(|e| REK::StoreWriteError.into_error_with_cause(e))
                    );

                    Ok((fle, opt_conhash, opt_perm, can))
                })
            )
        };

        for tpl in [
                Some(("ref",             Value::Table(BTreeMap::new()))),
                Some(("ref.permissions", Value::Table(BTreeMap::new()))),

                Some(("ref.path", Value::String(canonical_path))),

                content_hash.map(|h| ("ref.content_hash", Value::String(h))),
                permissions.map(|p| ("ref.permissions.ro", Value::Boolean(p.readonly()))),
            ].into_iter()
        {
            match tpl {
                &Some((ref s, ref v)) => {
                    match fle.get_header_mut().insert(s, v.clone()) {
                        Ok(false) => {
                            let e = REK::HeaderFieldAlreadyExistsError.into_error();
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        Err(e) => {
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        _ => (),
                    }
                }
                &None => {
                    debug!("Not going to insert.");
                }
            }
        }

        Ok(Ref(fle))
    }

    /// Creates a Hash from a PathBuf by making the PathBuf absolute and then running a hash
    /// algorithm on it
    fn hash_path(pb: &PathBuf) -> Result<String> {
        use std::io::Read;
        use crypto::sha1::Sha1;
        use crypto::digest::Digest;

        match pb.to_str() {
            Some(s) => {
                let mut hasher = Sha1::new();
                hasher.input_str(s);
                Ok(hasher.result_str())
            },
            None => return Err(REK::PathUTF8Error.into_error()),
        }
    }

    /// check whether the pointer the Ref represents still points to a file which exists
    pub fn fs_link_exists(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.exists())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_file()`
    pub fn is_ref_to_file(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_file())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_dir()`
    pub fn is_ref_to_dir(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_dir())
    }

    /// Alias for `!Ref::fs_link_exists()`
    pub fn is_dangling(&self) -> Result<bool> {
        self.fs_link_exists().map(|b| !b)
    }

    /// check whether the pointer the Ref represents is valid
    /// This includes:
    ///     - Hashsum of the file is still the same as stored in the Ref
    ///     - file permissions are still valid
    pub fn fs_link_valid(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the file permissions of the referenced file are equal to the stored
    /// permissions
    pub fn fs_link_valid_permissions(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the Hashsum of the referenced file is equal to the stored hashsum
    pub fn fs_link_valid_hash(&self) -> Result<bool> {
        let stored_hash = try!(match self.0.get_header().read("ref.content_hash") {
            // content hash stored...
            Ok(Some(Value::String(s))) => Ok(s),

            // content hash header field has wrong type
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),

            // content hash not stored
            Ok(None) => Err(REK::HeaderFieldMissingError.into_error()),

            // Error
            Err(e) => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        });

        let current_hash = try!(self.fs_file()
            .and_then(|pb| {
                File::open(pb)
                    .map_err(Box::new)
                    .map_err(|e| REK::IOError.into_error_with_cause(e))
            })
            .map(|mut file| hash_file_contents(&mut file))
        );

        Ok(stored_hash == current_hash)
    }

    /// Update the Ref by re-checking the file from FS
    /// This errors if the file is not present or cannot be read()
    pub fn update_ref(&mut self) -> Result<()> {
        unimplemented!()
    }

    /// Get the path of the file which is reffered to by this Ref
    pub fn fs_file(&self) -> Result<PathBuf> {
        match self.0.get_header().read("ref.path") {
            Ok(Some(Value::String(ref s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Check whether there is a reference to the file at `pb`
    pub fn exists(store: &Store, pb: PathBuf) -> Result<bool> {
        unimplemented!()
    }

    /// Re-find a referenced file
    ///
    /// This function tries to re-find a ref by searching all directories in `search_roots` recursively
    /// for a file which matches the hash of the Ref `ref`.
    ///
    /// If `search_roots` is `None`, it starts at the filesystem root `/`.
    ///
    /// # Warning
    ///
    /// This option causes heavy I/O as it recursively searches the Filesystem.
    pub fn refind(&self, search_roots: Option<Vec<PathBuf>>) -> Option<PathBuf> {
        unimplemented!()
    }

}

impl<'a> Deref for Ref<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Ref<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

fn hash_file_contents(f: &mut File) -> String {
    let mut hasher = Sha1::new();
    let mut s = String::new();
    f.read_to_string(&mut s);
    hasher.input_str(&s[..]);
    hasher.result_str()
}

<commit_msg>Impl Ref::exists()<commit_after>//! The Ref object is a helper over the link functionality, so one is able to create references to
//! files outside of the imag store.

use std::path::PathBuf;
use std::ops::Deref;
use std::ops::DerefMut;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use toml::Value;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

use error::RefErrorKind as REK;
use flags::RefFlags;
use result::Result;
use module_path::ModuleEntryPath;

pub struct Ref<'a>(FileLockEntry<'a>);

impl<'a> Ref<'a> {

    /// Try to get `si` as Ref object from the store
    pub fn get(store: &'a Store, si: StoreId) -> Result<Ref<'a>> {
        match store.get(si) {
            Err(e) => return Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
            Ok(None) => return Err(REK::RefNotInStore.into_error()),
            Ok(Some(fle)) => Ref::read_reference(&fle).map(|_| Ref(fle)),
        }
    }

    fn read_reference(fle: &FileLockEntry<'a>) -> Result<PathBuf> {
        match fle.get_header().read("ref.reference") {
            Ok(Some(Value::String(s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Create a Ref object which refers to `pb`
    pub fn create(store: &'a Store, pb: PathBuf, flags: RefFlags) -> Result<Ref<'a>> {
        if !pb.exists() {
            return Err(REK::RefTargetDoesNotExist.into_error());
        }
        if flags.get_content_hashing() && pb.is_dir() {
            return Err(REK::RefTargetCannotBeHashed.into_error());
        }

        let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
            try!(File::open(pb.clone())
                .map_err(Box::new)
                .map_err(|e| REK::RefTargetFileCannotBeOpened.into_error_with_cause(e))

                // If we were able to open this file,
                // we hash the contents of the file and return (file, hash)
                .and_then(|mut file| {
                    let opt_contenthash = if flags.get_content_hashing() {
                        Some(hash_file_contents(&mut file))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash))
                })

                // and then we get the permissions if we have to
                // and return (file, content hash, permissions)
                .and_then(|(file, opt_contenthash)| {
                    let opt_permissions = if flags.get_permission_tracking() {
                        Some(try!(file
                                  .metadata()
                                  .map(|md| md.permissions())
                                  .map_err(Box::new)
                                  .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
                        ))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash, opt_permissions))
                })

                // and then we try to canonicalize the PathBuf, because we want to store a
                // canonicalized path
                // and return (file, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_contenthash, opt_permissions)| {
                    pb.canonicalize()
                        .map(|can| (file, opt_contenthash, opt_permissions, can))
                        // if PathBuf::canonicalize() failed, build an error from the return value
                        .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(Box::new(e)))
                })

                // and then we hash the canonicalized path
                // and return (file, content hash, permissions, canonicalized path, path hash)
                .and_then(|(file, opt_contenthash, opt_permissions, can)| {
                    let path_hash = try!(Ref::hash_path(&can)
                        .map_err(Box::new)
                        .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
                    );

                    Ok((file, opt_contenthash, opt_permissions, can, path_hash))
                })

                // and then we convert the PathBuf of the canonicalized path to a String to be able
                // to save it in the Ref FileLockEntry obj
                // and return
                // (file, content hash, permissions, canonicalized path as String, path hash)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    match can.to_str().map(String::from) {
                        // UTF convert error in PathBuf::to_str(),
                        None      => Err(REK::PathUTF8Error.into_error()),
                        Some(can) => Ok((file, opt_conhash, opt_perm, can, path_hash))
                    }
                })

                // and then we create the FileLockEntry in the Store
                // and return (filelockentry, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    let fle = try!(store
                                   .create(ModuleEntryPath::new(path_hash))
                                   .map_err(Box::new)
                                   .map_err(|e| REK::StoreWriteError.into_error_with_cause(e))
                    );

                    Ok((fle, opt_conhash, opt_perm, can))
                })
            )
        };

        for tpl in [
                Some(("ref",             Value::Table(BTreeMap::new()))),
                Some(("ref.permissions", Value::Table(BTreeMap::new()))),

                Some(("ref.path", Value::String(canonical_path))),

                content_hash.map(|h| ("ref.content_hash", Value::String(h))),
                permissions.map(|p| ("ref.permissions.ro", Value::Boolean(p.readonly()))),
            ].into_iter()
        {
            match tpl {
                &Some((ref s, ref v)) => {
                    match fle.get_header_mut().insert(s, v.clone()) {
                        Ok(false) => {
                            let e = REK::HeaderFieldAlreadyExistsError.into_error();
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        Err(e) => {
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        _ => (),
                    }
                }
                &None => {
                    debug!("Not going to insert.");
                }
            }
        }

        Ok(Ref(fle))
    }

    /// Creates a Hash from a PathBuf by making the PathBuf absolute and then running a hash
    /// algorithm on it
    fn hash_path(pb: &PathBuf) -> Result<String> {
        use std::io::Read;
        use crypto::sha1::Sha1;
        use crypto::digest::Digest;

        match pb.to_str() {
            Some(s) => {
                let mut hasher = Sha1::new();
                hasher.input_str(s);
                Ok(hasher.result_str())
            },
            None => return Err(REK::PathUTF8Error.into_error()),
        }
    }

    /// check whether the pointer the Ref represents still points to a file which exists
    pub fn fs_link_exists(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.exists())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_file()`
    pub fn is_ref_to_file(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_file())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_dir()`
    pub fn is_ref_to_dir(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_dir())
    }

    /// Alias for `!Ref::fs_link_exists()`
    pub fn is_dangling(&self) -> Result<bool> {
        self.fs_link_exists().map(|b| !b)
    }

    /// check whether the pointer the Ref represents is valid
    /// This includes:
    ///     - Hashsum of the file is still the same as stored in the Ref
    ///     - file permissions are still valid
    pub fn fs_link_valid(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the file permissions of the referenced file are equal to the stored
    /// permissions
    pub fn fs_link_valid_permissions(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the Hashsum of the referenced file is equal to the stored hashsum
    pub fn fs_link_valid_hash(&self) -> Result<bool> {
        let stored_hash = try!(match self.0.get_header().read("ref.content_hash") {
            // content hash stored...
            Ok(Some(Value::String(s))) => Ok(s),

            // content hash header field has wrong type
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),

            // content hash not stored
            Ok(None) => Err(REK::HeaderFieldMissingError.into_error()),

            // Error
            Err(e) => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        });

        let current_hash = try!(self.fs_file()
            .and_then(|pb| {
                File::open(pb)
                    .map_err(Box::new)
                    .map_err(|e| REK::IOError.into_error_with_cause(e))
            })
            .map(|mut file| hash_file_contents(&mut file))
        );

        Ok(stored_hash == current_hash)
    }

    /// Update the Ref by re-checking the file from FS
    /// This errors if the file is not present or cannot be read()
    pub fn update_ref(&mut self) -> Result<()> {
        unimplemented!()
    }

    /// Get the path of the file which is reffered to by this Ref
    pub fn fs_file(&self) -> Result<PathBuf> {
        match self.0.get_header().read("ref.path") {
            Ok(Some(Value::String(ref s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Check whether there is a reference to the file at `pb`
    pub fn exists(store: &Store, pb: PathBuf) -> Result<bool> {
        pb.canonicalize()
            .map_err(Box::new)
            .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(e))
            .and_then(|can| {
                Ref::hash_path(&can)
                    .map_err(Box::new)
                    .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
            })
            .and_then(|hash| {
                store.retrieve_for_module("ref").map(|iter| (hash, iter))
                    .map_err(Box::new)
                    .map_err(|e| REK::StoreReadError.into_error_with_cause(e))
            })
            .and_then(|(hash, possible_refs)| {
                // This is kind of a manual Iterator::filter() call what we do here, but with the
                // actual ::filter method we cannot return the error in a nice way, so we do it
                // manually here. If you can come up with a better version of this, feel free to
                // take this note as a todo.
                for r in possible_refs {
                    let contains_hash = match r.to_str() {
                        None => { // couldn't parse StoreId -> PathBuf -> &str
                            // TODO: How to report this?
                            return Err(REK::TypeConversionError.into_error());
                        },
                        Some(s) => s.contains(&hash[..]),
                    };

                    if !contains_hash {
                        continue;
                    }

                    match store.get(r) {
                        Ok(Some(fle)) => {
                            if Ref::read_reference(&fle).map(|path| path == pb).unwrap_or(false) {
                                return Ok(true)
                            }
                        },

                        Ok(None) => { // Something weird just happened
                            return Err(REK::StoreReadError.into_error());
                        },

                        Err(e) => {
                            return Err(REK::StoreReadError.into_error_with_cause(Box::new(e)));
                        },
                    }
                }

                Ok(false)
            })
    }

    /// Re-find a referenced file
    ///
    /// This function tries to re-find a ref by searching all directories in `search_roots` recursively
    /// for a file which matches the hash of the Ref `ref`.
    ///
    /// If `search_roots` is `None`, it starts at the filesystem root `/`.
    ///
    /// # Warning
    ///
    /// This option causes heavy I/O as it recursively searches the Filesystem.
    pub fn refind(&self, search_roots: Option<Vec<PathBuf>>) -> Option<PathBuf> {
        unimplemented!()
    }

}

impl<'a> Deref for Ref<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Ref<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

fn hash_file_contents(f: &mut File) -> String {
    let mut hasher = Sha1::new();
    let mut s = String::new();
    f.read_to_string(&mut s);
    hasher.input_str(&s[..]);
    hasher.result_str()
}

<|endoftext|>


<commit_before>extern crate reqwest;
extern crate csv;
extern crate time;

use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use super::{Airport, LatLon, Type, Runway, RunwayIdentifier, Frequencies};

error_chain! {
    errors {
        FieldNotFound(name: String) {
            description("data field not found")
            display("data field {} not found", name)
        }
    }

    foreign_links {
        Reqwest(reqwest::Error);
        Csv(csv::Error);
        Io(::std::io::Error);
        ParseInt(::std::num::ParseIntError);
        ParseFloat(::std::num::ParseFloatError);
    }
}

const DATA_HOME:        &str = "http://ourairports.com/data";
const AIRPORTS_FILE:    &str = "airports.csv";
const FREQUENCIES_FILE: &str = "airport-frequencies.csv";
const RUNWAYS_FILE:     &str = "runways.csv";

const DOWNLOAD_DATE_FILE: &str = "month-downloaded";

fn download_data_file(client: &reqwest::Client, name: &str) -> Result<Vec<u8>> {
    println!("downloading {}", name);

    let url = format!("{}/{}", DATA_HOME, name);
    let mut request  = client.get(&url)?.send()?;
    let mut csv_data = Vec::new();

    request.read_to_end(&mut csv_data)?;
    Ok(csv_data)
}

trait HashMapExtras<V> {
    fn get_field(&mut self, name: &str) -> Result<V>;
}

impl<V> HashMapExtras<V> for HashMap<String, V> {
    fn get_field(&mut self, name: &str) -> Result<V> {
        match self.remove(name) {
            Some(v) => Ok(v),
            None    => bail!(ErrorKind::FieldNotFound(name.into())),
        }
    }
}

pub struct DataFiles {
    data_dir: PathBuf,
}

impl DataFiles {
    pub fn new(data_path: &Path) -> Result<DataFiles> {
        let mut base_dir = env::current_exe()?;
        base_dir.pop();
        base_dir.push(data_path);

        Ok(DataFiles {
            data_dir: base_dir,
        })
    }

    pub fn ensure_updated_data(&self) -> Result<()> {
        let path = self.get_path_in_data(DOWNLOAD_DATE_FILE);

        if path.exists() {
            let mut file  = File::open(path)?;
            let mut month = String::new();

            file.read_to_string(&mut month)?;

            if time::now_utc().tm_mon != month.parse::<i32>()? {
                self.get_new_data()?;
            }
        } else {
            self.get_new_data()?;
        }

        Ok(())
    }

    fn save_data_to_file(&self, name: &str, data: &[u8]) -> Result<()> {
        let mut path = self.data_dir.clone();
        path.push(name);

        let mut file = File::create(path)?;
        file.write_all(data)?;
        Ok(())
    }

    fn download_and_save_data(&self, client: &reqwest::Client, name: &str) -> Result<()> {
        let data = download_data_file(client, name)?;
        self.save_data_to_file(name, &data)
    }

    fn retrieve_runway_data(&self, client: &reqwest::Client) -> Result<()> {
        // The airport runways file contains an extra comma at the end of the headers
        // that breaks CSV parsing, so we need to remove it before saving the file
        let mut runways = download_data_file(&client, RUNWAYS_FILE)?;
        let comma_pos   = runways.windows(2)
                                 .position(|b| b == &[b',', b'\n']);

        match comma_pos {
            Some(comma_pos) => runways[comma_pos] = b' ',
            None => println!("warning: extra comma no longer exists in {} file", RUNWAYS_FILE),
        }

        self.save_data_to_file(RUNWAYS_FILE, &runways)?;
        Ok(())
    }

    pub fn get_new_data(&self) -> Result<()> {
        match fs::create_dir(&self.data_dir) {
            Ok(_) => (),
            Err(e) => {
                match e.kind() {
                    io::ErrorKind::AlreadyExists => (),
                    _ => bail!(e),
                }
            },
        };

        let client = reqwest::Client::new()?;

        self.download_and_save_data(&client, AIRPORTS_FILE)?;
        self.download_and_save_data(&client, FREQUENCIES_FILE)?;
        self.retrieve_runway_data(&client)?;

        let mut date_file = File::create(
            self.get_path_in_data(DOWNLOAD_DATE_FILE))?;

        write!(date_file, "{}", time::now_utc().tm_mon)?;

        println!("data download complete");
        Ok(())
    }

    pub fn parse(&self) -> Result<Vec<Airport>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(AIRPORTS_FILE))?;

        let mut airports    = Vec::new();
        let mut runways     = self.parse_runways()?;
        let mut frequencies = self.parse_frequencies()?;

        for airport in rdr.deserialize() {
            let mut data: HashMap<String, String> = airport?;

            let icao = data.get_field("ident")?;

            airports.push(Airport {
                icao: icao.clone(),
                pos: LatLon {
                    lat: data.get_field("latitude_deg")?.parse()?,
                    lon: data.get_field("longitude_deg")?.parse()?,
                },
                _type: match Type::parse(&data.get_field("type")?) {
                    Some(t) => t,
                    None    => continue,
                },
                runways:     runways.remove(&icao),
                frequencies: frequencies.remove(&icao),
            });
        }

        Ok(airports)
    }

    fn parse_runways(&self) -> Result<HashMap<String, Vec<Runway>>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(RUNWAYS_FILE))?;

        let mut runways = HashMap::new();

        for runway in rdr.deserialize() {
            let mut data: HashMap<String, String> = runway?;

            let icao = data.get_field("airport_ident")?;
            let runway_list = runways.entry(icao).or_insert(Vec::new());

            runway_list.push(Runway {
                ident: RunwayIdentifier {
                    north: data.get_field("le_ident")?,
                    south: data.get_field("he_ident")?,
                },
                width:  data.get_field("width_ft")?.parse().ok(),
                length: data.get_field("length_ft")?.parse().ok(),
                closed: data.get_field("closed")?.parse::<i32>().ok().map(|val| val == 1),
            });
        }

        Ok(runways)
    }

    fn parse_frequencies(&self) -> Result<HashMap<String, Frequencies>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(FREQUENCIES_FILE))?;

        let mut frequencies = HashMap::new();
        let mut temp_freqs  = HashMap::new();
        let mut last_icao   = String::new();

        for freq_data in rdr.deserialize() {
            let mut data: HashMap<String, String> = freq_data?;
            let icao = data.get_field("airport_ident")?;

            temp_freqs.insert(
                data.get_field("type")?,
                data.get_field("frequency_mhz")?
            );

            if icao != last_icao {
                let app_dep = temp_freqs.remove("A/D");

                frequencies.insert(last_icao.clone(), Frequencies {
                    ground:    temp_freqs.remove("GND"),
                    tower:     temp_freqs.remove("TWR"),
                    departure: app_dep.clone().or(temp_freqs.remove("DEP")),
                    approach:  app_dep.clone().or(temp_freqs.remove("APP")),
                    atis:      temp_freqs.remove("ATIS"),
                });

                last_icao = icao;
                temp_freqs.clear();
            }
        }

        Ok(frequencies)
    }

    fn get_path_in_data(&self, file: &str) -> PathBuf {
        let mut path = self.data_dir.clone();
        path.push(file);

        path
    }
}<commit_msg>Remove duplicate code<commit_after>extern crate reqwest;
extern crate csv;
extern crate time;

use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use super::{Airport, LatLon, Type, Runway, RunwayIdentifier, Frequencies};

error_chain! {
    errors {
        FieldNotFound(name: String) {
            description("data field not found")
            display("data field {} not found", name)
        }
    }

    foreign_links {
        Reqwest(reqwest::Error);
        Csv(csv::Error);
        Io(::std::io::Error);
        ParseInt(::std::num::ParseIntError);
        ParseFloat(::std::num::ParseFloatError);
    }
}

const DATA_HOME:        &str = "http://ourairports.com/data";
const AIRPORTS_FILE:    &str = "airports.csv";
const FREQUENCIES_FILE: &str = "airport-frequencies.csv";
const RUNWAYS_FILE:     &str = "runways.csv";

const DOWNLOAD_DATE_FILE: &str = "month-downloaded";

fn download_data_file(client: &reqwest::Client, name: &str) -> Result<Vec<u8>> {
    println!("downloading {}", name);

    let url = format!("{}/{}", DATA_HOME, name);
    let mut request  = client.get(&url)?.send()?;
    let mut csv_data = Vec::new();

    request.read_to_end(&mut csv_data)?;
    Ok(csv_data)
}

trait HashMapExtras<V> {
    fn get_field(&mut self, name: &str) -> Result<V>;
}

impl<V> HashMapExtras<V> for HashMap<String, V> {
    fn get_field(&mut self, name: &str) -> Result<V> {
        match self.remove(name) {
            Some(v) => Ok(v),
            None    => bail!(ErrorKind::FieldNotFound(name.into())),
        }
    }
}

pub struct DataFiles {
    data_dir: PathBuf,
}

impl DataFiles {
    pub fn new(data_path: &Path) -> Result<DataFiles> {
        let mut base_dir = env::current_exe()?;
        base_dir.pop();
        base_dir.push(data_path);

        Ok(DataFiles {
            data_dir: base_dir,
        })
    }

    pub fn ensure_updated_data(&self) -> Result<()> {
        let path = self.get_path_in_data(DOWNLOAD_DATE_FILE);

        if path.exists() {
            let mut file  = File::open(path)?;
            let mut month = String::new();

            file.read_to_string(&mut month)?;

            if time::now_utc().tm_mon != month.parse::<i32>()? {
                self.get_new_data()?;
            }
        } else {
            self.get_new_data()?;
        }

        Ok(())
    }

    fn save_data_to_file(&self, name: &str, data: &[u8]) -> Result<()> {
        let path = self.get_path_in_data(name);
        let mut file = File::create(path)?;

        file.write_all(data)?;
        Ok(())
    }

    fn download_and_save_data(&self, client: &reqwest::Client, name: &str) -> Result<()> {
        let data = download_data_file(client, name)?;
        self.save_data_to_file(name, &data)
    }

    fn retrieve_runway_data(&self, client: &reqwest::Client) -> Result<()> {
        // The airport runways file contains an extra comma at the end of the headers
        // that breaks CSV parsing, so we need to remove it before saving the file
        let mut runways = download_data_file(&client, RUNWAYS_FILE)?;
        let comma_pos   = runways.windows(2)
                                 .position(|b| b == &[b',', b'\n']);

        match comma_pos {
            Some(comma_pos) => runways[comma_pos] = b' ',
            None => println!("warning: extra comma no longer exists in {} file", RUNWAYS_FILE),
        }

        self.save_data_to_file(RUNWAYS_FILE, &runways)?;
        Ok(())
    }

    pub fn get_new_data(&self) -> Result<()> {
        match fs::create_dir(&self.data_dir) {
            Ok(_) => (),
            Err(e) => {
                match e.kind() {
                    io::ErrorKind::AlreadyExists => (),
                    _ => bail!(e),
                }
            },
        };

        let client = reqwest::Client::new()?;

        self.download_and_save_data(&client, AIRPORTS_FILE)?;
        self.download_and_save_data(&client, FREQUENCIES_FILE)?;
        self.retrieve_runway_data(&client)?;

        let mut date_file = File::create(
            self.get_path_in_data(DOWNLOAD_DATE_FILE))?;

        write!(date_file, "{}", time::now_utc().tm_mon)?;

        println!("data download complete");
        Ok(())
    }

    pub fn parse(&self) -> Result<Vec<Airport>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(AIRPORTS_FILE))?;

        let mut airports    = Vec::new();
        let mut runways     = self.parse_runways()?;
        let mut frequencies = self.parse_frequencies()?;

        for airport in rdr.deserialize() {
            let mut data: HashMap<String, String> = airport?;

            let icao = data.get_field("ident")?;

            airports.push(Airport {
                icao: icao.clone(),
                pos: LatLon {
                    lat: data.get_field("latitude_deg")?.parse()?,
                    lon: data.get_field("longitude_deg")?.parse()?,
                },
                _type: match Type::parse(&data.get_field("type")?) {
                    Some(t) => t,
                    None    => continue,
                },
                runways:     runways.remove(&icao),
                frequencies: frequencies.remove(&icao),
            });
        }

        Ok(airports)
    }

    fn parse_runways(&self) -> Result<HashMap<String, Vec<Runway>>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(RUNWAYS_FILE))?;

        let mut runways = HashMap::new();

        for runway in rdr.deserialize() {
            let mut data: HashMap<String, String> = runway?;

            let icao = data.get_field("airport_ident")?;
            let runway_list = runways.entry(icao).or_insert(Vec::new());

            runway_list.push(Runway {
                ident: RunwayIdentifier {
                    north: data.get_field("le_ident")?,
                    south: data.get_field("he_ident")?,
                },
                width:  data.get_field("width_ft")?.parse().ok(),
                length: data.get_field("length_ft")?.parse().ok(),
                closed: data.get_field("closed")?.parse::<i32>().ok().map(|val| val == 1),
            });
        }

        Ok(runways)
    }

    fn parse_frequencies(&self) -> Result<HashMap<String, Frequencies>> {
        let mut rdr = csv::Reader::from_path(
            self.get_path_in_data(FREQUENCIES_FILE))?;

        let mut frequencies = HashMap::new();
        let mut temp_freqs  = HashMap::new();
        let mut last_icao   = String::new();

        for freq_data in rdr.deserialize() {
            let mut data: HashMap<String, String> = freq_data?;
            let icao = data.get_field("airport_ident")?;

            temp_freqs.insert(
                data.get_field("type")?,
                data.get_field("frequency_mhz")?
            );

            if icao != last_icao {
                let app_dep = temp_freqs.remove("A/D");

                frequencies.insert(last_icao.clone(), Frequencies {
                    ground:    temp_freqs.remove("GND"),
                    tower:     temp_freqs.remove("TWR"),
                    departure: app_dep.clone().or(temp_freqs.remove("DEP")),
                    approach:  app_dep.clone().or(temp_freqs.remove("APP")),
                    atis:      temp_freqs.remove("ATIS"),
                });

                last_icao = icao;
                temp_freqs.clear();
            }
        }

        Ok(frequencies)
    }

    fn get_path_in_data(&self, file: &str) -> PathBuf {
        let mut path = self.data_dir.clone();
        path.push(file);

        path
    }
}<|endoftext|>


<commit_before>extern crate lapin_async as lapin;
extern crate amq_protocol;

use std::net::TcpStream;
use std::{thread,time};

use amq_protocol::types::*;

use lapin::connection::*;
use lapin::buffer::Buffer;
use lapin::generated::basic;

#[test]
fn connection() {
      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();
      stream.set_nonblocking(true);

      let capacity = 8192;
      let mut send_buffer    = Buffer::with_capacity(capacity as usize);
      let mut receive_buffer = Buffer::with_capacity(capacity as usize);

      let mut conn: Connection = Connection::new();
      assert_eq!(conn.connect().unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));
      loop {
        match conn.run(&mut stream, &mut send_buffer, &mut receive_buffer) {
          Err(e) => panic!("could not connect: {:?}", e),
          Ok(ConnectionState::Connected) => break,
          Ok(state) => println!("now at state {:?}, continue", state),
        }
        thread::sleep(time::Duration::from_millis(100));
      }
      println!("CONNECTED");

      //now connected

      let channel_a: u16 = conn.create_channel();
      let channel_b: u16 = conn.create_channel();
      //send channel
      conn.channel_open(channel_a, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //receive channel
      conn.channel_open(channel_b, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //create the hello queue
      conn.queue_declare(channel_a, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      conn.queue_declare(channel_b, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will consume");
      conn.basic_consume(channel_b, 0, "hello-async".to_string(), "my_consumer".to_string(), false, true, false, false, FieldTable::new()).expect("basic_consume");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will publish");
      conn.basic_publish(channel_a, 0, "".to_string(), "hello-async".to_string(), false, false).expect("basic_publish");
      let payload = b"Hello world!";
      conn.send_content_frames(channel_a, 60, payload, basic::Properties::default());
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      let msg = conn.next_message(channel_b, "hello-async", "my_consumer").unwrap();
      println!("received message: {:?}", msg);
      println!("data: {}", std::str::from_utf8(&msg.data).unwrap());

      assert_eq!(msg.data, b"Hello world!");
}
<commit_msg>async: fix connection test when test queue already has data in it<commit_after>extern crate lapin_async as lapin;
extern crate amq_protocol;

use std::net::TcpStream;
use std::{thread,time};

use amq_protocol::types::*;

use lapin::connection::*;
use lapin::buffer::Buffer;
use lapin::generated::basic;

#[test]
fn connection() {
      let mut stream = TcpStream::connect("127.0.0.1:5672").unwrap();
      stream.set_nonblocking(true);

      let capacity = 8192;
      let mut send_buffer    = Buffer::with_capacity(capacity as usize);
      let mut receive_buffer = Buffer::with_capacity(capacity as usize);

      let mut conn: Connection = Connection::new();
      assert_eq!(conn.connect().unwrap(), ConnectionState::Connecting(ConnectingState::SentProtocolHeader));
      loop {
        match conn.run(&mut stream, &mut send_buffer, &mut receive_buffer) {
          Err(e) => panic!("could not connect: {:?}", e),
          Ok(ConnectionState::Connected) => break,
          Ok(state) => println!("now at state {:?}, continue", state),
        }
        thread::sleep(time::Duration::from_millis(100));
      }
      println!("CONNECTED");

      //now connected

      let channel_a: u16 = conn.create_channel();
      let channel_b: u16 = conn.create_channel();
      //send channel
      conn.channel_open(channel_a, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //receive channel
      conn.channel_open(channel_b, "".to_string()).expect("channel_open");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //create the hello queue
      conn.queue_declare(channel_a, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      //purge the hello queue in case it already exists with contents in it
      conn.queue_purge(channel_a, 0, "hello-async".to_string(), false).expect("queue_purge");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      conn.queue_declare(channel_b, 0, "hello-async".to_string(), false, false, false, false, false, FieldTable::new()).expect("queue_declare");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will consume");
      conn.basic_consume(channel_b, 0, "hello-async".to_string(), "my_consumer".to_string(), false, true, false, false, FieldTable::new()).expect("basic_consume");
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());

      println!("will publish");
      conn.basic_publish(channel_a, 0, "".to_string(), "hello-async".to_string(), false, false).expect("basic_publish");
      let payload = b"Hello world!";
      conn.send_content_frames(channel_a, 60, payload, basic::Properties::default());
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      thread::sleep(time::Duration::from_millis(100));
      println!("[{}] state: {:?}", line!(), conn.run(&mut stream, &mut send_buffer, &mut receive_buffer).unwrap());
      let msg = conn.next_message(channel_b, "hello-async", "my_consumer").unwrap();
      println!("received message: {:?}", msg);
      println!("data: {}", std::str::from_utf8(&msg.data).unwrap());

      assert_eq!(msg.data, b"Hello world!");
}
<|endoftext|>