<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::ops::{Add,Sub,Mul,Div};

extern crate rand;
use rand::{Rng, XorShiftRng, SeedableRng};

#[derive(Debug,Clone,Copy)]
struct Vec3d {
    x: f64,
    y: f64,
    z: f64
}

impl Vec3d {
    fn normalized(self) -> Vec3d {
        self / self.dot(self).sqrt()
    }
    fn dot(self, other: Vec3d) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
    fn new(x: f64, y: f64, z: f64) -> Vec3d {
        Vec3d { x: x, y: y, z: z }
    }
    fn zero() -> Vec3d {
        Vec3d { x: 0.0, y: 0.0, z: 0.0 }
    }
    fn cross(self, other: Vec3d) -> Vec3d {
        Vec3d {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }
    fn maxComponent(self) -> f64 {
        if self.x > self.y && self.x > self.z { self.x }
        else if self.y > self.x && self.y > self.z { self.y }
        else { self.z }
    }
    fn neg(self) -> Vec3d {
        Vec3d { x: -self.x, y: -self.y, z: -self.z }
    }
}

impl Add for Vec3d {
    type Output = Vec3d;

    fn add(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
    }
}

impl Sub for Vec3d {
    type Output = Vec3d;

    fn sub(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
    }
}

impl Mul for Vec3d {
    type Output = Vec3d;

    fn mul(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x * other.x, y: self.y * other.y, z: self.z * other.z }
    }
}

impl Mul<f64> for Vec3d {
    type Output = Vec3d;

    fn mul(self, other: f64) -> Vec3d {
        Vec3d { x: self.x * other, y: self.y * other, z: self.z * other }
    }
}

impl Div<f64> for Vec3d {
    type Output = Vec3d;

    fn div(self, other: f64) -> Vec3d {
        Vec3d { x: self.x / other, y: self.y / other, z: self.z / other }
    }
}

struct Ray {
    origin: Vec3d,
    direction: Vec3d
}

impl Ray {
    fn new(origin: Vec3d, direction: Vec3d) -> Ray {
        Ray { origin: origin, direction: direction }
    }
}

enum Material {
    Diffuse,
    Specular,
    Refractive
}

struct Sphere {
    material: Material,
    radius: f64,
    position: Vec3d,
    emission: Vec3d,
    colour: Vec3d
}

impl Sphere {
    fn new(material: Material, radius: f64, position: Vec3d, emission: Vec3d, colour: Vec3d) -> Sphere {
        Sphere {
          material: material,
          radius: radius,
          position: position,
          emission: emission,
          colour: colour
        }
    }
    fn intersect(&self, ray: &Ray) -> Option<f64> {
        let op = self.position - ray.origin;
        let b = op.dot(ray.direction);
        let determinant = b * b - op.dot(op) + self.radius * self.radius;
        if determinant < 0.0 { return None; }
        let determinant = determinant.sqrt();
        let t1 = b - determinant;
        let t2 = b + determinant;
        const Epsilon : f64 = 0.0001;
        if t1 > Epsilon {
            Some(t1)
        } else if t2 > Epsilon {
            Some(t2)
        } else {
            None
        }
    }
}

#[test]
fn intersection() {
    let sphere = Sphere::new(
        Material::Diffuse,
        100.0,
        Vec3d::new(0.0, 0.0, 200.0),
        Vec3d::zero(),
        Vec3d::zero());
    let ray = Ray::new(Vec3d::zero(), Vec3d::new(0.0, 0.0, 1.0));
    match sphere.intersect(&ray) {
        Some(x) => assert_eq!(x, 100.0),
        None => panic!("unexpected")
    }
    let ray = Ray::new(Vec3d::zero(), Vec3d::new(0.0, 1.0, 0.0));
    match sphere.intersect(&ray) {
        Some(_) => panic!("unexpected"),
        None => {}
    }
}

struct HitRecord<'a> {
    sphere: &'a Sphere,
    dist: f64
}

fn intersect<'a>(scene: &'a Vec<Sphere>, ray: &Ray) -> Option<HitRecord<'a>> {
    let mut result : Option<HitRecord<'a>> = None;
    for sph in scene.iter() {
        if let Some(dist) = sph.intersect(&ray) {
            // TODO: what's the difference between Some(&x) and Some(ref x) ? the latter works
            if match result { None => true, Some(ref x) => dist < x.dist } {
                result = Some(HitRecord { sphere: &sph, dist: dist });
            }
        }
    }
    result
}

fn radiance<R: Rng>(scene: &Vec<Sphere>, ray: &Ray, depth: i32, rng: &mut R) -> Vec3d {
    if let Some(hit) = intersect(&scene, &ray) {
        let hitPos = ray.origin + ray.direction * hit.dist;
        let hitNormal = (hitPos - hit.sphere.position).normalized();
        let n1 = if hitNormal.dot(ray.direction) < 0.0 { hitNormal } else { hitNormal.neg() };
        let mut colour = hit.sphere.colour;
        let maxReflectance = colour.maxComponent();
        let depth = depth + 1;
        if depth > 5 {
            let rand = rng.gen::<f64>();
            if rand < maxReflectance {
               colour = colour * (1.0 / maxReflectance);
            } else {
                return hit.sphere.emission;
            }
        }
        match hit.sphere.material {
            Material::Diffuse => {
            },
            Material::Specular => {
                //let reflection = ray.direction - hitNormal * 2.0 * hitNormal.dot(ray.direction);
                //colour = hit.sphere.emission + colour * radiance(scene, &Ray::new(hitPos, reflection), depth, rng);
            },
            Material::Refractive => {
            }
        }
        colour
    } else {
        Vec3d::zero()
    }
}

fn randomSamp<T: Rng>(rng: &mut T) -> f64 {
    let r = 2.0 * rng.gen::<f64>();
    if r < 1.0 { r.sqrt() - 1.0 } else { 1.0 - (2.0 - r).sqrt() }
}

fn to_int(v: f64) -> u8 {
    if v < 0.0 {
        0
    } else if v > 1.0 {
        1
    } else {
        (v * 255.0) as u8
    }
}

fn main() {
    const Black : Vec3d = Vec3d { x: 0.0, y: 0.0, z: 0.0 };
    const Red : Vec3d = Vec3d { x: 0.75, y: 0.25, z: 0.25 };
    const Blue : Vec3d = Vec3d { x: 0.25, y: 0.25, z: 0.75 };
    const Grey : Vec3d = Vec3d { x: 0.75, y: 0.75, z: 0.75 };
    const White : Vec3d = Vec3d { x: 0.999, y: 0.999, z: 0.999 };
    let scene = vec!{
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(1e5+1.0, 40.8, 81.6),
            Black, Red),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(-1e5+99.0, 40.8, 81.6),
            Black, Blue),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 40.8, 1e5),
            Black, Grey),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 40.8, -1e5 + 170.0),
            Black, Black),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 1e5, 81.6),
            Black, Grey),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, -1e5 + 81.6, 81.6),
            Black, Red),
        Sphere::new(Material::Specular, 16.5,
            Vec3d::new(27.0, 16.5, 47.0),
            Black, White),
        Sphere::new(Material::Refractive, 16.5,
            Vec3d::new(73.0, 16.5, 78.0),
            Black, White),
        Sphere::new(Material::Diffuse, 600.0,
            Vec3d::new(50.0, 681.6 - 0.27, 81.6),
            Vec3d::new(12.0, 12.0, 12.0), Black),
    };

    const Width: usize = 256;//1024;
    const Height: usize = 192;//768;
    let Samps = 1;
    let cameraPos = Vec3d::new(50.0, 52.0, 295.6);
    let cameraDir = Vec3d::new(0.0, -0.042612, -1.0);
    let camera = Ray::new(cameraPos, cameraDir.normalized());
    let cameraX = Vec3d::new(Width as f64 * 0.5135 / Height as f64, 0.0, 0.0);
    let cameraY = cameraX.cross(camera.direction).normalized() * 0.5135;

    let mut rng = XorShiftRng::new_unseeded();
    let mut outputFile = File::create("image.ppm").unwrap();
    write!(&mut outputFile, "P3\n{} {}\n255\n", Width, Height);

    for y in 0..Height {
        println!("Rendering ({} spp) {:.4}%...", Samps * 4, 100.0 * y as f64 / Height as f64);
        for x in 0..Width {
            rng.reseed([10, 200, 999999, y as u32]);
            let mut sum = Vec3d::zero();
            for sx in 0..2 {
                for sy in 0..2 {
                    for s in 0..Samps {
                        let dx = randomSamp(&mut rng);
                        let dy = randomSamp(&mut rng);
                        let dir = cameraX * (((sx as f64 + 0.5 + dx)/2.0 + x as f64) / Width as f64 - 0.5) +
                            cameraY * (((sy as f64 + 0.5 + dy)/2.0 + y as f64) / Height as f64  - 0.5) + cameraDir;
                        let jitteredRay = Ray::new(cameraPos + dir * 140.0, dir.normalized());
                        sum = sum + radiance(&scene, &jitteredRay, 0, &mut rng) / (Samps * 4) as f64;
                    }
                }
            }
            write!(&mut outputFile, "{} {} {} ", to_int(sum.x), to_int(sum.y), to_int(sum.z));
        }
    }
}
<commit_msg>Actually renders something halfway resembling the target image<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::ops::{Add,Sub,Mul,Div};

extern crate rand;
use rand::{Rng, XorShiftRng, SeedableRng};

#[derive(Debug,Clone,Copy)]
struct Vec3d {
    x: f64,
    y: f64,
    z: f64
}

impl Vec3d {
    fn normalized(self) -> Vec3d {
        self / self.dot(self).sqrt()
    }
    fn dot(self, other: Vec3d) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
    fn new(x: f64, y: f64, z: f64) -> Vec3d {
        Vec3d { x: x, y: y, z: z }
    }
    fn zero() -> Vec3d {
        Vec3d { x: 0.0, y: 0.0, z: 0.0 }
    }
    fn cross(self, other: Vec3d) -> Vec3d {
        Vec3d {
            x: self.y * other.z - self.z * other.y,
            y: self.z * other.x - self.x * other.z,
            z: self.x * other.y - self.y * other.x
        }
    }
    fn maxComponent(self) -> f64 {
        if self.x > self.y && self.x > self.z { self.x }
        else if self.y > self.x && self.y > self.z { self.y }
        else { self.z }
    }
    fn neg(self) -> Vec3d {
        Vec3d { x: -self.x, y: -self.y, z: -self.z }
    }
}

impl Add for Vec3d {
    type Output = Vec3d;

    fn add(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z }
    }
}

impl Sub for Vec3d {
    type Output = Vec3d;

    fn sub(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z }
    }
}

impl Mul for Vec3d {
    type Output = Vec3d;

    fn mul(self, other: Vec3d) -> Vec3d {
        Vec3d { x: self.x * other.x, y: self.y * other.y, z: self.z * other.z }
    }
}

impl Mul<f64> for Vec3d {
    type Output = Vec3d;

    fn mul(self, other: f64) -> Vec3d {
        Vec3d { x: self.x * other, y: self.y * other, z: self.z * other }
    }
}

impl Div<f64> for Vec3d {
    type Output = Vec3d;

    fn div(self, other: f64) -> Vec3d {
        Vec3d { x: self.x / other, y: self.y / other, z: self.z / other }
    }
}

struct Ray {
    origin: Vec3d,
    direction: Vec3d
}

impl Ray {
    fn new(origin: Vec3d, direction: Vec3d) -> Ray {
        Ray { origin: origin, direction: direction }
    }
}

enum Material {
    Diffuse,
    Specular,
    Refractive
}

struct Sphere {
    material: Material,
    radius: f64,
    position: Vec3d,
    emission: Vec3d,
    colour: Vec3d
}

impl Sphere {
    fn new(material: Material, radius: f64, position: Vec3d, emission: Vec3d, colour: Vec3d) -> Sphere {
        Sphere {
          material: material,
          radius: radius,
          position: position,
          emission: emission,
          colour: colour
        }
    }
    fn intersect(&self, ray: &Ray) -> Option<f64> {
        let op = self.position - ray.origin;
        let b = op.dot(ray.direction);
        let determinant = b * b - op.dot(op) + self.radius * self.radius;
        if determinant < 0.0 { return None; }
        let determinant = determinant.sqrt();
        let t1 = b - determinant;
        let t2 = b + determinant;
        const Epsilon : f64 = 0.0001;
        if t1 > Epsilon {
            Some(t1)
        } else if t2 > Epsilon {
            Some(t2)
        } else {
            None
        }
    }
}

#[test]
fn intersection() {
    let sphere = Sphere::new(
        Material::Diffuse,
        100.0,
        Vec3d::new(0.0, 0.0, 200.0),
        Vec3d::zero(),
        Vec3d::zero());
    let ray = Ray::new(Vec3d::zero(), Vec3d::new(0.0, 0.0, 1.0));
    match sphere.intersect(&ray) {
        Some(x) => assert_eq!(x, 100.0),
        None => panic!("unexpected")
    }
    let ray = Ray::new(Vec3d::zero(), Vec3d::new(0.0, 1.0, 0.0));
    match sphere.intersect(&ray) {
        Some(_) => panic!("unexpected"),
        None => {}
    }
}

struct HitRecord<'a> {
    sphere: &'a Sphere,
    dist: f64
}

fn intersect<'a>(scene: &'a Vec<Sphere>, ray: &Ray) -> Option<HitRecord<'a>> {
    let mut result : Option<HitRecord<'a>> = None;
    for sph in scene.iter() {
        if let Some(dist) = sph.intersect(&ray) {
            // TODO: what's the difference between Some(&x) and Some(ref x) ? the latter works
            if match result { None => true, Some(ref x) => dist < x.dist } {
                result = Some(HitRecord { sphere: &sph, dist: dist });
            }
        }
    }
    result
}

fn radiance<R: Rng>(scene: &Vec<Sphere>, ray: &Ray, depth: i32, rng: &mut R) -> Vec3d {
    if let Some(hit) = intersect(&scene, &ray) {
        let hitPos = ray.origin + ray.direction * hit.dist;
        let hitNormal = (hitPos - hit.sphere.position).normalized();
        let n1 = if hitNormal.dot(ray.direction) < 0.0 { hitNormal } else { hitNormal.neg() };
        let mut colour = hit.sphere.colour;
        let maxReflectance = colour.maxComponent();
        let depth = depth + 1;
        if depth > 5 {
            let rand = rng.gen::<f64>();
            if rand < maxReflectance {
               colour = colour * (1.0 / maxReflectance);
            } else {
                return hit.sphere.emission;
            }
        }
        match hit.sphere.material {
            Material::Diffuse => {
                let r1 = rng.gen::<f64>() * 2.0 * std::f64::consts::PI;
                let r2 = rng.gen::<f64>();
                let r2s = r2.sqrt();
                let w = n1;
                let u = if n1.x.abs() > 0.1 { Vec3d::new(0.0, 1.0, 0.0) } else { Vec3d::new(1.0, 0.0, 0.0) }.cross(w);
                let v = w.cross(u);
                let d = u * r1.cos() * r2s + v * r1.sin() * r2s + w * (1.0 - r2).sqrt();
                colour = hit.sphere.emission + colour * radiance(scene, &Ray::new(hitPos, d.normalized()), depth, rng);
            },
            Material::Specular => {
                let reflection = ray.direction - hitNormal * 2.0 * hitNormal.dot(ray.direction);
                colour = hit.sphere.emission + colour * radiance(scene, &Ray::new(hitPos, reflection), depth, rng);
            },
            Material::Refractive => {
            }
        }
        colour
    } else {
        Vec3d::zero()
    }
}

fn randomSamp<T: Rng>(rng: &mut T) -> f64 {
    let r = 2.0 * rng.gen::<f64>();
    if r < 1.0 { r.sqrt() - 1.0 } else { 1.0 - (2.0 - r).sqrt() }
}

fn to_int(v: f64) -> u8 {
    if v < 0.0 {
        0
    } else if v > 1.0 {
        1
    } else {
        (v * 255.0) as u8
    }
}

fn main() {
    const Black : Vec3d = Vec3d { x: 0.0, y: 0.0, z: 0.0 };
    const Red : Vec3d = Vec3d { x: 0.75, y: 0.25, z: 0.25 };
    const Blue : Vec3d = Vec3d { x: 0.25, y: 0.25, z: 0.75 };
    const Grey : Vec3d = Vec3d { x: 0.75, y: 0.75, z: 0.75 };
    const White : Vec3d = Vec3d { x: 0.999, y: 0.999, z: 0.999 };
    let scene = vec!{
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(1e5+1.0, 40.8, 81.6),
            Black, Red),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(-1e5+99.0, 40.8, 81.6),
            Black, Blue),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 40.8, 1e5),
            Black, Grey),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 40.8, -1e5 + 170.0),
            Black, Black),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, 1e5, 81.6),
            Black, Grey),
        Sphere::new(Material::Diffuse, 1e5,
            Vec3d::new(50.0, -1e5 + 81.6, 81.6),
            Black, Red),
        Sphere::new(Material::Specular, 16.5,
            Vec3d::new(27.0, 16.5, 47.0),
            Black, White),
        Sphere::new(Material::Refractive, 16.5,
            Vec3d::new(73.0, 16.5, 78.0),
            Black, White),
        Sphere::new(Material::Diffuse, 600.0,
            Vec3d::new(50.0, 681.6 - 0.27, 81.6),
            Vec3d::new(12.0, 12.0, 12.0), Black),
    };

    const Width: usize = 256;//1024;
    const Height: usize = 192;//768;
    let Samps = 64;
    let cameraPos = Vec3d::new(50.0, 52.0, 295.6);
    let cameraDir = Vec3d::new(0.0, -0.042612, -1.0);
    let camera = Ray::new(cameraPos, cameraDir.normalized());
    let cameraX = Vec3d::new(Width as f64 * 0.5135 / Height as f64, 0.0, 0.0);
    let cameraY = cameraX.cross(camera.direction).normalized() * 0.5135;

    let mut rng = XorShiftRng::new_unseeded();
    let mut outputFile = File::create("image.ppm").unwrap();
    write!(&mut outputFile, "P3\n{} {}\n255\n", Width, Height);

    for y in 0..Height {
        println!("Rendering ({} spp) {:.4}%...", Samps * 4, 100.0 * y as f64 / Height as f64);
        for x in 0..Width {
            rng.reseed([10, 200, 999999, y as u32]);
            let mut sum = Vec3d::zero();
            for sx in 0..2 {
                for sy in 0..2 {
                    for s in 0..Samps {
                        let dx = randomSamp(&mut rng);
                        let dy = randomSamp(&mut rng);
                        let dir = cameraX * (((sx as f64 + 0.5 + dx)/2.0 + x as f64) / Width as f64 - 0.5) +
                            cameraY * (((sy as f64 + 0.5 + dy)/2.0 + y as f64) / Height as f64  - 0.5) + cameraDir;
                        let jitteredRay = Ray::new(cameraPos + dir * 140.0, dir.normalized());
                        sum = sum + radiance(&scene, &jitteredRay, 0, &mut rng) / (Samps * 4) as f64;
                    }
                }
            }
            write!(&mut outputFile, "{} {} {} ", to_int(sum.x), to_int(sum.y), to_int(sum.z));
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
#[macro_use] extern crate derive_error;

use std::process;
use std::io::Write;
use std::io;

#[macro_use]
mod git;
mod author;
mod concat;
mod author_selection;
mod error;
mod commands;

use git::Config;
use clap::App;
use error::PartnersError;

pub type Result<T, E=PartnersError> = ::std::result::Result<T, E>;

fn run() -> Result<()> {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml).version(crate_version!()).author(crate_authors!());
    let matches = app.get_matches();

    let config_path = std::env::home_dir().ok_or(PartnersError::HomeDirectoryNotFound)?.join(".partners.cfg");

    let partners_config = Config::File(&config_path);

    match matches.subcommand() {
        ("list", Some(sub_matches)) => commands::list(&partners_config, sub_matches),
        ("current", Some(sub_matches)) => commands::current(&partners_config, sub_matches),
        ("set", Some(sub_matches)) => commands::set(&partners_config, sub_matches),
        ("add", Some(sub_matches)) => commands::add(&partners_config, sub_matches),
        _ => {
            println!("{}", matches.usage());
            Ok(())
        }
    }
}

fn main() {
    match run() {
        Ok(_) => {},
        Err(e) => {
            writeln!(&mut io::stderr(), "ERROR: {}", e).unwrap();
            process::exit(1);
        }
    }
}
<commit_msg>Check whether config file exists<commit_after>#[macro_use] extern crate clap;
#[macro_use] extern crate derive_error;

use std::process;
use std::io::Write;
use std::io;

#[macro_use]
mod git;
mod author;
mod concat;
mod author_selection;
mod error;
mod commands;

use git::Config;
use clap::App;
use error::PartnersError;

pub type Result<T, E=PartnersError> = ::std::result::Result<T, E>;

fn run() -> Result<()> {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml).version(crate_version!()).author(crate_authors!());
    let matches = app.get_matches();

    let config_path = std::env::home_dir().ok_or(PartnersError::HomeDirectoryNotFound)?.join(".partners.cfg");

    if config_path.exists() {
        let partners_config = Config::File(&config_path);

        match matches.subcommand() {
            ("list", Some(sub_matches)) => commands::list(&partners_config, sub_matches),
            ("current", Some(sub_matches)) => commands::current(&partners_config, sub_matches),
            ("set", Some(sub_matches)) => commands::set(&partners_config, sub_matches),
            ("add", Some(sub_matches)) => commands::add(&partners_config, sub_matches),
            _ => {
                println!("{}", matches.usage());
                Ok(())
            }
        }
    } else {
        println!("config file not found at {:?}", config_path);
        Ok(())
    }
}

fn main() {
    match run() {
        Ok(_) => {},
        Err(e) => {
            writeln!(&mut io::stderr(), "ERROR: {}", e).unwrap();
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>extern crate liner;

use liner::Context;
use liner::KeyBindings;
use std::collections::HashMap;
use std::io::ErrorKind;

fn main() {
    let mut cache = Box::new(HashMap::new());

    let empty_value = String::from("");

    let mut con = Context::new();

    loop {
        let res = con.read_line("> ", &mut |_| {});

        match res {
            Ok(res) => {
                match res.as_str() {
                    "emacs" => {
                        con.key_bindings = KeyBindings::Emacs;
                        println!("emacs mode");
                    }
                    "vi" | "vim" =>  {
                        con.key_bindings = KeyBindings::Vi;
                        println!("vi mode");
                    }
                    s if s.starts_with("get ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        println!("{}", cache.get(&key_trimmed).unwrap_or(&empty_value));
                    }
                    s if s.starts_with("set ") =>  {
                        let (_, key_value) = s.split_at(4);
                        match key_value.find(' ') {
                            Some(i) => {
                                let (key, value) = key_value.split_at(i);
                                let key_trimmed = String::from(key.trim());
                                let value_trimmed = String::from(value.trim());
                                cache.insert(key_trimmed, value_trimmed);
                            }
                            None => println!("no value specified")
                        }
                    }
                    "exit" =>  {
                        break;
                    }
                    _ => {}
                }

                con.history.push(res.into()).unwrap();
            }
            Err(e) => {
                match e.kind() {
                    // ctrl-c pressed
                    ErrorKind::Interrupted => {}
                    // ctrl-d pressed
                    ErrorKind::UnexpectedEof => {
                        break;
                    }
                    _ => panic!("error: {:?}", e),
                }
            }
        }
    }
}
<commit_msg>Reoganize operations<commit_after>extern crate liner;

use liner::Context;
use liner::KeyBindings;
use std::collections::HashMap;
use std::io::ErrorKind;

fn main() {
    let mut cache = Box::new(HashMap::new());

    let empty_value = String::from("");

    let mut con = Context::new();

    loop {
        let res = con.read_line("> ", &mut |_| {});

        match res {
            Ok(res) => {
                match res.as_str() {
                    s if s.trim() == "" =>  {}
                    s if s.starts_with("get ") =>  {
                        let (_, key) = s.split_at(4);
                        let key_trimmed = String::from(key.trim());
                        if key_trimmed.find(' ').is_some() {
                            println!("key cannot contain space");
                            continue
                        }
                        println!("{}", cache.get(&key_trimmed).unwrap_or(&empty_value));
                    }
                    s if s.starts_with("set ") =>  {
                        let (_, key_value) = s.split_at(4);
                        match key_value.find(' ') {
                            Some(i) => {
                                let (key, value) = key_value.split_at(i);
                                let key_trimmed = String::from(key.trim());
                                let value_trimmed = String::from(value.trim());
                                cache.insert(key_trimmed, value_trimmed);
                            }
                            None => println!("no value specified")
                        }
                    }
                    "keys" =>  {
                        for key in cache.keys() {
                            println!("{}", key);
                        }
                    }
                    "emacs" => {
                        con.key_bindings = KeyBindings::Emacs;
                        println!("emacs mode");
                    }
                    "vi" | "vim" =>  {
                        con.key_bindings = KeyBindings::Vi;
                        println!("vi mode");
                    }
                    "exit" =>  {
                        break;
                    }
                    _ => {
                        println!("operation not defined")
                    }
                }

                con.history.push(res.into()).unwrap();
            }
            Err(e) => {
                match e.kind() {
                    // ctrl-c pressed
                    ErrorKind::Interrupted => {}
                    // ctrl-d pressed
                    ErrorKind::UnexpectedEof => {
                        break;
                    }
                    _ => panic!("error: {:?}", e),
                }
            }
        }
    }
}
<|endoftext|>


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

const U4_LOW:  u8 = 0b00001111;
const U4_HIGH: u8 = 0b11110000;

#[deriving(PartialEq,Show)]
enum CpuState {
	Continue,
	Halt,
}

/// The P150 virtual machine
struct P150Cpu {
	ip:  u8,
	ir: u16,

	reg: [u8, ..16],
	mem: [u8, ..256],
}

impl P150Cpu {
	/// Initializes the P150 CPU
	///
	/// NOTE: This implementation 0s memory; but this is not guaranteed
	/// by the machine specification.
	///
	/// Programs must start at memory address 0x00
	fn new() -> P150Cpu {
		P150Cpu {
			ip:  0x00,
			ir:  0x0000,

			reg: [0u8, ..16],
			mem: [0u8, ..256],
		}
	}

	/// Prints the current machine state to the console window
	/// This includes the IP, IR, and all registers.
	/// (Registers will be formatted as 2s complement numbers.)
	fn dump(&self) {
		println!("IP: 0x{:02X}, IR: 0x{:04X}", self.ip, self.ir);

		println!("---\nRegisters\n---")
		for (addr, cell) in self.reg.iter().enumerate() {
			println!("{:01X}: {}", addr, cell)
		}

	#[cfg(test)]
	fn get_reg(&self) -> &[u8] {
		self.reg
	}

	/// Read an array of instructions into main memory
	/// This reads two bytes at a time from the `memory` array
	/// and loads them into the P150s RAM bank, starting from address 0.
	fn init_mem(&mut self, memory: &[u16]) {
		let mut next_cell = 0x00;

		for op in memory.iter() {
			let byte_1 = (*op >> 8) as u8;
			let byte_2 = *op as u8;

			self.mem[next_cell]     = byte_1;
			self.mem[next_cell + 1] = byte_2;
			next_cell += 2
		}
	}

	/// Runs the entire fetch, execute, decode cycle against the current IP
	fn tick(&mut self) -> CpuState {
		self.fetch();

		// decode
		let op = (self.ir >> 12) as u8;
		match op {
			0x0   => { // ADDB
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);   // first input: lower nibble of first byte
				let rloc_i1 = h_nibble(self.ir as u8);          // second input: upper nibble of second byte
				let rloc_o0 = l_nibble(self.ir as u8);          // output: lower nibble of second byte

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] + self.reg[rloc_i1 as uint];
				Continue
			},

			0x3   => { // AND
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] & self.reg[rloc_i1 as uint];
				Continue
			},

			0x4   => { // OR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] | self.reg[rloc_i1 as uint];
				Continue
			},

			0x5   => { // XOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] ^ self.reg[rloc_i1 as uint];
				Continue
			},

			0x6   => { // MLOAD
				let rloc_o0 = l_nibble((self.ir >> 8) as u8);
				let mloc_i0 = self.ir as u8;

				self.reg[rloc_o0 as uint] = self.mem[mloc_i0 as uint];
				Continue
			},

			0x7   => { // MSTOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let mloc_o0 = self.ir as u8;

				self.mem[mloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x8   => { // RMOV
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_o0 = h_nibble(self.ir as u8);

				debug!("moving from {:02X} to {:02X}", rloc_i0, rloc_o0)
				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x9   => { // RSET
				let rloc = l_nibble((self.ir >> 8) as u8);  // lower nibble of first byte
				let rval = self.ir as u8;                    // value is entire second byte

				self.reg[rloc as uint] = rval;               // store value in register
				Continue
			},

			0xA   => { // JMPEQ
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let next_ip = self.ir as u8;

				if self.reg[rloc_i0 as uint] == self.reg[0] { self.ip = next_ip }
				Continue
			},

			0xB   => { Halt },
			_     => { debug!("halt, cpu on fire: {}", op); Halt },
		}
	}

	/// Load the instruction at `IP` and advance the pointer by two bytes.
	/// The instruction is packed into a single `u16` and stored in the instruction register.
	fn fetch(&mut self) {
		// load PC -> IR
		let byte_1 = self.mem[(self.ip+0) as uint];
		let byte_2 = self.mem[(self.ip+1) as uint];

		self.ir  = (byte_1 as u16 << 8) | (byte_2 as u16);
		self.ip += 2;

		debug!("IR set to 0x{:04X} ({:02X},{:02X})", self.ir, byte_1, byte_2)
	}
}

/// Take the lower nibble of a byte
fn l_nibble(byte: u8) -> u8 {
	(byte & U4_LOW)
}

/// Take the upper nibble of a byte and shift it
/// towards the least significant bits.
fn h_nibble(byte: u8) -> u8 {
	(byte & U4_HIGH) >> 4
}

fn main() {
	let mut cpu = P150Cpu::new();
	let program = [0x911E, 0x920C, 0x0123, 0x7340, 0x6040, 0xA310, 0x9500, 0xB000, 0x9501, 0xB000];
	cpu.init_mem(program);

	loop {
		match cpu.tick() {
			Continue => { continue; },
			Halt => { println!("CPU halted."); cpu.dump(); break; },
		}
	}
}

#[test]
fn test_hammer_time() {
	// cpu should stop
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0xB000]);

	assert_eq!(cpu.tick(), Halt)
}

#[test]
fn test_registers() {
	// cpu should set, move registers accordingly
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9110, 0x8130, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x3], 16)
}

#[test]
fn test_memory() {
	// memory sets and memory stores should read back successfully
	// uninitialized registers should not match initialized registers
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9120, 0x9330, 0x7140, 0x6240, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert!(cpu.get_reg()[0x1] == cpu.get_reg()[0x2]);
	assert!(cpu.get_reg()[0x1] != cpu.get_reg()[0x3]);
}

#[test]
fn test_bin() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9121, 0x9222, 0x3123, 0x4124, 0x5125, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert!(cpu.get_reg()[0x3] == (0x21 & 0x22));
	assert!(cpu.get_reg()[0x4] == (0x21 | 0x22));
	assert!(cpu.get_reg()[0x5] == (0x21 ^ 0x22));
}

#[test]
fn test_math() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9120, 0x920A, 0x0123, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x3], cpu.get_reg()[0x1] + cpu.get_reg()[0x2])
}

#[test]
fn test_branch() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9021, 0x9121, 0xA108, 0xB000, 0x922A, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x2], 0x2A)
}

<commit_msg>Rename l_nibble and h_nibble to be more self descriptive<commit_after>#![feature(phase)]
#[phase(plugin, link)] extern crate log;

const U4_LOW:  u8 = 0b00001111;
const U4_HIGH: u8 = 0b11110000;

#[deriving(PartialEq,Show)]
enum CpuState {
	Continue,
	Halt,
}

/// The P150 virtual machine
struct P150Cpu {
	ip:  u8,
	ir: u16,

	reg: [u8, ..16],
	mem: [u8, ..256],
}

impl P150Cpu {
	/// Initializes the P150 CPU
	///
	/// NOTE: This implementation 0s memory; but this is not guaranteed
	/// by the machine specification.
	///
	/// Programs must start at memory address 0x00
	fn new() -> P150Cpu {
		P150Cpu {
			ip:  0x00,
			ir:  0x0000,

			reg: [0u8, ..16],
			mem: [0u8, ..256],
		}
	}

	/// Prints the current machine state to the console window
	/// This includes the IP, IR, and all registers.
	/// (Registers will be formatted as 2s complement numbers.)
	fn dump(&self) {
		println!("IP: 0x{:02X}, IR: 0x{:04X}", self.ip, self.ir);

		println!("---\nRegisters\n---")
		for (addr, cell) in self.reg.iter().enumerate() {
			println!("{:01X}: {}", addr, cell)
		}

	#[cfg(test)]
	fn get_reg(&self) -> &[u8] {
		self.reg
	}

	/// Read an array of instructions into main memory
	/// This reads two bytes at a time from the `memory` array
	/// and loads them into the P150s RAM bank, starting from address 0.
	fn init_mem(&mut self, memory: &[u16]) {
		let mut next_cell = 0x00;

		for op in memory.iter() {
			let byte_1 = (*op >> 8) as u8;
			let byte_2 = *op as u8;

			self.mem[next_cell]     = byte_1;
			self.mem[next_cell + 1] = byte_2;
			next_cell += 2
		}
	}

	/// Runs the entire fetch, execute, decode cycle against the current IP
	fn tick(&mut self) -> CpuState {
		self.fetch();

		// decode
		let op = (self.ir >> 12) as u8;
		match op {
			0x0   => { // ADDB
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);   // first input: lower nibble of first byte
				let rloc_i1 = hi_nibble(self.ir as u8);          // second input: upper nibble of second byte
				let rloc_o0 = lo_nibble(self.ir as u8);          // output: lower nibble of second byte

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] + self.reg[rloc_i1 as uint];
				Continue
			},

			0x3   => { // AND
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let rloc_i1 = hi_nibble(self.ir as u8);
				let rloc_o0 = lo_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] & self.reg[rloc_i1 as uint];
				Continue
			},

			0x4   => { // OR
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let rloc_i1 = hi_nibble(self.ir as u8);
				let rloc_o0 = lo_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] | self.reg[rloc_i1 as uint];
				Continue
			},

			0x5   => { // XOR
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let rloc_i1 = hi_nibble(self.ir as u8);
				let rloc_o0 = lo_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] ^ self.reg[rloc_i1 as uint];
				Continue
			},

			0x6   => { // MLOAD
				let rloc_o0 = lo_nibble((self.ir >> 8) as u8);
				let mloc_i0 = self.ir as u8;

				self.reg[rloc_o0 as uint] = self.mem[mloc_i0 as uint];
				Continue
			},

			0x7   => { // MSTOR
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let mloc_o0 = self.ir as u8;

				self.mem[mloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x8   => { // RMOV
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let rloc_o0 = hi_nibble(self.ir as u8);

				debug!("moving from {:02X} to {:02X}", rloc_i0, rloc_o0)
				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x9   => { // RSET
				let rloc = lo_nibble((self.ir >> 8) as u8);  // lower nibble of first byte
				let rval = self.ir as u8;                    // value is entire second byte

				self.reg[rloc as uint] = rval;               // store value in register
				Continue
			},

			0xA   => { // JMPEQ
				let rloc_i0 = lo_nibble((self.ir >> 8) as u8);
				let next_ip = self.ir as u8;

				if self.reg[rloc_i0 as uint] == self.reg[0] { self.ip = next_ip }
				Continue
			},

			0xB   => { Halt },
			_     => { debug!("halt, cpu on fire: {}", op); Halt },
		}
	}

	/// Load the instruction at `IP` and advance the pointer by two bytes.
	/// The instruction is packed into a single `u16` and stored in the instruction register.
	fn fetch(&mut self) {
		// load PC -> IR
		let byte_1 = self.mem[(self.ip+0) as uint];
		let byte_2 = self.mem[(self.ip+1) as uint];

		self.ir  = (byte_1 as u16 << 8) | (byte_2 as u16);
		self.ip += 2;

		debug!("IR set to 0x{:04X} ({:02X},{:02X})", self.ir, byte_1, byte_2)
	}
}

/// Take the lower nibble of a byte
fn lo_nibble(byte: u8) -> u8 {
	(byte & U4_LOW)
}

/// Take the upper nibble of a byte and shift it
/// towards the least significant bits.
fn hi_nibble(byte: u8) -> u8 {
	(byte & U4_HIGH) >> 4
}

fn main() {
	let mut cpu = P150Cpu::new();
	let program = [0x911E, 0x920C, 0x0123, 0x7340, 0x6040, 0xA310, 0x9500, 0xB000, 0x9501, 0xB000];
	cpu.init_mem(program);

	loop {
		match cpu.tick() {
			Continue => { continue; },
			Halt => { println!("CPU halted."); cpu.dump(); break; },
		}
	}
}

#[test]
fn test_hammer_time() {
	// cpu should stop
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0xB000]);

	assert_eq!(cpu.tick(), Halt)
}

#[test]
fn test_registers() {
	// cpu should set, move registers accordingly
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9110, 0x8130, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x3], 16)
}

#[test]
fn test_memory() {
	// memory sets and memory stores should read back successfully
	// uninitialized registers should not match initialized registers
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9120, 0x9330, 0x7140, 0x6240, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert!(cpu.get_reg()[0x1] == cpu.get_reg()[0x2]);
	assert!(cpu.get_reg()[0x1] != cpu.get_reg()[0x3]);
}

#[test]
fn test_bin() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9121, 0x9222, 0x3123, 0x4124, 0x5125, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert!(cpu.get_reg()[0x3] == (0x21 & 0x22));
	assert!(cpu.get_reg()[0x4] == (0x21 | 0x22));
	assert!(cpu.get_reg()[0x5] == (0x21 ^ 0x22));
}

#[test]
fn test_math() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9120, 0x920A, 0x0123, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x3], cpu.get_reg()[0x1] + cpu.get_reg()[0x2])
}

#[test]
fn test_branch() {
	let mut cpu = P150Cpu::new();
	cpu.init_mem([0x9021, 0x9121, 0xA108, 0xB000, 0x922A, 0xB000]);

	loop {
		if cpu.tick() == Halt { break; }
	}

	assert_eq!(cpu.get_reg()[0x2], 0x2A)
}

<|endoftext|>


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

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize, XKeysymToString, XKeycodeToKeysym};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
use std::c_str::CString;
mod xtst;
mod xlib;
mod xlibint;
mod xutil;

struct XRecordDatum {
  xtype: ::libc::c_uchar,
  event: ::xlib::XEvent,
  req:   ::xlibint::xResourceReq,
  reply: ::xlibint::xGenericReply,
  error: ::xlibint::xError,
  setup: ::xlibint::xConnSetupPrefix,
}

// let mut display_control: *mut xlib::Display  = std::mem::transmute(0);
// let mut display_data: *mut xlib::Display  = std::mem::transmute(0);
static mut display_control: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut display_data: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut event_count:u32 = 0;
fn main() {
	unsafe {
		let mut a:  i8 = 0;
		display_control = XOpenDisplay(&a);
		display_data = XOpenDisplay(&a);

		if display_data.is_null() || display_control.is_null() {
			fail!("XOpenDisplay() failed!");
		}

		XSynchronize(display_control, 1);

		let display_name = unsafe {XDisplayName(&a)};
		let ext_name = "RECORD";
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			1,
			recordRangePtr,
			1
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		xtst::XRecordFreeContext(display_data, context);
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, raw_data: *mut XRecordInterceptData) {

	unsafe {

		let data = &*raw_data;
		// println!("Category {}", data.category);
		if data.category != xtst::XRecordFromServer {
			return;
		}
		println!("Event count: {}", event_count);
		event_count += 1;
		println!("Time {}", data.server_time);
		println!("Datalen {}", data.data_len);
		let mut xdatum_ptr: *mut XRecordDatum = data.data as *mut XRecordDatum;
		let mut xdatum = &*xdatum_ptr;

		let mut event = xdatum.event;
		println!("Type {}", xdatum.xtype);

		// Catch key event
		if xdatum.xtype == xtst::KeyPress || xdatum.xtype == xtst::KeyRelease {
			// extract key code
			let raw_bytes: &mut [u8,..4] = std::mem::transmute(data.data);
			let c_char  = XKeysymToString(XKeycodeToKeysym(display_control, raw_bytes[1], 0));
			let c_string = CString::new(std::mem::transmute(c_char), false);
			let char: &str = c_string.as_str().unwrap();
			println!("Keycode: {}, Character {}", raw_bytes[1], char);

			// println!("nitems {}", (&*wm_name).nitems);
		}
		// get current focus window
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		xlib::XGetInputFocus(display_control, current_window, revert_to_return);
		println!("revertToReturn {}", *revert_to_return);
		let mut j = 0u;
		let mut wm_name: *mut xutil::XTextProperty = std::mem::transmute(&mut j);
		let mut wm_name_true: &str = "";
		let mut tmp =0i8;
		let mut c_wm_name: CString = CString::new(&tmp,false);
		let mut res = 0;
		// res = xutil::XGetWMName(display_control, *current_window, wm_name);
		let mut i = 0u;
		while res == 0 && i < 2 {
			print!(".");
			println!("current_window {}", *current_window);
			if *current_window == 0 {
				break;
			}
			res = xutil::XGetWMName(display_control, *current_window, wm_name);

			if res == 0 {
				println!("Move to parent");
				let mut root: xlib::Window = 0;
				let mut parent: xlib::Window = 0;
				let mut childrens: *mut xlib::Window = &mut 0u64;
				let mut nchildren: u32 = 0;
				let r2 = xlib::XQueryTree(display_control, *current_window, &mut root, &mut parent, &mut childrens, &mut nchildren);
				if r2 == 0 {
					print!("*");
				} else {
					println!("parent {}", parent);
					*current_window = parent;
				}
			}
			// get parent window
			i += 1;
		}
		println!("---");
		if res == 0 {
			println!("no wmname");
		} else {
			// extract name from XTextProperty
			println!("wmname found!");
			println!("format: {}", (*wm_name).format);
			if (*wm_name).format != 8 {
				fail!("");
			}
			println!("encoding: {}", (*wm_name).encoding);
			let encoding_name = xlib::XGetAtomName(display_control, (*wm_name).encoding);
			let encoding_name_string = CString::new(std::mem::transmute(encoding_name), false);
			println!("encoding name: {}", encoding_name_string.as_str().unwrap());
			let mut tmp2 = 0i8;
			let mut list: *mut *mut ::libc::c_char = std::mem::transmute(&mut &mut tmp2);
			let mut list_count: i32 = 0;
			let res3 = xutil::XmbTextPropertyToTextList(display_control, std::mem::transmute(wm_name), &mut list, &mut list_count);
			println!("convert result: {}", res3);
			if res3 == 0 {
				println!("list count {}", list_count);
				c_wm_name = CString::new(std::mem::transmute(*list), false);
				wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name: {}", wm_name_true);
				xlib::XFreeStringList(list);
			} else {
				c_wm_name = CString::new(std::mem::transmute((*wm_name).value), false);
				// wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name bytes: {}", c_wm_name.as_bytes());
				// ая -      27 45 76 208 239 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// бв -      27 45 76 209 210 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx -      122 120 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// длодлод - 27 45 76 212 219 222 212 219 222 212 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx • - Sublime Text (UNREGISTERED)

				println!("wm_name: {}", c_wm_name);
				println!("wm_name len w/o null: {}", c_wm_name.len());
			}

		}

		XRecordFreeData(raw_data);
	}
	println!("\n");
}

// fn string_convert(string: *mut libc::c_char) -> &'static str{
// 	let temp = unsafe{CString::new(std::mem::transmute(string), true)};
// 	let a: &str = temp.as_str().unwrap();
// }
struct Display {
    display: *mut xlib::Display,
}

impl Display {
	fn get_input_focus(&self) {
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		xlib::XGetInputFocus(self.display, current_window, revert_to_return);
		Window {display: &self}
	}
}

struct Window {
    id: u64, // XID
    display: &Display
}

impl Window {
	fn get_wm_name(&self) {
		let prop: xutil::XTextProperty;
		let res = xutil::XGetWMName(self.display.display, self.id, prop);
	}
}<commit_msg>lifetimes<commit_after>#![feature(globs)]
extern crate libc;

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize, XKeysymToString, XKeycodeToKeysym};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
use std::c_str::CString;
mod xtst;
mod xlib;
mod xlibint;
mod xutil;

struct XRecordDatum {
  xtype: ::libc::c_uchar,
  event: ::xlib::XEvent,
  req:   ::xlibint::xResourceReq,
  reply: ::xlibint::xGenericReply,
  error: ::xlibint::xError,
  setup: ::xlibint::xConnSetupPrefix,
}

// let mut display_control: *mut xlib::Display  = std::mem::transmute(0);
// let mut display_data: *mut xlib::Display  = std::mem::transmute(0);
static mut display_control: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut display_data: *mut xlib::Display = 0 as *mut xlib::Struct__XDisplay;
static mut event_count:u32 = 0;
fn main() {
	unsafe {
		let mut a:  i8 = 0;
		display_control = XOpenDisplay(&a);
		display_data = XOpenDisplay(&a);

		if display_data.is_null() || display_control.is_null() {
			fail!("XOpenDisplay() failed!");
		}

		XSynchronize(display_control, 1);

		let display_name = unsafe {XDisplayName(&a)};
		let ext_name = "RECORD";
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *const i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			1,
			recordRangePtr,
			1
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		xtst::XRecordFreeContext(display_data, context);
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, raw_data: *mut XRecordInterceptData) {

	unsafe {

		let data = &*raw_data;
		// println!("Category {}", data.category);
		if data.category != xtst::XRecordFromServer {
			return;
		}
		println!("Event count: {}", event_count);
		event_count += 1;
		println!("Time {}", data.server_time);
		println!("Datalen {}", data.data_len);
		let mut xdatum_ptr: *mut XRecordDatum = data.data as *mut XRecordDatum;
		let mut xdatum = &*xdatum_ptr;

		let mut event = xdatum.event;
		println!("Type {}", xdatum.xtype);

		// Catch key event
		if xdatum.xtype == xtst::KeyPress || xdatum.xtype == xtst::KeyRelease {
			// extract key code
			let raw_bytes: &mut [u8,..4] = std::mem::transmute(data.data);
			let c_char  = XKeysymToString(XKeycodeToKeysym(display_control, raw_bytes[1], 0));
			let c_string = CString::new(std::mem::transmute(c_char), false);
			let char: &str = c_string.as_str().unwrap();
			println!("Keycode: {}, Character {}", raw_bytes[1], char);

			// println!("nitems {}", (&*wm_name).nitems);
		}
		// get current focus window
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		xlib::XGetInputFocus(display_control, current_window, revert_to_return);
		println!("revertToReturn {}", *revert_to_return);
		let mut j = 0u;
		let mut wm_name: *mut xutil::XTextProperty = std::mem::transmute(&mut j);
		let mut wm_name_true: &str = "";
		let mut tmp =0i8;
		let mut c_wm_name: CString = CString::new(&tmp,false);
		let mut res = 0;
		// res = xutil::XGetWMName(display_control, *current_window, wm_name);
		let mut i = 0u;
		while res == 0 && i < 2 {
			print!(".");
			println!("current_window {}", *current_window);
			if *current_window == 0 {
				break;
			}
			res = xutil::XGetWMName(display_control, *current_window, wm_name);

			if res == 0 {
				println!("Move to parent");
				let mut root: xlib::Window = 0;
				let mut parent: xlib::Window = 0;
				let mut childrens: *mut xlib::Window = &mut 0u64;
				let mut nchildren: u32 = 0;
				let r2 = xlib::XQueryTree(display_control, *current_window, &mut root, &mut parent, &mut childrens, &mut nchildren);
				if r2 == 0 {
					print!("*");
				} else {
					println!("parent {}", parent);
					*current_window = parent;
				}
			}
			// get parent window
			i += 1;
		}
		println!("---");
		if res == 0 {
			println!("no wmname");
		} else {
			// extract name from XTextProperty
			println!("wmname found!");
			println!("format: {}", (*wm_name).format);
			if (*wm_name).format != 8 {
				fail!("");
			}
			println!("encoding: {}", (*wm_name).encoding);
			let encoding_name = xlib::XGetAtomName(display_control, (*wm_name).encoding);
			let encoding_name_string = CString::new(std::mem::transmute(encoding_name), false);
			println!("encoding name: {}", encoding_name_string.as_str().unwrap());
			let mut tmp2 = 0i8;
			let mut list: *mut *mut ::libc::c_char = std::mem::transmute(&mut &mut tmp2);
			let mut list_count: i32 = 0;
			let res3 = xutil::XmbTextPropertyToTextList(display_control, std::mem::transmute(wm_name), &mut list, &mut list_count);
			println!("convert result: {}", res3);
			if res3 == 0 {
				println!("list count {}", list_count);
				c_wm_name = CString::new(std::mem::transmute(*list), false);
				wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name: {}", wm_name_true);
				xlib::XFreeStringList(list);
			} else {
				c_wm_name = CString::new(std::mem::transmute((*wm_name).value), false);
				// wm_name_true = c_wm_name.as_str().unwrap();
				println!("wm_name bytes: {}", c_wm_name.as_bytes());
				// ая -      27 45 76 208 239 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// бв -      27 45 76 209 210 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx -      122 120 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// длодлод - 27 45 76 212 219 222 212 219 222 212 32 27 37 71 226 128 162 27 37 64 32 45 32 83 117 98 108 105 109 101 32 84 101 120 116 32 40 85 78 82 69 71 73 83 84 69 82 69 68 41 0
				// zx • - Sublime Text (UNREGISTERED)

				println!("wm_name: {}", c_wm_name);
				println!("wm_name len w/o null: {}", c_wm_name.len());
			}

		}

		XRecordFreeData(raw_data);
	}
	println!("\n");
}

// fn string_convert(string: *mut libc::c_char) -> &'static str{
// 	let temp = unsafe{CString::new(std::mem::transmute(string), true)};
// 	let a: &str = temp.as_str().unwrap();
// }
struct Display<'a> {
    display: *mut xlib::Display,
}

impl<'a> Display<'a> {
	fn get_input_focus(&self) -> Window{
		let current_window: *mut xlib::Window = &mut 0;
		let revert_to_return: *mut i32 = &mut 0;
		unsafe{xlib::XGetInputFocus(self.display, current_window, revert_to_return)};
		Window {id: 0, display: self}
	}
}

struct Window<'a> {
    id: u64, // XID
    display: &'a Display<'a>
}

impl<'a> Window<'a> {
	fn get_wm_name(&self) {
		let mut prop: *mut xutil::XTextProperty = 0 as *mut xutil::XTextProperty;
		let res = unsafe{xutil::XGetWMName(self.display.display, self.id, prop)};
	}
}<|endoftext|>


<commit_before>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is an implementation of Sokoban in Rust.

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate clap;
extern crate sdl2;
extern crate xml;

use clap::App;
use sdl2::event::Event;
use sdl2::image::LoadTexture;
use sdl2::image::INIT_PNG;
use sdl2::keyboard::Keycode;
use sdl2::render::TextureCreator;
use sdl2::video::WindowContext;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::str::FromStr;
use xml::reader::EventReader;
use xml::reader::XmlEvent;

pub mod error;
pub mod game;
pub mod painter;
pub mod shadow;
pub mod tileset;

use game::Level;
use painter::Painter;
use tileset::Tileset;

pub fn main() {
    let yml = load_yaml!("clap.yml");
    let matches = App::from_yaml(yml).get_matches();

    let slc_file = matches.value_of("slc_file").unwrap();
    let width = value_t!(matches.value_of("width"), u32).unwrap_or(1024);
    let height = value_t!(matches.value_of("height"), u32).unwrap_or(768);

    let sdl_context =
        sdl2::init().unwrap_or_else(|err| panic!("Failed to initialize an SDL context: {}", err));

    let video_subsystem = sdl_context
        .video()
        .unwrap_or_else(|err| panic!("Failed to initialize the video subsystem: {}", err));

    let mut window_builder = video_subsystem.window("sokoban-rs", width, height);
    if matches.is_present("fullscreen") {
        window_builder.fullscreen();
    } else {
        window_builder.position_centered();
    }

    let window = window_builder
        .opengl()
        .build()
        .unwrap_or_else(|err| panic!("Failed to create the window: {}", err));

    let mut canvas = window
        .into_canvas()
        .build()
        .unwrap_or_else(|err| panic!("Failed to get an SDL canvas for the main window: {}", err));

    let creator = canvas.texture_creator();

    let _image_context = sdl2::image::init(INIT_PNG).unwrap();
    let ttf_context = sdl2::ttf::init().unwrap();

    let mut painter = {
        let big_set = load_tileset(&creator, "assets/image/tileset.png", 101, 171, 83, 40);
        let small_set = load_tileset(&creator, "assets/image/tileset-small.png", 50, 85, 41, 20);
        Painter::new(&mut canvas, big_set, small_set, &ttf_context)
    };

    let mut collection = load_slc_file(Path::new(&slc_file))
        .unwrap_or_else(|err| panic!("{}", err))
        .into_iter();
    let mut reference_level = collection.next().unwrap();
    let mut level = reference_level.clone();

    let mut running = true;
    let mut event_pump = sdl_context.event_pump().unwrap();
    let mut skip = false;
    while running {
        if level.is_completed() || skip {
            match collection.next() {
                Some(l) => {
                    level = l;
                    reference_level = level.clone();
                    skip = false;
                }
                None => {
                    break;
                }
            }
        }
        painter.paint(&mut canvas, &level);

        match event_pump.wait_event() {
            Event::Quit { .. }
            | Event::KeyDown {
                keycode: Some(Keycode::Escape),
                ..
            } => running = false,
            Event::KeyDown {
                keycode: Some(Keycode::Left),
                ..
            } => {
                level.step(game::Direction::Left);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Right),
                ..
            } => {
                level.step(game::Direction::Right);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Up),
                ..
            } => {
                level.step(game::Direction::Up);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Down),
                ..
            } => {
                level.step(game::Direction::Down);
            }
            Event::KeyDown {
                keycode: Some(Keycode::R),
                ..
            } => {
                level = reference_level.clone();
            }
            Event::KeyDown {
                keycode: Some(Keycode::N),
                ..
            } => {
                skip = true;
            }
            _ => {}
        }
    }
}

fn load_tileset<P: AsRef<Path>>(texture_creator: &TextureCreator<WindowContext>, path: P, width: u32, height: u32, effective_height: u32, offset: i32) -> Tileset {
    let texture = texture_creator
        .load_texture(path.as_ref())
        .unwrap();
    Tileset::new(texture, width, height, effective_height, offset)
}

/// Builds levels from a level collection file in the SLC format.
fn load_slc_file(path: &Path) -> Result<Vec<Level>, error::SokobanError> {
    let mut collection = Vec::new();
    let file = try!(File::open(&path));
    let reader = BufReader::new(file);
    let parser = EventReader::new(reader);

    let mut level_title = String::new();
    let mut level_str = String::new();
    let mut reading_level = false;
    for e in parser {
        match e {
            Ok(XmlEvent::StartElement {
                ref name,
                ref attributes,
                ..
            }) => {
                if name.local_name == "L" {
                    reading_level = true;
                } else if name.local_name == "Level" {
                    if let Some(id) = attributes.iter().find(|&attr| attr.name.local_name == "Id") {
                        level_title = id.value.clone();
                    }
                }
            }
            Ok(XmlEvent::EndElement { name }) => {
                if name.local_name == "Level" {
                    let mut level = try!(Level::from_str(&level_str));
                    level.set_title(level_title.clone());
                    collection.push(level);
                    level_str.clear();
                }
            }
            Ok(XmlEvent::Characters(ref data)) => {
                if reading_level {
                    level_str.push_str(data);
                    level_str.push('\n');
                }
            }
            _ => {}
        }
    }

    Ok(collection)
}
<commit_msg>Added a get_window function<commit_after>// This file is part of sokoban-rs
// Copyright 2015 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This is an implementation of Sokoban in Rust.

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate clap;
extern crate sdl2;
extern crate xml;

use clap::{App, ArgMatches};
use sdl2::event::Event;
use sdl2::image::LoadTexture;
use sdl2::image::INIT_PNG;
use sdl2::keyboard::Keycode;
use sdl2::render::TextureCreator;
use sdl2::video::{Window, WindowContext};
use sdl2::Sdl;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use std::str::FromStr;
use xml::reader::EventReader;
use xml::reader::XmlEvent;

pub mod error;
pub mod game;
pub mod painter;
pub mod shadow;
pub mod tileset;

use game::Level;
use painter::Painter;
use tileset::Tileset;

pub fn main() {
    let yml = load_yaml!("clap.yml");
    let matches = App::from_yaml(yml).get_matches();

    let slc_file = matches.value_of("slc_file").unwrap();

    let sdl_context =
        sdl2::init().unwrap_or_else(|err| panic!("Failed to initialize an SDL context: {}", err));

    let window = get_window(&sdl_context, &matches);

    let mut canvas = window
        .into_canvas()
        .build()
        .unwrap_or_else(|err| panic!("Failed to get an SDL canvas for the main window: {}", err));

    let creator = canvas.texture_creator();

    let _image_context = sdl2::image::init(INIT_PNG).unwrap();
    let ttf_context = sdl2::ttf::init().unwrap();

    let mut painter = {
        let big_set = load_tileset(&creator, "assets/image/tileset.png", 101, 171, 83, 40);
        let small_set = load_tileset(&creator, "assets/image/tileset-small.png", 50, 85, 41, 20);
        Painter::new(&mut canvas, big_set, small_set, &ttf_context)
    };

    let mut collection = load_slc_file(Path::new(&slc_file))
        .unwrap_or_else(|err| panic!("{}", err))
        .into_iter();
    let mut reference_level = collection.next().unwrap();
    let mut level = reference_level.clone();

    let mut running = true;
    let mut event_pump = sdl_context.event_pump().unwrap();
    let mut skip = false;
    while running {
        if level.is_completed() || skip {
            match collection.next() {
                Some(l) => {
                    level = l;
                    reference_level = level.clone();
                    skip = false;
                }
                None => {
                    break;
                }
            }
        }
        painter.paint(&mut canvas, &level);

        match event_pump.wait_event() {
            Event::Quit { .. }
            | Event::KeyDown {
                keycode: Some(Keycode::Escape),
                ..
            } => running = false,
            Event::KeyDown {
                keycode: Some(Keycode::Left),
                ..
            } => {
                level.step(game::Direction::Left);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Right),
                ..
            } => {
                level.step(game::Direction::Right);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Up),
                ..
            } => {
                level.step(game::Direction::Up);
            }
            Event::KeyDown {
                keycode: Some(Keycode::Down),
                ..
            } => {
                level.step(game::Direction::Down);
            }
            Event::KeyDown {
                keycode: Some(Keycode::R),
                ..
            } => {
                level = reference_level.clone();
            }
            Event::KeyDown {
                keycode: Some(Keycode::N),
                ..
            } => {
                skip = true;
            }
            _ => {}
        }
    }
}

fn get_window(sdl_context: &Sdl, matches: &ArgMatches) -> Window {
    let width = value_t!(matches.value_of("width"), u32).unwrap_or(1024);
    let height = value_t!(matches.value_of("height"), u32).unwrap_or(768);

    let video_subsystem = sdl_context
        .video()
        .unwrap_or_else(|err| panic!("Failed to initialize the video subsystem: {}", err));

    let mut window_builder = video_subsystem.window("sokoban-rs", width, height);
    if matches.is_present("fullscreen") {
        window_builder.fullscreen();
    } else {
        window_builder.position_centered();
    }

    let window = window_builder
        .opengl()
        .build()
        .unwrap_or_else(|err| panic!("Failed to create the window: {}", err));

    window
}

fn load_tileset<P: AsRef<Path>>(texture_creator: &TextureCreator<WindowContext>, path: P, width: u32, height: u32, effective_height: u32, offset: i32) -> Tileset {
    let texture = texture_creator
        .load_texture(path.as_ref())
        .unwrap();
    Tileset::new(texture, width, height, effective_height, offset)
}

/// Builds levels from a level collection file in the SLC format.
fn load_slc_file(path: &Path) -> Result<Vec<Level>, error::SokobanError> {
    let mut collection = Vec::new();
    let file = try!(File::open(&path));
    let reader = BufReader::new(file);
    let parser = EventReader::new(reader);

    let mut level_title = String::new();
    let mut level_str = String::new();
    let mut reading_level = false;
    for e in parser {
        match e {
            Ok(XmlEvent::StartElement {
                ref name,
                ref attributes,
                ..
            }) => {
                if name.local_name == "L" {
                    reading_level = true;
                } else if name.local_name == "Level" {
                    if let Some(id) = attributes.iter().find(|&attr| attr.name.local_name == "Id") {
                        level_title = id.value.clone();
                    }
                }
            }
            Ok(XmlEvent::EndElement { name }) => {
                if name.local_name == "Level" {
                    let mut level = try!(Level::from_str(&level_str));
                    level.set_title(level_title.clone());
                    collection.push(level);
                    level_str.clear();
                }
            }
            Ok(XmlEvent::Characters(ref data)) => {
                if reading_level {
                    level_str.push_str(data);
                    level_str.push('\n');
                }
            }
            _ => {}
        }
    }

    Ok(collection)
}
<|endoftext|>


<commit_before>extern crate rustless;
extern crate hyper;
extern crate iron;
extern crate rustc_serialize;
extern crate valico;

use hyper::status::StatusCode;
use iron::Iron;
use rustless::{
    Application, Api, Nesting, Versioning
};
use rustless::server::header::AccessControlAllowOrigin;
use rustc_serialize::json::ToJson;
use std::process::Command;

fn main() {

  println!("Starting RPI Management ...");

  let api = Api::build(|api| {

    api.post("shutdown", |endpoint| {
        endpoint.handle(|mut client, params| {
            println!("Shutdown requested");
            client.set_header(AccessControlAllowOrigin::Any);

            let output = Command::new("shutdown")
                     .arg("-h")
                     .arg("now")
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
            let strStdout = String::from_utf8(output.stdout).unwrap();
            client.text(strStdout)
            // client.empty()
        })
    });
  });

  let app = Application::new(api);

  Iron::new(app).http("localhost:4000").unwrap();

}
<commit_msg>Add 'ping' command<commit_after>extern crate rustless;
extern crate hyper;
extern crate iron;
extern crate rustc_serialize;
extern crate valico;

use hyper::status::StatusCode;
use iron::Iron;
use rustless::{
    Application, Api, Nesting, Versioning
};
use rustless::server::header::AccessControlAllowOrigin;
use rustc_serialize::json::ToJson;
use std::process::Command;

fn main() {

  println!("Starting RPI Management ...");

  let api = Api::build(|api| {

    api.get("ping", |endpoint| {
      endpoint.handle(|mut client, params| {
        client.set_header(AccessControlAllowOrigin::Any);
        client.empty()
      })
    });

    api.post("shutdown", |endpoint| {
        endpoint.handle(|mut client, params| {
            println!("Shutdown requested");
            client.set_header(AccessControlAllowOrigin::Any);

            let output = Command::new("shutdown")
                     .arg("-h")
                     .arg("now")
                     .output()
                     .unwrap_or_else(|e| { panic!("failed to execute process: {}", e) });
            let str_stdout = String::from_utf8(output.stdout).unwrap();
            client.text(str_stdout)
            // client.empty()
        })
    });
  });

  let app = Application::new(api);

  Iron::new(app).http("localhost:4000").unwrap();

}
<|endoftext|>


<commit_before>extern crate petgraph;
extern crate mime;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::collections::HashMap;
use petgraph::prelude::*;
use petgraph::dot::{Dot, Config};

fn mimelist_init() -> Result<Vec<String>, std::io::Error> {
    let ftypes = File::open("/usr/share/mime/types")?;
    let rtypes = BufReader::new(ftypes);
    let mut mimelist = Vec::<String>::new();

    for line in rtypes.lines() {
        let mime = line?.split_whitespace().nth(0).unwrap_or("").to_string();
        mimelist.push(mime);
    }

    let mimelist = mimelist;
    Ok(mimelist)
}

fn aliaslist_init() -> Result<Vec<(String, String)>, std::io::Error> {
    let faliases = File::open("/usr/share/mime/aliases")?;
    let raliases = BufReader::new(faliases);
    let mut aliaslist = Vec::<(String, String)>::new();

    for line in raliases.lines() {
        let line_raw = line?;

        let a = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        let b = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        aliaslist.push((a,b));
    }

    let aliaslist = aliaslist;
    Ok(aliaslist)
}

fn graph_init() -> Result<DiGraph<String, u32>, std::io::Error> {

    let fsubclasses = File::open("/usr/share/mime/subclasses")?;
    let rsubclasses = BufReader::new(fsubclasses);

    let mut graph = DiGraph::<String, u32>::new();
    let mut added_mimes = HashMap::<String, NodeIndex>::new();

    let mut node_text: NodeIndex = NodeIndex::default();
    let mut node_octet: NodeIndex = NodeIndex::default();
    let mut node_allall: NodeIndex = NodeIndex::default();
    let mut node_allfiles: NodeIndex = NodeIndex::default();

    // Get list of MIME types
    let mimelist = mimelist_init()?;
    // Get list of MIME aliases (doesn't need to exist.)
    let aliaslist = aliaslist_init().unwrap_or(Vec::<(String, String)>::new());

    // Create all nodes
    for mimetype in mimelist.iter() {
        let node = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node);

        // Record well-used parent types now
        if mimetype == "text/plain" {
            node_text = node;
        } else if mimetype == "application/octet-stream" {
            node_octet = node;
        } else if mimetype == "all/all" {
            node_allall = node;
        } else if mimetype == "all/allfiles" {
            node_allfiles = node;
        }
    }

    if node_text == NodeIndex::default() {
        let mimetype = "text/plain".to_string();
        node_text = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node_text);
    }

    if node_octet == NodeIndex::default() {
        let mimetype = "application/octet-stream".to_string();
        node_octet = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node_octet);
    }

    let node_text = node_text;
    let node_octet = node_octet;

    // If a relation exists, add child to parent node
    for line in rsubclasses.lines() {
        let line_raw = line?;
        let child_raw = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        let parent_raw = line_raw.split_whitespace().nth(1).unwrap_or("").to_string();

        let parent: NodeIndex;
        let child: NodeIndex;

        match added_mimes.get(&parent_raw) {
            Some(node) => {parent = *node;}
            None => {continue;}
        }

        match added_mimes.get(&child_raw) {
            Some(node) => {child = *node;}
            None => {continue;}
        }

        graph.update_edge(parent, child, 1);
    }

    //Otherwise, add to applicaton/octet-stream, all/all, or text/plain, depending on top-level
    graph.update_edge(node_octet, node_text, 1);
    graph.update_edge(node_allall, node_allfiles, 1);
    graph.update_edge(node_allfiles, node_octet, 1);

    let mut edge_list = Vec::<(NodeIndex, NodeIndex)>::new();
    for mimenode in graph.externals(Incoming) {

        let ref mimetype = graph[mimenode];
        let toplevel = mimetype.split("/").nth(0).unwrap_or("");

        if mimenode == node_text || mimenode == node_octet {
            continue;
        }

        if toplevel == "text" {
            edge_list.push( (node_text, mimenode) );
        } else if toplevel == "inode" {
            edge_list.push( (node_allall, mimenode) );
        } else {
            edge_list.push( (node_octet, mimenode) );
        }
    }

    graph.extend_with_edges(edge_list);

    let graph = graph;
    println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));

    Ok(graph)
}

fn main() {

    match graph_init() {
        Err(why) => panic!("{:?}", why),
        Ok(graph) => {
            let type_graph = graph;
        },
    };
}
<commit_msg>Handle filetype aliases<commit_after>extern crate petgraph;
extern crate mime;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;
use std::collections::HashMap;
use petgraph::prelude::*;
use petgraph::dot::{Dot, Config};

fn mimelist_init() -> Result<Vec<String>, std::io::Error> {
    let ftypes = File::open("/usr/share/mime/types")?;
    let rtypes = BufReader::new(ftypes);
    let mut mimelist = Vec::<String>::new();

    for line in rtypes.lines() {
        let mime = line?.split_whitespace().nth(0).unwrap_or("").to_string();
        mimelist.push(mime);
    }

    let mimelist = mimelist;
    Ok(mimelist)
}

fn aliaslist_init() -> Result<HashMap<String, String>, std::io::Error> {
    let faliases = File::open("/usr/share/mime/aliases")?;
    let raliases = BufReader::new(faliases);
    let mut aliaslist = HashMap::<String, String>::new();

    for line in raliases.lines() {
        let line_raw = line?;

        let a = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        let b = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        aliaslist.insert(a,b);
    }

    let aliaslist = aliaslist;
    Ok(aliaslist)
}

fn graph_init() -> Result<DiGraph<String, u32>, std::io::Error> {

    let fsubclasses = File::open("/usr/share/mime/subclasses")?;
    let rsubclasses = BufReader::new(fsubclasses);

    let mut graph = DiGraph::<String, u32>::new();
    let mut added_mimes = HashMap::<String, NodeIndex>::new();

    let mut node_text: NodeIndex = NodeIndex::default();
    let mut node_octet: NodeIndex = NodeIndex::default();
    let mut node_allall: NodeIndex = NodeIndex::default();
    let mut node_allfiles: NodeIndex = NodeIndex::default();

    // Get list of MIME types
    let mimelist = mimelist_init()?;
    // Get list of MIME aliases (doesn't need to exist.)
    let aliaslist = aliaslist_init().unwrap_or(HashMap::<String, String>::new());

    // Create all nodes
    for mimetype in mimelist.iter() {

        // Do not insert aliases
        let mut mimetype = mimetype;
        match aliaslist.get(mimetype) {
            Some(alias) => {mimetype = alias;}
            None => {}
        }
        let mimetype = mimetype;

        // Do not insert "x-content/*" or "multipart/*"
        let toplevel = mimetype.split("/").nth(0).unwrap_or("");
        if toplevel == "x-content" || toplevel == "multipart" {
            continue;
        }

        let node = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node);

        // Record well-used parent types now
        if mimetype == "text/plain" {
            node_text = node;
        } else if mimetype == "application/octet-stream" {
            node_octet = node;
        } else if mimetype == "all/all" {
            node_allall = node;
        } else if mimetype == "all/allfiles" {
            node_allfiles = node;
        }
    }

    if node_text == NodeIndex::default() {
        let mimetype = "text/plain".to_string();
        node_text = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node_text);
    }

    if node_octet == NodeIndex::default() {
        let mimetype = "application/octet-stream".to_string();
        node_octet = graph.add_node(mimetype.clone());
        added_mimes.insert(mimetype.clone(), node_octet);
    }

    let node_text = node_text;
    let node_octet = node_octet;

    // If a relation exists, add child to parent node
    for line in rsubclasses.lines() {
        let line_raw = line?;
        let mut child_raw = line_raw.split_whitespace().nth(0).unwrap_or("").to_string();
        let mut parent_raw = line_raw.split_whitespace().nth(1).unwrap_or("").to_string();

        // If child or parent refers to an alias, change it to the real type
        match aliaslist.get(&child_raw) {
            Some(alias) => {child_raw = alias.clone();}
            None => {}
        }
        match aliaslist.get(&parent_raw) {
            Some(alias) => {parent_raw = alias.clone();}
            None => {}
        }
        let child_raw = child_raw;
        let parent_raw = parent_raw;

        let parent: NodeIndex;
        let child: NodeIndex;

        match added_mimes.get(&parent_raw) {
            Some(node) => {parent = *node;}
            None => {continue;}
        }

        match added_mimes.get(&child_raw) {
            Some(node) => {child = *node;}
            None => {continue;}
        }

        graph.update_edge(parent, child, 1);
    }

    //Otherwise, add to applicaton/octet-stream, all/all, or text/plain, depending on top-level
    graph.update_edge(node_octet, node_text, 1);
    graph.update_edge(node_allall, node_allfiles, 1);
    graph.update_edge(node_allfiles, node_octet, 1);

    let mut edge_list = Vec::<(NodeIndex, NodeIndex)>::new();
    for mimenode in graph.externals(Incoming) {

        let ref mimetype = graph[mimenode];
        let toplevel = mimetype.split("/").nth(0).unwrap_or("");

        if mimenode == node_text || mimenode == node_octet ||
           mimenode == node_allfiles || mimenode == node_allall
        {
            continue;
        }

        if toplevel == "text" {
            edge_list.push( (node_text, mimenode) );
        } else if toplevel == "inode" {
            edge_list.push( (node_allall, mimenode) );
        } else {
            edge_list.push( (node_octet, mimenode) );
        }
    }

    graph.extend_with_edges(edge_list);

    let graph = graph;
    println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel]));

    Ok(graph)
}

fn main() {

    match graph_init() {
        Err(why) => panic!("{:?}", why),
        Ok(graph) => {
            let type_graph = graph;
        },
    };
}
<|endoftext|>


<commit_before>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};

use rand::distributions::{IndependentSample, Range};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

fn lda(num_topics: usize, dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>) {
    // Initialization
    let mut rng = rand::thread_rng();
    let topics = Range::new(0, num_topics);

    let vocab_size: usize = {
        let mut have_some = false;
        let mut max_index = 0;
        for bag in &dataset {
            for &index in bag.keys() {
                have_some = true;
                if index > max_index {
                    max_index = index;
                }
            }
        }
        if have_some {
            max_index + 1
        }
        else {
            0
        }
    };
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // z
        let mut z_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    lda(3, dataset, vec![1.0, 1.0, 1.0], vec![1.0, 1.0, 1.0]);
}
<commit_msg>Initialize w<commit_after>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};

use rand::distributions::{IndependentSample, Range};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

fn lda(num_topics: usize, dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>) {
    // Initialization
    let mut rng = rand::thread_rng();
    let topics = Range::new(0, num_topics);

    let vocab_size: usize = {
        let mut have_some = false;
        let mut max_index = 0;
        for bag in &dataset {
            for &index in bag.keys() {
                have_some = true;
                if index > max_index {
                    max_index = index;
                }
            }
        }
        if have_some {
            max_index + 1
        }
        else {
            0
        }
    };
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::new();
    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // w
        let mut w_d = Vec::new();
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    lda(3, dataset, vec![1.0, 1.0, 1.0], vec![1.0, 1.0, 1.0]);
}
<|endoftext|>