<commit_before>extern crate hyper;
extern crate rustc_serialize;
extern crate time;
extern crate toml;
extern crate ws;

mod ws_handler;

use std::env;
use std::fs::File;
use std::io::Read;
use std::result::Result;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

use rustc_serialize::json;

#[derive(RustcDecodable, Eq, PartialEq, Clone, Debug)]
struct CanaryConfig {
    target: Vec<CanaryTarget>,
    server_listen_address: String
}

#[derive(RustcDecodable, RustcEncodable, Eq, PartialEq, Clone, Debug)]
struct CanaryTarget {
    name: String,
    host: String,
    interval_s: u64
}

#[derive(RustcEncodable, Eq, PartialEq, Clone, Debug)]
pub struct CanaryCheck {
    target: CanaryTarget,
    info: String,
    status_code: String,
    time: String
}

fn main() {
    // Read config
    let config_path = match env::args().nth(1) {
        Some(c) => c,
        None => panic!("no configuration file supplied as the first argument")
    };

    let config = match read_config(&config_path) {
        Ok(c) => c,
        Err(err) => panic!("{} -- Invalid configuration file {}", err, config_path.clone())
    };

    // Start polling
    let (poll_tx, poll_rx) = mpsc::channel();

    for target in config.clone().target {
        let child_poll_tx = poll_tx.clone();

        thread::spawn(move || {
            loop {
                let _ = child_poll_tx.send(check_host(target.clone()));
                thread::sleep(Duration::new(target.interval_s, 0));
            }
        });
    }

    // Start up websocket server
    let me = ws::WebSocket::new(ws_handler::ClientFactory).unwrap();
    let broadcaster = me.broadcaster();

    thread::spawn(move || {
        me.listen(config.server_listen_address.as_str()).unwrap();
    });

    // Broadcast to all clients
    loop {
        let result = poll_rx.recv().unwrap();
        log_result(result.clone());
        println!("{:#?}", result);
        let _ = broadcaster.send(json::encode(&result).unwrap());
    }
}

fn check_host(target: CanaryTarget) -> CanaryCheck {
    let response_raw = hyper::Client::new().get(&target.host).send();
    let time = format!("{}", time::now_utc().rfc3339());

    if let Err(err) = response_raw {
        return CanaryCheck {
            target: target,
            time: time,
            info: format!("failed to poll server: {}", err),
            status_code: "null".to_string()
        }
    }

    // Should never panic on unwrap
    let response = response_raw.unwrap();
    let info = if response.status.is_success() {
        "okay".to_string()
    } else {
        "no idea".to_string()
    };

    CanaryCheck {
        target: target,
        time: format!("{}", time::now_utc().rfc3339()),
        info: info,
        status_code: format!("{}", response.status)
    }
}

fn log_result(result: CanaryCheck) {
    println!("logging! {:?}", result);
}

fn read_config(path: &str) -> Result<CanaryConfig, String> {
    println!("Reading configuration from `{}`", path);

    let mut file = match File::open(&path) {
        Ok(f) => f,
        Err(err) => return Err(format!("Failed to read file {}", err))
    };

    let mut config_toml = String::new();
    if let Err(err) = file.read_to_string(&mut config_toml) {
        return Err(format!("Error reading config: {}", err))
    }

    let parsed_toml = toml::Parser::new(&config_toml).parse().unwrap();
        // .unwrap_or_else(|err| panic!("Error parsing config file: {}", err));

    let config = toml::Value::Table(parsed_toml);
    match toml::decode(config) {
        Some(c) => Ok(c),
        None => Err("Error while deserializing config".to_string())
    }
}

#[cfg(test)]
mod tests {
    use super::{CanaryConfig, CanaryTarget, read_config};

    #[test]
    fn it_reads_and_parses_a_config_file() {
        let expected = CanaryConfig {
            server_listen_address: "127.0.0.1:8099".to_string(),
            target: vec!(
                CanaryTarget {
                    name: "Hello,".to_string(),
                    host: "world!".to_string(),
                    interval_s: 60
                },
                CanaryTarget {
                    name: "Google".to_string(),
                    host: "http://www.google.com".to_string(),
                    interval_s: 5
                },
            )
        };

        let actual = read_config("test/fixtures/config.toml").unwrap();

        assert_eq!(expected, actual);
    }
}<commit_msg>Remove some clone()s<commit_after>extern crate hyper;
extern crate rustc_serialize;
extern crate time;
extern crate toml;
extern crate ws;

mod ws_handler;

use std::env;
use std::fs::File;
use std::io::Read;
use std::result::Result;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

use rustc_serialize::json;

#[derive(RustcDecodable, Eq, PartialEq, Clone, Debug)]
struct CanaryConfig {
    target: Vec<CanaryTarget>,
    server_listen_address: String
}

#[derive(RustcDecodable, RustcEncodable, Eq, PartialEq, Clone, Debug)]
struct CanaryTarget {
    name: String,
    host: String,
    interval_s: u64
}

#[derive(RustcEncodable, Eq, PartialEq, Clone, Debug)]
pub struct CanaryCheck {
    target: CanaryTarget,
    info: String,
    status_code: String,
    time: String
}

fn main() {
    // Read config
    let config_path = match env::args().nth(1) {
        Some(c) => c,
        None => panic!("no configuration file supplied as the first argument")
    };

    let config = match read_config(&config_path) {
        Ok(c) => c,
        Err(err) => panic!("{} -- Invalid configuration file {}", err, config_path.clone())
    };

    // Start polling
    let (poll_tx, poll_rx) = mpsc::channel();

    for target in config.clone().target {
        let child_poll_tx = poll_tx.clone();

        thread::spawn(move || {
            loop {
                let _ = child_poll_tx.send(check_host(&target));
                thread::sleep(Duration::new(target.interval_s, 0));
            }
        });
    }

    // Start up websocket server
    let me = ws::WebSocket::new(ws_handler::ClientFactory).unwrap();
    let broadcaster = me.broadcaster();

    thread::spawn(move || {
        me.listen(config.server_listen_address.as_str()).unwrap();
    });

    // Broadcast to all clients
    loop {
        let result = poll_rx.recv().unwrap();
        log_result(&result);
        println!("{:#?}", result);
        let _ = broadcaster.send(json::encode(&result).unwrap());
    }
}

fn check_host(target: &CanaryTarget) -> CanaryCheck {
    let response_raw = hyper::Client::new().get(&target.host).send();
    let time = format!("{}", time::now_utc().rfc3339());

    if let Err(err) = response_raw {
        return CanaryCheck {
            target: target.clone(),
            time: time,
            info: format!("failed to poll server: {}", err),
            status_code: "null".to_string()
        }
    }

    // Should never panic on unwrap
    let response = response_raw.unwrap();
    let info = if response.status.is_success() {
        "okay".to_string()
    } else {
        "no idea".to_string()
    };

    CanaryCheck {
        target: target.clone(),
        time: format!("{}", time::now_utc().rfc3339()),
        info: info,
        status_code: format!("{}", response.status)
    }
}

fn log_result(result: &CanaryCheck) {
    println!("logging! {:?}", result);
}

fn read_config(path: &str) -> Result<CanaryConfig, String> {
    println!("Reading configuration from `{}`", path);

    let mut file = match File::open(&path) {
        Ok(f) => f,
        Err(err) => return Err(format!("Failed to read file {}", err))
    };

    let mut config_toml = String::new();
    if let Err(err) = file.read_to_string(&mut config_toml) {
        return Err(format!("Error reading config: {}", err))
    }

    let parsed_toml = toml::Parser::new(&config_toml).parse().unwrap();
        // .unwrap_or_else(|err| panic!("Error parsing config file: {}", err));

    let config = toml::Value::Table(parsed_toml);
    match toml::decode(config) {
        Some(c) => Ok(c),
        None => Err("Error while deserializing config".to_string())
    }
}

#[cfg(test)]
mod tests {
    use super::{CanaryConfig, CanaryTarget, read_config};

    #[test]
    fn it_reads_and_parses_a_config_file() {
        let expected = CanaryConfig {
            server_listen_address: "127.0.0.1:8099".to_string(),
            target: vec!(
                CanaryTarget {
                    name: "Hello,".to_string(),
                    host: "world!".to_string(),
                    interval_s: 60
                },
                CanaryTarget {
                    name: "Google".to_string(),
                    host: "http://www.google.com".to_string(),
                    interval_s: 5
                },
            )
        };

        let actual = read_config("test/fixtures/config.toml").unwrap();

        assert_eq!(expected, actual);
    }
}<|endoftext|>


<commit_before>extern crate reqwest;
extern crate rand;
extern crate serde_json;

use std::error::Error;
use std::boxed::Box;
use clap::{ArgMatches, Values};
use std::fmt;
use std::fmt::Display;
use reqwest::header::UserAgent;
use geo::Point;
use geo::haversine_distance::HaversineDistance;
use rand::distributions::{IndependentSample, Range};
use std::f64::consts::PI;

static NOMINATIM_ENDPOINT: &str = "http://nominatim.openstreetmap.org";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = env!("CARGO_PKG_NAME");
const EARTH_RADIUS_KM: f64 = 6373.;

#[derive(Deserialize, Debug)]
struct Location {
    lat: String,
    lon: String,
}

impl Location {
    fn to_point(&self) -> Result<Point<f64>, Box<Error>> {
        to_point((self.lon.as_str(), self.lat.as_str()))
    }
}

impl Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{},{}", self.lon, self.lat)
    }
}

#[derive(Deserialize, Debug)]
struct Place {
    display_name: String,
}

impl Display for Place {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.display_name)
    }
}

fn get_query_string(params: Vec<(&str, &str)>) -> String {
    let pairs: Vec<String> = params
        .into_iter()
        .map(|(k, v)| format!("{}={}", k, v))
        .collect();
    pairs.join("&")
}

fn reverse_geocode(lon: &str, lat: &str) -> Result<Place, Box<Error>> {
    let params = vec![("format", "json"), ("lon", lon), ("lat", lat)];
    let query_string = get_query_string(params);
    let url = format!("{}/reverse?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let result = res.json::<Place>()?;
    Ok(result)
}

fn search(place_name: &str) -> Result<Location, Box<Error>> {
    let params = vec![("format", "jsonv2"), ("q", place_name), ("limit", "1")];
    let query_string = get_query_string(params);
    let url = format!("{}/search?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let mut results = res.json::<Vec<Location>>()?;
    results.reverse();
    let first = results.pop().ok_or("No result found")?;
    Ok(first)
}

fn get_random_point(center: &Point<f64>, radius: f64) -> Point<f64> {
    let mut rng = rand::thread_rng();
    let dist_range = Range::new(0., radius);
    let distance = dist_range.ind_sample(&mut rng);
    let bearing_range = Range::new(0., 360.);
    let bearing = bearing_range.ind_sample(&mut rng);

    direction(center, bearing, distance)
}

#[cfg(test)]
mod get_random_point {
    use super::*;
    use geo::contains::Contains;
    use geo::{LineString, Polygon};
    use std::fs::File;

    #[derive(Deserialize, Debug)]
    struct TestCoordinates(f64, f64);

    #[test]
    fn stays_within_the_given_radius() {
        let file = File::open("test/circle.json").unwrap();
        let coordinates: Vec<TestCoordinates> = serde_json::from_reader(file).unwrap();
        let points: Vec<Point<f64>> = coordinates
            .into_iter()
            .map(|t| Point::new(t.0, t.1))
            .collect();
        let exterior = LineString(points);
        let polygon = Polygon::new(exterior, vec![]);

        let center_point = Point::new(9.177789688110352, 48.776781529534965);
        for _ in 0..1000 {
            let random_point = get_random_point(&center_point, 9.9);
            let contained = polygon.contains(&random_point);
            assert_eq!(contained, true);
        }
    }
}

fn direction(point: &Point<f64>, bearing: f64, distance: f64) -> Point<f64> {
    let deg_to_rad = PI / 180.;
    let rad_to_deg = 180. / PI;
    let center_lng = deg_to_rad * point.x();
    let center_lat = deg_to_rad * point.y();
    let bearing_rad = deg_to_rad * bearing;

    let rad = distance / EARTH_RADIUS_KM;

    let lat = {
            center_lat.sin() * rad.cos() + center_lat.cos() * rad.sin() * bearing_rad.cos()
        }
        .asin();
    let lng = {
            bearing_rad.sin() * rad.sin() * center_lat.cos()
        }
        .atan2(rad.cos() - center_lat.sin() * lat.sin()) + center_lng;

    Point::new(lng * rad_to_deg, lat * rad_to_deg)
}

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

    #[test]
    fn returns_a_new_point() {
        let point_1 = Point::new(9.177789688110352, 48.776781529534965);
        let point_2 = direction(&point_1, 45., 10.);
        assert_eq!(point_2, Point::new(9.274379723017008, 48.840312896632746));
    }
}

fn get_arg_value<'a>(matches: &'a ArgMatches, key: &str) -> Result<&'a str, Box<Error>> {
    matches
        .value_of(key)
        .ok_or(From::from(format!("Could not parse {} argument", key)))
}

fn get_arg_values<'a>(matches: &'a ArgMatches, key: &str) -> Result<Values<'a>, Box<Error>> {
    let values = matches
        .values_of(key)
        .ok_or(format!("Could not parse {} argument", key))?;
    Ok(values)
}

fn parse_loc_string(mut loc: Values) -> Result<(&str, &str), Box<Error>> {
    let lon = loc.next().ok_or("Could not parse longitude")?;
    let lat = loc.next().ok_or("Could not parse latitute")?;
    Ok((lon, lat))
}

fn to_point(loc: (&str, &str)) -> Result<Point<f64>, Box<Error>> {
    let (lon, lat) = loc;
    let lon_f = lon.parse::<f64>()?;
    let lat_f = lat.parse::<f64>()?;
    Ok(Point::new(lon_f, lat_f))
}

fn parse_point(matches: &ArgMatches, key: &str) -> Result<Point<f64>, Box<Error>> {
    get_arg_values(matches, key)
        .and_then(parse_loc_string)
        .and_then(to_point)
}

fn parse_float(matches: &ArgMatches, key: &str) -> Result<f64, Box<Error>> {
    let rad_str = get_arg_value(matches, key)?;
    let rad = rad_str.parse::<f64>()?;
    Ok(rad)
}

pub fn handle_rev(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let (lon, lat) = get_arg_values(matches, "location")
        .and_then(parse_loc_string)?;
    reverse_geocode(lon, lat).map(|place| format!("{}", place))
}

pub fn handle_dis(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let point_1 = parse_point(matches, "location1")?;
    let point_2 = parse_point(matches, "location2")?;
    let dist = point_1.haversine_distance(&point_2);
    Ok(format!("{:.0}", dist))
}

pub fn handle_rnd(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let center_point = match matches.value_of("place") {
        Some(place) => search(place).and_then(|loc| loc.to_point()),
        None => parse_point(matches, "location"),
    }?;
    let rad = parse_float(matches, "radius")?;
    let random_point = get_random_point(&center_point, rad);
    Ok(format!("{},{}", random_point.x(), random_point.y()))
}

pub fn handle_loc(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let place = get_arg_value(matches, "place")?;
    search(place).map(|result| format!("{}", result))
}
<commit_msg>Replace naive rnd algo with sqrt to offset unequal distribution.<commit_after>extern crate reqwest;
extern crate rand;
extern crate serde_json;

use std::error::Error;
use std::boxed::Box;
use clap::{ArgMatches, Values};
use std::fmt;
use std::fmt::Display;
use reqwest::header::UserAgent;
use geo::Point;
use geo::haversine_distance::HaversineDistance;
use rand::distributions::{IndependentSample, Range};
use num_traits::Float;

static NOMINATIM_ENDPOINT: &str = "http://nominatim.openstreetmap.org";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = env!("CARGO_PKG_NAME");
const EARTH_RADIUS_KM: f64 = 6373.;

#[derive(Deserialize, Debug)]
struct Location {
    lat: String,
    lon: String,
}

impl Location {
    fn to_point(&self) -> Result<Point<f64>, Box<Error>> {
        to_point((self.lon.as_str(), self.lat.as_str()))
    }
}

impl Display for Location {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{},{}", self.lon, self.lat)
    }
}

#[derive(Deserialize, Debug)]
struct Place {
    display_name: String,
}

impl Display for Place {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.display_name)
    }
}

fn get_query_string(params: Vec<(&str, &str)>) -> String {
    let pairs: Vec<String> = params
        .into_iter()
        .map(|(k, v)| format!("{}={}", k, v))
        .collect();
    pairs.join("&")
}

fn reverse_geocode(lon: &str, lat: &str) -> Result<Place, Box<Error>> {
    let params = vec![("format", "json"), ("lon", lon), ("lat", lat)];
    let query_string = get_query_string(params);
    let url = format!("{}/reverse?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let result = res.json::<Place>()?;
    Ok(result)
}

fn search(place_name: &str) -> Result<Location, Box<Error>> {
    let params = vec![("format", "jsonv2"), ("q", place_name), ("limit", "1")];
    let query_string = get_query_string(params);
    let url = format!("{}/search?{}", NOMINATIM_ENDPOINT, query_string);
    let client = reqwest::Client::new()?;
    let mut res = client
        .get(&url)
        .header(UserAgent(format!("{} v{}", NAME, VERSION)))
        .send()?;
    let mut results = res.json::<Vec<Location>>()?;
    results.reverse();
    let first = results.pop().ok_or("No result found")?;
    Ok(first)
}

fn get_random_point(center: &Point<f64>, radius: f64) -> Point<f64> {
    let mut rng = rand::thread_rng();
    let dist_range = Range::new(0., 1.0);
    let rnd_factor = dist_range.ind_sample(&mut rng).sqrt();
    let distance = rnd_factor * radius;
    let bearing_range = Range::new(0., 360.);
    let bearing = bearing_range.ind_sample(&mut rng);

    direction(center, bearing, distance)
}

#[cfg(test)]
mod get_random_point {
    use super::*;
    use geo::contains::Contains;
    use geo::{LineString, Polygon};
    use std::fs::File;

    #[derive(Deserialize, Debug)]
    struct TestCoordinates(f64, f64);

    #[test]
    fn stays_within_the_given_radius() {
        let file = File::open("test/circle.json").unwrap();
        let coordinates: Vec<TestCoordinates> = serde_json::from_reader(file).unwrap();
        let points: Vec<Point<f64>> = coordinates
            .into_iter()
            .map(|t| Point::new(t.0, t.1))
            .collect();
        let exterior = LineString(points);
        let polygon = Polygon::new(exterior, vec![]);

        let center_point = Point::new(9.177789688110352, 48.776781529534965);
        for _ in 0..1000 {
            let random_point = get_random_point(&center_point, 9.9);
            let contained = polygon.contains(&random_point);
            assert_eq!(contained, true);
        }
    }
}

fn direction(point: &Point<f64>, bearing: f64, distance: f64) -> Point<f64> {
    let center_lng = point.x().to_radians();
    let center_lat = point.y().to_radians();
    let bearing_rad = bearing.to_radians();

    let rad = distance / EARTH_RADIUS_KM;

    let lat = {
            center_lat.sin() * rad.cos() + center_lat.cos() * rad.sin() * bearing_rad.cos()
        }
        .asin();
    let lng = {
            bearing_rad.sin() * rad.sin() * center_lat.cos()
        }
        .atan2(rad.cos() - center_lat.sin() * lat.sin()) + center_lng;

    Point::new(lng.to_degrees(), lat.to_degrees())
}

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

    #[test]
    fn returns_a_new_point() {
        let point_1 = Point::new(9.177789688110352, 48.776781529534965);
        let point_2 = direction(&point_1, 45., 10.);
        assert_eq!(point_2, Point::new(9.274379723017008, 48.840312896632746));
    }
}

fn get_arg_value<'a>(matches: &'a ArgMatches, key: &str) -> Result<&'a str, Box<Error>> {
    matches
        .value_of(key)
        .ok_or(From::from(format!("Could not parse {} argument", key)))
}

fn get_arg_values<'a>(matches: &'a ArgMatches, key: &str) -> Result<Values<'a>, Box<Error>> {
    let values = matches
        .values_of(key)
        .ok_or(format!("Could not parse {} argument", key))?;
    Ok(values)
}

fn parse_loc_string(mut loc: Values) -> Result<(&str, &str), Box<Error>> {
    let lon = loc.next().ok_or("Could not parse longitude")?;
    let lat = loc.next().ok_or("Could not parse latitute")?;
    Ok((lon, lat))
}

fn to_point(loc: (&str, &str)) -> Result<Point<f64>, Box<Error>> {
    let (lon, lat) = loc;
    let lon_f = lon.parse::<f64>()?;
    let lat_f = lat.parse::<f64>()?;
    Ok(Point::new(lon_f, lat_f))
}

fn parse_point(matches: &ArgMatches, key: &str) -> Result<Point<f64>, Box<Error>> {
    get_arg_values(matches, key)
        .and_then(parse_loc_string)
        .and_then(to_point)
}

fn parse_float(matches: &ArgMatches, key: &str) -> Result<f64, Box<Error>> {
    let rad_str = get_arg_value(matches, key)?;
    let rad = rad_str.parse::<f64>()?;
    Ok(rad)
}

pub fn handle_rev(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let (lon, lat) = get_arg_values(matches, "location")
        .and_then(parse_loc_string)?;
    reverse_geocode(lon, lat).map(|place| format!("{}", place))
}

pub fn handle_dis(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let point_1 = parse_point(matches, "location1")?;
    let point_2 = parse_point(matches, "location2")?;
    let dist = point_1.haversine_distance(&point_2);
    Ok(format!("{:.0}", dist))
}

pub fn handle_rnd(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let center_point = match matches.value_of("place") {
        Some(place) => search(place).and_then(|loc| loc.to_point()),
        None => parse_point(matches, "location"),
    }?;
    let rad = parse_float(matches, "radius")?;
    let random_point = get_random_point(&center_point, rad);
    Ok(format!("{},{}", random_point.x(), random_point.y()))
}

pub fn handle_loc(matches: &ArgMatches) -> Result<String, Box<Error>> {
    let place = get_arg_value(matches, "place")?;
    search(place).map(|result| format!("{}", result))
}
<|endoftext|>


<commit_before>use super::capi::*;
use std::ptr::null_mut;

pub struct JudyL {
    m: Pvoid_t,
}

impl JudyL {
    pub fn new() -> JudyL {
        JudyL { m: null_mut() }
    }

    pub fn insert(&mut self, index: Word_t, value: Word_t) -> bool {
        unsafe {
            let v = JudyLIns(&mut self.m, index, null_mut());
            if v == null_mut() {
                false
            } else if *v != null_mut() {
                false
            } else {
                *v = value as Pvoid_t;
                true
            }
        }
    }

    pub fn get(&self, index: Word_t) -> Option<Word_t> {
        unsafe {
            let v = JudyLGet(self.m, index, null_mut());
            if v == null_mut() {
                None
            } else {
                Some(*v as Word_t)
            }
        }
    }

    pub fn free(&mut self) -> Word_t {
        if self.m != null_mut() {
            unsafe {
                let ret = JudyLFreeArray(&mut self.m, null_mut());
                assert!(self.m == null_mut());
                ret
            }
        } else {
            0
        }
    }

    pub fn iter<'a>(&'a self) -> JudyLIterator<'a> {
        JudyLIterator { j: self, i: 0 }
    }

    pub fn count(&self, index1: Word_t, index2: Word_t) -> Word_t {
        unsafe { JudyLCount(self.m, index1, index2, null_mut()) }
    }

    pub fn remove(&mut self, index: &Word_t) -> bool {
        1 == unsafe { JudyLDel(&mut self.m, *index, null_mut()) }
    }

    pub fn clear(&mut self) {
        self.free();
    }

    pub fn len(&self) -> usize {
        self.count(0, Word_t::max_value()) as usize
    }

    pub fn is_empty(&self) -> bool {
        self.m == null_mut()
    }
}

pub struct JudyLIterator<'a> {
    j: &'a JudyL,
    i: Word_t,
}

impl<'a> Iterator for JudyLIterator<'a> {
    type Item = (Word_t, Word_t);

    fn next(&mut self) -> Option<(Word_t, Word_t)> {
        unsafe {
            let v = JudyLNext(self.j.m, &mut self.i, null_mut());
            if v == null_mut() {
                None
            } else {
                Some((self.i, *v as Word_t))
            }
        }
    }
}

impl Drop for JudyL {
    fn drop(&mut self) {
        self.free();
    }
}

//impl<V> RandomAccessIterator<(Word_t, V)> for JudyLIterator<V> {
//    type Item = (Word_t, V);
//
//    fn indexable(&self) -> usize {
//        unsafe {
//            JudyLCount(self.m, 0, -1, null_mut()) as usize
//        }
//    }
//
//    fn idx(&self, index: usize) -> Option<(Word_t, V)> {
//        unsafe {
//            // TODO: maybe JudyLByCount would be better here?
//            let v = JudyLGet(self.m, index as Word_t, null_mut());
//            if v == null_mut() {
//                None
//            } else {
//                let vv = *v as *mut V;
//                Some((self.i, transmute_copy(&*vv)))
//
//            }
//        }
//    }
//}
<commit_msg>Add JudyL::insert_bulk_sorted<commit_after>use super::capi::*;
use std::ptr::null_mut;

pub struct JudyL {
    m: Pvoid_t,
}

impl JudyL {
    pub fn new() -> JudyL {
        JudyL { m: null_mut() }
    }

    pub fn insert(&mut self, index: Word_t, value: Word_t) -> bool {
        unsafe {
            let v = JudyLIns(&mut self.m, index, null_mut());
            #[allow(clippy::if_same_then_else)]
            if v == null_mut() {
                false
            } else if *v != null_mut() {
                false
            } else {
                *v = value as Pvoid_t;
                true
            }
        }
    }

    pub fn insert_bulk_sorted(&mut self, count: Word_t, keys: &[Word_t], vals: &[Word_t]) -> bool {
        assert!(keys.len() as u64 >= count && vals.len() as u64 >= count, "insertBulk: Array less than passed count!");
        unsafe {
            let result = JudyLInsArray(&mut self.m, count, keys.as_ptr(), vals.as_ptr(), null_mut());
            result == 0 || result == 1
        }

    }

    pub fn get(&self, index: Word_t) -> Option<Word_t> {
        unsafe {
            let v = JudyLGet(self.m, index, null_mut());
            if v == null_mut() {
                None
            } else {
                Some(*v as Word_t)
            }
        }
    }

    pub fn free(&mut self) -> Word_t {
        if self.m != null_mut() {
            unsafe {
                let ret = JudyLFreeArray(&mut self.m, null_mut());
                assert!(self.m == null_mut());
                ret
            }
        } else {
            0
        }
    }

    pub fn iter<'a>(&'a self) -> JudyLIterator<'a> {
        JudyLIterator { j: self, i: 0 }
    }

    pub fn count(&self, index1: Word_t, index2: Word_t) -> Word_t {
        unsafe { JudyLCount(self.m, index1, index2, null_mut()) }
    }

    pub fn remove(&mut self, index: &Word_t) -> bool {
        1 == unsafe { JudyLDel(&mut self.m, *index, null_mut()) }
    }

    pub fn clear(&mut self) {
        self.free();
    }

    pub fn len(&self) -> usize {
        self.count(0, Word_t::max_value()) as usize
    }

    pub fn is_empty(&self) -> bool {
        self.m == null_mut()
    }
}

pub struct JudyLIterator<'a> {
    j: &'a JudyL,
    i: Word_t,
}

impl<'a> Iterator for JudyLIterator<'a> {
    type Item = (Word_t, Word_t);

    fn next(&mut self) -> Option<(Word_t, Word_t)> {
        unsafe {
            let v = JudyLNext(self.j.m, &mut self.i, null_mut());
            if v == null_mut() {
                None
            } else {
                Some((self.i, *v as Word_t))
            }
        }
    }
}

impl Drop for JudyL {
    fn drop(&mut self) {
        self.free();
    }
}

//impl<V> RandomAccessIterator<(Word_t, V)> for JudyLIterator<V> {
//    type Item = (Word_t, V);
//
//    fn indexable(&self) -> usize {
//        unsafe {
//            JudyLCount(self.m, 0, -1, null_mut()) as usize
//        }
//    }
//
//    fn idx(&self, index: usize) -> Option<(Word_t, V)> {
//        unsafe {
//            // TODO: maybe JudyLByCount would be better here?
//            let v = JudyLGet(self.m, index as Word_t, null_mut());
//            if v == null_mut() {
//                None
//            } else {
//                let vv = *v as *mut V;
//                Some((self.i, transmute_copy(&*vv)))
//
//            }
//        }
//    }
//}
<|endoftext|>


<commit_before>#[allow(dead_code)]
#[path = "../libm/src/math/mod.rs"]
mod libm;

macro_rules! no_mangle {
    ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => {
        intrinsics! {
            $(
                pub extern "C" fn $fun($($iid: $ity),+) -> $oty {
                    self::libm::$fun($($iid),+)
                }
            )+
        }
    }
}

// only for the wasm32-unknown-unknown target
#[cfg(any(all(target_arch = "wasm32", target_os = "unknown"),
          all(target_vendor = "fortanix", target_env = "sgx")))]
no_mangle! {
    fn acos(x: f64) -> f64;
    fn asin(x: f64) -> f64;
    fn atan(x: f64) -> f64;
    fn atan2(x: f64, y: f64) -> f64;
    fn cbrt(x: f64) -> f64;
    fn cosh(x: f64) -> f64;
    fn expm1(x: f64) -> f64;
    fn hypot(x: f64, y: f64) -> f64;
    fn log1p(x: f64) -> f64;
    fn sinh(x: f64) -> f64;
    fn tan(x: f64) -> f64;
    fn tanh(x: f64) -> f64;
    fn cos(x: f64) -> f64;
    fn cosf(x: f32) -> f32;
    fn exp(x: f64) -> f64;
    fn expf(x: f32) -> f32;
    fn log2(x: f64) -> f64;
    fn log2f(x: f32) -> f32;
    fn log10(x: f64) -> f64;
    fn log10f(x: f32) -> f32;
    fn log(x: f64) -> f64;
    fn logf(x: f32) -> f32;
    fn round(x: f64) -> f64;
    fn roundf(x: f32) -> f32;
    fn sin(x: f64) -> f64;
    fn sinf(x: f32) -> f32;
    fn pow(x: f64, y: f64) -> f64;
    fn powf(x: f32, y: f32) -> f32;
    fn exp2(x: f64) -> f64;
    fn exp2f(x: f32) -> f32;
    fn fmod(x: f64, y: f64) -> f64;
    fn fmodf(x: f32, y: f32) -> f32;
    fn fma(x: f64, y: f64, z: f64) -> f64;
    fn fmaf(x: f32, y: f32, z: f32) -> f32;
    fn acosf(n: f32) -> f32;
    fn asinf(n: f32) -> f32;
    fn atan2f(a: f32, b: f32) -> f32;
    fn atanf(n: f32) -> f32;
    fn cbrtf(n: f32) -> f32;
    fn coshf(n: f32) -> f32;
    fn expm1f(n: f32) -> f32;
    fn fdimf(a: f32, b: f32) -> f32;
    fn hypotf(x: f32, y: f32) -> f32;
    fn log1pf(n: f32) -> f32;
    fn sinhf(n: f32) -> f32;
    fn tanf(n: f32) -> f32;
    fn tanhf(n: f32) -> f32;
}

#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
no_mangle! {
    fn ceil(x: f64) -> f64;
    fn ceilf(x: f32) -> f32;
    fn floor(x: f64) -> f64;
    fn floorf(x: f32) -> f32;
    fn trunc(x: f64) -> f64;
    fn truncf(x: f32) -> f32;
}

// only for the thumb*-none-eabi* targets
#[cfg(all(target_arch = "arm", target_os = "none"))]
no_mangle! {
    // `f64 % f64`
    fn fmod(x: f64, y: f64) -> f64;
    // `f32 % f32`
    fn fmodf(x: f32, y: f32) -> f32;
}
<commit_msg>Don't compile math symbols on wasm32-unknown-wasi<commit_after>#[allow(dead_code)]
#[path = "../libm/src/math/mod.rs"]
mod libm;

macro_rules! no_mangle {
    ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => {
        intrinsics! {
            $(
                pub extern "C" fn $fun($($iid: $ity),+) -> $oty {
                    self::libm::$fun($($iid),+)
                }
            )+
        }
    }
}

#[cfg(any(
    all(
        target_arch = "wasm32",
        target_os = "unknown",
        not(target_env = "wasi")
    ),
    all(target_vendor = "fortanix", target_env = "sgx")
))]
no_mangle! {
    fn acos(x: f64) -> f64;
    fn asin(x: f64) -> f64;
    fn atan(x: f64) -> f64;
    fn atan2(x: f64, y: f64) -> f64;
    fn cbrt(x: f64) -> f64;
    fn cosh(x: f64) -> f64;
    fn expm1(x: f64) -> f64;
    fn hypot(x: f64, y: f64) -> f64;
    fn log1p(x: f64) -> f64;
    fn sinh(x: f64) -> f64;
    fn tan(x: f64) -> f64;
    fn tanh(x: f64) -> f64;
    fn cos(x: f64) -> f64;
    fn cosf(x: f32) -> f32;
    fn exp(x: f64) -> f64;
    fn expf(x: f32) -> f32;
    fn log2(x: f64) -> f64;
    fn log2f(x: f32) -> f32;
    fn log10(x: f64) -> f64;
    fn log10f(x: f32) -> f32;
    fn log(x: f64) -> f64;
    fn logf(x: f32) -> f32;
    fn round(x: f64) -> f64;
    fn roundf(x: f32) -> f32;
    fn sin(x: f64) -> f64;
    fn sinf(x: f32) -> f32;
    fn pow(x: f64, y: f64) -> f64;
    fn powf(x: f32, y: f32) -> f32;
    fn exp2(x: f64) -> f64;
    fn exp2f(x: f32) -> f32;
    fn fmod(x: f64, y: f64) -> f64;
    fn fmodf(x: f32, y: f32) -> f32;
    fn fma(x: f64, y: f64, z: f64) -> f64;
    fn fmaf(x: f32, y: f32, z: f32) -> f32;
    fn acosf(n: f32) -> f32;
    fn asinf(n: f32) -> f32;
    fn atan2f(a: f32, b: f32) -> f32;
    fn atanf(n: f32) -> f32;
    fn cbrtf(n: f32) -> f32;
    fn coshf(n: f32) -> f32;
    fn expm1f(n: f32) -> f32;
    fn fdimf(a: f32, b: f32) -> f32;
    fn hypotf(x: f32, y: f32) -> f32;
    fn log1pf(n: f32) -> f32;
    fn sinhf(n: f32) -> f32;
    fn tanf(n: f32) -> f32;
    fn tanhf(n: f32) -> f32;
}

#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
no_mangle! {
    fn ceil(x: f64) -> f64;
    fn ceilf(x: f32) -> f32;
    fn floor(x: f64) -> f64;
    fn floorf(x: f32) -> f32;
    fn trunc(x: f64) -> f64;
    fn truncf(x: f32) -> f32;
}

// only for the thumb*-none-eabi* targets
#[cfg(all(target_arch = "arm", target_os = "none"))]
no_mangle! {
    // `f64 % f64`
    fn fmod(x: f64, y: f64) -> f64;
    // `f32 % f32`
    fn fmodf(x: f32, y: f32) -> f32;
}
<|endoftext|>


<commit_before>#[feature(globs,phase)];
#[phase(syntax, link)] extern crate log;

extern crate leveldb;
extern crate serialize;

pub mod utils {
  use leveldb::database::Database;
  use leveldb::options::{Options};

  pub fn open_database(name: ~str, create_if_missing: bool) -> Database {
    let mut opts = Options::new();
    opts.create_if_missing(create_if_missing);
    match Database::open(name, opts) {
      Ok(db) => { db },
      Err(_) => { fail!("failed to open database") }
    }
  }
}

#[cfg(test)]
mod binary_tests {
  use super::utils::{open_database};
  use leveldb::database::Database;
  use leveldb::database::binary::Interface;
  use leveldb::iterator::Iterable;
  use leveldb::options::{Options,ReadOptions,WriteOptions};

  fn db_put_simple(database: &mut Database, key: &[u8], val: &[u8]) {
    let write_opts = WriteOptions::new();
    match database.put(write_opts, key, val) {
      Ok(_) => { () },
      Err(_) => { fail!("failed to write to database") }
    }
  }

  #[test]
  fn test_create_options() {
    Options::new();
  }

  #[test]
  fn test_open_database() {
    let mut opts = Options::new();
    opts.create_if_missing(true);
    let res = Database::open(~"testdbs/create_if_missing", opts);
    assert!(res.is_ok());
  }

  #[test]
  fn test_open_non_existant_database_without_create() {
    let mut opts = Options::new();
    opts.create_if_missing(false);
    let res = Database::open(~"testdbs/missing", opts);
    assert!(res.is_err());
  }

  #[test]
  fn test_write_to_database() {
    let mut database = open_database(~"testdbs/put_simple", true);
    let write_opts = WriteOptions::new();
    let result = database.put(write_opts,
                              &[1],
                              &[1]);
    assert!(result.is_ok());
  }

  #[test]
  fn test_delete_from_database() {
    let mut database = open_database(~"testdbs/delete_simple", true);
    db_put_simple(&mut database, &[1], &[1]);

    let write2 = WriteOptions::new();
    let res2 = database.delete(write2,
                               &[1]);
    assert!(res2.is_ok());
  }

  #[test]
  fn test_get_from_empty_database() {
    let mut database = open_database(~"testdbs/get_simple", true);
    let read_opts = ReadOptions::new();
    let res = database.get(read_opts, [1,2,3]);
    match res {
      Ok(data) => { assert!(data.is_none()) },
      Err(_) => { fail!("failed reading data") }
    }
  }

  #[test]
  fn test_get_from_filled_database() {
    let mut database = open_database(~"testdbs/get_filled", true);
    db_put_simple(&mut database, &[1], &[1]);

    let read_opts = ReadOptions::new();
    let res = database.get(read_opts,
                            &[1]);
    match res {
      Ok(data) => {
        assert!(data.is_some())
        let data = data.unwrap();
        assert_eq!(data, ~[1]);
      },
      Err(_) => { fail!("failed reading data") }
    }
  }

  #[test]
  fn test_iterator() {
    let mut database = open_database(~"testdbs/iter", true);
    db_put_simple(&mut database, &[1], &[1]);
    db_put_simple(&mut database, &[2], &[2]);

    let read_opts = ReadOptions::new();
    let mut iter = database.iter(read_opts);
    assert!(iter.valid());
    assert!(iter.next().is_some());
    assert!(iter.next().is_some());
    assert!(iter.next().is_none());
  }
}

#[cfg(test)]
mod json_tests {
  use super::utils::{open_database};
  use leveldb::database::json::Interface;
  use leveldb::options::{ReadOptions,WriteOptions};
  use serialize::{Encodable,Decodable};
  use serialize::json;

  #[deriving(Encodable,Decodable)]
  struct ToEncode {
    test: ~str,
  }

  #[test]
  fn test_write_to_database() {
    let mut database = open_database(~"testdbs/json_put", true);
    let write_opts = WriteOptions::new();
    let key = ToEncode { test: ~"string" };
    let val = ToEncode { test: ~"string2" };
    let result = database.put(write_opts,
                              &key,
                              &val);
    assert!(result.is_ok());
  }

  #[test]
  fn test_read_from_database() {
    let mut database = open_database(~"testdbs/json_read", true);
    let write_opts = WriteOptions::new();
    let key = ToEncode { test: ~"string" };
    let val = ToEncode { test: ~"string2" };
    let result = database.put(write_opts,
                              &key,
                              &val);
    assert!(result.is_ok());
    let read_opts = ReadOptions::new();
    let read = database.get(read_opts,
                            &key);
    match read {
      Ok(data) => {
        assert!(data.is_some())
        let data = data.unwrap();
        assert!(data.is_object());
        let mut decoder = json::Decoder::new(data);
        let decoded_object: ToEncode = Decodable::decode(&mut decoder);
        assert_eq!(decoded_object.test, ~"string2" );
      },
      Err(_) => { fail!("failed reading data") }
    }
  }

}
<commit_msg>Fix tests for newest rust<commit_after>#![feature(globs,phase)]
#![phase(syntax, link)] extern crate log;

extern crate leveldb;
extern crate serialize;

pub mod utils {
  use leveldb::database::Database;
  use leveldb::options::{Options};

  pub fn open_database(name: ~str, create_if_missing: bool) -> Database {
    let mut opts = Options::new();
    opts.create_if_missing(create_if_missing);
    match Database::open(name, opts) {
      Ok(db) => { db },
      Err(_) => { fail!("failed to open database") }
    }
  }
}

#[cfg(test)]
mod binary_tests {
  use super::utils::{open_database};
  use leveldb::database::Database;
  use leveldb::database::binary::Interface;
  use leveldb::iterator::Iterable;
  use leveldb::options::{Options,ReadOptions,WriteOptions};

  fn db_put_simple(database: &mut Database, key: &[u8], val: &[u8]) {
    let write_opts = WriteOptions::new();
    match database.put(write_opts, key, val) {
      Ok(_) => { () },
      Err(_) => { fail!("failed to write to database") }
    }
  }

  #[test]
  fn test_create_options() {
    Options::new();
  }

  #[test]
  fn test_open_database() {
    let mut opts = Options::new();
    opts.create_if_missing(true);
    let res = Database::open(~"testdbs/create_if_missing", opts);
    assert!(res.is_ok());
  }

  #[test]
  fn test_open_non_existant_database_without_create() {
    let mut opts = Options::new();
    opts.create_if_missing(false);
    let res = Database::open(~"testdbs/missing", opts);
    assert!(res.is_err());
  }

  #[test]
  fn test_write_to_database() {
    let mut database = open_database(~"testdbs/put_simple", true);
    let write_opts = WriteOptions::new();
    let result = database.put(write_opts,
                              &[1],
                              &[1]);
    assert!(result.is_ok());
  }

  #[test]
  fn test_delete_from_database() {
    let mut database = open_database(~"testdbs/delete_simple", true);
    db_put_simple(&mut database, &[1], &[1]);

    let write2 = WriteOptions::new();
    let res2 = database.delete(write2,
                               &[1]);
    assert!(res2.is_ok());
  }

  #[test]
  fn test_get_from_empty_database() {
    let mut database = open_database(~"testdbs/get_simple", true);
    let read_opts = ReadOptions::new();
    let res = database.get(read_opts, [1,2,3]);
    match res {
      Ok(data) => { assert!(data.is_none()) },
      Err(_) => { fail!("failed reading data") }
    }
  }

  #[test]
  fn test_get_from_filled_database() {
    let mut database = open_database(~"testdbs/get_filled", true);
    db_put_simple(&mut database, &[1], &[1]);

    let read_opts = ReadOptions::new();
    let res = database.get(read_opts,
                            &[1]);
    match res {
      Ok(data) => {
        assert!(data.is_some())
        let data = data.unwrap();
        assert_eq!(data, ~[1]);
      },
      Err(_) => { fail!("failed reading data") }
    }
  }

  #[test]
  fn test_iterator() {
    let mut database = open_database(~"testdbs/iter", true);
    db_put_simple(&mut database, &[1], &[1]);
    db_put_simple(&mut database, &[2], &[2]);

    let read_opts = ReadOptions::new();
    let mut iter = database.iter(read_opts);
    assert!(iter.valid());
    assert!(iter.next().is_some());
    assert!(iter.next().is_some());
    assert!(iter.next().is_none());
  }
}

#[cfg(test)]
mod json_tests {
  use super::utils::{open_database};
  use leveldb::database::json::Interface;
  use leveldb::options::{ReadOptions,WriteOptions};
  use serialize::{Encodable,Decodable};
  use serialize::json;

  #[deriving(Encodable,Decodable)]
  struct ToEncode {
    test: ~str,
  }

  #[test]
  fn test_write_to_database() {
    let mut database = open_database(~"testdbs/json_put", true);
    let write_opts = WriteOptions::new();
    let key = ToEncode { test: ~"string" };
    let val = ToEncode { test: ~"string2" };
    let result = database.put(write_opts,
                              &key,
                              &val);
    assert!(result.is_ok());
  }

  #[test]
  fn test_read_from_database() {
    let mut database = open_database(~"testdbs/json_read", true);
    let write_opts = WriteOptions::new();
    let key = ToEncode { test: ~"string" };
    let val = ToEncode { test: ~"string2" };
    let result = database.put(write_opts,
                              &key,
                              &val);
    assert!(result.is_ok());
    let read_opts = ReadOptions::new();
    let read = database.get(read_opts,
                            &key);
    match read {
      Ok(data) => {
        assert!(data.is_some())
        let data = data.unwrap();
        assert!(data.is_object());
        let mut decoder = json::Decoder::new(data);
        let decoded_object: Result<ToEncode,json::Error> = Decodable::decode(&mut decoder);
        assert!(decoded_object.is_ok())
        assert_eq!(decoded_object.unwrap().test, ~"string2" );
      },
      Err(_) => { fail!("failed reading data") }
    }
  }

}
<|endoftext|>


<commit_before>use instr::Instr;
use cpu::Cpu;
use cpu::CpuInterrupt;
use time::precise_time_ns;
use std::fs::File;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

use glium::DisplayBuild;
use glium::Surface;
use glium::SwapBuffersError;
use glium::glutin::Api;
use glium::glutin::GlRequest;
use glium::glutin::Event;

extern crate time;
extern crate getopts;
#[macro_use]
extern crate glium;
extern crate nalgebra;

mod instr;
mod cpu;
mod mem;
mod render;

#[derive(Copy, Clone)]
pub enum IntType {
    Vblank,
    Hblank,
}

struct ClockInt {
    pub int_target: u64,
    pub int_type: IntType,
}

impl PartialEq for ClockInt {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.int_target == other.int_target
    }
}

impl Eq for ClockInt {}

impl PartialOrd for ClockInt {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.int_target.partial_cmp(&other.int_target) {
            Some(Ordering::Less) => Some(Ordering::Greater),
            Some(Ordering::Greater) => Some(Ordering::Less),
            ord => ord,
        }
    }
}

impl Ord for ClockInt {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        match self.int_target.cmp(&other.int_target) {
            Ordering::Less => Ordering::Greater,
            Ordering::Greater => Ordering::Less,
            ord => ord,
        }
    }
}

const NS_PER_S: u64 = 1_000_000_000;
const MS_PER_NS: u64 = 1_000_000;

// 10ms
const BUSY_WAIT_THRESHOLD: u64 = 10_000_000;

pub struct Clock {
    freq:       u32,
    period:     u64,
    int_heap:   BinaryHeap<ClockInt>,
}

impl Clock {

    pub fn new(freq: u32) -> Clock {
        Clock {
            freq: freq,
            period: NS_PER_S / (freq as u64),
            int_heap: BinaryHeap::new(),
        }
    }

    pub fn set_interrupt(&mut self, itype: IntType, period: u64) {
        let start = precise_time_ns();
        let int = ClockInt {
            int_type: itype,
            int_target: start + period,
        };
        self.int_heap.push(int);
    }

    pub fn wait_cycles(&mut self, n: u32) -> Option<IntType> {
        let start = precise_time_ns();
        let real_wait = self.period * (n as u64);
        let real_target = real_wait + start;
        let (target, result) = if let Some(interrupt) = self.int_heap.pop() {
            if real_target > interrupt.int_target {
                (interrupt.int_target, Some(interrupt.int_type))
            } else {
                self.int_heap.push(interrupt);
                (real_target, None)
            }
        } else {
            (real_target, None)
        };
        let mut curtime = start;
        if target > start && target - start > BUSY_WAIT_THRESHOLD {
            std::thread::sleep_ms(((target - start) * MS_PER_NS) as u32);
            return result;
        } else {
            loop {
                if curtime >= target {
                    return result;
                }
                curtime = precise_time_ns();
            }
        }
    }

}

fn main() {
    //  Gather command line args
    let args: Vec<String> = std::env::args().collect();
    let mut opts = getopts::Options::new();
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(e) => panic!("Error: {}", e),
    };
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        println!("No input ROM");
        return;
    };

    // Build graphics context and window
    let display = glium::glutin::WindowBuilder::new()
        .with_title("Gameboy Rust".to_string())
        .with_gl(GlRequest::Specific(Api::OpenGl, (3, 2)))
        .build_glium()
        .unwrap();

    // Do machine initialization
    let mut cpu = Cpu::new();
    cpu.init();
    {
        let mut ram = cpu.get_ram();
        let mut biosfile = match File::open(std::path::Path::new("rom/bios.bin")) {
            Ok(f) => { f },
            Err(e) => {
                println!("Error opening bios file");
                return;
            },
        };
        let mut romfile = match File::open(std::path::Path::new(&input)) {
            Ok(f) => { f },
            Err(e) => {
                println!("Error opening file: {}", e);
                return;
            }
        };
        if let Err(e) = ram.load_bios(&mut biosfile) {
            println!("Error loading bios data: {}", e);
            return;
        }
        if let Err(e) = ram.load_rom(&mut romfile) {
            println!("Error loading rom data: {}", e);
            return;
        }
    }

    // Initialize virtual LCD
    let mut lcd = render::GbDisplay::new(&display);

    let mut viewport = {
        let window = display.get_window();
        let (width, height) = window.unwrap().get_inner_size_pixels().unwrap();
        render::calculate_viewport(width, height)
    };

    // Initialize virtual hardware clocks
    let mut clock = Clock::new(cpu::GB_FREQUENCY);
    clock.set_interrupt(IntType::Hblank, render::VBLANK_PERIOD);

    // Simulate CPU
    'main: loop {
        // Collect user input
        for ev in display.poll_events() {
            match ev {
                Event::Closed => {
                    break 'main;
                },
                Event::Resized(..) => {
                    let window = display.get_window();
                    let (width, height) = window.unwrap().get_inner_size_pixels().unwrap();
                    viewport = render::calculate_viewport(width, height);
                },
                _ => (),
            }
        }

        // Simulate CPU and hardware timers
        'sim: loop  {
            if let Some(int) = clock.wait_cycles(cpu.do_instr()) {
                // Handle timer interrupt
                match int {
                    // Interrupt at the start of the vblank period
                    IntType::Vblank => {
                        clock.set_interrupt(IntType::Vblank, render::VBLANK_PERIOD);
                        cpu.interrupt(CpuInterrupt::Vblank);
                        let ly = lcd.set_ly_vblank();
                        let ram = cpu.get_ram();
                        ram[mem::IOREG_LY] = ly;
                    }
                    // ~10 H-Blanks occur after the V-Blank starts
                    IntType::Hblank => {
                        clock.set_interrupt(IntType::Hblank, render::HBLANK_PERIOD);
                        let ly = lcd.inc_ly_counter();
                        let ram = cpu.get_ram();
                        ram[mem::IOREG_LY] = ly;
                        // At the end, collect data from VRAM and render it
                        if ly == 0 {
                            break 'sim;
                        }
                    }
                }
            }
        }

        // Redraw screen
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        lcd.clear_viewport(&mut target, viewport, (1.0, 1.0, 1.0, 1.0));
        lcd.draw(&display, &mut target, viewport, cpu.get_ram());
        match target.finish().err() {
            Some(SwapBuffersError::ContextLost) => {
                panic!("OpenGL contetxt lost!");
            },
            Some(SwapBuffersError::AlreadySwapped) => {
                println!("Warning: OpenGL buffer already swapped");
            },
            None => (),
        }
    }
}
<commit_msg>Correctly set up clock interrupts<commit_after>use instr::Instr;
use cpu::Cpu;
use cpu::CpuInterrupt;
use time::precise_time_ns;
use std::fs::File;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

use glium::DisplayBuild;
use glium::Surface;
use glium::SwapBuffersError;
use glium::glutin::Api;
use glium::glutin::GlRequest;
use glium::glutin::Event;

extern crate time;
extern crate getopts;
#[macro_use]
extern crate glium;
extern crate nalgebra;

mod instr;
mod cpu;
mod mem;
mod render;

#[derive(Copy, Clone)]
pub enum IntType {
    Vblank,
    Hblank,
}

struct ClockInt {
    pub int_target: u64,
    pub int_type: IntType,
}

impl PartialEq for ClockInt {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.int_target == other.int_target
    }
}

impl Eq for ClockInt {}

impl PartialOrd for ClockInt {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.int_target.partial_cmp(&other.int_target) {
            Some(Ordering::Less) => Some(Ordering::Greater),
            Some(Ordering::Greater) => Some(Ordering::Less),
            ord => ord,
        }
    }
}

impl Ord for ClockInt {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        match self.int_target.cmp(&other.int_target) {
            Ordering::Less => Ordering::Greater,
            Ordering::Greater => Ordering::Less,
            ord => ord,
        }
    }
}

const NS_PER_S: u64 = 1_000_000_000;
const MS_PER_NS: u64 = 1_000_000;

// 10ms
const BUSY_WAIT_THRESHOLD: u64 = 10_000_000;

pub struct Clock {
    freq:       u32,
    period:     u64,
    int_heap:   BinaryHeap<ClockInt>,
}

impl Clock {

    pub fn new(freq: u32) -> Clock {
        Clock {
            freq: freq,
            period: NS_PER_S / (freq as u64),
            int_heap: BinaryHeap::new(),
        }
    }

    pub fn set_interrupt(&mut self, itype: IntType, period: u64) {
        let start = precise_time_ns();
        let int = ClockInt {
            int_type: itype,
            int_target: start + period,
        };
        self.int_heap.push(int);
    }

    pub fn wait_cycles(&mut self, n: u32) -> Option<IntType> {
        let start = precise_time_ns();
        let real_wait = self.period * (n as u64);
        let real_target = real_wait + start;
        let (target, result) = if let Some(interrupt) = self.int_heap.pop() {
            if real_target > interrupt.int_target {
                (interrupt.int_target, Some(interrupt.int_type))
            } else {
                self.int_heap.push(interrupt);
                (real_target, None)
            }
        } else {
            (real_target, None)
        };
        let mut curtime = start;
        if target > start && target - start > BUSY_WAIT_THRESHOLD {
            std::thread::sleep_ms(((target - start) * MS_PER_NS) as u32);
            return result;
        } else {
            loop {
                if curtime >= target {
                    return result;
                }
                curtime = precise_time_ns();
            }
        }
    }

}

fn main() {
    //  Gather command line args
    let args: Vec<String> = std::env::args().collect();
    let mut opts = getopts::Options::new();
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m },
        Err(e) => panic!("Error: {}", e),
    };
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        println!("No input ROM");
        return;
    };

    // Build graphics context and window
    let display = glium::glutin::WindowBuilder::new()
        .with_title("Gameboy Rust".to_string())
        .with_gl(GlRequest::Specific(Api::OpenGl, (3, 2)))
        .build_glium()
        .unwrap();

    // Do machine initialization
    let mut cpu = Cpu::new();
    cpu.init();
    {
        let mut ram = cpu.get_ram();
        let mut biosfile = match File::open(std::path::Path::new("rom/bios.bin")) {
            Ok(f) => { f },
            Err(e) => {
                println!("Error opening bios file");
                return;
            },
        };
        let mut romfile = match File::open(std::path::Path::new(&input)) {
            Ok(f) => { f },
            Err(e) => {
                println!("Error opening file: {}", e);
                return;
            }
        };
        if let Err(e) = ram.load_bios(&mut biosfile) {
            println!("Error loading bios data: {}", e);
            return;
        }
        if let Err(e) = ram.load_rom(&mut romfile) {
            println!("Error loading rom data: {}", e);
            return;
        }
    }

    // Initialize virtual LCD
    let mut lcd = render::GbDisplay::new(&display);

    let mut viewport = {
        let window = display.get_window();
        let (width, height) = window.unwrap().get_inner_size_pixels().unwrap();
        render::calculate_viewport(width, height)
    };

    // Initialize virtual hardware clocks
    let mut clock = Clock::new(cpu::GB_FREQUENCY);
    clock.set_interrupt(IntType::Vblank, render::VBLANK_PERIOD);
    clock.set_interrupt(IntType::Hblank, render::HBLANK_PERIOD);

    // Simulate CPU
    'main: loop {
        // Collect user input
        for ev in display.poll_events() {
            match ev {
                Event::Closed => {
                    break 'main;
                },
                Event::Resized(..) => {
                    let window = display.get_window();
                    let (width, height) = window.unwrap().get_inner_size_pixels().unwrap();
                    viewport = render::calculate_viewport(width, height);
                },
                _ => (),
            }
        }

        // Simulate CPU and hardware timers
        'sim: loop  {
            if let Some(int) = clock.wait_cycles(cpu.do_instr()) {
                // Handle timer interrupt
                match int {
                    // Interrupt at the start of the vblank period
                    IntType::Vblank => {
                        clock.set_interrupt(IntType::Vblank, render::VBLANK_PERIOD);
                        cpu.interrupt(CpuInterrupt::Vblank);
                        let ly = lcd.set_ly_vblank();
                        let ram = cpu.get_ram();
                        ram[mem::IOREG_LY] = ly;
                    }
                    // ~10 H-Blanks occur after the V-Blank starts
                    IntType::Hblank => {
                        clock.set_interrupt(IntType::Hblank, render::HBLANK_PERIOD);
                        let ly = lcd.inc_ly_counter();
                        let ram = cpu.get_ram();
                        ram[mem::IOREG_LY] = ly;
                        // At the end, collect data from VRAM and render it
                        if ly == 0 {
                            break 'sim;
                        }
                    }
                }
            }
        }

        // Redraw screen
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 1.0);
        lcd.clear_viewport(&mut target, viewport, (1.0, 1.0, 1.0, 1.0));
        lcd.draw(&display, &mut target, viewport, cpu.get_ram());
        match target.finish().err() {
            Some(SwapBuffersError::ContextLost) => {
                panic!("OpenGL contetxt lost!");
            },
            Some(SwapBuffersError::AlreadySwapped) => {
                println!("Warning: OpenGL buffer already swapped");
            },
            None => (),
        }
    }
}
<|endoftext|>


<commit_before>extern crate clap;
use clap::{Arg, App, AppSettings};
use slog::{Logger, LevelFilter, Level, DrainExt};
use yaml_rust::YamlLoader;
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::Yaml;
use model::*;
use std::path::Path;
use std::fs;

#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_stdlog;
extern crate yaml_rust;

#[cfg(test)]
extern crate spectral;

mod model;
mod parser;

fn main() {
  let matches: clap::ArgMatches = create_app().get_matches();
  let stream = slog_term::streamer().full().build();
  let verbose: bool = matches.is_present("verbose");
  let force: bool = matches.is_present("force");
  let log = if verbose {
    slog::Logger::root(stream.fuse(), o!())
  } else {
    slog::Logger::root(LevelFilter::new(stream, Level::Info).fuse(), o!())
  };

  let config_file = matches.value_of("config_file").unwrap();
  info!(log, "Starting engine"; "config_file" => config_file);

  let config = match load_config_file(config_file) {
    Ok(content) => content,
    Err(e) => {
      error!(log, "Failed to load config file."; "error" => format!("{:?}", e));
      panic!(1)
    }
  };

  let yaml_documents = match YamlLoader::load_from_str(&config) {
    Ok(yaml) => yaml,
    Err(e) => {
      error!(log, "Failed to parse config file."; "error" => format!("{:?}", e));
      panic!(2)
    }
  };
  let yaml_config = &yaml_documents[0];
  let dot_files: &Yaml = &yaml_config["files"];
  if dot_files.is_badvalue() {
    warn!(log, "Empty files list");
  }

  info!(log, "Parsed config file. Liftoff!");
  for dot_file in parser::parse_dot_files(&log, dot_files) {
    process_dot_file(&log, dot_file, force);
  }
}

fn process_dot_file(log: &Logger, dot_file: DotFile, force: bool) {
  let log = &log.new(o!("target" => dot_file.target.clone(), "source" => dot_file.source.clone(), "type" => format!("{:?}", dot_file.dot_file_type)));
  info!(log, "Process entry");
  let source_path = Path::new(&dot_file.source);
  let target_path = Path::new(&dot_file.target);
  if !source_path.exists() {
    warn!(log, "Source path does not exist");
    return;
  }
  match already_linked(source_path, target_path) {
    Ok(true) => info!(log, "Link already exists"),
    Ok(false) => {
      if !force && target_path.exists() {
        error!(log, "Target exists but does not point to source")
      } else {
        let result = link_dot_file(source_path, target_path);
        match result {
          Err(e) => error!(log, "Failed to create link"; "error" => format!("{:?}", e)),
          Ok(_) => info!(log, "Link created successfully"),
        }
      }
    }
    Err(e) => error!(log, "Failed to check link existence"; "error" => format!("{:?}", e)),
  }
}

fn already_linked(source: &Path, target: &Path) -> Result<bool, std::io::Error> {
  if target.exists() {
    let canonicalized_target = try!(fs::canonicalize(target));
    let canonicalized_source = try!(fs::canonicalize(source));
    Ok(canonicalized_source == canonicalized_target)
  } else {
    Ok(false)
  }
}

fn link_dot_file(source: &Path, target: &Path) -> Result<(), std::io::Error> {
  if let Some(parent) = target.parent() {
    try!(fs::create_dir_all(parent));
  }
  if target.exists() {
    if target.is_file() {
      try!(fs::remove_file(target))
    } else if target.is_dir() {
      try!(fs::remove_dir_all(target))
    }
  }
  let canonicalized_source = try!(fs::canonicalize(source));
  try!(std::os::unix::fs::symlink(canonicalized_source, target));
  Ok(())
}

fn load_config_file(file: &str) -> Result<String, std::io::Error> {
  let mut file = try!(File::open(file));
  let mut content = String::new();
  try!(file.read_to_string(&mut content));
  return Ok(content);
}

fn create_app<'a>() -> App<'a, 'a> {
  App::new("dotcopter")
    .version("0.1")
    .setting(AppSettings::ColoredHelp)
    .author("Patrick Haun <bomgar85@googlemail.com>")
    .about("manages dotfiles installation")
    .arg(Arg::with_name("force").short("f").long("force").takes_value(false))
    .arg(Arg::with_name("verbose")
           .long("verbose")
           .short("v")
           .help("debug output")
           .required(false)
           .takes_value(false))
    .arg(Arg::with_name("config_file").required(true))
}
<commit_msg>use nicer error messages<commit_after>extern crate clap;
use clap::{Arg, App, AppSettings};
use slog::{Logger, LevelFilter, Level, DrainExt};
use yaml_rust::YamlLoader;
use std::io::prelude::*;
use std::fs::File;
use yaml_rust::Yaml;
use model::*;
use std::path::Path;
use std::fs;
use std::error::Error;

#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_stdlog;
extern crate yaml_rust;

#[cfg(test)]
extern crate spectral;

mod model;
mod parser;

fn main() {
  let matches: clap::ArgMatches = create_app().get_matches();
  let stream = slog_term::streamer().full().build();
  let verbose: bool = matches.is_present("verbose");
  let force: bool = matches.is_present("force");
  let log = if verbose {
    slog::Logger::root(stream.fuse(), o!())
  } else {
    slog::Logger::root(LevelFilter::new(stream, Level::Info).fuse(), o!())
  };

  let config_file = matches.value_of("config_file").unwrap();
  info!(log, "Starting engine"; "config_file" => config_file);

  let config = match load_config_file(config_file) {
    Ok(content) => content,
    Err(e) => {
      error!(log, "Failed to load config file."; "error" => e.description());
      panic!(1)
    }
  };

  let yaml_documents = match YamlLoader::load_from_str(&config) {
    Ok(yaml) => yaml,
    Err(e) => {
      error!(log, "Failed to parse config file."; "error" => e.description());
      panic!(2)
    }
  };
  let yaml_config = &yaml_documents[0];
  let dot_files: &Yaml = &yaml_config["files"];
  if dot_files.is_badvalue() {
    warn!(log, "Empty files list");
  }

  info!(log, "Parsed config file. Liftoff!");
  for dot_file in parser::parse_dot_files(&log, dot_files) {
    process_dot_file(&log, dot_file, force);
  }
}

fn process_dot_file(log: &Logger, dot_file: DotFile, force: bool) {
  let log = &log.new(o!("target" => dot_file.target.clone(), "source" => dot_file.source.clone(), "type" => format!("{:?}", dot_file.dot_file_type)));
  info!(log, "Process entry");
  let source_path = Path::new(&dot_file.source);
  let target_path = Path::new(&dot_file.target);
  if !source_path.exists() {
    warn!(log, "Source path does not exist");
    return;
  }
  match already_linked(source_path, target_path) {
    Ok(true) => info!(log, "Link already exists"),
    Ok(false) => {
      if !force && target_path.exists() {
        error!(log, "Target exists but does not point to source")
      } else {
        let result = link_dot_file(source_path, target_path);
        match result {
          Err(e) => error!(log, "Failed to create link"; "error" => e.description()),
          Ok(_) => info!(log, "Link created successfully"),
        }
      }
    }
    Err(e) => error!(log, "Failed to check link existence"; "error" => e.description()),
  }
}

fn already_linked(source: &Path, target: &Path) -> Result<bool, std::io::Error> {
  if target.exists() {
    let canonicalized_target = try!(fs::canonicalize(target));
    let canonicalized_source = try!(fs::canonicalize(source));
    Ok(canonicalized_source == canonicalized_target)
  } else {
    Ok(false)
  }
}

fn link_dot_file(source: &Path, target: &Path) -> Result<(), std::io::Error> {
  if let Some(parent) = target.parent() {
    try!(fs::create_dir_all(parent));
  }
  if target.exists() {
    if target.is_file() {
      try!(fs::remove_file(target))
    } else if target.is_dir() {
      try!(fs::remove_dir_all(target))
    }
  }
  let canonicalized_source = try!(fs::canonicalize(source));
  try!(std::os::unix::fs::symlink(canonicalized_source, target));
  Ok(())
}

fn load_config_file(file: &str) -> Result<String, std::io::Error> {
  let mut file = try!(File::open(file));
  let mut content = String::new();
  try!(file.read_to_string(&mut content));
  return Ok(content);
}

fn create_app<'a>() -> App<'a, 'a> {
  App::new("dotcopter")
    .version("0.1")
    .setting(AppSettings::ColoredHelp)
    .author("Patrick Haun <bomgar85@googlemail.com>")
    .about("manages dotfiles installation")
    .arg(Arg::with_name("force").short("f").long("force").takes_value(false))
    .arg(Arg::with_name("verbose")
           .long("verbose")
           .short("v")
           .help("debug output")
           .required(false)
           .takes_value(false))
    .arg(Arg::with_name("config_file").required(true))
}
<|endoftext|>


<commit_before>use std::env;
use std::io;
use std::io::Write;
use std::io::Read;
use std::io::BufRead;
use std::process;
use std::str;
//use std::sync::mpsc::{Sender, Receiver};
//use std::sync::mpsc;
use std::thread;

extern crate mio;
use mio::{Events, Ready, Poll, PollOpt, Token};
use mio::net::TcpStream;

//use std::collections::HashMap;

fn main() {
    // arg parsing
    let args: Vec<_> = env::args().collect();
    if args.len() != 3 {
        println!("Usage: {} <ip> <port>", args[0]);
    }
    let port: u32 = args[2].parse().expect("Invalid Port");
    let ref host = args[1];

    ///////////////////////////////////////////////////////////////

    // Pick a token that will not be used by any other socket and
    // use that one for the listener.
    const SOCKREADER: Token = Token(0);
    const SOCKWRITER: Token = Token(1);
    const STDINREADER: Token = Token(2);

    // The `Poll` instance
    let poll = Poll::new().unwrap();

    let addr = format!("{}:{}", host, port).parse().unwrap(); //TODO catch parse failure

    let mut stream = TcpStream::connect(&addr).unwrap();
    let mut write_stream = stream.try_clone().expect("cloning failed, yikes");

    // Register the listener
    poll.register(&stream,
                  SOCKREADER,
                  Ready::readable(),
                  PollOpt::edge()).unwrap();
    //poll.register(&stream, SOCKWRITER, Writer::writable(), PollOpt::edge())?;

    // Event storage
    let mut events = Events::with_capacity(1024);

    // Read buffer, this will never actually get filled
    let mut buf = [0; 256];

    let stdin_thread = thread::spawn(move || {
        loop {
            let input = std::io::stdin();
            for line in input.lock().lines() {
                let l = line.unwrap(); // this could be an invalid string.
                let bytes = l.as_bytes();
                let byte_length = bytes.len();
                let written = write_stream.write(bytes).unwrap();
                assert_eq!(byte_length, written);
                write_stream.write("\x0A".as_bytes()); // TODO allow -C switch to write 0A0D
            }
        }
    });

    // The main event loop
    loop {
        // Wait for events
        poll.poll(&mut events, None).expect("Can't poll. Aborting.");

        for event in &events {
            match event.token() {
                SOCKREADER => {
                    // Continue reading in a loop until `WouldBlock` is
                    // encountered.
                    loop {
                        match stream.read(&mut buf) {
                            Ok(read_len) => {
                                println!("{:?}", String::from_utf8_lossy(&buf[0..read_len]));
                                break;
                            }
                            // Data is not actually sent in this example
                            //Ok(_) => unreachable!(),
                            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                                // Socket is not ready anymore, stop reading
                                break;
                            },
                            Err(ref e) if e.kind() == io::ErrorKind::ConnectionRefused => {
                                println!("connect to {} port {} (tcp) failed: Connection refused", host, port);
                                process::exit(1);
                            }
                            e => panic!("err={:?}", e), // Unexpected error, e.g., connection refused
                        }
                    }
                },
                x => panic!("unexpected token {:?}", x),
            }
        }
    }
}
<commit_msg>properly sending 0x0a in same packet<commit_after>use std::env;
use std::io;
use std::io::Write;
use std::io::Read;
use std::io::BufRead;
use std::process;
use std::thread;

extern crate mio;
use mio::{Events, Ready, Poll, PollOpt, Token};
use mio::net::TcpStream;

//use std::collections::HashMap;

fn main() {
    // arg parsing
    let args: Vec<_> = env::args().collect();
    if args.len() != 3 {
        println!("Usage: {} <ip> <port>", args[0]);
    }
    let port: u32 = args[2].parse().expect("Invalid Port");
    let host = &args[1];

    let ending = "\x0A";
    ///////////////////////////////////////////////////////////////

    // Pick a token that will not be used by any other socket and
    // use that one for the listener.
    const SOCKREADER: Token = Token(0);

    // The `Poll` instance
    let poll = Poll::new().unwrap();

    let addr = format!("{}:{}", host, port).parse().unwrap(); //TODO catch parse failure

    let mut stream = TcpStream::connect(&addr).unwrap();
    let mut write_stream = stream.try_clone().expect("cloning failed, yikes");

    // Register the listener
    poll.register(&stream,
                  SOCKREADER,
                  Ready::readable(), // andere events wären toll, z.b. disconnect
                  PollOpt::edge()).unwrap();

    // Event storage
    let mut events = Events::with_capacity(1024);

    // Read buffer, this will never actually get filled
    let mut buf = [0; 256];

    thread::spawn(move || {
        loop {
            let input = std::io::stdin();
            for line in input.lock().lines() {
                let l = line.unwrap() + ending; // this could be an invalid string.
                let bytes = l.as_bytes();
                let byte_length = bytes.len();
                let written = write_stream.write(bytes).unwrap(); // dont unwrap, could be broken pipe
                assert_eq!(byte_length, written);
            }
        }
    });

    // The main event loop
    loop {
        // Wait for events
        poll.poll(&mut events, None).expect("Can't poll. Aborting.");

        for event in &events {
            match event.token() {
                SOCKREADER => {
                    // Continue reading in a loop until `WouldBlock` is
                    // encountered.
                    loop {
                        match stream.read(&mut buf) {
                            Ok(read_len) => {
                                println!("{:?}", String::from_utf8_lossy(&buf[0..read_len]));
                                break;
                            }
                            // Data is not actually sent in this example
                            //Ok(_) => unreachable!(),
                            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                                // Socket is not ready anymore, stop reading
                                break;
                            },
                            Err(ref e) if e.kind() == io::ErrorKind::ConnectionRefused => {
                                println!("connect to {} port {} (tcp) failed: Connection refused", host, port);
                                process::exit(1);
                            }
                            e => panic!("err={:?}", e), // Unexpected error, e.g., connection refused
                        }
                    }
                },
                x => panic!("unexpected token {:?}", x),
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::Write;
use std::process::Command;

fn main() {
    println!("Welcome to sksh");
    loop {
        print!("$ ");
        let line: String = read_line();
        let parsed: Vec<&str> = split_line(&line);
        let (command, args) = match parsed.split_first() {
            Some((first, elements)) => (first.trim(), elements),
            None => {
                return ();
            }
        };

        execute(command, args);
    }
}

fn execute(c: &str, args: &[&str]) {
    if c.len() == 0 {
        println!("");
        return;
    }

    let mut trimmed_args = Vec::new();

    for i in args {
        trimmed_args.push(i.trim());
    }

    let s = &trimmed_args[..];

    let output = Command::new(c)
        .args(s)
        .output()
        .expect("failed to execute process.");

    if output.status.success() {
        println!("{}", String::from_utf8_lossy(&output.stdout));
    }
}

fn split_line(line: &str) -> Vec<&str> {
    let v: Vec<&str> = line.split(' ').collect();
    return v;
}

fn read_line() -> String {
    let mut line = String::new();
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut line)
        .expect("Failed to read line");
    return line;
}
<commit_msg>move loop into a function<commit_after>use std::io;
use std::io::Write;
use std::process::Command;

fn main() {
    println!("Welcome to sksh");
    looper();
}

fn execute(c: &str, args: &[&str]) {
    if c.len() == 0 {
        println!("");
        return;
    }

    let mut trimmed_args = Vec::new();

    for i in args {
        trimmed_args.push(i.trim());
    }

    let s = &trimmed_args[..];

    let output = Command::new(c)
        .args(s)
        .output()
        .expect("failed to execute process.");

    if output.status.success() {
        println!("{}", String::from_utf8_lossy(&output.stdout));
    }
}

fn split_line(line: &str) -> Vec<&str> {
    let v: Vec<&str> = line.split(' ').collect();
    return v;
}

fn read_line() -> String {
    let mut line = String::new();
    io::stdout().flush().unwrap();
    io::stdin().read_line(&mut line)
        .expect("Failed to read line");
    return line;
}

fn looper() {
    loop {
        print!("$ ");
        let line: String = read_line();
        let parsed: Vec<&str> = split_line(&line);
        let (command, args) = match parsed.split_first() {
            Some((first, elements)) => (first.trim(), elements),
            None => {
                return ();
            }
        };

        execute(command, args);
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate conrod;
extern crate find_folder;
extern crate piston_window;
extern crate rand;

use piston_window::{EventLoop, PistonWindow, WindowSettings, Event, UpdateEvent, clear};

mod board;
mod colors;
mod game;
mod randomizer;
mod tetromino;
mod settings;
mod stats;
mod ui;

use game::{Rustris, Game};
use settings::*;
use ui::{create_ui, set_ui};

fn main() {
    // Setup
    let window_title = format!("Rustris {}", VERSION);

    // Game Window
    let window: PistonWindow =
        WindowSettings::new(window_title, [WINDOW_WIDTH, WINDOW_HEIGHT])
        .exit_on_esc(true)
        .vsync(true)
        .build()
        .unwrap();

    // UI Struct
    let mut ui = create_ui(&window);

    let mut game = Rustris::new();

    // Game Loop
    for e in window.ups(60) {
        // let the UI handle the event
        ui.handle_event(&e);

        match e.event {
            Some(Event::Input(input)) => {
                game.on_input(input);
            }
            Some(Event::Update(update_args)) => {
                game.on_update(update_args);
                e.update(|_| ui.set_widgets(|ui| set_ui(ui, &game)));
            }
            Some(Event::Render(_)) => {
                e.draw_2d(|c, g| {
                    clear([0.0, 0.0, 0.0, 1.0], g);
                    ui.draw(c, g);
                    // TODO: Make the game itself a custom widget.
                    game.render(c, g);
                });
            }
            _ => {}
        }
    }
}
<commit_msg>remove needless comments<commit_after>#[macro_use] extern crate conrod;
extern crate find_folder;
extern crate piston_window;
extern crate rand;

use piston_window::{EventLoop, PistonWindow, WindowSettings, Event, UpdateEvent, clear};

mod board;
mod colors;
mod game;
mod randomizer;
mod tetromino;
mod settings;
mod stats;
mod ui;

use game::{Rustris, Game};
use settings::*;
use ui::{create_ui, set_ui};

fn main() {
    let window_title = format!("Rustris {}", VERSION);

    let window: PistonWindow =
        WindowSettings::new(window_title, [WINDOW_WIDTH, WINDOW_HEIGHT])
        .exit_on_esc(true)
        .vsync(true)
        .build()
        .unwrap();

    let mut ui = create_ui(&window);
    let mut game = Rustris::new();

    for e in window.ups(60) {
        // let the UI handle the event
        ui.handle_event(&e);

        match e.event {
            Some(Event::Input(input)) => {
                game.on_input(input);
            }
            Some(Event::Update(update_args)) => {
                game.on_update(update_args);
                e.update(|_| ui.set_widgets(|ui| set_ui(ui, &game)));
            }
            Some(Event::Render(_)) => {
                e.draw_2d(|c, g| {
                    clear([0.0, 0.0, 0.0, 1.0], g);
                    ui.draw(c, g);
                    // TODO: Make the game itself a custom widget.
                    game.render(c, g);
                });
            }
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate hyper;

use rustc_serialize::json;
use rustc_serialize::json::Json;
#[macro_use] extern crate nickel;

use nickel::status::StatusCode;
use nickel::{Nickel, HttpRouter, MediaType};

#[derive(RustcDecodable, RustcEncodable)]
struct Todo {
  status: i32,
  title: String,
}

fn main() {
  let mut server = Nickel::new();
  let mut router = Nickel::router();

  // index
  router.get("/api/todos", middleware! { |_, mut _res|
    let mut v: Vec<Todo> = vec![];
    let todo1 = Todo{
      status: 0,
      title: "Shopping".to_string(),
    };
    v.push(todo1);
    let todo2 = Todo{
      status: 1,
      title: "Movie".to_string(),
    };
    v.push(todo2);

    let json_obj = json::encode(&v).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  // detail
  router.get("/api/todos/:id", middleware! { |_req, mut _res|
    let id = _req.param("id");
    println!("id: {:?}", id);

    let todo1 = Todo{
      status: 0,
      title: "Shopping".to_string(),
    };
    let json_obj = json::encode(&todo1).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  // delete
  router.delete("/api/todos/:id", middleware! { |_req, mut _res|
    let id = _req.param("id");
    println!("delete id: {:?}", id);

    let json_obj = Json::from_str("{}").unwrap();
    _res.set(MediaType::Json);
    //_res.set(StatusCode::NoContent);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  server.utilize(router);
  server.listen("127.0.0.1:6767");
}
<commit_msg>add update api<commit_after>extern crate rustc_serialize;
extern crate hyper;

use rustc_serialize::json;
use rustc_serialize::json::Json;
#[macro_use] extern crate nickel;

use nickel::status::StatusCode;
use nickel::{Nickel, HttpRouter, MediaType, JsonBody};

#[derive(RustcDecodable, RustcEncodable)]
struct Todo {
  status: i32,
  title: String,
}

fn main() {
  let mut server = Nickel::new();
  let mut router = Nickel::router();

  // index
  router.get("/api/todos", middleware! { |_, mut _res|
    let mut v: Vec<Todo> = vec![];
    let todo1 = Todo{
      status: 0,
      title: "Shopping".to_string(),
    };
    v.push(todo1);
    let todo2 = Todo{
      status: 1,
      title: "Movie".to_string(),
    };
    v.push(todo2);

    let json_obj = json::encode(&v).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  // detail
  router.get("/api/todos/:id", middleware! { |_req, mut _res|
    let id = _req.param("id");
    println!("id: {:?}", id);

    let todo1 = Todo{
      status: 0,
      title: "Shopping".to_string(),
    };
    let json_obj = json::encode(&todo1).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  // delete
  router.delete("/api/todos/:id", middleware! { |_req, mut _res|
    let id = _req.param("id");
    println!("delete id: {:?}", id);

    let json_obj = Json::from_str("{}").unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  // create
  router.post("/api/todos", middleware! { |_req, mut _res|
    let todo = _req.json_as::<Todo>().unwrap();
    println!("post todo: {} {}", todo.status, todo.title);

    let json_obj = json::encode(&todo).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Created);
    return _res.send(json_obj);
  });

  // update
  router.put("/api/todos/:id", middleware! { |_req, mut _res|
    // let id = _req.param("id");
    let todo = _req.json_as::<Todo>().unwrap();
    // println!("post todo: {:?} {} {}", id, todo.status, todo.title);
    println!("post todo: {} {}", todo.status, todo.title);

    let json_obj = json::encode(&todo).unwrap();
    _res.set(MediaType::Json);
    _res.set(StatusCode::Ok);
    return _res.send(json_obj);
  });

  server.utilize(router);
  server.listen("127.0.0.1:6767");
}
<|endoftext|>


<commit_before>#![feature(phase)]
extern crate serialize;
#[phase(plugin)] extern crate docopt_macros;
extern crate docopt;
extern crate core;
extern crate collections;

use docopt::FlagParser;
use std::io::BufferedReader;
use std::io::File;
use core::result::Result;
use collections::string::String;
use collections::vec::Vec;

docopt!(Args, "
interleaver

Usage: interleaver FILENAMES...
", )

type BrType = BufferedReader<core::result::Result<std::io::fs::File,std::io::IoError>>;

fn main() {
  let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

  // The Args struct satisfies `Show`:
  println!("{}", args);

  let paths_it = args.arg_FILENAMES.iter ().map (|n| Path::new(n.clone ()));
  let files_it = paths_it.map (|path| File::open(&path));
  let mut buffered_readers_it = files_it.map (|file| BufferedReader::new (file));
  let mut buffered_readers_vec : Vec<BrType> = buffered_readers_it.collect ();

  let mut done;

  loop {
    done = true;
    for buffered_reader in buffered_readers_vec.mut_iter () {
      let mut lines = buffered_reader.lines ();
      match lines.next () {
        None => (),
        Some (line) => {
          println! ("{}", line);
          done = false;
        }
      }
    }
    if done { break; }
  }

  // let line_readers_it = buffered_readers_vec.iter().map (|mut buffered_reader| { buffered_reader.read_to_string(); });

  // let line_iterators = readers.map (|mut reader| reader.lines ());

  // let c = args.arg_FILENAMES.len();

  // let mut candidates : Vec<Option<IoResult<String>>> = Vec::new ();

  // for line_iterator in line_iterators.iter () {
  //   // let line = line_iterator.next ();
  //   // candidates.push (line);
  // }

  // let path = Path::new("p054_poker.txt");

  // let mut file = BufferedReader::new(File::open(&path));
  // for line in file.lines() {
  //   let l = line.unwrap ();
  // }
}
<commit_msg>Trying to write to files<commit_after>#![feature(phase)]
extern crate serialize;
#[phase(plugin)] extern crate docopt_macros;
extern crate docopt;
extern crate core;
extern crate collections;

use docopt::FlagParser;
use std::io::BufferedReader;
use std::io::BufferedWriter;
use std::io::File;
use core::result::Result;
use collections::string::String;
use collections::vec::Vec;

docopt!(Args, "
interleaver

Usage: interleaver FILENAMES...
", )

type BrType = BufferedReader<core::result::Result<std::io::fs::File,std::io::IoError>>;
type BwType = BufferedWriter<core::result::Result<std::io::fs::File,std::io::IoError>>;

fn main() {
  let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

  // The Args struct satisfies `Show`:
  println!("{}", args);

  let file_names = args.arg_FILENAMES;
  let paths_it = file_names.iter ().map (|n| Path::new(n.clone ()));
  let files_it = paths_it.map (|path| File::open(&path));
  let mut buffered_readers_it = files_it.map (|file| BufferedReader::new (file));
  let mut buffered_readers_vec : Vec<BrType> = buffered_readers_it.collect ();

  let paths_out_it = range (0u, file_names.len ()).map (|i| Path::new (i.to_string()));
  let files_out_it = paths_out_it.map (|path_out| File::open(&path_out));
  let mut buffered_writers_it = files_out_it.map (|file_out| BufferedWriter::new (file_out));
  let mut buffered_writers_vec : Vec<BwType> = buffered_writers_it.collect ();

  let mut done;
  let mut i = 0;

  loop {
    done = true;
    for buffered_reader in buffered_readers_vec.mut_iter () {
      let mut lines = buffered_reader.lines ();
      match lines.next () {
        None => (),
        Some (line) => {
          buffered_writers_vec.get_mut (i).write_str (line.unwrap ().as_slice ());
          i = i + 1;
          done = false;
        }
      }
    }
    if done { break; }
  }

  // let line_readers_it = buffered_readers_vec.iter().map (|mut buffered_reader| { buffered_reader.read_to_string(); });

  // let line_iterators = readers.map (|mut reader| reader.lines ());

  // let c = args.arg_FILENAMES.len();

  // let mut candidates : Vec<Option<IoResult<String>>> = Vec::new ();

  // for line_iterator in line_iterators.iter () {
  //   // let line = line_iterator.next ();
  //   // candidates.push (line);
  // }

  // let path = Path::new("p054_poker.txt");

  // let mut file = BufferedReader::new(File::open(&path));
  // for line in file.lines() {
  //   let l = line.unwrap ();
  // }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate itertools;
extern crate unicode_xid;
extern crate lalrpop_util;
use clap::{Arg, App};

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

mod ast;
mod parser;
mod lexer;
mod diagnostics;
mod ir;
mod codegen;

fn read_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
    let mut file = File::open(path)?;
    let mut buffer = String::new();
    file.read_to_string(&mut buffer)?;
    Ok(buffer)
}

fn main() {
    let matches = App::new("Elang Compiler")
        .version("0.1")
        .author("Paul CACHEUX <paulcacheux@gmail.com>")
        .arg(Arg::with_name("ast").long("ast").help("Dump AST"))
        .arg(Arg::with_name("ir").long("ir").help("Dump IR"))
        .arg(Arg::with_name("opt")
                 .short("O")
                 .help("Activate optimizations"))
        .arg(Arg::with_name("INPUT")
                 .help("Input file")
                 .required(true)
                 .index(1))
        .arg(Arg::with_name("OUTPUT")
                 .help("Output file")
                 .long("output")
                 .short("o")
                 .value_name("FILE")
                 .takes_value(true))
        .get_matches();

    let input_path = matches.value_of("INPUT").unwrap();
    let input = read_file(input_path).expect("Can't read input file");
    let lex = lexer::Lexer::new(&input);
    let tu = match parser::parse_TranslationUnit(lex) {
        Ok(tu) => tu,
        Err(err) => {
            return diagnostics::print_diagnostic(&input, err);
        }
    };

    if matches.is_present("ast") {
        ast::printer::print_ast(&tu);
    }

    let mut tu = match ir::builder::build_translation_unit(tu) {
        Ok(tu) => tu,
        Err(err) => {
            return diagnostics::print_diagnostic(&input, err);
        }
    };

    if matches.is_present("opt") {
        ir::opt::opt_translation_unit(&mut tu);
    }

    if matches.is_present("ir") {
        ir::printer::print_ir(&tu);
    }

    let default_output_path = format!("{}.c", input_path);
    let output_path = matches.value_of("OUTPUT").unwrap_or(&default_output_path);
    let mut file = File::create(output_path).unwrap();
    codegen::c_gen::gen_translation_unit(&mut file, tu).expect("error gen");
}
<commit_msg>Default output now to stdout<commit_after>extern crate clap;
extern crate itertools;
extern crate unicode_xid;
extern crate lalrpop_util;
use clap::{Arg, App};

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

mod ast;
mod parser;
mod lexer;
mod diagnostics;
mod ir;
mod codegen;

fn read_file<P: AsRef<Path>>(path: P) -> io::Result<String> {
    let mut file = File::open(path)?;
    let mut buffer = String::new();
    file.read_to_string(&mut buffer)?;
    Ok(buffer)
}

fn main() {
    let matches = App::new("Elang Compiler")
        .version("0.1")
        .author("Paul CACHEUX <paulcacheux@gmail.com>")
        .arg(Arg::with_name("ast").long("ast").help("Dump AST"))
        .arg(Arg::with_name("ir").long("ir").help("Dump IR"))
        .arg(Arg::with_name("opt")
                 .short("O")
                 .help("Activate optimizations"))
        .arg(Arg::with_name("INPUT")
                 .help("Input file")
                 .required(true)
                 .index(1))
        .arg(Arg::with_name("OUTPUT")
                 .help("Output file")
                 .long("output")
                 .short("o")
                 .value_name("FILE")
                 .takes_value(true))
        .get_matches();

    let input_path = matches.value_of("INPUT").unwrap();
    let input = read_file(input_path).expect("Can't read input file");
    let lex = lexer::Lexer::new(&input);
    let tu = match parser::parse_TranslationUnit(lex) {
        Ok(tu) => tu,
        Err(err) => {
            return diagnostics::print_diagnostic(&input, err);
        }
    };

    if matches.is_present("ast") {
        ast::printer::print_ast(&tu);
    }

    let mut tu = match ir::builder::build_translation_unit(tu) {
        Ok(tu) => tu,
        Err(err) => {
            return diagnostics::print_diagnostic(&input, err);
        }
    };

    if matches.is_present("opt") {
        ir::opt::opt_translation_unit(&mut tu);
    }

    if matches.is_present("ir") {
        ir::printer::print_ir(&tu);
    }

    let mut output_writer: Box<std::io::Write> = if let Some(output_path) = matches.value_of("OUTPUT") {
        Box::new(File::create(output_path).unwrap())
    } else {
        Box::new(std::io::stdout())
    };

    codegen::c_gen::gen_translation_unit(&mut output_writer, tu).expect("error gen");
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

use std::fmt;

use rocket::http::Status;
use rocket::request::{self, Request, FromRequest};
use rocket::response::content;
use rocket::{Outcome, Response};

struct IndexData(String);

impl<'a, 'r> FromRequest<'a, 'r> for IndexData {
    type Error = ();
    fn from_request(request: &'a Request<'r>) -> request::Outcome<IndexData, ()> {
        Outcome::Success(IndexData(format!("{}", request)))
    }
}

impl fmt::Display for IndexData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[get("/")]
fn index() -> content::HTML<&'static str> {
    content::HTML("<!DOCTYPE html>

            <title>HTTPTIN</title>

HTTPTIN - HTTP tester in Rust and Rocket

    ")
}

#[get("/test")]
fn test(data: IndexData) -> String {
    format!("<!DOCTYPE html><title>HTTPTIN></title>{}", data)
}

#[get("/ip")]
fn origin() -> String {
    String::from("Remote address decoding is not implemented yet")
}

#[get("/get")]
fn get() -> String {
    String::from("method")
}

#[get("/status/")]
pub fn status<'r>(code: u16) -> Response<'r> {
    Response::build().status(Status::raw(code)).finalize()
}

fn main() {
    rocket::ignite().mount("/", routes![index, origin, get, status, test]).launch();
}
<commit_msg>/get should produce json<commit_after>#![feature(custom_derive)]
#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

use std::fmt;

use rocket::http::Status;
use rocket::request::{self, Request, FromRequest};
use rocket::response::content;
use rocket::{Outcome, Response};

struct IndexData(String);

impl<'a, 'r> FromRequest<'a, 'r> for IndexData {
    type Error = ();
    fn from_request(request: &'a Request<'r>) -> request::Outcome<IndexData, ()> {
        Outcome::Success(IndexData(format!("{}", request)))
    }
}

impl fmt::Display for IndexData {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[get("/")]
fn index() -> content::HTML<&'static str> {
    content::HTML("<!DOCTYPE html>

            <title>HTTPTIN</title>

HTTPTIN - HTTP tester in Rust and Rocket

    ")
}

#[get("/test")]
fn test(data: IndexData) -> String {
    format!("<!DOCTYPE html><title>HTTPTIN></title>{}", data)
}

#[get("/ip")]
fn origin() -> String {
    String::from("Remote address decoding is not implemented yet")
}

#[derive(Serialize)]
struct GetData {
    args: String,
    headers: String,
}

#[get("/get")]
fn get() -> content::JSON<&'static str> {
    content::JSON("{agrs: {}}")
}

#[get("/status/")]
pub fn status<'r>(code: u16) -> Response<'r> {
    Response::build().status(Status::raw(code)).finalize()
}

fn main() {
    rocket::ignite().mount("/", routes![index, origin, get, status, test]).launch();
}
<|endoftext|>