<commit_before>#[macro_use]
extern crate glium;
extern crate image;
extern crate zip;
extern crate cgmath;
extern crate notify;

use cgmath::{Vector, Vector2, Vector3, Vector4};
use cgmath::{Basis3};
use cgmath::{Matrix, SquareMatrix, Matrix3, Matrix4};
use cgmath::{Angle, Rad, Deg};
use cgmath::{Rotation, Rotation3};
use cgmath::{PerspectiveFov};

use glium::glutin::{Event, MouseButton, ElementState, MouseScrollDelta};
use glium::debug::DebugCallbackBehavior;

//use glium::texture::{Texture2d, RawImage2d};
use glium::uniforms::Sampler;
//use glium::buffer::{Buffer, BufferMode, BufferSlice};

mod lightfield;
use lightfield::Lightfield;

mod reloading_program;
use reloading_program::ReloadingProgram;

fn main() {
    use glium::{DisplayBuild, Surface};
    let display = glium::glutin::WindowBuilder::new()
        .with_vsync()
        .build_glium_debug(DebugCallbackBehavior::PrintAll)
        .unwrap();

    #[derive(Copy, Clone)]
    struct Vertex {
        position: [f32; 2],
        tex_coords: [f32; 2],
    }

    implement_vertex!(Vertex, position, tex_coords);

    let vertex1 = Vertex { position: [-0.5, -0.5], tex_coords: [0.0, 0.0] };
    let vertex2 = Vertex { position: [ 0.0,  0.5], tex_coords: [0.0, 1.0] };
    let vertex3 = Vertex { position: [ 0.5, -0.25], tex_coords: [1.0, 0.0] };
    let shape = vec![vertex1, vertex2, vertex3];

    let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let mut reloading_program = ReloadingProgram::from_source(&display, "shaders/lightfield.vsh", "shaders/lightfield.fsh", None);

    let lf = Lightfield::new(&display, "chess.jpg.zip");
    let lf_sampler = Sampler::new(&lf.tex);

    let mut cursor_pos          = Vector2::new(0f32, 0f32);
    let mut cursor_startpos     = Vector2::new(0f32, 0f32);
    let mut cursor_totaloff     = Vector2::new(0f32, 0f32);
    let mut cursor_totaloff_old = Vector2::new(0f32, 0f32);
    let mut scale = 1f32;
    let mut mouse_pressed = false;
    let mut mouse_scrolled = false;
    let mut mat_model = Matrix4::<f32>::identity();
    let mut mat_view = Matrix4::<f32>::identity();
    mat_view[3][2] = -5.0;
    let mut window_size = display.get_window().unwrap().get_inner_size_pixels().unwrap();
    let mut shaders_broken = false;
    loop {
        if shaders_broken {
            println!("Shaders are broken, waiting for updated shader before resuming...");
            reloading_program.wait_for_change();
        }
        let program = match reloading_program.current() {
            &Err(ref err) => {
                println!("Error compiling shader: {:?}.", err);
                shaders_broken = true;
                continue
            }
            &Ok(ref prog) => {
                shaders_broken = false;
                prog
            }
        };

        for ev in display.poll_events() {
            match ev {
                Event::Closed => return,
                Event::Resized(w,h) => {
                    window_size = (w,h);
                },
                Event::MouseMoved(m) => {
                    cursor_pos.x = m.0 as f32 / window_size.0 as f32 - 0.5;
                    cursor_pos.y = m.1 as f32 / window_size.1 as f32 - 0.5;
                },
                Event::MouseInput(ElementState::Pressed,  MouseButton::Left) => {
                    cursor_startpos = cursor_pos;
                    mouse_pressed = true;
                },
                Event::MouseInput(ElementState::Released, MouseButton::Left) => {
                    cursor_totaloff_old = cursor_totaloff;
                    mouse_pressed = false;
                },
                Event::MouseWheel(MouseScrollDelta::LineDelta(_, lines)) => {
                    scale *= f32::powf(1.1, lines);
                    //println!("scroll: {}, scale {}", lines, scale);
                    mouse_scrolled = true;
                },
                _ => ()
            }
        }
        if mouse_pressed || mouse_scrolled {
            let offset = Vector2::from((cursor_startpos - cursor_pos));
            cursor_totaloff = cursor_totaloff_old + offset;
            //println!("{:?}", cursor_totaloff);
            let yaw   = Rad::<f32>::full_turn() * cursor_totaloff.x;
            let pitch   = Rad::<f32>::full_turn() * cursor_totaloff.y;
            let mat_rot = Matrix4::<f32>::from(Matrix3::from_euler(pitch, yaw, Rad::zero()));
            let mat_scale = Matrix4::<f32>::from_diagonal(Vector4::new(scale, scale, scale, 1.0));
            mat_model = mat_rot * mat_scale;
            mouse_scrolled = false; // only recompute once!
        }

        let mut target = display.draw();
        target.clear_color(0.3, 0.3, 0.3, 1.0);
        let (width, height) = target.get_dimensions();

        let mat_projection: Matrix4<f32> =  PerspectiveFov {
            fovy:   Deg::new(60f32).into(),
            aspect: height as f32 / width as f32,
            near:   0.1,
            far:    1024.,
        }.into();

        let uniforms = uniform! {
            model:      Into::<[[f32; 4]; 4]>::into(mat_model),
            view:       Into::<[[f32; 4]; 4]>::into(mat_view),
            projection: Into::<[[f32; 4]; 4]>::into(mat_projection),
            tex: lf_sampler,
        };

        target.draw(&vertex_buffer, &indices, &program, &uniforms,
                    &Default::default()).unwrap();

        target.finish().unwrap();
        /*
        println!("model: {:#?}", mat_model);
        println!("view: {:#?}", mat_view);
        println!("projection: {:#?}", mat_projection);
        println!("");
        */
    }
}
<commit_msg>fix compile err (glium change?)<commit_after>#[macro_use]
extern crate glium;
extern crate image;
extern crate zip;
extern crate cgmath;
extern crate notify;

use cgmath::{Vector2, Vector3, Vector4};
use cgmath::{Basis3};
use cgmath::{Matrix, SquareMatrix, Matrix3, Matrix4};
use cgmath::{Angle, Rad, Deg};
use cgmath::{Rotation, Rotation3};
use cgmath::{PerspectiveFov};

use glium::glutin::{Event, MouseButton, ElementState, MouseScrollDelta};
use glium::debug::DebugCallbackBehavior;

//use glium::texture::{Texture2d, RawImage2d};
use glium::uniforms::Sampler;
//use glium::buffer::{Buffer, BufferMode, BufferSlice};

mod lightfield;
use lightfield::Lightfield;

mod reloading_program;
use reloading_program::ReloadingProgram;

fn main() {
    use glium::{DisplayBuild, Surface};
    let display = glium::glutin::WindowBuilder::new()
        .with_vsync()
        .build_glium_debug(DebugCallbackBehavior::PrintAll)
        .unwrap();

    #[derive(Copy, Clone)]
    struct Vertex {
        position: [f32; 2],
        tex_coords: [f32; 2],
    }

    implement_vertex!(Vertex, position, tex_coords);

    let vertex1 = Vertex { position: [-0.5, -0.5], tex_coords: [0.0, 0.0] };
    let vertex2 = Vertex { position: [ 0.0,  0.5], tex_coords: [0.0, 1.0] };
    let vertex3 = Vertex { position: [ 0.5, -0.25], tex_coords: [1.0, 0.0] };
    let shape = vec![vertex1, vertex2, vertex3];

    let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let mut reloading_program = ReloadingProgram::from_source(&display, "shaders/lightfield.vsh", "shaders/lightfield.fsh", None);

    let lf = Lightfield::new(&display, "chess.jpg.zip");
    let lf_sampler = Sampler::new(&lf.tex);

    let mut cursor_pos          = Vector2::new(0f32, 0f32);
    let mut cursor_startpos     = Vector2::new(0f32, 0f32);
    let mut cursor_totaloff     = Vector2::new(0f32, 0f32);
    let mut cursor_totaloff_old = Vector2::new(0f32, 0f32);
    let mut scale = 1f32;
    let mut mouse_pressed = false;
    let mut mouse_scrolled = false;
    let mut mat_model = Matrix4::<f32>::identity();
    let mut mat_view = Matrix4::<f32>::identity();
    mat_view[3][2] = -5.0;
    let mut window_size = display.get_window().unwrap().get_inner_size_pixels().unwrap();
    let mut shaders_broken = false;
    loop {
        if shaders_broken {
            println!("Shaders are broken, waiting for updated shader before resuming...");
            reloading_program.wait_for_change();
        }
        let program = match reloading_program.current() {
            &Err(ref err) => {
                println!("Error compiling shader: {:?}.", err);
                shaders_broken = true;
                continue
            }
            &Ok(ref prog) => {
                shaders_broken = false;
                prog
            }
        };

        for ev in display.poll_events() {
            match ev {
                Event::Closed => return,
                Event::Resized(w,h) => {
                    window_size = (w,h);
                },
                Event::MouseMoved(m) => {
                    cursor_pos.x = m.0 as f32 / window_size.0 as f32 - 0.5;
                    cursor_pos.y = m.1 as f32 / window_size.1 as f32 - 0.5;
                },
                Event::MouseInput(ElementState::Pressed,  MouseButton::Left) => {
                    cursor_startpos = cursor_pos;
                    mouse_pressed = true;
                },
                Event::MouseInput(ElementState::Released, MouseButton::Left) => {
                    cursor_totaloff_old = cursor_totaloff;
                    mouse_pressed = false;
                },
                Event::MouseWheel(MouseScrollDelta::LineDelta(_, lines)) => {
                    scale *= f32::powf(1.1, lines);
                    //println!("scroll: {}, scale {}", lines, scale);
                    mouse_scrolled = true;
                },
                _ => ()
            }
        }
        if mouse_pressed || mouse_scrolled {
            let offset = Vector2::from((cursor_startpos - cursor_pos));
            cursor_totaloff = cursor_totaloff_old + offset;
            //println!("{:?}", cursor_totaloff);
            let yaw   = Rad::<f32>::full_turn() * cursor_totaloff.x;
            let pitch   = Rad::<f32>::full_turn() * cursor_totaloff.y;
            let mat_rot = Matrix4::<f32>::from(Matrix3::from_euler(pitch, yaw, Rad::zero()));
            let mat_scale = Matrix4::<f32>::from_diagonal(Vector4::new(scale, scale, scale, 1.0));
            mat_model = mat_rot * mat_scale;
            mouse_scrolled = false; // only recompute once!
        }

        let mut target = display.draw();
        target.clear_color(0.3, 0.3, 0.3, 1.0);
        let (width, height) = target.get_dimensions();

        let mat_projection: Matrix4<f32> =  PerspectiveFov {
            fovy:   Deg::new(60f32).into(),
            aspect: height as f32 / width as f32,
            near:   0.1,
            far:    1024.,
        }.into();

        let uniforms = uniform! {
            model:      Into::<[[f32; 4]; 4]>::into(mat_model),
            view:       Into::<[[f32; 4]; 4]>::into(mat_view),
            projection: Into::<[[f32; 4]; 4]>::into(mat_projection),
            tex: lf_sampler,
        };

        target.draw(&vertex_buffer, &indices, &program, &uniforms,
                    &Default::default()).unwrap();

        target.finish().unwrap();
        /*
        println!("model: {:#?}", mat_model);
        println!("view: {:#?}", mat_view);
        println!("projection: {:#?}", mat_projection);
        println!("");
        */
    }
}
<|endoftext|>


<commit_before>#![feature(slice_patterns)]

extern crate getopts;

use std::fs;
use std::io;
use std::io::{Read, Write};

use getopts::Options;

mod optimizer;
mod parser;
mod runner;
mod structs;

use parser::parse;
use runner::State;
use structs::OpStream;

fn main() {
    let mut opts = Options::new();
    opts.optflag("n", "dry-run", "don't actually run");
    opts.optflag("0", "no-optimize", "don't optimize");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(std::env::args().skip(1)) {
        Ok(m) => m,
        Err(f) => {
            writeln!(&mut io::stderr(), "{}", f).unwrap();
            std::process::exit(2);
        }
    };
    if matches.opt_present("h") {
        print!("{}", opts.usage("Usage: brain_rust [options] FILE... "));
        return;
    }

    let dry_run = matches.opt_present("n");
    let no_optimize = matches.opt_present("0");

    for filename in &matches.free[..] {
        let buffer = match read_file(filename) {
            Ok(v) => v,
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while reading {}: {}", filename, e).unwrap();
                continue;
            }
        };
        let ops = match parse(&buffer[..]) {
            Ok(v) => v,
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while parsing {}: {}", filename, e).unwrap();
                continue;
            }
        };
        let mut opstream = OpStream { ops: ops };
        if !no_optimize {
            opstream.optimize();
        }
        if !dry_run {
            let mut state: State = Default::default();
            state.run(opstream.get());
        }
    }
}

fn read_file(filename: &str) -> Result<Vec<u8>, io::Error> {
    let file = try!(fs::File::open(filename));
    let mut reader = io::BufReader::new(file);
    let mut buffer = Vec::new();
    try!(reader.read_to_end(&mut buffer));
    Ok(buffer)
}
<commit_msg>fix: use stderr for help message<commit_after>#![feature(slice_patterns)]

extern crate getopts;

use std::fs;
use std::io;
use std::io::{Read, Write};

use getopts::Options;

mod optimizer;
mod parser;
mod runner;
mod structs;

use parser::parse;
use runner::State;
use structs::OpStream;

fn main() {
    let mut opts = Options::new();
    opts.optflag("n", "dry-run", "don't actually run");
    opts.optflag("0", "no-optimize", "don't optimize");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(std::env::args().skip(1)) {
        Ok(m) => m,
        Err(f) => {
            writeln!(&mut io::stderr(), "{}", f).unwrap();
            std::process::exit(2);
        }
    };
    if matches.opt_present("h") {
        write!(&mut io::stderr(), "{}", opts.usage("Usage: brain_rust [options] FILE... ")).unwrap();
        return;
    }

    let dry_run = matches.opt_present("n");
    let no_optimize = matches.opt_present("0");

    for filename in &matches.free[..] {
        let buffer = match read_file(filename) {
            Ok(v) => v,
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while reading {}: {}", filename, e).unwrap();
                continue;
            }
        };
        let ops = match parse(&buffer[..]) {
            Ok(v) => v,
            Err(e) => {
                writeln!(&mut io::stderr(), "Error while parsing {}: {}", filename, e).unwrap();
                continue;
            }
        };
        let mut opstream = OpStream { ops: ops };
        if !no_optimize {
            opstream.optimize();
        }
        if !dry_run {
            let mut state: State = Default::default();
            state.run(opstream.get());
        }
    }
}

fn read_file(filename: &str) -> Result<Vec<u8>, io::Error> {
    let file = try!(fs::File::open(filename));
    let mut reader = io::BufReader::new(file);
    let mut buffer = Vec::new();
    try!(reader.read_to_end(&mut buffer));
    Ok(buffer)
}
<|endoftext|>


<commit_before>extern crate log;
extern crate pretty_env_logger;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate trust_dns;

use log::info;

use serde_json::value::*;

use std::env;
use std::io;
use std::io::prelude::*;

use trust_dns::client::{Client as _Client, SyncClient};
use trust_dns::rr::dns_class::DNSClass;
use trust_dns::rr::record_type::RecordType;
use trust_dns::rr::domain;
use trust_dns::rr::record_data::RData;
use trust_dns::udp::UdpClientConnection;

const NS1_GOOGLE_COM_IP_ADDR: &'static str = "216.239.32.10:53";

fn env_var(n: &str) -> String {
    let err = format!("Environment Variable '{}' must be set!", &n);
    env::var(n).ok().expect(&err)
}

// overloaded function. no body is treated as a get, body is treated as a put
fn cloudflare_api(url: &str, body: Option<String>) -> Result<Value, String> {
    let cloudflare_apikey = env_var("CLOUDFLARE_APIKEY");
    let cloudflare_email = env_var("CLOUDFLARE_EMAIL");

    let client = reqwest::Client::new();
    let request = match body {
        Some(body) => { client.put(url).body(body) }
        None => { client.get(url) }
    };
    let response_json : Value = request
        .header("X-Auth-Key", cloudflare_apikey.to_owned())
        .header("X-Auth-Email", cloudflare_email.to_owned())
        .send().unwrap()
        .json().unwrap();

    let success = response_json
        .as_object().unwrap()
        .get("success").unwrap()
        .as_bool().unwrap();
    if !success {
        return Err(format!("Request not successful: {}", response_json));
    }

    Ok(response_json)
}

fn get_current_ip() -> Result<String, ()> {
    let gdns_addr = (NS1_GOOGLE_COM_IP_ADDR).parse().expect("Couldn't get Google DNS Socket Addr");
    let conn = UdpClientConnection::new(gdns_addr).expect("Couldn't open DNS UDP Connection");
    let client = SyncClient::new(conn);

    let name = domain::Name::new();
    let name = name.append_label("o-o").unwrap()
        .append_label("myaddr").unwrap()
        .append_label("l").unwrap()
        .append_label("google").unwrap()
        .append_label("com").unwrap();
    let response = client.query(&name, DNSClass::IN, RecordType::TXT).unwrap();

    let record = &response.answers()[0];
    match record.rdata() {
        &RData::TXT(ref txt) => {
            let val = txt.txt_data();
            return Ok(String::from_utf8(val[0].to_vec()).unwrap())
        },
        _ => return Err(())
    }
}

fn main() {
    pretty_env_logger::init();

    let current_ip = get_current_ip().ok().expect("Was unable to determine current IP address.");
    info!("{}", current_ip);

    let cloudflare_records_env = env_var("CLOUDFLARE_RECORDS");
    let cloudflare_records: Vec<&str> = cloudflare_records_env.split(|c: char| c == ',').collect();

    let zones_url = "https://api.cloudflare.com/client/v4/zones";
    let zones_json = cloudflare_api(zones_url, None).unwrap();

    let zone_ids = zones_json
        .as_object().unwrap()
        .get("result").unwrap()
        .as_array().unwrap()
        .iter()
        .map(|ref zone_node|
             zone_node.get("id").unwrap()
             .as_str().unwrap());

    for zone_id in zone_ids {
        let records_url = format!("https://api.cloudflare.com/client/v4/zones/{}/dns_records", zone_id);
        let records_json = cloudflare_api(&*records_url, None).unwrap();

        let records = records_json
            .as_object().unwrap()
            .get("result").unwrap()
            .as_array().unwrap()
            .iter();

        for record in records {
            let record_id = record.get("id").unwrap().as_str().unwrap();
            let record_type = record.get("type").unwrap().as_str().unwrap();
            let record_name = record.get("name").unwrap().as_str().unwrap();
            let record_content = record.get("content").unwrap().as_str().unwrap();

            if !cloudflare_records.contains(&record_name) || record_type != "A" {
                continue
            }

            if record_content == current_ip {
                info!("{} skipped, up to date", record_name);
                continue;
            }

            print!("{} ({} -> {})... ", record_name, record_content, current_ip);
            io::stdout().flush().ok();

            let record_url = format!(
                "https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}",
                zone_id,
                record_id);
            let record_update_body = format!(
                r#"{{"name": "{}", "content": "{}", "type": "{}"}}"#,
                record_name,
                current_ip,
                record_type);
            cloudflare_api(&*record_url, Some(record_update_body.to_string())).unwrap();
        }
    }
}
<commit_msg>Mark DNS records as proxied by default<commit_after>extern crate log;
extern crate pretty_env_logger;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
extern crate trust_dns;

use log::info;

use serde_json::value::*;

use std::env;
use std::io;
use std::io::prelude::*;

use trust_dns::client::{Client as _Client, SyncClient};
use trust_dns::rr::dns_class::DNSClass;
use trust_dns::rr::record_type::RecordType;
use trust_dns::rr::domain;
use trust_dns::rr::record_data::RData;
use trust_dns::udp::UdpClientConnection;

const NS1_GOOGLE_COM_IP_ADDR: &'static str = "216.239.32.10:53";

fn env_var(n: &str) -> String {
    let err = format!("Environment Variable '{}' must be set!", &n);
    env::var(n).ok().expect(&err)
}

// overloaded function. no body is treated as a get, body is treated as a put
fn cloudflare_api(url: &str, body: Option<String>) -> Result<Value, String> {
    let cloudflare_apikey = env_var("CLOUDFLARE_APIKEY");
    let cloudflare_email = env_var("CLOUDFLARE_EMAIL");

    let client = reqwest::Client::new();
    let request = match body {
        Some(body) => { client.put(url).body(body) }
        None => { client.get(url) }
    };
    let response_json : Value = request
        .header("X-Auth-Key", cloudflare_apikey.to_owned())
        .header("X-Auth-Email", cloudflare_email.to_owned())
        .send().unwrap()
        .json().unwrap();

    let success = response_json
        .as_object().unwrap()
        .get("success").unwrap()
        .as_bool().unwrap();
    if !success {
        return Err(format!("Request not successful: {}", response_json));
    }

    Ok(response_json)
}

fn get_current_ip() -> Result<String, ()> {
    let gdns_addr = (NS1_GOOGLE_COM_IP_ADDR).parse().expect("Couldn't get Google DNS Socket Addr");
    let conn = UdpClientConnection::new(gdns_addr).expect("Couldn't open DNS UDP Connection");
    let client = SyncClient::new(conn);

    let name = domain::Name::new();
    let name = name.append_label("o-o").unwrap()
        .append_label("myaddr").unwrap()
        .append_label("l").unwrap()
        .append_label("google").unwrap()
        .append_label("com").unwrap();
    let response = client.query(&name, DNSClass::IN, RecordType::TXT).unwrap();

    let record = &response.answers()[0];
    match record.rdata() {
        &RData::TXT(ref txt) => {
            let val = txt.txt_data();
            return Ok(String::from_utf8(val[0].to_vec()).unwrap())
        },
        _ => return Err(())
    }
}

fn main() {
    pretty_env_logger::init();

    let current_ip = get_current_ip().ok().expect("Was unable to determine current IP address.");
    info!("{}", current_ip);

    let cloudflare_records_env = env_var("CLOUDFLARE_RECORDS");
    let cloudflare_records: Vec<&str> = cloudflare_records_env.split(|c: char| c == ',').collect();

    let zones_url = "https://api.cloudflare.com/client/v4/zones";
    let zones_json = cloudflare_api(zones_url, None).unwrap();

    let zone_ids = zones_json
        .as_object().unwrap()
        .get("result").unwrap()
        .as_array().unwrap()
        .iter()
        .map(|ref zone_node|
             zone_node.get("id").unwrap()
             .as_str().unwrap());

    for zone_id in zone_ids {
        let records_url = format!("https://api.cloudflare.com/client/v4/zones/{}/dns_records", zone_id);
        let records_json = cloudflare_api(&*records_url, None).unwrap();

        let records = records_json
            .as_object().unwrap()
            .get("result").unwrap()
            .as_array().unwrap()
            .iter();

        for record in records {
            let record_id = record.get("id").unwrap().as_str().unwrap();
            let record_type = record.get("type").unwrap().as_str().unwrap();
            let record_name = record.get("name").unwrap().as_str().unwrap();
            let record_content = record.get("content").unwrap().as_str().unwrap();

            if !cloudflare_records.contains(&record_name) || record_type != "A" {
                continue
            }

            if record_content == current_ip {
                info!("{} skipped, up to date", record_name);
                continue;
            }

            print!("{} ({} -> {})... ", record_name, record_content, current_ip);
            io::stdout().flush().ok();

            let record_url = format!(
                "https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}",
                zone_id,
                record_id);
            let record_update_body = format!(
                r#"{{"name": "{}", "content": "{}", "type": "{}", "proxied": true}}"#,
                record_name,
                current_ip,
                record_type);
            cloudflare_api(&*record_url, Some(record_update_body.to_string())).unwrap();
        }
    }
}
<|endoftext|>


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

extern crate oak_runtime;
use oak_runtime::*;

use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;

grammar! awesome {
    #![show_api]

    program
        = ((expr / decl / stmt) terminator?)*

    decl
        = class_decl > class_decl
        / method_decl > method_decl

    class_decl
        = kw_class spacing ident class_body

    class_body
        = lbracket method_decl* rbracket

    method_decl
        = kw_def spacing ident lparen param_list? rparen block

    block
        = lbracket ((stmt / expr) terminator?)* rbracket

    stmt
        = if_stmt > if_stmt
        / while_stmt > while_stmt

    if_stmt
        = kw_if expr block (kw_else block)?

    while_stmt
        = kw_while expr block

    assign_expr
        = ident bind_op expr

    expr = cond_expr

    cond_expr
        = spacing add_expr (cond_expr_op add_expr)* > fold_left

    add_expr
        = mult_expr (add_expr_op mult_expr)* > fold_left

    mult_expr
        = primary_expr (mult_expr_op primary_expr)* > fold_left

    primary_expr
        = assign_expr > assign_expr
        / call > call_expr
        / string > string_expr
        / number > number_expr
        / ident > variable_expr
        / lparen expr rparen

    call
        = (ident ".")? ident lparen arg_list? rparen

    arg_list
        = (expr ("," spacing expr)*)

    param_list
        = (ident ("," spacing ident)*)

    add_expr_op
        = add_op > add_bin_op
        / sub_op > sub_bin_op

    mult_expr_op
        = mul_op > mul_bin_op
        / div_op > div_bin_op

    cond_expr_op
        = lt_op > lt_bin_op /
        lte_op > lte_bin_op /
        gt_op > gt_bin_op /
        gte_op > gte_bin_op /
        ne_op > ne_bin_op /
        eq_op > eq_bin_op /
        andand_op > and_bin_op /
        oror_op > or_bin_op

    ident = !digit !keyword ident_char+ spacing > to_string
    ident_char = ["a-zA-Z0-9_"]
    sym_char = ["!@#$%^&*()-=_+[]\\{}|;:,./<>? \n\r\t"]

    digit = ["0-9"]
    number = digit+ spacing > to_number
    string = (dbl_quot_string / sng_quot_string) spacing
    dbl_quot_string = dbl_quot (ident_char / digit / sym_char)* dbl_quot
    sng_quot_string = sng_quot (ident_char / digit / sym_char)* sng_quot
    spacing = [" \n\r\t"]* -> ()

    kw_def = "def"
    kw_class = "class"
    kw_true = "true"
    kw_false = "false"
    kw_nil = "nil"
    kw_if = "if"
    kw_else = "else"
    kw_while = "while"
    kw_tail = !ident_char spacing

    keyword
        = kw_def
        / kw_if
        / kw_else
        / kw_class
        / kw_true
        / kw_false
        / kw_nil
        / kw_tail

    bind_op = "=" spacing
    add_op = "+" spacing
    sub_op = "-" spacing
    mul_op = "*" spacing
    div_op = "/" spacing
    lt_op = "<" spacing
    lte_op = "<=" spacing
    gt_op = ">" spacing
    gte_op = ">=" spacing
    ne_op = "!=" spacing
    eq_op = "==" spacing
    andand_op  = "&&" spacing
    oror_op = "||" spacing

    lparen = "(" spacing
    rparen = ")" spacing
    lbracket = spacing "{" spacing
    rbracket = spacing "}" spacing
    dbl_quot = "\""
    sng_quot = "'"

    terminator = ";" spacing

    use std::str::FromStr;
    use self::Expression::*;
    use self::BinOp::*;

    pub type PExpr = Box<Expression>;

    #[derive(Debug)]
    pub enum Expression {
        Variable(String),
        NumberLiteral(u32),
        StringLiteral(String),
        BinaryExpr(BinOp, PExpr, PExpr),
        Call(Option<String>, String, Option<(PExpr, Vec<PExpr>)>),
        AssingExpr(String, PExpr),
        MethodDecl(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>),
        ClassDecl(String, Vec<(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>)>),
        IfStatement(PExpr, Vec<(PExpr, Option<()>)>, Option<Vec<(PExpr, Option<()>)>>),
        WhileStatement(PExpr, Vec<(PExpr, Option<()>)>),
        Block(Vec<PExpr>)
    }

    #[derive(Debug)]
    pub enum BinOp {
        Add, Sub, Mul, Div, Lt, Lte, Gt, Gte, Ne, Eq, And, Or
    }

    fn to_number(raw_text: Vec<char>) -> u32 {
        u32::from_str(&*to_string(raw_text)).unwrap()
    }

    fn number_expr(value: u32) -> PExpr {
        Box::new(NumberLiteral(value))
    }

    fn string_expr(raw_text: Vec<char>) -> PExpr {
        Box::new(StringLiteral(to_string(raw_text)))
    }

    fn variable_expr(ident: String) -> PExpr {
        Box::new(Variable(ident))
    }

    fn to_string(raw_text: Vec<char>) -> String {
        raw_text.into_iter().collect()
    }

    fn fold_left(head: PExpr, rest: Vec<(BinOp, PExpr)>) -> PExpr {
        rest.into_iter().fold(head,
          |accu, (op, expr)| Box::new(BinaryExpr(op, accu, expr)))
    }

    fn fold_right(front: Vec<(PExpr, BinOp)>, last: PExpr) -> PExpr {
        front.into_iter().rev().fold(last,
          |accu, (expr, op)| Box::new(BinaryExpr(op, expr, accu)))
    }

    fn add_bin_op() -> BinOp { Add }
    fn sub_bin_op() -> BinOp { Sub }
    fn mul_bin_op() -> BinOp { Mul }
    fn div_bin_op() -> BinOp { Div }
    fn lt_bin_op() -> BinOp { Lt }
    fn lte_bin_op() -> BinOp { Lte }
    fn gt_bin_op() -> BinOp { Gt }
    fn gte_bin_op() -> BinOp { Gte }
    fn ne_bin_op() -> BinOp { Ne }
    fn eq_bin_op() -> BinOp { Eq }
    fn and_bin_op() -> BinOp { And }
    fn or_bin_op() -> BinOp { Or }

    fn call_expr(receiver: Option<String>, method: String, args: Option<(PExpr, Vec<PExpr>)>) -> PExpr {
        Box::new(Call(receiver, method, args))
    }

    fn assign_expr(variable: String, exp: PExpr) -> PExpr {
        Box::new(AssingExpr(variable, exp))
    }

    fn class_decl(name: String, methods: Vec<(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>)>) -> PExpr {
        Box::new(ClassDecl(name, methods))
    }

    fn method_decl(name: String, params: Option<(String, Vec<String>)>, body: Vec<(PExpr, Option<()>)>) -> PExpr {
        Box::new(MethodDecl(name, params, body))
    }

    fn if_stmt(condition: PExpr, block: Vec<(PExpr, Option<()>)>, else_block: Option<Vec<(PExpr, Option<()>)>>) -> PExpr {
        Box::new(IfStatement(condition, block, else_block))
    }

    fn while_stmt(condition: PExpr,  block: Vec<(PExpr, Option<()>)>) -> PExpr {
      Box::new(WhileStatement(condition, block))
    }
}

fn main() {
    let f = File::open("./src/example.awm").ok().expect("failed to open file");
    let mut reader = BufReader::new(f);
    let mut contents = String::new();
    reader.read_to_string(&mut contents);
    println!("{:?}", awesome::parse_program(contents.stream()));
}
<commit_msg>More reorganization of rules.<commit_after>#![feature(plugin)]
#![plugin(oak)]

extern crate oak_runtime;
use oak_runtime::*;

use std::io::prelude::*;
use std::fs::File;
use std::io::BufReader;

grammar! awesome {
    #![show_api]

    program
        = ((expr / decl / stmt) terminator?)*

    decl
        = class_decl > class_decl
        / method_decl > method_decl

    class_decl
        = kw_class spacing ident class_body

    class_body
        = lbracket method_decl* rbracket

    method_decl
        = kw_def spacing ident lparen param_list? rparen block

    block
        = lbracket ((stmt / expr) terminator?)* rbracket

    stmt
        = if_stmt > if_stmt
        / while_stmt > while_stmt

    if_stmt
        = kw_if expr block (kw_else block)?

    while_stmt
        = kw_while expr block

    assign_expr
        = ident bind_op expr

    expr = cond_expr

    cond_expr
        = spacing add_expr (cond_expr_op add_expr)* > fold_left

    add_expr
        = mult_expr (add_expr_op mult_expr)* > fold_left

    mult_expr
        = primary_expr (mult_expr_op primary_expr)* > fold_left

    primary_expr
        = assign_expr > assign_expr
        / call > call_expr
        / string > string_expr
        / number > number_expr
        / ident > variable_expr
        / lparen expr rparen

    call
        = (ident ".")? ident lparen arg_list? rparen

    arg_list
        = (expr ("," spacing expr)*)

    param_list
        = (ident ("," spacing ident)*)

    ident = !digit !keyword ident_char+ spacing > to_string
    ident_char = ["a-zA-Z0-9_"]
    sym_char = ["!@#$%^&*()-=_+[]\\{}|;:,./<>? \n\r\t"]

    digit = ["0-9"]
    number = digit+ spacing > to_number
    string = (dbl_quot_string / sng_quot_string) spacing
    dbl_quot_string = dbl_quot (ident_char / digit / sym_char)* dbl_quot
    sng_quot_string = sng_quot (ident_char / digit / sym_char)* sng_quot
    spacing = [" \n\r\t"]* -> ()

    kw_class = "class"
    kw_def = "def"
    kw_else = "else"
    kw_false = "false"
    kw_if = "if"
    kw_nil = "nil"
    kw_true = "true"
    kw_while = "while"

    keyword
        = kw_def
        / kw_if
        / kw_else
        / kw_class
        / kw_true
        / kw_false
        / kw_nil

    add_expr_op
        = add_op > add_bin_op
        / sub_op > sub_bin_op

    mult_expr_op
        = mul_op > mul_bin_op
        / div_op > div_bin_op

    cond_expr_op
        = lt_op > lt_bin_op /
        lte_op > lte_bin_op /
        gt_op > gt_bin_op /
        gte_op > gte_bin_op /
        ne_op > ne_bin_op /
        eq_op > eq_bin_op /
        andand_op > and_bin_op /
        oror_op > or_bin_op

    bind_op = "=" spacing
    add_op = "+" spacing
    sub_op = "-" spacing
    mul_op = "*" spacing
    div_op = "/" spacing
    lt_op = "<" spacing
    lte_op = "<=" spacing
    gt_op = ">" spacing
    gte_op = ">=" spacing
    ne_op = "!=" spacing
    eq_op = "==" spacing
    andand_op  = "&&" spacing
    oror_op = "||" spacing

    lparen = "(" spacing
    rparen = ")" spacing
    lbracket = spacing "{" spacing
    rbracket = spacing "}" spacing
    dbl_quot = "\""
    sng_quot = "'"

    terminator = ";" spacing

    use std::str::FromStr;
    use self::Expression::*;
    use self::BinOp::*;

    pub type PExpr = Box<Expression>;

    #[derive(Debug)]
    pub enum Expression {
        Variable(String),
        NumberLiteral(u32),
        StringLiteral(String),
        BinaryExpr(BinOp, PExpr, PExpr),
        Call(Option<String>, String, Option<(PExpr, Vec<PExpr>)>),
        AssingExpr(String, PExpr),
        MethodDecl(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>),
        ClassDecl(String, Vec<(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>)>),
        IfStatement(PExpr, Vec<(PExpr, Option<()>)>, Option<Vec<(PExpr, Option<()>)>>),
        WhileStatement(PExpr, Vec<(PExpr, Option<()>)>),
        Block(Vec<PExpr>)
    }

    #[derive(Debug)]
    pub enum BinOp {
        Add, Sub, Mul, Div, Lt, Lte, Gt, Gte, Ne, Eq, And, Or
    }

    fn to_number(raw_text: Vec<char>) -> u32 {
        u32::from_str(&*to_string(raw_text)).unwrap()
    }

    fn number_expr(value: u32) -> PExpr {
        Box::new(NumberLiteral(value))
    }

    fn string_expr(raw_text: Vec<char>) -> PExpr {
        Box::new(StringLiteral(to_string(raw_text)))
    }

    fn variable_expr(ident: String) -> PExpr {
        Box::new(Variable(ident))
    }

    fn to_string(raw_text: Vec<char>) -> String {
        raw_text.into_iter().collect()
    }

    fn fold_left(head: PExpr, rest: Vec<(BinOp, PExpr)>) -> PExpr {
        rest.into_iter().fold(head,
          |accu, (op, expr)| Box::new(BinaryExpr(op, accu, expr)))
    }

    fn fold_right(front: Vec<(PExpr, BinOp)>, last: PExpr) -> PExpr {
        front.into_iter().rev().fold(last,
          |accu, (expr, op)| Box::new(BinaryExpr(op, expr, accu)))
    }

    fn add_bin_op() -> BinOp { Add }
    fn sub_bin_op() -> BinOp { Sub }
    fn mul_bin_op() -> BinOp { Mul }
    fn div_bin_op() -> BinOp { Div }
    fn lt_bin_op() -> BinOp { Lt }
    fn lte_bin_op() -> BinOp { Lte }
    fn gt_bin_op() -> BinOp { Gt }
    fn gte_bin_op() -> BinOp { Gte }
    fn ne_bin_op() -> BinOp { Ne }
    fn eq_bin_op() -> BinOp { Eq }
    fn and_bin_op() -> BinOp { And }
    fn or_bin_op() -> BinOp { Or }

    fn call_expr(receiver: Option<String>, method: String, args: Option<(PExpr, Vec<PExpr>)>) -> PExpr {
        Box::new(Call(receiver, method, args))
    }

    fn assign_expr(variable: String, exp: PExpr) -> PExpr {
        Box::new(AssingExpr(variable, exp))
    }

    fn class_decl(name: String, methods: Vec<(String, Option<(String, Vec<String>)>, Vec<(PExpr, Option<()>)>)>) -> PExpr {
        Box::new(ClassDecl(name, methods))
    }

    fn method_decl(name: String, params: Option<(String, Vec<String>)>, body: Vec<(PExpr, Option<()>)>) -> PExpr {
        Box::new(MethodDecl(name, params, body))
    }

    fn if_stmt(condition: PExpr, block: Vec<(PExpr, Option<()>)>, else_block: Option<Vec<(PExpr, Option<()>)>>) -> PExpr {
        Box::new(IfStatement(condition, block, else_block))
    }

    fn while_stmt(condition: PExpr,  block: Vec<(PExpr, Option<()>)>) -> PExpr {
      Box::new(WhileStatement(condition, block))
    }
}

fn main() {
    let f = File::open("./src/example.awm").ok().expect("failed to open file");
    let mut reader = BufReader::new(f);
    let mut contents = String::new();
    reader.read_to_string(&mut contents);
    println!("{:?}", awesome::parse_program(contents.stream()));
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(raw_pointer_derive)]
#![feature(path_ext)]
#![feature(libc)]
#![feature(hashmap_hasher)]
#![feature(drain)]
#![feature(arc_counts)]
#![cfg_attr(test, feature(test))]
#![feature(str_match_indices)]

#[cfg(test)] extern crate test;
extern crate env_logger;
#[macro_use] extern crate log;
extern crate nix;
extern crate mio;
extern crate num_cpus;
extern crate threadpool;
extern crate time;
extern crate rustc_serialize;
extern crate toml;
extern crate linked_hash_map;
extern crate fnv;
extern crate spin;
extern crate libc;
extern crate rand;

mod config;
mod queue;
mod server;
mod protocol;
mod queue_backend;
mod utils;
mod rev;
mod atom;
mod cookie;
mod offset_index;

use config::ServerConfig;
use server::Server;

#[cfg(not(test))]
fn main() {
    env_logger::init().unwrap();
    info!("starting up");
    let server_config = ServerConfig::read();
    let (mut server_handler, mut ev_loop) = Server::new(server_config);
    info!("starting event loop");
    ev_loop.run(&mut server_handler).unwrap();
}
<commit_msg>move use to avoid warnings<commit_after>#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(raw_pointer_derive)]
#![feature(path_ext)]
#![feature(libc)]
#![feature(hashmap_hasher)]
#![feature(drain)]
#![feature(arc_counts)]
#![cfg_attr(test, feature(test))]
#![feature(str_match_indices)]

#[cfg(test)] extern crate test;
extern crate env_logger;
#[macro_use] extern crate log;
extern crate nix;
extern crate mio;
extern crate num_cpus;
extern crate threadpool;
extern crate time;
extern crate rustc_serialize;
extern crate toml;
extern crate linked_hash_map;
extern crate fnv;
extern crate spin;
extern crate libc;
extern crate rand;

mod config;
mod queue;
mod server;
mod protocol;
mod queue_backend;
mod utils;
mod rev;
mod atom;
mod cookie;
mod offset_index;

#[cfg(not(test))]
fn main() {
    use config::ServerConfig;
    use server::Server;

    env_logger::init().unwrap();
    info!("starting up");
    let server_config = ServerConfig::read();
    let (mut server_handler, mut ev_loop) = Server::new(server_config);
    info!("starting event loop");
    ev_loop.run(&mut server_handler).unwrap();
}
<|endoftext|>


<commit_before>type Num = f32;

/// Represents the state of a neuron.
struct State {
    /// membrane potential of neuron (in mV)
    v: Num,

    /// recovery variable
    u: Num
}

/// The neuron configuration parameters.
struct Config {

    /// Rate of recovery.
    a: Num,

    /// Sensitivity of recovery variable `u` to the membrane potential `v`.
    b: Num,

    /// After-spike reset value of membrane potential `v`.
    c: Num,

    /// After-spike reset of recovery variable `u`.
    d: Num
}

impl Config {
    /// Generates an excitatory neuron configuration according to Izhikevich's paper [reentry]
    /// where `r` is a random variable uniformly distributed in [0, 1].
    fn excitatory(r: Num) -> Config {
        debug_assert!(r >= 0.0 && r <= 1.0);

        let r2 = r*r;
        Config {
            a: 0.02,
            b: 0.2,
            c: -65.0 + 15.0 * r2,
            d: 8.0 - 6.0 * r2
        }
    }

    fn inhibitory(r: Num) -> Config {
        debug_assert!(r >= 0.0 && r <= 1.0);

        Config {
            a: 0.02 + 0.08 * r,
            b: 0.25 - 0.05 * r,
            c: -65.0,
            d: 2.0
        }
    }

    /// Regular spiking (RS) cell configuration.
    fn regular_spiking() -> Config {
        Config::excitatory(0.0)
    }

    /// Chattering (CH) cell configuration.
    fn chattering() -> Config {
        Config::excitatory(1.0)
    }
}

#[inline(always)]
fn dv(u: Num, v: Num, i_syn: Num) -> Num {
    0.04 * (v*v) + 5.0 * v + 140.0 - u - i_syn
}

#[inline(always)]
fn du(u: Num, v: Num, a: Num, b: Num) -> Num {
    a * (b*v - u)
}

impl State {
    /// Calculate the state after `dt` ms.
    #[inline(always)]
    fn calc(self, dt: Num, i_syn: Num, config: &Config) -> State {
        State {
            v: self.v + dt*dv(self.u, self.v, i_syn),
            u: self.u + dt*du(self.u, self.v, config.a, config.b)
        }
    }

    /// Checks if the neuron has fired, updates the state accordingly
    /// and return `true` in second parameter in this case.
    #[inline(always)]
    fn check_fired(self, config: &Config) -> (State, bool) {
        if self.v >= 30.0 {
            (State { v: config.c, u: self.u + config.d }, true)
        } else {
            (self, false)
        }
    }

    /// Calculate the new state after 1ms. Uses Eulers method for numerical stabilty.
    /// If second return parameter is true, then the neuron fired.
    fn step_1ms(self, i_syn: Num, config: &Config) -> (State, bool) {
        self.calc(0.5, i_syn, config).calc(0.5, i_syn, config).check_fired(config)
    }

    /// Calculate the state after `dt` ms. Does not use Eulers method.
    fn _step(self, dt: Num, i_syn: Num, config: &Config) -> (State, bool) {
        self.calc(dt, i_syn, config).check_fired(config)
    }
}

fn main() {
}
<commit_msg>Euler method -> first-order Euler<commit_after>type Num = f32;

/// Represents the state of a neuron.
struct State {
    /// membrane potential of neuron (in mV)
    v: Num,

    /// recovery variable
    u: Num
}

/// The neuron configuration parameters.
struct Config {

    /// Rate of recovery.
    a: Num,

    /// Sensitivity of recovery variable `u` to the membrane potential `v`.
    b: Num,

    /// After-spike reset value of membrane potential `v`.
    c: Num,

    /// After-spike reset of recovery variable `u`.
    d: Num
}

impl Config {
    /// Generates an excitatory neuron configuration according to Izhikevich's paper [reentry]
    /// where `r` is a random variable uniformly distributed in [0, 1].
    fn excitatory(r: Num) -> Config {
        debug_assert!(r >= 0.0 && r <= 1.0);

        let r2 = r*r;
        Config {
            a: 0.02,
            b: 0.2,
            c: -65.0 + 15.0 * r2,
            d: 8.0 - 6.0 * r2
        }
    }

    fn inhibitory(r: Num) -> Config {
        debug_assert!(r >= 0.0 && r <= 1.0);

        Config {
            a: 0.02 + 0.08 * r,
            b: 0.25 - 0.05 * r,
            c: -65.0,
            d: 2.0
        }
    }

    /// Regular spiking (RS) cell configuration.
    fn regular_spiking() -> Config {
        Config::excitatory(0.0)
    }

    /// Chattering (CH) cell configuration.
    fn chattering() -> Config {
        Config::excitatory(1.0)
    }
}

#[inline(always)]
fn dv(u: Num, v: Num, i_syn: Num) -> Num {
    0.04 * (v*v) + 5.0 * v + 140.0 - u - i_syn
}

#[inline(always)]
fn du(u: Num, v: Num, a: Num, b: Num) -> Num {
    a * (b*v - u)
}

impl State {
    /// Calculate the state after `dt` ms.
    #[inline(always)]
    fn calc(self, dt: Num, i_syn: Num, config: &Config) -> State {
        State {
            v: self.v + dt*dv(self.u, self.v, i_syn),
            u: self.u + dt*du(self.u, self.v, config.a, config.b)
        }
    }

    /// Checks if the neuron has fired, updates the state accordingly
    /// and return `true` in second parameter in this case.
    #[inline(always)]
    fn check_fired(self, config: &Config) -> (State, bool) {
        if self.v >= 30.0 {
            (State { v: config.c, u: self.u + config.d }, true)
        } else {
            (self, false)
        }
    }

    /// Calculate the new state after 1ms. Uses first-order Euler method for numerical stabilty.
    /// If second return parameter is true, then the neuron fired.
    fn step_1ms(self, i_syn: Num, config: &Config) -> (State, bool) {
        self.calc(0.5, i_syn, config).calc(0.5, i_syn, config).check_fired(config)
    }

    /// Calculate the state after `dt` ms. Does not use first-order Euler method.
    fn _step(self, dt: Num, i_syn: Num, config: &Config) -> (State, bool) {
        self.calc(dt, i_syn, config).check_fired(config)
    }
}

fn main() {
}
<|endoftext|>


<commit_before>use bit_field::BitField;
use std::fmt::Debug;
use thiserror::Error;

#[derive(Debug, Error)]
enum DecodeError {
    #[error("Invalid ESR, res0 is {res0}")]
    InvalidRes0 { res0: u64 },
    #[error("Invalid EC {ec}")]
    InvalidEc { ec: u64 },
}

fn decode(esr: u64) -> Result<String, DecodeError> {
    let res0 = esr.get_bits(37..64);
    let iss2 = esr.get_bits(32..37);
    let ec = esr.get_bits(26..32);
    let il = esr.get_bit(25);
    let iss = esr.get_bits(0..25);
    if res0 != 0 {
        return Err(DecodeError::InvalidRes0 { res0 });
    }
    let class = match ec {
        0b000000 => "Unknown reason",
        0b000001 => "Wrapped WF* instruction execution",
        0b000011 => "Trapped MCR or MRC access with coproc=0b1111",
        0b000100 => "Trapped MCRR or MRRC access with coproc=0b1111",
        0b000101 => "Trapped MCR or MRC access with coproc=0b1110",
        0b000110 => "Trapped LDC or STC access",
        0b000111 => "Trapped access to SVE, Advanced SIMD or floating point",
        0b001010 => "Trapped execution of an LD64B, ST64B, ST64BV, or ST64BV0 instruction",
        0b001100 => "Trapped MRRC access with (coproc==0b1110)",
        0b001101 => "Branch Target Exception",
        0b001110 => "Illegal Execution state",
        0b010001 => "SVC instruction execution in AArch32 state",
        0b010101 => "SVC instruction execution in AArch64 state",
        0b011000 => "Trapped MSR, MRS or System instruction execution in AArch64 state, that is not reported using EC 0b000000, 0b000001, or 0b000111",
        0b011001 => "Access to SVE functionality trapped as a result of CPACR_EL1.ZEN, CPTR_EL2.ZEN, CPTR_EL2.TZ, or CPTR_EL3.EZ, that is not reported using EC 0b000000",
        0b011100 => "Exception from a Pointer Authentication instruction authentication failure",
        0b100000 => "Instruction Abort from a lower Exception level",
        0b100001 => "Instruction Abort taken without a change in Exception level",
        0b100010 => "PC alignment fault exception",
        0b100100 => "Data Abort from a lower Exception level",
        0b100101 => "Data Abort taken without a change in Exception level",
        0b100110 => "SP alignment fault exception",
        0b101000 => "Trapped floating-point exception taken from AArch32 state",
        0b101100 => "Trapped floating-point exception taken from AArch64 state",
        0b101111 => "SError interrupt",
        0b110000 => "Breakpoint exception from a lower Exception level",
        0b110001 => "Breakpoint exception taken without a change in Exception level",
        0b110010 => "Software Step exception from a lower Exception level",
        0b110011 => "Software Step exception taken without a change in Exception level",
        0b110100 => "Watchpoint exception from a lower Exception level",
        0b110101 => "Watchpoint exception taken without a change in Exception level",
        0b111000 => "BKPT instruction execution in AArch32 state",
        0b111100 => "BRK instruction execution in AArch64 state",
        _ => return Err(DecodeError::InvalidEc { ec }),
    };
    Ok(format!(
        "EC:{:#08b} '{}', IL:{}, ISS:{:#x}, ISS2:{:#x}",
        ec, class, il, iss, iss2
    ))
}

fn main() {
    let esr = 2516582480;
    println!("{:#034x}: {}", esr, decode(esr).unwrap());
}
<commit_msg>Shorten some messages.<commit_after>use bit_field::BitField;
use std::fmt::Debug;
use thiserror::Error;

#[derive(Debug, Error)]
enum DecodeError {
    #[error("Invalid ESR, res0 is {res0}")]
    InvalidRes0 { res0: u64 },
    #[error("Invalid EC {ec}")]
    InvalidEc { ec: u64 },
}

fn decode(esr: u64) -> Result<String, DecodeError> {
    let res0 = esr.get_bits(37..64);
    let iss2 = esr.get_bits(32..37);
    let ec = esr.get_bits(26..32);
    let il = esr.get_bit(25);
    let iss = esr.get_bits(0..25);
    if res0 != 0 {
        return Err(DecodeError::InvalidRes0 { res0 });
    }
    let class = match ec {
        0b000000 => "Unknown reason",
        0b000001 => "Wrapped WF* instruction execution",
        0b000011 => "Trapped MCR or MRC access with coproc=0b1111",
        0b000100 => "Trapped MCRR or MRRC access with coproc=0b1111",
        0b000101 => "Trapped MCR or MRC access with coproc=0b1110",
        0b000110 => "Trapped LDC or STC access",
        0b000111 => "Trapped access to SVE, Advanced SIMD or floating point",
        0b001010 => "Trapped execution of an LD64B, ST64B, ST64BV, or ST64BV0 instruction",
        0b001100 => "Trapped MRRC access with (coproc==0b1110)",
        0b001101 => "Branch Target Exception",
        0b001110 => "Illegal Execution state",
        0b010001 => "SVC instruction execution in AArch32 state",
        0b010101 => "SVC instruction execution in AArch64 state",
        0b011000 => "Trapped MSR, MRS or System instruction execution in AArch64 state",
        0b011001 => "Access to SVE functionality trapped as a result of CPACR_EL1.ZEN, CPTR_EL2.ZEN, CPTR_EL2.TZ, or CPTR_EL3.EZ",
        0b011100 => "Exception from a Pointer Authentication instruction authentication failure",
        0b100000 => "Instruction Abort from a lower Exception level",
        0b100001 => "Instruction Abort taken without a change in Exception level",
        0b100010 => "PC alignment fault exception",
        0b100100 => "Data Abort from a lower Exception level",
        0b100101 => "Data Abort taken without a change in Exception level",
        0b100110 => "SP alignment fault exception",
        0b101000 => "Trapped floating-point exception taken from AArch32 state",
        0b101100 => "Trapped floating-point exception taken from AArch64 state",
        0b101111 => "SError interrupt",
        0b110000 => "Breakpoint exception from a lower Exception level",
        0b110001 => "Breakpoint exception taken without a change in Exception level",
        0b110010 => "Software Step exception from a lower Exception level",
        0b110011 => "Software Step exception taken without a change in Exception level",
        0b110100 => "Watchpoint exception from a lower Exception level",
        0b110101 => "Watchpoint exception taken without a change in Exception level",
        0b111000 => "BKPT instruction execution in AArch32 state",
        0b111100 => "BRK instruction execution in AArch64 state",
        _ => return Err(DecodeError::InvalidEc { ec }),
    };
    Ok(format!(
        "EC:{:#08b} '{}', IL:{}, ISS:{:#x}, ISS2:{:#x}",
        ec, class, il, iss, iss2
    ))
}

fn main() {
    let esr = 2516582480;
    println!("{:#034x}: {}", esr, decode(esr).unwrap());
}
<|endoftext|>


<commit_before>#![feature(globs)]
extern crate libc;

use libc::{c_int, size_t};
use std::io;
use std::ptr;
use std::mem;
use std::io::process::{Command, StdioContainer};

use termios::*;
use signal::*;
use constants::*;

mod termios;
mod signal;
mod constants;

type Stdr = io::stdio::StdinReader;
type Stdw = io::LineBufferedWriter<io::stdio::StdWriter>;

// start off as null pointer
static mut instate_location:size_t = 0;

struct InputState {
    line: Vec<String>,
    word: String,
    part: String,
    bpart: String
}

impl InputState {
    fn new() -> InputState {
        InputState {
            line: Vec::<String>::new(),
            word: String::new(),
            part: String::new(),
            bpart: String::new()
        }
    }

    fn clear(&mut self) {
        self.word.clear();
        self.line.clear();
        self.part.clear();
        self.bpart.clear();
    }
}

#[allow(unused_variables)]
unsafe extern fn handle_sigint(signum:c_int, siginfo:*const SigInfo, context:size_t) {
    if instate_location == 0 {
        panic!("Shell state location uninitialized");
    }
    print!("^C\n");
    // Below: completely disregarding everything Rust stands for
    let state:&mut InputState = mem::transmute(instate_location);
    state.clear();
    io::stdio::flush();
}

fn set_instate_location(state:&mut InputState) {
    unsafe {
        if instate_location != 0 {
            panic!("Tried to set shell state location twice");
        }
        instate_location = mem::transmute::<&mut InputState, size_t>(state);
    }
}

fn prepare_terminal(tios:&mut Termios) {
    tios.ldisable(ICANON);
    tios.ldisable(ECHO);
}

fn update_terminal(tios:Termios, stderr:&mut Stdw) -> bool {
    if !tios.set() {
        stderr.write_str("Warning: Could not set terminal mode\n").unwrap();
        return false;
    }
    return true;
}

fn handle_escape(stdin:&mut Stdr, stdout:&mut Stdw,
                 line:&mut Vec<String>, word:&mut String,
                 part:&mut String, bpart:&mut String) {
    // Handle an ANSI escape sequence
    if stdin.read_char() != Ok(ANSI) {
        return;
    }
    match stdin.read_char() {
        Err(_) => return,
        Ok('D') => {
            // left
            match word.pop() {
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    part.push(c);
                    cursor_left(stdout);
                },
                None => match line.pop() {
                    Some(s) => {
                        part.push(' ');
                        word.clear();
                        word.push_str(s.as_slice());
                        cursor_left(stdout);
                    }
                    None => return
                }
            }
        },
        Ok('C') => {
            // right
            match part.pop() {
                Some(' ') => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    line.push(word.clone());
                    word.clear();
                    cursor_right(stdout);
                },
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    word.push(c);
                    cursor_right(stdout);
                },
                None => return
            }
        },
        Ok(_) => return
    }
}

fn build_string(ch:char, count:uint) -> String {
    let mut s = String::new();
    let mut i = 0u;
    loop {
        if i == count {
            return s;
        }
        i += 1;
        s.push(ch);
    }
}

fn cursor_left(stdout:&mut Stdw) {
    stdout.write_char(DEL).unwrap();
}

fn cursor_right(stdout:&mut Stdw) {
    stdout.write(&[ESC as u8, ANSI as u8, 'C' as u8]).unwrap();
}

fn draw_part(part:&String, bpart:&mut String) {
    // quick out if part is empty
    if part.is_empty() {
        return;
    }
    if bpart.is_empty() {
        // only calculate bpart when it needs to be recalculated
        let mut cpart = part.clone();
        loop {
            match cpart.pop() {
                Some(c) => bpart.push(c),
                None => break
            }
        }
    }
    print!("{}", bpart);
}

fn cursors_left(by:uint) {
    // move back by a given number of characters
    print!("{}", build_string(DEL, by));
}

fn idraw_part(part:&String, bpart:&mut String) {
    // in-place draw of the line part
    draw_part(part, bpart);
    cursors_left(part.len());
}

fn prepare_signals(stderr:&mut Stdw) {
    let mut sa = SigAction {
        handler: handle_sigint,
        mask: [0; SIGSET_NWORDS],
        flags: SA_RESTART | SA_SIGINFO
    };
    unsafe {
        if sigfillset(&mut sa.mask) != 0 {
            stderr.write_str("Warning: could not fill mask set for SIGINT handler\n").unwrap();
        }
        if sigaction(SIGINT, &sa, ptr::null_mut::<SigAction>()) != 0 {
            stderr.write_str("Warning: could not set handler for SIGINT\n").unwrap();
        }
    }
}

fn run_command(line:&Vec<String>) {
    let mut process = Command::new(&line[0]);
    process.args(line.slice_from(1));
    process.stdout(StdioContainer::InheritFd(STDOUT));
    process.stdin(StdioContainer::InheritFd(STDIN));
    process.stderr(StdioContainer::InheritFd(STDERR));
    let mut child = match process.spawn() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't spawn {}: {}\n", &line[0], e)).unwrap();
            return;
        },
        Ok(child) => child
    };
    match child.wait() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't wait for child to exit: {}\n", e.desc)).unwrap();
        },
        Ok(_) => {
            // nothing
        }
    };
}

fn main() {
    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut stderr = io::stderr();
    prepare_signals(&mut stderr);
    let mut tios = Termios::new();
    tios.get();
    let old_tios = tios.clone();
    prepare_terminal(&mut tios);
    update_terminal(tios, &mut stderr);
    let mut state = InputState::new();
    set_instate_location(&mut state);
    loop {
        // Note: in non-canonical mode
        match stdin.read_char() {
            Ok(EOF) => {
                if state.line.is_empty() && state.word.is_empty() {
                    break;
                }
            },
            Ok(NL) => {
                // start command output on next line
                stdout.write_char(NL).unwrap();
                // push any remaining word onto the line
                if !state.word.is_empty() {
                    state.line.push(state.word.clone());
                }
                // run command if one was specified
                if !state.line.is_empty() {
                    // run command
                    update_terminal(old_tios, &mut stderr);
                    run_command(&state.line);
                    update_terminal(tios, &mut stderr);
                }
                // clear the state
                state.clear();
            },
            Ok(DEL) => {
                if state.word.is_empty() {
                    state.word = match state.line.pop() {
                        Some(s) => s,
                        None => continue
                    };
                    cursor_left(&mut stdout);
                } else {
                    state.word.pop();
                    cursor_left(&mut stdout);
                    draw_part(&state.part, &mut state.bpart);
                    stdout.write_char(NL).unwrap();
                    cursors_left(state.part.len() + 1);
                }
            },
            Ok(ESC) => handle_escape(&mut stdin, &mut stdout,
                                     &mut state.line, &mut state.word,
                                     &mut state.part, &mut state.bpart),
            Ok(SPC) => {
                state.line.push(state.word.clone());
                state.word.clear();
                stdout.write_char(SPC).unwrap();
                idraw_part(&state.part, &mut state.bpart);
            },
            Ok(c) => {
                state.word.push(c);
                stdout.write_char(c).unwrap();
                idraw_part(&state.part, &mut state.bpart);
            },
            Err(e) => {
                stdout.write_fmt(format_args!("Error: {}\n", e)).unwrap();
                break;
            }
        }
        // flush output
        stdout.flush().unwrap();
    }
    stdout.write_str("Exiting\n").unwrap();
    // restore old term state
    update_terminal(old_tios, &mut stderr);
}
<commit_msg>Fix backspace issues<commit_after>#![feature(globs)]
extern crate libc;

use libc::{c_int, size_t};
use std::io;
use std::ptr;
use std::mem;
use std::io::process::{Command, StdioContainer};

use termios::*;
use signal::*;
use constants::*;

mod termios;
mod signal;
mod constants;

type Stdr = io::stdio::StdinReader;
type Stdw = io::LineBufferedWriter<io::stdio::StdWriter>;

// start off as null pointer
static mut instate_location:size_t = 0;

struct InputState {
    line: Vec<String>,
    word: String,
    part: String,
    bpart: String
}

impl InputState {
    fn new() -> InputState {
        InputState {
            line: Vec::<String>::new(),
            word: String::new(),
            part: String::new(),
            bpart: String::new()
        }
    }

    fn clear(&mut self) {
        self.word.clear();
        self.line.clear();
        self.part.clear();
        self.bpart.clear();
    }
}

#[allow(unused_variables)]
unsafe extern fn handle_sigint(signum:c_int, siginfo:*const SigInfo, context:size_t) {
    if instate_location == 0 {
        panic!("Shell state location uninitialized");
    }
    print!("^C\n");
    // Below: completely disregarding everything Rust stands for
    let state:&mut InputState = mem::transmute(instate_location);
    state.clear();
    io::stdio::flush();
}

fn set_instate_location(state:&mut InputState) {
    unsafe {
        if instate_location != 0 {
            panic!("Tried to set shell state location twice");
        }
        instate_location = mem::transmute::<&mut InputState, size_t>(state);
    }
}

fn prepare_terminal(tios:&mut Termios) {
    tios.ldisable(ICANON);
    tios.ldisable(ECHO);
}

fn update_terminal(tios:Termios, stderr:&mut Stdw) -> bool {
    if !tios.set() {
        stderr.write_str("Warning: Could not set terminal mode\n").unwrap();
        return false;
    }
    return true;
}

fn handle_escape(stdin:&mut Stdr, stdout:&mut Stdw,
                 line:&mut Vec<String>, word:&mut String,
                 part:&mut String, bpart:&mut String) {
    // Handle an ANSI escape sequence
    if stdin.read_char() != Ok(ANSI) {
        return;
    }
    match stdin.read_char() {
        Err(_) => return,
        Ok('D') => {
            // left
            match word.pop() {
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    part.push(c);
                    cursor_left(stdout);
                },
                None => match line.pop() {
                    Some(s) => {
                        part.push(' ');
                        word.clear();
                        word.push_str(s.as_slice());
                        cursor_left(stdout);
                    }
                    None => return
                }
            }
        },
        Ok('C') => {
            // right
            match part.pop() {
                Some(' ') => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    line.push(word.clone());
                    word.clear();
                    cursor_right(stdout);
                },
                Some(c) => {
                    if !bpart.is_empty() {
                        bpart.clear();
                    }
                    word.push(c);
                    cursor_right(stdout);
                },
                None => return
            }
        },
        Ok(_) => return
    }
}

fn build_string(ch:char, count:uint) -> String {
    let mut s = String::new();
    let mut i = 0u;
    loop {
        if i == count {
            return s;
        }
        i += 1;
        s.push(ch);
    }
}

fn cursor_left(stdout:&mut Stdw) {
    stdout.write_char(DEL).unwrap();
}

fn cursor_right(stdout:&mut Stdw) {
    stdout.write(&[ESC as u8, ANSI as u8, 'C' as u8]).unwrap();
}

fn draw_part(part:&String, bpart:&mut String, stdout:&mut Stdw) {
    // quick out if part is empty
    if part.is_empty() {
        return;
    }
    if bpart.is_empty() {
        // only calculate bpart when it needs to be recalculated
        let mut cpart = part.clone();
        loop {
            match cpart.pop() {
                Some(c) => bpart.push(c),
                None => break
            }
        }
    }
    stdout.write_str(bpart.as_slice()).unwrap();
}

fn cursors_left(by:uint) {
    // move back by a given number of characters
    print!("{}", build_string(DEL, by));
}

fn idraw_part(part:&String, bpart:&mut String, stdout:&mut Stdw) {
    // in-place draw of the line part
    draw_part(part, bpart, stdout);
    cursors_left(part.len());
}

fn prepare_signals(stderr:&mut Stdw) {
    let mut sa = SigAction {
        handler: handle_sigint,
        mask: [0; SIGSET_NWORDS],
        flags: SA_RESTART | SA_SIGINFO
    };
    unsafe {
        if sigfillset(&mut sa.mask) != 0 {
            stderr.write_str("Warning: could not fill mask set for SIGINT handler\n").unwrap();
        }
        if sigaction(SIGINT, &sa, ptr::null_mut::<SigAction>()) != 0 {
            stderr.write_str("Warning: could not set handler for SIGINT\n").unwrap();
        }
    }
}

fn run_command(line:&Vec<String>) {
    let mut process = Command::new(&line[0]);
    process.args(line.slice_from(1));
    process.stdout(StdioContainer::InheritFd(STDOUT));
    process.stdin(StdioContainer::InheritFd(STDIN));
    process.stderr(StdioContainer::InheritFd(STDERR));
    let mut child = match process.spawn() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't spawn {}: {}\n", &line[0], e)).unwrap();
            return;
        },
        Ok(child) => child
    };
    match child.wait() {
        Err(e) => {
            io::stderr().write_fmt(format_args!("Couldn't wait for child to exit: {}\n", e.desc)).unwrap();
        },
        Ok(_) => {
            // nothing
        }
    };
}

fn main() {
    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut stderr = io::stderr();
    prepare_signals(&mut stderr);
    let mut tios = Termios::new();
    tios.get();
    let old_tios = tios.clone();
    prepare_terminal(&mut tios);
    update_terminal(tios, &mut stderr);
    let mut state = InputState::new();
    set_instate_location(&mut state);
    loop {
        // Note: in non-canonical mode
        match stdin.read_char() {
            Ok(EOF) => {
                if state.line.is_empty() && state.word.is_empty() {
                    break;
                }
            },
            Ok(NL) => {
                // start command output on next line
                stdout.write_char(NL).unwrap();
                // push any remaining word onto the line
                if !state.word.is_empty() {
                    state.line.push(state.word.clone());
                }
                // run command if one was specified
                if !state.line.is_empty() {
                    // run command
                    update_terminal(old_tios, &mut stderr);
                    run_command(&state.line);
                    update_terminal(tios, &mut stderr);
                }
                // clear the state
                state.clear();
            },
            Ok(DEL) => {
                if state.word.is_empty() {
                    state.word = match state.line.pop() {
                        Some(s) => s,
                        None => continue
                    };
                } else {
                    state.word.pop();
                }
                cursor_left(&mut stdout);
                draw_part(&state.part, &mut state.bpart, &mut stdout);
                stdout.write_char(SPC).unwrap();
                cursors_left(state.part.len() + 1);
            },
            Ok(ESC) => handle_escape(&mut stdin, &mut stdout,
                                     &mut state.line, &mut state.word,
                                     &mut state.part, &mut state.bpart),
            Ok(SPC) => {
                state.line.push(state.word.clone());
                state.word.clear();
                stdout.write_char(SPC).unwrap();
                idraw_part(&state.part, &mut state.bpart, &mut stdout);
            },
            Ok(c) => {
                state.word.push(c);
                stdout.write_char(c).unwrap();
                idraw_part(&state.part, &mut state.bpart, &mut stdout);
            },
            Err(e) => {
                stdout.write_fmt(format_args!("Error: {}\n", e)).unwrap();
                break;
            }
        }
        // flush output
        stdout.flush().unwrap();
    }
    stdout.write_str("Exiting\n").unwrap();
    // restore old term state
    update_terminal(old_tios, &mut stderr);
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate num;
extern crate rustfft;
extern crate rustty;
extern crate rustc_serialize;
extern crate docopt;

mod radio;
mod drawing;

use std::sync::mpsc::{Receiver, Sender, channel};
use num::Complex;
use rustfft::FFT;
use rustty::{Terminal, Event};
use docopt::Docopt;

use radio::hackrf::HackRF;
use drawing::draw_spectrum;

const USAGE: &'static str = "
Terminal Spectrograph

Usage:
  terminal_spectrograph <freq-hz> <bandwidth-hz> [--fft-len=<len>]
  terminal_spectrograph (-h | --help)
  terminal_spectrograph --version

Options:
  -h --help        Show this screen.
  --version        Show version.
  --fft-len=<len>  Length of the FFT [default: 4096].
";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_freq_hz: Option<u64>,
    arg_bandwidth_hz: Option<f64>,
    flag_fft_len: usize,
    flag_version: bool,
}

fn process_buffer(recv: Receiver<Vec<Complex<i8>>>, send: Sender<Vec<Complex<f32>>>, fft_len: usize) {
    let mut fft = FFT::new(fft_len, false);
    let mut spectrum = vec![Complex::new(0.0, 0.0); fft_len];
    let mut signal = Vec::with_capacity(fft_len);
    for buff in recv.iter() {
        for x in buff {
            signal.push(Complex::new(x.re as f32, x.im as f32));

            if signal.len() >= signal.capacity() {
                fft.process(&signal[..], &mut spectrum[..]);
                if let Err(_) = send.send(spectrum.clone()) {
                    return;
                }
                signal.clear();
            }
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                                .and_then(|d| d.decode())
                                .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("{}", VERSION);
        return;
    }

    let mut radio = HackRF::open().unwrap_or_else(|_| {
        panic!("Couldn't open HackRF radio.");
    });

    let mut term = Terminal::new().unwrap_or_else(|e| {
        panic!("Couldn't open terminal: {}", e);
    });

    radio.set_frequency(args.arg_freq_hz.unwrap()).unwrap();
    radio.set_sample_rate(args.arg_bandwidth_hz.unwrap()).unwrap();
    let (spec_send, spec_recv) = channel();
    let recv = radio.start_rx();

    let child = std::thread::spawn(move || {
        process_buffer(recv, spec_send, args.flag_fft_len);
    });

    for spec in spec_recv.iter() {
        draw_spectrum(&mut term, spec);
        term.swap_buffers().unwrap();
        if let Ok(Some(Event::Key('q'))) = term.get_event(0) {
            break;
        }
    }
    drop(spec_recv);

    radio.stop_rx().unwrap_or_else(|_| {
        panic!("Couldn't stop receiving");
    });

    child.join().unwrap_or_else(|_| {
        panic!("Error joining with FFT thread");
    });
}
<commit_msg>Implemented rate limiting.<commit_after>extern crate libc;
extern crate num;
extern crate rustfft;
extern crate rustty;
extern crate rustc_serialize;
extern crate docopt;

mod radio;
mod drawing;

use std::sync::mpsc::{Receiver, Sender, channel};
use num::Complex;
use rustfft::FFT;
use rustty::{Terminal, Event};
use docopt::Docopt;

use radio::hackrf::HackRF;
use drawing::draw_spectrum;

const USAGE: &'static str = "
Terminal Spectrograph

Usage:
  terminal_spectrograph <freq-hz> <bandwidth-hz> [options]
  terminal_spectrograph (-h | --help)
  terminal_spectrograph --version

Options:
  -h --help          Show this screen.
  --version          Show version.
  --fft-len=<len>    Length of the FFT [default: 4096].
  --fft-rate=<rate>  Number of FFTs per second. [default: 30].
";
const VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_freq_hz: Option<u64>,
    arg_bandwidth_hz: Option<f64>,
    flag_fft_len: usize,
    flag_fft_rate: usize,
    flag_version: bool,
}

fn process_buffer(recv: Receiver<Vec<Complex<i8>>>, send: Sender<Vec<Complex<f32>>>,
                  fft_len: usize, fft_rate: usize, sample_rate_hz: usize) {
    let mut fft = FFT::new(fft_len, false);
    let mut spectrum = vec![Complex::new(0.0, 0.0); fft_len];
    let mut signal = Vec::with_capacity(fft_len);
    let num_samples_to_discard = (sample_rate_hz - fft_rate * fft_len) / fft_rate;
    let mut samples_discarded = 0;
    for buff in recv.iter() {
        for x in buff {
            if samples_discarded >= num_samples_to_discard {
                signal.push(Complex::new(x.re as f32, x.im as f32));

                if signal.len() >= signal.capacity() {
                    fft.process(&signal[..], &mut spectrum[..]);
                    if let Err(_) = send.send(spectrum.clone()) {
                        return;
                    }
                    signal.clear();
                    samples_discarded = 0;
                }
            } else {
                // discard these samples to maintain the desired FFT rate.
                samples_discarded += 1;
            }
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                                .and_then(|d| d.decode())
                                .unwrap_or_else(|e| e.exit());

    if args.flag_version {
        println!("{}", VERSION);
        return;
    }

    let mut radio = HackRF::open().unwrap_or_else(|_| {
        panic!("Couldn't open HackRF radio.");
    });

    let mut term = Terminal::new().unwrap_or_else(|e| {
        panic!("Couldn't open terminal: {}", e);
    });

    radio.set_frequency(args.arg_freq_hz.unwrap()).unwrap();
    radio.set_sample_rate(args.arg_bandwidth_hz.unwrap()).unwrap();
    let (spec_send, spec_recv) = channel();
    let recv = radio.start_rx();

    std::thread::spawn(move || {
        process_buffer(recv, spec_send, args.flag_fft_len, args.flag_fft_rate,
                       args.arg_bandwidth_hz.unwrap() as usize);
    });

    for spec in spec_recv.iter() {
        draw_spectrum(&mut term, spec);
        term.swap_buffers().unwrap();
        if let Ok(Some(Event::Key('q'))) = term.get_event(0) {
            break;
        }
    }
    drop(spec_recv);

    radio.stop_rx().unwrap_or_else(|_| {
        panic!("Couldn't stop receiving");
    });
}
<|endoftext|>


<commit_before>// fs.rs
use std::env; // env::home_dir()
use std::fs; // fs::read_dir()
//use std::path::Path;
use std::path::PathBuf;

fn main() {
   //let mut idg_dir_path = PathBuf::from("~/Files/Doom/idgames");
   // create an empty PathBuf
   let mut idg_dir = PathBuf::new();
   // call `home_dir()` and act on what it returns
   match env::home_dir() {
      //Some(idg_dir) => println!("{}", idg_dir.display()),
      // home_dir() returned something
      Some(home_dir) => idg_dir = home_dir,
      // home_dir() returned nothing
      None => println!("Can't obtain home directory path!"),
   }

   // append more directories on to idg_dir
   idg_dir.push("Files");
   idg_dir.push("Doom");
   idg_dir.push("idgames");

   // try and read the contents of idg_dir/
   match fs::read_dir(idg_dir) {
      // nope, can't read for some reason
      Err(why) => println!("! {:?}", why.kind()),
      // yep, can read contents of idg_dir, see what items are there
      Ok(items) => for item in items {
         println!("- {:?}", item.unwrap().path());
      }
   }
}
<commit_msg>src/main.rs: match on sucessfully getting item metadata<commit_after>// fs.rs
use std::env; // env::home_dir()
use std::fs; // fs::read_dir()
//use std::path::Path;
use std::path::PathBuf;

fn main() {
   //let mut idg_dir_path = PathBuf::from("~/Files/Doom/idgames");
   // create an empty PathBuf
   let mut idg_dir = PathBuf::new();
   // call `home_dir()` and act on what it returns
   match env::home_dir() {
      //Some(idg_dir) => println!("{}", idg_dir.display()),
      // home_dir() returned something
      Some(home_dir) => idg_dir = home_dir,
      // home_dir() returned nothing
      None => println!("Can't obtain home directory path!"),
   }

   // append more directories on to idg_dir
   idg_dir.push("Files");
   idg_dir.push("Doom");
   idg_dir.push("idgames");

   // try and read the contents of idg_dir/
   match fs::read_dir(idg_dir) {
      // nope, can't read for some reason
      Err(why) => println!("! {:?}", why.kind()),
      // yep, can read contents of idg_dir, see what items are there
      Ok(items) => for item in items {
         // Result<Metadata>
         match item.unwrap().metadata() {
            Err(why) => println!("! {:?}", why.kind()),
            //Ok(metadata) => println!("- {:?}", metadata.file_type()),
            //Ok(metadata) => println!("- {:?}", metadata.permissions()),
            // is this a file, directory, or ???
            Ok(metadata) => {
               println!("- {:?}", metadata.is_dir());
            }
         }
      }
   }
}
<|endoftext|>


<commit_before>extern crate time;
use time::{Timespec, Duration};
use std::thread;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{self, channel};

macro_rules! printfl {
    ($($tt:tt)*) => {{
        use std::io::{self, Write};
        print!($($tt)*);
        io::stdout().flush().ok().expect("flush() fail");
    }}
}

pub struct ProgressBar {
    start_time: Timespec,
    total: i64,
    current: i64,
    is_finish: bool,
    more: mpsc::Sender<bool>,
}

impl ProgressBar {
    pub fn new(total: i64) -> Arc<Mutex<ProgressBar>> {
        let (tx, rx) = channel::<bool>();
        let l1 = Arc::new(Mutex::new(
            ProgressBar {
                total: total,
                current: 0,
                start_time: time::get_time(),
                is_finish: false,
                more: tx,
            }));
        let l2 = l1.clone();
        thread::spawn(|| ProgressBar::writer(l2, rx));
        l1
    }

    fn add(&mut self, i: i64) -> i64 {
        self.current += i;
        let more = if self.current > self.total {
            false
        } else {
            true
        };
        let _ = self.more.send(more);
        self.current
    }

    fn write(&self) {
        let width = 143;    // replace to -> get_tty_size()
        let percent_box;
        let counter_box;
        let mut time_left_box = format!("");
        let speed_box;
        let mut bar_box = "[".to_string();
        let mut out;
        // precent box
        let percent = self.current as f64 / (self.total as f64 / 100f64);
        percent_box = format!(" {:.*} % ", 2, percent);
        // counter box
        counter_box = format!("{} / {} ", self.current, self.total);
        // time left box
        let from_start = time::get_time() - self.start_time;
        let per_entry = from_start / self.current as i32; // Why the hack
        let mut left = per_entry * (self.total - self.current) as i32;
        let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as i32;
        left = (left / sec_nano) * sec_nano;
        if left.num_seconds() > 0 {
            time_left_box = format!("{}s", left.num_seconds());
        }
        // NOT WORKING: speed box
        let speed = (from_start / sec_nano) / self.current as i32;
        speed_box = format!("{}/s", speed.num_nanoseconds().unwrap() as f64);
        // bar_box - Add prefix & suffix(2)
        let size = width -
                   (percent_box.to_string() + &counter_box + &time_left_box + &speed_box).len();
        // Test if size > 0
        let curr_count = ((self.current as f64 / self.total as f64) * size as f64).ceil();
        let err_count = size as f64 - curr_count;
        bar_box = bar_box + &std::iter::repeat("=").take(curr_count as usize).collect::<String>();
        if self.current < self.total {
            bar_box = bar_box + ">";
        } else {
            bar_box = bar_box + "=";
        }
        bar_box = bar_box + &std::iter::repeat("-").take(err_count as usize).collect::<String>() +
                  "]";
        out = counter_box.to_string() + &bar_box + &percent_box + &time_left_box;
        // Print
        if out.len() < width {
            let gap = width - out.len();
            out = out + &std::iter::repeat(" ").take(gap as usize).collect::<String>();
        }
        printfl!("\r{}", out);
    }

    fn writer(mu: Arc<Mutex<ProgressBar>>, rx: mpsc::Receiver<bool>) {
        let mut prev = -1;
        let mut more;
        loop {
            let pb = mu.lock().unwrap();
            if pb.current != prev && pb.current > 0 {
                prev = pb.current;
                pb.write();
            }
            drop(pb);
            more = rx.recv().unwrap();
            if !more {
                break;
            }
        }
    }

    fn finish(&mut self) {
        self.is_finish = true;
    }
}

fn main() {
    let pb = ProgressBar::new(1000);
    for _ in 0..1000 {
        let mut pb = pb.lock().unwrap();
        pb.add(1);
        thread::sleep_ms(200);
    }
    pb.lock().unwrap().finish();
    println!("The end!");
}
<commit_msg>back to non-threaded example<commit_after>extern crate time;
use time::{Timespec, Duration};
use std::thread;

macro_rules! printfl {
    ($($tt:tt)*) => {{
        use std::io::{self, Write};
        print!($($tt)*);
        io::stdout().flush().ok().expect("flush() fail");
    }}
}

pub struct ProgressBar {
    start_time: Timespec,
    total: i64,
    current: i64,
    is_finish: bool,
}

impl ProgressBar {
    pub fn new(total: i64) -> ProgressBar {
            ProgressBar {
                total: total,
                current: 0,
                start_time: time::get_time(),
                is_finish: false,
            }
    }

    fn add(&mut self, i: i64) -> i64 {
        self.current += i;
        if self.current <= self.total {
            self.write()
        };
        self.current
    }

    fn write(&self) {
        let width = 143;    // replace to -> get_tty_size()
        let percent_box;
        let counter_box;
        let mut time_left_box = format!("");
        let speed_box;
        let mut bar_box = "[".to_string();
        let mut out;
        // precent box
        let percent = self.current as f64 / (self.total as f64 / 100f64);
        percent_box = format!(" {:.*} % ", 2, percent);
        // counter box
        counter_box = format!("{} / {} ", self.current, self.total);
        // time left box
        let from_start = time::get_time() - self.start_time;
        let per_entry = from_start / self.current as i32; // Why the hack
        let mut left = per_entry * (self.total - self.current) as i32;
        let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as i32;
        left = (left / sec_nano) * sec_nano;
        if left.num_seconds() > 0 {
            time_left_box = format!("{}s", left.num_seconds());
        }
        // NOT WORKING: speed box
        let speed = (from_start / sec_nano) / self.current as i32;
        speed_box = format!("{}/s", speed.num_nanoseconds().unwrap() as f64);
        // bar_box - Add prefix & suffix(2)
        let size = width -
                   (percent_box.to_string() + &counter_box + &time_left_box + &speed_box).len();
        // Test if size > 0
        let curr_count = ((self.current as f64 / self.total as f64) * size as f64).ceil();
        let err_count = size as f64 - curr_count;
        bar_box = bar_box + &std::iter::repeat("=").take(curr_count as usize).collect::<String>();
        if self.current < self.total {
            bar_box = bar_box + ">";
        } else {
            bar_box = bar_box + "=";
        }
        bar_box = bar_box + &std::iter::repeat("-").take(err_count as usize).collect::<String>() +
                  "]";
        out = counter_box.to_string() + &bar_box + &percent_box + &time_left_box;
        // Print
        if out.len() < width {
            let gap = width - out.len();
            out = out + &std::iter::repeat(" ").take(gap as usize).collect::<String>();
        }
        printfl!("\r{}", out);
    }

    fn finish(&mut self) {
        if self.current < self.total {
            self.current = self.total;
            self.write();
        }
        println!("");
        self.is_finish = true;
    }
}

fn main() {
    let mut pb = ProgressBar::new(1000);
    for _ in 0..1000 {
        pb.add(1);
        thread::sleep_ms(2);
    }
    pb.finish();
    print!("The end!");
}
<|endoftext|>


<commit_before>#![allow(unstable_features)]
#![allow(non_snake_case)]
// Since both ConfigReader and Logger are not functional yet allow dead code.
#![allow(dead_code)]
#![feature(core,old_io,old_path)]
extern crate iron;
extern crate hyper;
extern crate url;
extern crate "rustc-serialize" as serialize;
extern crate toml;
extern crate cookie;
extern crate ldap;

//use std::error::Error;
use std::os;
use std::path::PathBuf;
use std::old_io::net::ip::{SocketAddr, IpAddr};

use iron::prelude::*;
//use iron::AroundMiddleware;

//use controller::Reservation;

use api::API;
use urlparser::URLParser;
use cookieparser::CookieParser;
use cookiesetter::CookieSetter;
use redstart::RedStart;

mod api;
mod authentication;
mod controller;
mod model;
mod configreader;
mod cookiesetter;
mod cookieparser;
mod urlparser;
mod session;
mod redstart;

/// The setup function
///
/// This function sets up the environment needed for RedStart's main loop to function.
/// The main work this function does is building the chain and populating the API.
fn setup() -> (API, iron::Chain)
{
    let mut api = API::new();
    let redstart = RedStart::new(&api);
    let cookieparser = CookieParser::new(&api);
    let cookesetter = CookieSetter::new(&api);
    let mut chain = Chain::new(redstart);
    chain.link_before(URLParser);
    chain.link_before(cookieparser);
    chain.link_after(cookesetter);
    return (api, chain);
}

/// The main function
///
/// This is the main loop of RedStart
fn main()
{
    let (mut api, chain) = setup();

    let addr: IpAddr = api.config.get_value_or::<String>("Networking.address", "localhost".to_string()).parse().unwrap();
    let port = api.config.get_value_or::<u16>("Networking.port", 3000);
    let sock_addr = SocketAddr { ip: addr, port: port.clone() };

    let guards;

    // Is HTTPS enabled?
    if api.config.get_value_or::<bool>("Security.https", false)
    {
        // If yes, get two paths located at the current pwd.
        let mut cert_path = os::self_exe_path().unwrap();
        let mut key_path = cert_path.clone();

        // Get the location of the Certificate file.
        let cert_conf = api.config.get_value_or::<String>("Security.certificate", "snakeoil.key".to_string());
        cert_path.push(cert_conf);

        // Get the location of the Key file.
        let key_conf = api.config.get_value_or::<String>("Security.key", "snakeoil.cert".to_string());
        key_path.push(key_conf);

        // Start up Iron in HTTPS mode
        guards = Iron::new(chain).https(sock_addr, cert_path, key_path).unwrap();
    }
    else
    {
        // If no, start up Iron in HTTP mode.
        guards = Iron::new(chain).http(sock_addr).unwrap();
    }

    println!("Started RedStart on port {}", port);
}

#[cfg(test)]
/// Test module
///
/// This module only gets compiled in test mode.
/// It provides mostly helper functions for other unit tests.
mod tests
{
    use super::*;

    use std::old_io::util::NullReader;
    use std::old_io::net::ip::{SocketAddr, IpAddr};
    use hyper::http::HttpReader::EmptyReader;
    use iron::request::{Request, Url};
    use iron::headers::Headers;
    use iron::request::Body;
    use iron::method::Method;
    use iron::TypeMap;

    pub fn create_fake_request(method: Method, url: &str) // -> Request
    {
        let addr: IpAddr = "localhost".parse().unwrap();
        /* Request
        {
            url: Url::parse(url).unwrap(),
            remote_addr: SocketAddr { ip: addr, port: 8123 },
            local_addr: SocketAddr { ip: addr, port: 3000 },
            headers: Headers::new(),
            body: Body::new(EmptyReader(MockStream::new())),
            method: Method::Get,
            extensions: TypeMap::new()
        } */
    }
}

<commit_msg>Added thread guard Doc<commit_after>#![allow(unstable_features)]
#![allow(non_snake_case)]
// Since both ConfigReader and Logger are not functional yet allow dead code.
#![allow(dead_code)]
#![feature(core,old_io,old_path)]
extern crate iron;
extern crate hyper;
extern crate url;
extern crate "rustc-serialize" as serialize;
extern crate toml;
extern crate cookie;
extern crate ldap;

//use std::error::Error;
use std::os;
use std::thread;
use std::path::PathBuf;
use std::old_io::net::ip::{SocketAddr, IpAddr};

use iron::prelude::*;
//use iron::AroundMiddleware;

//use controller::Reservation;

use api::API;
use urlparser::URLParser;
use cookieparser::CookieParser;
use cookiesetter::CookieSetter;
use redstart::RedStart;

mod api;
mod authentication;
mod controller;
mod model;
mod configreader;
mod cookiesetter;
mod cookieparser;
mod urlparser;
mod session;
mod redstart;

/// The setup function
///
/// This function sets up the environment needed for RedStart's main loop to function.
/// The main work this function does is building the chain and populating the API.
fn setup() -> (API, iron::Chain)
{
    let mut api = API::new();
    let redstart = RedStart::new(&api);
    let cookieparser = CookieParser::new(&api);
    let cookesetter = CookieSetter::new(&api);
    let mut chain = Chain::new(redstart);
    chain.link_before(URLParser);
    chain.link_before(cookieparser);
    chain.link_after(cookesetter);
    return (api, chain);
}

/// The main function
///
/// This is the main loop of RedStart
fn main()
{
    let (mut api, chain) = setup();

    let addr: IpAddr = api.config.get_value_or::<String>("Networking.address", "localhost".to_string()).parse().unwrap();
    let port = api.config.get_value_or::<u16>("Networking.port", 3000);
    let sock_addr = SocketAddr { ip: addr, port: port.clone() };

    let guards; // JoinGuards that will make sure the child processes don't get dropped when the main thread is finished.

    // Is HTTPS enabled?
    if api.config.get_value_or::<bool>("Security.https", false)
    {
        // If yes, get two paths located at the current pwd.
        let mut cert_path = os::self_exe_path().unwrap();
        let mut key_path = cert_path.clone();

        // Get the location of the Certificate file.
        let cert_conf = api.config.get_value_or::<String>("Security.certificate", "snakeoil.key".to_string());
        cert_path.push(cert_conf);

        // Get the location of the Key file.
        let key_conf = api.config.get_value_or::<String>("Security.key", "snakeoil.cert".to_string());
        key_path.push(key_conf);

        // Start up Iron in HTTPS mode
        guards = Iron::new(chain).https(sock_addr, cert_path, key_path).unwrap();
    }
    else
    {
        // If no, start up Iron in HTTP mode.
        guards = Iron::new(chain).http(sock_addr).unwrap();
    }

    println!("Started RedStart on port {}", port);
}

#[cfg(test)]
/// Test module
///
/// This module only gets compiled in test mode.
/// It provides mostly helper functions for other unit tests.
mod tests
{
    use super::*;

    use std::old_io::util::NullReader;
    use std::old_io::net::ip::{SocketAddr, IpAddr};
    use hyper::http::HttpReader::EmptyReader;
    use iron::request::{Request, Url};
    use iron::headers::Headers;
    use iron::request::Body;
    use iron::method::Method;
    use iron::TypeMap;

    pub fn create_fake_request(method: Method, url: &str) // -> Request
    {
        let addr: IpAddr = "localhost".parse().unwrap();
        /* Request
        {
            url: Url::parse(url).unwrap(),
            remote_addr: SocketAddr { ip: addr, port: 8123 },
            local_addr: SocketAddr { ip: addr, port: 3000 },
            headers: Headers::new(),
            body: Body::new(EmptyReader(MockStream::new())),
            method: Method::Get,
            extensions: TypeMap::new()
        } */
    }
}

<|endoftext|>