<commit_before>extern crate i2cdev;
extern crate rand;

use std::collections::HashMap;
use i2cdev::core::I2CDevice;
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CError};

const MODE_REGISTER: u8 = 0x00;
const FRAME_REGISTER: u8 = 0x01;
const AUTOPLAY1_REGISTER: u8 = 0x02;
const AUTOPLAY2_REGISTER: u8 = 0x03;
const BLINK_REGISTER: u8 = 0x05;
const AUDIOSYNC_REGISTER: u8 = 0x06;
const BREATH1_REGISTER: u8 = 0x08;
const BREATH2_REGISTER: u8 = 0x09;
const SHUTDOWN_REGISTER: u8 = 0x0a;
const GAIN_REGISTER: u8 = 0x0b;
const ADC_REGISTER: u8 = 0x0c;

const CONFIG_BANK: u8 = 0x0b;
const BANK_ADDRESS: u8 = 0xfd;

const PICTURE_MODE: u8 = 0x00;
const AUTOPLAY_MODE: u8 = 0x08;
const AUDIOPLAY_MODE: u8 = 0x18;

const ENABLE_OFFSET: u8 = 0x00;
const BLINK_OFFSET: u8 = 0x12;
const COLOR_OFFSET: u8 = 0x24;

const ADDRESS: u16 = 0x74;

const EMPTY_COLUMN: [u8; 7] = [0; 7];

type Glyph = [&'static str; 7];

#[cfg_attr(rustfmt, rustfmt_skip)]
fn font() -> HashMap<char, Glyph> {
    let mut glyphs = HashMap::new();
    glyphs.insert('A', [
                  "    " ,
                  " xx ",
                  "x  x",
                  "x  x",
                  "xxxx",
                  "x  x",
                  "x  x"]);
    glyphs.insert('B', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "xxx ",
                  "x  x",
                  "x  x",
                  "xxx "]);
    glyphs.insert('C', [
                  "    " ,
                  " xxx",
                  "x   ",
                  "x   ",
                  "x   ",
                  "x   ",
                  " xxx"]);
    glyphs.insert('D', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  "xxx "]);
    glyphs.insert('E', [
                  "    " ,
                  "xxxx",
                  "x   ",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "xxxx"]);
    glyphs.insert('F', [
                  "    " ,
                  "xxxx",
                  "x   ",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "x   "]);
    glyphs.insert('G', [
                  "    " ,
                  " xxx",
                  "x   ",
                  "x   ",
                  "x xx",
                  "x  x",
                  " xxx"]);
    glyphs.insert('H', [
                  "    " ,
                  "x  x",
                  "x  x",
                  "xxxx",
                  "x  x",
                  "x  x",
                  "x  x"]);
    glyphs.insert('I', [
                  " " ,
                  "x",
                  "x",
                  "x",
                  "x",
                  "x",
                  "x"]);
    glyphs.insert('J', [
                  "    " ,
                  "   x",
                  "   x",
                  "   x",
                  "   x",
                  "x  x",
                  " xx "]);
    glyphs.insert('K', [
                  "    " ,
                  "x  x",
                  "x x ",
                  "xx  ",
                  "x x ",
                  "x  x",
                  "x  x"]);
    glyphs.insert('L', [
                  "   " ,
                  "x  ",
                  "x  ",
                  "x  ",
                  "x  ",
                  "x  ",
                  "xxx"]);
    glyphs.insert('M', [
                  "     " ,
                  "x   x",
                  "xx xx",
                  "x x x",
                  "x   x",
                  "x   x",
                  "x   x"]);
    glyphs.insert('N', [
                  "    " ,
                  "x  x",
                  "xx x",
                  "x xx",
                  "x  x",
                  "x  x",
                  "x  x"]);
    glyphs.insert('O', [
                  "    " ,
                  " xx ",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('P', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "x   "]);
    glyphs.insert('Q', [
                  "     " ,
                  " xx  ",
                  "x  x ",
                  "x  x ",
                  "x  x ",
                  "x xx ",
                  " xx x"]);
    glyphs.insert('R', [
                  "     " ,
                  "xxx  ",
                  "x  x ",
                  "xxx  ",
                  "x  x ",
                  "x  x ",
                  "x  x "]);
    glyphs.insert('S', [
                  "    " ,
                  " xxx",
                  "x   ",
                  " xx ",
                  "   x",
                  "   x",
                  "xxx "]);
    glyphs.insert('T', [
                  "     " ,
                  "xxxxx",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  "]);
    glyphs.insert('U', [
                  "    " ,
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('V', [
                  "     " ,
                  "x   x",
                  "x   x",
                  "x   x",
                  "x   x",
                  " x x ",
                  "  x  "]);
    glyphs.insert('W', [
                  "     " ,
                  "x   x",
                  "x   x",
                  "x   x",
                  "x x x",
                  "x x x",
                  " x x "]);
    glyphs.insert('X', [
                  "     " ,
                  "x   x",
                  " x x ",
                  "  x  ",
                  " x x ",
                  "x   x",
                  "x   x"]);
    glyphs.insert('Y', [
                  "     " ,
                  "x   x",
                  " x x ",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  "]);
    glyphs.insert('Z', [
                  "    " ,
                  "xxxx",
                  "   x",
                  "  x ",
                  " x  ",
                  "x   ",
                  "xxxx"]);
    glyphs
}

struct Display {
    device: LinuxI2CDevice,
    scroll: usize,
    buffer: Vec<[u8; 7]>,
    frame: u8,
    brightness: u8,
}

impl Display {
    fn new() -> Display {
        let d = LinuxI2CDevice::new("/dev/i2c-1", ADDRESS).unwrap();
        Display {
            device: d,
            scroll: 0,
            buffer: vec![EMPTY_COLUMN],
            frame: 0,
            brightness: 0x0F,
        }
    }

    fn bank(&mut self, bank: u8) {
        self.device.smbus_write_byte_data(BANK_ADDRESS, bank).unwrap();
    }

    fn scroll(&mut self) {
        self.scroll += 1;
        if self.scroll >= self.buffer.len() {
            self.scroll = 0;
        }
    }

    fn register(&mut self, bank: u8, register: u8, value: u8) {
        self.bank(bank);
        self.device.smbus_write_block_data(register, &[value]).unwrap();
    }

    fn frame(&mut self, frame: u8) {
        self.register(CONFIG_BANK, FRAME_REGISTER, frame);
    }

    fn reset(&mut self) {
        self.sleep(true);
        std::thread::sleep(std::time::Duration::from_millis(10));
        self.sleep(false);
    }

    fn sleep(&mut self, value: bool) {
        self.register(CONFIG_BANK, SHUTDOWN_REGISTER, if value { 0 } else { 1 });
    }

    fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= 7 {
            return;
        }
        if x >= self.buffer.len() {
            for _ in self.buffer.len()..(x + 1) {
                self.buffer.push(EMPTY_COLUMN);
            }
        }
        self.buffer[x][y] = value;
    }

    fn set_text(&mut self, text: &str) {
        let font = font();
        let brightness = self.brightness;
        let mut offset = 0;
        for c in text.chars() {
            if let Some(glyph) = font.get(&c) {
                for y in 0..glyph.len() {
                    let row = glyph[y];
                    for x in 0..row.len() {
                        let pixel = row.chars().nth(x).unwrap();
                        self.set_pixel(x + offset, y, if pixel == ' ' { 0x00 } else { brightness });
                    }
                }
                // We assume that all the rows have equal length.
                offset += glyph[0].len() + 1;
            }
        }
    }

    fn show(&mut self) {
        // TODO(tzn): Double buffering.
        // let new_frame = (self.frame + 1) % 2;
        let new_frame = 1;
        self.bank(new_frame);
        for y in 0..7 {
            for x in 0..17 {
                let offset = if x >= 8 {
                    (x - 8) * 16 + y
                } else {
                    (8 - x) * 16 - (y + 2)
                };
                let value = match self.buffer.get(self.scroll + x as usize) {
                    Some(column) => column[y as usize],
                    None => 0,
                };
                match self.device.smbus_write_byte_data(COLOR_OFFSET + offset, value) {
                    Ok(_) => {}
                    Err(err) => println!("error writing to i2c device: {}", err),
                };
            }
        }
        self.frame(new_frame);
        self.frame = new_frame;
    }

    fn test(&mut self) {
        self.register(CONFIG_BANK, MODE_REGISTER, PICTURE_MODE);
        self.set_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

        for _ in 0..3000 {
            self.show();
            std::thread::sleep(std::time::Duration::from_millis(100));
            self.scroll();
        }
    }
}

fn main() {
    font();
    println!("start");
    let mut d = Display::new();
    d.test();
    println!("end");
}
<commit_msg>numbers<commit_after>extern crate i2cdev;
extern crate rand;

use std::collections::HashMap;
use i2cdev::core::I2CDevice;
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CError};

const MODE_REGISTER: u8 = 0x00;
const FRAME_REGISTER: u8 = 0x01;
const AUTOPLAY1_REGISTER: u8 = 0x02;
const AUTOPLAY2_REGISTER: u8 = 0x03;
const BLINK_REGISTER: u8 = 0x05;
const AUDIOSYNC_REGISTER: u8 = 0x06;
const BREATH1_REGISTER: u8 = 0x08;
const BREATH2_REGISTER: u8 = 0x09;
const SHUTDOWN_REGISTER: u8 = 0x0a;
const GAIN_REGISTER: u8 = 0x0b;
const ADC_REGISTER: u8 = 0x0c;

const CONFIG_BANK: u8 = 0x0b;
const BANK_ADDRESS: u8 = 0xfd;

const PICTURE_MODE: u8 = 0x00;
const AUTOPLAY_MODE: u8 = 0x08;
const AUDIOPLAY_MODE: u8 = 0x18;

const ENABLE_OFFSET: u8 = 0x00;
const BLINK_OFFSET: u8 = 0x12;
const COLOR_OFFSET: u8 = 0x24;

const ADDRESS: u16 = 0x74;

const EMPTY_COLUMN: [u8; 7] = [0; 7];

type Glyph = [&'static str; 7];

#[cfg_attr(rustfmt, rustfmt_skip)]
fn font() -> HashMap<char, Glyph> {
    let mut glyphs = HashMap::new();
    glyphs.insert('0', [
                  "    " ,
                  " xx ",
                  "x  x",
                  "x xx",
                  "xx x",
                  "x  x",
                  " xx "]);
    glyphs.insert('1', [
                  "   " ,
                  " x ",
                  "xx ",
                  " x ",
                  " x ",
                  " x ",
                  "xxx"]);
    glyphs.insert('2', [
                  "    " ,
                  "xxx ",
                  "   x",
                  "  x ",
                  " x  ",
                  "x   ",
                  "xxxx"]);
    glyphs.insert('3', [
                  "    " ,
                  "xxx ",
                  "   x",
                  " xx ",
                  "   x",
                  "   x",
                  "xxx "]);
    glyphs.insert('4', [
                  "    " ,
                  "   x",
                  "  x ",
                  " x  ",
                  "x  x",
                  "xxxx",
                  "   x"]);
    glyphs.insert('5', [
                  "    " ,
                  "xxxx",
                  "x   ",
                  "xxx ",
                  "   x",
                  "   x",
                  "xxx "]);
    glyphs.insert('6', [
                  "    " ,
                  " xxx",
                  "x   ",
                  "xxx ",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('7', [
                  "    " ,
                  "xxxx",
                  "   x",
                  "  x ",
                  " x  ",
                  "x   ",
                  "x   "]);
    glyphs.insert('8', [
                  "    " ,
                  " xx ",
                  "x  x",
                  " xx ",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('9', [
                  "    " ,
                  " xx ",
                  "x  x",
                  " xxx",
                  "   x",
                  "   x",
                  " xx "]);
    glyphs.insert('A', [
                  "    " ,
                  " xx ",
                  "x  x",
                  "x  x",
                  "xxxx",
                  "x  x",
                  "x  x"]);
    glyphs.insert('B', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "xxx ",
                  "x  x",
                  "x  x",
                  "xxx "]);
    glyphs.insert('C', [
                  "    " ,
                  " xxx",
                  "x   ",
                  "x   ",
                  "x   ",
                  "x   ",
                  " xxx"]);
    glyphs.insert('D', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  "xxx "]);
    glyphs.insert('E', [
                  "    " ,
                  "xxxx",
                  "x   ",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "xxxx"]);
    glyphs.insert('F', [
                  "    " ,
                  "xxxx",
                  "x   ",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "x   "]);
    glyphs.insert('G', [
                  "    " ,
                  " xxx",
                  "x   ",
                  "x   ",
                  "x xx",
                  "x  x",
                  " xxx"]);
    glyphs.insert('H', [
                  "    " ,
                  "x  x",
                  "x  x",
                  "xxxx",
                  "x  x",
                  "x  x",
                  "x  x"]);
    glyphs.insert('I', [
                  " " ,
                  "x",
                  "x",
                  "x",
                  "x",
                  "x",
                  "x"]);
    glyphs.insert('J', [
                  "    " ,
                  "   x",
                  "   x",
                  "   x",
                  "   x",
                  "x  x",
                  " xx "]);
    glyphs.insert('K', [
                  "    " ,
                  "x  x",
                  "x x ",
                  "xx  ",
                  "x x ",
                  "x  x",
                  "x  x"]);
    glyphs.insert('L', [
                  "   " ,
                  "x  ",
                  "x  ",
                  "x  ",
                  "x  ",
                  "x  ",
                  "xxx"]);
    glyphs.insert('M', [
                  "     " ,
                  "x   x",
                  "xx xx",
                  "x x x",
                  "x   x",
                  "x   x",
                  "x   x"]);
    glyphs.insert('N', [
                  "    " ,
                  "x  x",
                  "xx x",
                  "x xx",
                  "x  x",
                  "x  x",
                  "x  x"]);
    glyphs.insert('O', [
                  "    " ,
                  " xx ",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('P', [
                  "    " ,
                  "xxx ",
                  "x  x",
                  "xxx ",
                  "x   ",
                  "x   ",
                  "x   "]);
    glyphs.insert('Q', [
                  "     " ,
                  " xx  ",
                  "x  x ",
                  "x  x ",
                  "x  x ",
                  "x xx ",
                  " xx x"]);
    glyphs.insert('R', [
                  "     " ,
                  "xxx  ",
                  "x  x ",
                  "xxx  ",
                  "x  x ",
                  "x  x ",
                  "x  x "]);
    glyphs.insert('S', [
                  "    " ,
                  " xxx",
                  "x   ",
                  " xx ",
                  "   x",
                  "   x",
                  "xxx "]);
    glyphs.insert('T', [
                  "     " ,
                  "xxxxx",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  "]);
    glyphs.insert('U', [
                  "    " ,
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  "x  x",
                  " xx "]);
    glyphs.insert('V', [
                  "     " ,
                  "x   x",
                  "x   x",
                  "x   x",
                  "x   x",
                  " x x ",
                  "  x  "]);
    glyphs.insert('W', [
                  "     " ,
                  "x   x",
                  "x   x",
                  "x   x",
                  "x x x",
                  "x x x",
                  " x x "]);
    glyphs.insert('X', [
                  "     " ,
                  "x   x",
                  " x x ",
                  "  x  ",
                  " x x ",
                  "x   x",
                  "x   x"]);
    glyphs.insert('Y', [
                  "     " ,
                  "x   x",
                  " x x ",
                  "  x  ",
                  "  x  ",
                  "  x  ",
                  "  x  "]);
    glyphs.insert('Z', [
                  "    " ,
                  "xxxx",
                  "   x",
                  "  x ",
                  " x  ",
                  "x   ",
                  "xxxx"]);
    glyphs
}

struct Display {
    device: LinuxI2CDevice,
    scroll: usize,
    buffer: Vec<[u8; 7]>,
    frame: u8,
    brightness: u8,
}

impl Display {
    fn new() -> Display {
        let d = LinuxI2CDevice::new("/dev/i2c-1", ADDRESS).unwrap();
        Display {
            device: d,
            scroll: 0,
            buffer: vec![EMPTY_COLUMN],
            frame: 0,
            brightness: 0x0F,
        }
    }

    fn bank(&mut self, bank: u8) {
        self.device.smbus_write_byte_data(BANK_ADDRESS, bank).unwrap();
    }

    fn scroll(&mut self) {
        self.scroll += 1;
        if self.scroll >= self.buffer.len() {
            self.scroll = 0;
        }
    }

    fn register(&mut self, bank: u8, register: u8, value: u8) {
        self.bank(bank);
        self.device.smbus_write_block_data(register, &[value]).unwrap();
    }

    fn frame(&mut self, frame: u8) {
        self.register(CONFIG_BANK, FRAME_REGISTER, frame);
    }

    fn reset(&mut self) {
        self.sleep(true);
        std::thread::sleep(std::time::Duration::from_millis(10));
        self.sleep(false);
    }

    fn sleep(&mut self, value: bool) {
        self.register(CONFIG_BANK, SHUTDOWN_REGISTER, if value { 0 } else { 1 });
    }

    fn set_pixel(&mut self, x: usize, y: usize, value: u8) {
        if y >= 7 {
            return;
        }
        if x >= self.buffer.len() {
            for _ in self.buffer.len()..(x + 1) {
                self.buffer.push(EMPTY_COLUMN);
            }
        }
        self.buffer[x][y] = value;
    }

    fn set_text(&mut self, text: &str) {
        let font = font();
        let brightness = self.brightness;
        let mut offset = 0;
        for c in text.chars() {
            if let Some(glyph) = font.get(&c) {
                for y in 0..glyph.len() {
                    let row = glyph[y];
                    for x in 0..row.len() {
                        let pixel = row.chars().nth(x).unwrap();
                        self.set_pixel(x + offset, y, if pixel == ' ' { 0x00 } else { brightness });
                    }
                }
                // We assume that all the rows have equal length.
                offset += glyph[0].len() + 1;
            }
        }
    }

    fn show(&mut self) {
        // TODO(tzn): Double buffering.
        // let new_frame = (self.frame + 1) % 2;
        let new_frame = 1;
        self.bank(new_frame);
        for y in 0..7 {
            for x in 0..17 {
                let offset = if x >= 8 {
                    (x - 8) * 16 + y
                } else {
                    (8 - x) * 16 - (y + 2)
                };
                let value = match self.buffer.get(self.scroll + x as usize) {
                    Some(column) => column[y as usize],
                    None => 0,
                };
                match self.device.smbus_write_byte_data(COLOR_OFFSET + offset, value) {
                    Ok(_) => {}
                    Err(err) => println!("error writing to i2c device: {}", err),
                };
            }
        }
        self.frame(new_frame);
        self.frame = new_frame;
    }

    fn test(&mut self) {
        self.register(CONFIG_BANK, MODE_REGISTER, PICTURE_MODE);
        self.set_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");

        for _ in 0..3000 {
            self.show();
            std::thread::sleep(std::time::Duration::from_millis(100));
            self.scroll();
        }
    }
}

fn main() {
    font();
    println!("start");
    let mut d = Display::new();
    d.test();
    println!("end");
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate clap;
extern crate requests;
extern crate serde;
extern crate serde_json;

use clap::{App, SubCommand, AppSettings, ArgMatches};
mod crates;

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
        }
    }

    pub fn report(&self, name: &str) {
        if let Some(krate) = query(name).map(|r| r.krate) {
            for flag in &self.flags {
                match *flag {
                    Flag::Repository => krate.print_repository(self.verbose),
                    Flag::Documentation => krate.print_documentation(self.verbose),
                    Flag::Downloads => krate.print_downloads(self.verbose),
                    Flag::Homepage => krate.print_homepage(self.verbose),
                    Flag::Default => reportv(&krate, self.verbose),
                }
            }
        }
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> Option<crates::Reply> {
    let response = requests::get(&format!("http://crates.io/api/v1/crates/{}", krate)).unwrap();
    // println!("{:?}", response.json().unwrap());
    response.from_json::<crates::Reply>()
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Queries registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg_from_usage("-d, --documentation 'Report documentation URL'")
            .arg_from_usage("-D, --downloads 'Report number of crate downloads'")
            .arg_from_usage("-H, --homepage 'Report home page URL'")
            .arg_from_usage("-r, --repository 'Report crate repository URL'")
            .arg_from_usage("-v, --verbose 'Provides more info'")
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<commit_msg>Update help text<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate clap;
extern crate requests;
extern crate serde;
extern crate serde_json;

use clap::{App, SubCommand, AppSettings, ArgMatches};
mod crates;

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
        }
    }

    pub fn report(&self, name: &str) {
        if let Some(krate) = query(name).map(|r| r.krate) {
            for flag in &self.flags {
                match *flag {
                    Flag::Repository => krate.print_repository(self.verbose),
                    Flag::Documentation => krate.print_documentation(self.verbose),
                    Flag::Downloads => krate.print_downloads(self.verbose),
                    Flag::Homepage => krate.print_homepage(self.verbose),
                    Flag::Default => reportv(&krate, self.verbose),
                }
            }
        }
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> Option<crates::Reply> {
    let response = requests::get(&format!("http://crates.io/api/v1/crates/{}", krate)).unwrap();
    // println!("{:?}", response.json().unwrap());
    response.from_json::<crates::Reply>()
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Queries registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg_from_usage("-d, --documentation 'Report documentation URL'")
            .arg_from_usage("-D, --downloads 'Report number of crate downloads'")
            .arg_from_usage("-H, --homepage 'Report home page URL'")
            .arg_from_usage("-r, --repository 'Report crate repository URL'")
            .arg_from_usage("-v, --verbose 'Report more details'")
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::iter::repeat;
use std::str::FromStr;
use std::num::Int;
use std::num::ToPrimitive;

fn main() {
    let title = "RUSTYHAM: A HAMMING CODE GENERATOR IN RUST";
    let border: String = repeat('=').take(title.len()).collect::<>();
    println!("{}", border);
    println!("{}", title);
    println!("{}", border);

    loop {
        let mut linebuf = String::new();
        println!("(1) Encode ASCII");
        println!("(2) Encode binary");
        println!("(3) Decode to ASCII");
        println!("(4) Decode to binary");
        print!("Enter your choice: ");
        io::stdout().flush();
        io::stdin().read_line(&mut linebuf);

        let num = i32::from_str(linebuf.trim());
        match num.ok() {
            Some(n) => {
                let mut good = true;
                println!("{}", match n {
                    1 => hamming(),
                    2...4 => "Sorry, not implemented yet.".to_string(),
                    _ => { good = false; "Invalid input.".to_string() }
                });
                if good { break; }
            }
            None => {
                println!("Invalid input.");
            }
        };
    }
}

fn hamming() -> String {
    let mut message = String::new();
    print!("Enter string to encode: ");
    io::stdout().flush();
    io::stdin().read_line(&mut message);

    message = message.trim().to_string();
    let mlen = message.len().to_u32().unwrap();
    let len = 2.pow((2..).find(|&r| 2.pow(r) - r - 1 >= mlen).unwrap()) - 1;

    message
}
<commit_msg>ascii -> hamming code finished<commit_after>use std::io;
use std::io::prelude::*;
use std::iter::repeat;
use std::str::FromStr;
use std::num::Int;
use std::num::ToPrimitive;
use std::collections::BitVec;

fn main() {
    let title = "RUSTYHAM: A HAMMING CODE GENERATOR IN RUST";
    let border: String = repeat('=').take(title.len()).collect::<>();
    println!("{}", border);
    println!("{}", title);
    println!("{}", border);

    loop {
        let mut linebuf = String::new();
        println!("(1) Encode ASCII");
        println!("(2) Encode binary");
        println!("(3) Decode to ASCII");
        println!("(4) Decode to binary");
        print!("Enter your choice: ");
        io::stdout().flush();
        io::stdin().read_line(&mut linebuf);

        let num = i32::from_str(linebuf.trim());
        match num.ok() {
            Some(n) => {
                let mut good = true;
                println!("{}", match n {
                    1 => hamming(),
                    2...4 => "Sorry, not implemented yet.".to_string(),
                    _ => { good = false; "Invalid input.".to_string() }
                });
                if good { break; }
            }
            None => {
                println!("Invalid input.");
            }
        };
    }
}

fn hamming() -> String {
    // prompt for ASCII input
    let mut message = String::new();
    print!("Enter string to encode: ");
    io::stdout().flush();
    io::stdin().read_line(&mut message);

    // compute block and message length
    message = message.trim().to_string();
    let mlen = message.len().to_u32().unwrap() * 7;
    let lenpow = (2..).find(|&r| 2.pow(r) - r - 1 >= mlen).unwrap();
    let len = 2.pow(lenpow) - 1;

    // the thing we're storing the hamming code in
    let mut bv = BitVec::from_elem(len, false);

    // convert ASCII string to binary
    // IMPORTANT NOTE: the following line takes ownership of the `message'
    // variable. We no longer have access to the original string from this
    // point onwards.
    let bytes = message.into_bytes();
    let bytes_str = bytes.iter()
        .map(|&c| format!("{:0>1$b}", c, 7))
        .collect::<Vec<String>>()
        .concat();
    let mut bytes_iter = bytes_str.chars();

    // set data bits
    for i in 1..len {
        if (i & (i - 1)) != 0 {
            bv.set(i-1, bytes_iter.next().unwrap_or('0') == '1');
        }
    }

    // set parity bits
    for i in 0..lenpow {
        let bi = 2.pow(i)-1;
        let mut parity = false;
        let mut ignore = false;
        let mut counter = 0;
        for j in bi..len {
            if !ignore {
                if bv.get(j).unwrap() {
                    parity = !parity;
                }
            }
            counter += 1;
            if counter >= 2.pow(i) {
                ignore = !ignore;
                counter = 0;
            }
        }
        bv.set(bi, parity);
    }

    format!("{:?}", bv)
}
<|endoftext|>


<commit_before>extern crate socket;

use socket::{AF_INET, Socket, SOCK_DGRAM, IP_MULTICAST_TTL, IPPROTO_IP};
use std::net::SocketAddr;
use std::str::FromStr;
use std::time::Instant;

fn main() {
    Discover::new().start(None, Some(3))
}

struct Discover {
    pub devices: Vec<String>,
    multicast: SocketAddr,
    socket: Socket
}

impl Discover {
    pub fn new() -> Self {
        Discover {
            devices: Vec::new(),
            multicast: SocketAddr::from_str("239.255.255.250:1900").unwrap(),
            socket: Discover::create_socket()
        }
    }

    fn create_socket() -> Socket {
        let socket = Socket::new(AF_INET, SOCK_DGRAM, 0).unwrap();
        let _ = socket.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 4);

        socket
    }

    fn send_search(&self) {
        let player_search = r#"M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1"#.as_bytes();
        let _ = self.socket.sendto(player_search, 0, &self.multicast);
    }

    pub fn start(self, timeout: Option<u32>, device_count: Option<u32>) {
        let timeout = match timeout {
            Some(value) => { value }
            None => 5
        };
        let device_count = match device_count {
            Some(value) => { value }
            None => std::u32::MAX
        };

        self.send_search();
        let mut count = 0;
        let time = Instant::now();

        while time.elapsed().as_secs() < timeout as u64 && count < device_count {
            let (_addr, data) = self.socket.recvfrom(1024, 0).unwrap();
            let data = String::from_utf8_lossy(&data);
            if data.contains("Sonos") {
                println!("{}", data);
                count += 1;
            }
        }

        let _ = self.socket.close();
    }
}
<commit_msg>Epic threading implementation start(timeout, device_count) now stops on reaching either timeout or device_count<commit_after>extern crate socket;

use socket::{AF_INET, Socket, SOCK_DGRAM, IP_MULTICAST_TTL, IPPROTO_IP};
use std::collections::HashSet;
use std::net::SocketAddr;
use std::str::FromStr;
use std::sync::{Arc, mpsc};
use std::thread;
use std::time::Instant;

fn main() {
    Discover::new().start(None, Some(4))
}

struct Discover {
    pub devices: Vec<String>,
    multicast: SocketAddr,
    socket: Arc<Socket>
}

impl Discover {
    pub fn new() -> Self {
        Discover {
            devices: Vec::new(),
            multicast: SocketAddr::from_str("239.255.255.250:1900").unwrap(),
            socket: Discover::create_socket()
        }
    }

    fn create_socket() -> Arc<Socket> {
        let socket = Socket::new(AF_INET, SOCK_DGRAM, 0).unwrap();
        let _ = socket.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 4);

        Arc::new(socket)
    }

    fn send_search(&self) {
        let player_search = r#"M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 1
ST: urn:schemas-upnp-org:device:ZonePlayer:1"#.as_bytes();
        let _ = self.socket.sendto(player_search, 0, &self.multicast);
    }

    pub fn start(self, timeout: Option<u32>, device_count: Option<usize>) {
        let timeout = match timeout {
            Some(value) => { value }
            None => 5
        };
        let device_count = match device_count {
            Some(value) => { value }
            None => std::u32::MAX as usize
        };

        let time = Instant::now();

        self.send_search();
        let mut devices = HashSet::new();
        let socket = self.socket.clone();
        while time.elapsed().as_secs() < timeout as u64 && devices.len() < device_count {
            let socket = socket.clone();
            let (sender, receiver) = mpsc::channel();
            let _ = thread::spawn(move ||
                {
                    match socket.recvfrom(1024, 0) {
                        Ok((__addr, _data)) => {
                            let _ = sender.send((__addr, _data));
                        }
                        Err(_) => {}
                    }
                }
            );

            let (_addr, data) = match receiver.recv_timeout(std::time::Duration::new(0, 500000000)) {
                Ok((_addr, data)) => (_addr, data),
                Err(_) => continue
            };
            if devices.contains(&_addr.ip()) || data.is_empty() {
                println!("{:?}", &_addr.ip());
                continue
            }

            let data = String::from_utf8_lossy(&data);
            if data.contains("Sonos") {
                devices.insert(_addr.ip());
            }
        }
        println!("{:#?}", devices.len());
    }
}

/*impl Drop for Discover {
    fn drop(&mut self) {
        // Socket closes on drop automatically, better safe than sorry
        let _ = self.socket.close();
    }
}*/

impl Default for Discover {
    fn default() -> Self {
        Discover::new()
    }
}
<|endoftext|>


<commit_before>extern crate clipboard_win;
extern crate docopt;
extern crate rustc_serialize;
extern crate winapi;
extern crate user32;
extern crate kernel32;

use clipboard_win::{WindowsError, set_clipboard};
use clipboard_win::wrapper::{get_last_error, open_clipboard, close_clipboard};
use clipboard_win::clipboard_formats::CF_UNICODETEXT;
use docopt::Docopt;
use kernel32::{GlobalLock, GlobalUnlock};
use winapi::winnt::HANDLE;
use user32::GetClipboardData;
use std::io;
use std::io::Read;

const USAGE: &'static str = "
win32yank

Usage:
    win32yank -o [--lf]
    win32yank -i

Options:
    -o          Print clipboard contents to stdout
    -i          Set clipboard from stdin
    --lf        Replace CRLF with LF before printing to stdout
";
// TODO:    --crlf      Replace LF with CRLF before setting the clipboard

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_o: bool,
    flag_i: bool,
    flag_lf: bool,
    flag_crlf: bool,
}

fn from_wide_ptr(ptr: *const u16) -> String {
    use std::ffi::OsString;
    use std::os::windows::ffi::OsStringExt;

    if ptr.is_null() {
        return String::new();
    }

    unsafe {
        assert!(!ptr.is_null());
        let len = (0..std::isize::MAX).position(|i| *ptr.offset(i) == 0).unwrap();
        let slice = std::slice::from_raw_parts(ptr, len);
        OsString::from_wide(slice).to_string_lossy().into_owned()
    }
}

fn get_clipboard() -> Result<String, WindowsError> {
    let result: Result<String, WindowsError>;
    try!(open_clipboard());
    unsafe {
        let text_handler: HANDLE = GetClipboardData(CF_UNICODETEXT as u32);

        if text_handler.is_null() {
            result = Err(get_last_error());
        } else {
            let text_p = GlobalLock(text_handler) as *const u16;
            result = Ok(from_wide_ptr(text_p));
            GlobalUnlock(text_handler);
        }
    }
    try!(close_clipboard());
    result
}

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

    if args.flag_o {
        let mut content = get_clipboard().unwrap();
        if args.flag_lf {
            content = content.replace("\r\n", "\n");
        }
        println!("{}", content);
    } else if args.flag_i {
        let mut stdin = io::stdin();
        let mut content = String::new();
        stdin.read_to_string(&mut content).unwrap();
// TODO
//        if args.flag_crlf {
//            content = content.split("\r\n")
//                .map(|item| item.replace("\n", "\r\n"))
//                .fold(String::new(), |acc, x| acc + "\r\n" + &x );
//        }
        set_clipboard(&content).unwrap();
    }
}

#[test]
fn test() {
    // Windows dislikes if we lock the clipboard too long
    // sleep for bit
    use std::thread::sleep;
    use std::time::Duration;
    let sleep_time = 300;

    let v = "Hello\nfrom\nwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard().unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\rfrom\rwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard().unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\r\nfrom\r\nwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard().unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard().unwrap(), v);
}
<commit_msg>Add test for get_clipboard with --lf<commit_after>extern crate clipboard_win;
extern crate docopt;
extern crate rustc_serialize;
extern crate winapi;
extern crate user32;
extern crate kernel32;

use clipboard_win::{WindowsError, set_clipboard};
use clipboard_win::wrapper::{get_last_error, open_clipboard, close_clipboard};
use clipboard_win::clipboard_formats::CF_UNICODETEXT;
use docopt::Docopt;
use kernel32::{GlobalLock, GlobalUnlock};
use winapi::winnt::HANDLE;
use user32::GetClipboardData;
use std::io;
use std::io::Read;

const USAGE: &'static str = "
win32yank

Usage:
    win32yank -o [--lf]
    win32yank -i

Options:
    -o          Print clipboard contents to stdout
    -i          Set clipboard from stdin
    --lf        Replace CRLF with LF before printing to stdout
";
// TODO:    --crlf      Replace LF with CRLF before setting the clipboard

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_o: bool,
    flag_i: bool,
    flag_lf: bool,
    flag_crlf: bool,
}

fn from_wide_ptr(ptr: *const u16) -> String {
    use std::ffi::OsString;
    use std::os::windows::ffi::OsStringExt;

    if ptr.is_null() {
        return String::new();
    }

    unsafe {
        assert!(!ptr.is_null());
        let len = (0..std::isize::MAX).position(|i| *ptr.offset(i) == 0).unwrap();
        let slice = std::slice::from_raw_parts(ptr, len);
        OsString::from_wide(slice).to_string_lossy().into_owned()
    }
}

fn get_clipboard(replace_crlf: bool) -> Result<String, WindowsError> {
    let result: Result<String, WindowsError>;
    try!(open_clipboard());
    unsafe {
        let text_handler: HANDLE = GetClipboardData(CF_UNICODETEXT as u32);

        if text_handler.is_null() {
            result = Err(get_last_error());
        } else {
            let text_p = GlobalLock(text_handler) as *const u16;
            result = Ok(from_wide_ptr(text_p));
            GlobalUnlock(text_handler);
        }
    }
    try!(close_clipboard());

    if replace_crlf {
        result.map(|data| data.replace("\r\n", "\n"))
    } else {
        result
    }
}

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

    if args.flag_o {
        let content = get_clipboard(args.flag_lf).unwrap();
        println!("{}", content);
    } else if args.flag_i {
        let mut stdin = io::stdin();
        let mut content = String::new();
        stdin.read_to_string(&mut content).unwrap();
// TODO
//        if args.flag_crlf {
//            content = content.split("\r\n")
//                .map(|item| item.replace("\n", "\r\n"))
//                .fold(String::new(), |acc, x| acc + "\r\n" + &x );
//        }
        set_clipboard(&content).unwrap();
    }
}

#[test]
fn test() {
    // Windows dislikes if we lock the clipboard too long
    // sleep for bit
    use std::thread::sleep;
    use std::time::Duration;
    let sleep_time = 300;

    let v = "Hello\nfrom\nwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\rfrom\rwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\r\nfrom\r\nwin32yank";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v).unwrap();
    assert_eq!(get_clipboard(true).unwrap(),
               "\nfrom\nwin32yank\n\n...\\r\n");
}
<|endoftext|>


<commit_before>//! Main module of way-cooler

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate dbus_macros;

#[cfg(not(test))]
extern crate rustwlc;

extern crate getopts;

#[cfg(test)]
extern crate dummy_rustwlc as rustwlc;

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

#[macro_use]
extern crate hlua;
extern crate rustc_serialize;
#[macro_use]
extern crate json_macro;

extern crate nix;

extern crate petgraph;

extern crate uuid;

extern crate dbus;

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use getopts::Options;
use log::LogLevel;

use nix::sys::signal::{SigHandler, SigSet, SigAction, SaFlags};
use nix::sys::signal;

use rustwlc::types::LogType;

#[macro_use] // As it happens, it's important to declare the macros first.
mod macros;
mod convert;

mod callbacks;
mod keys;

mod lua;
mod registry;
mod commands;
mod ipc;

mod layout;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const MODULE_PATH: &'static str = "/proc/modules";

/// Callback to route wlc logs into env_logger
fn log_handler(level: LogType, message: &str) {
    match level {
        LogType::Info => info!("wlc: {}", message),
        LogType::Warn => warn!("wlc: {}", message),
        LogType::Error => error!("wlc: {}", message),
        LogType::Wayland => info!("wayland: {}", message)
    }
}

/// Formats the log strings properly
fn log_format(record: &log::LogRecord) -> String {
    let color = match record.level() {
        LogLevel::Info => "",
        LogLevel::Trace => "\x1B[37m",
        LogLevel::Debug => "\x1B[37m",
        LogLevel::Warn =>  "\x1B[33m",
        LogLevel::Error => "\x1B[31m",
    };
    let location = record.location();
    let file = location.file();
    let line = location.line();
    let mut module_path = location.module_path();
    if let Some(index) = module_path.find("way_cooler::") {
        let index = index + "way_cooler::".len();
        module_path = &module_path[index..];
    }
    format!("{} {} [{}] \x1B[37m{}:{}\x1B[0m{0} {} \x1B[0m",
            color, record.level(), module_path, file, line, record.args())
}

/// Checks the loaded modules, and reports any problematic proprietary ones
fn detect_proprietary() {
    if env::var("DISPLAY").is_ok() {
        // If DISPLAY is present, we are running embedded
        return
    }
    match File::open(Path::new(MODULE_PATH)) {
        Ok(file) => {
            let reader = BufReader::new(&file);
            for line in reader.lines() {
                if let Ok(line) = line {
                    if line.contains("nvidia") {
                        error!("Warning: Proprietary nvidia graphics drivers are installed, \
                               but they are not compatible with Wayland. Consider using nouveau drivers for Wayland.");
                        break;
                    } else if line.contains("fglrx") {
                        error!("Warning: Proprietary AMD graphics drivers are installed, but they are not compatible with Wayland. \
                               Consider using radeon drivers for Waylad.");
                        break;
                    }
                }
            }
        },
        Err(err) => {
            warn!("Could not read proprietary modules at \"{}\", because: {:#?}",
                  MODULE_PATH, err);
        }
    }
}

/// Initializes the logging system.
/// Can be called from within test methods.
pub fn init_logs() {
    // Prepare log builder
    let mut builder = env_logger::LogBuilder::new();
    builder.format(log_format);
    builder.filter(None, log::LogLevelFilter::Trace);
    if env::var("WAY_COOLER_LOG").is_ok() {
        builder.parse(&env::var("WAY_COOLER_LOG").expect("Asserted unwrap!"));
    }
    builder.init().expect("Unable to initialize logging!");
    info!("Logger initialized, setting wlc handlers.");
}

/// Handler for signals, should close the ipc
extern "C" fn sig_handle(_: nix::libc::c_int) {
    rustwlc::terminate();
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("", "version", "show version information");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("{}", f.to_string());
            std::process::exit(1);
        }
    };
    if matches.opt_present("version") {
        println!("Way Cooler {}", VERSION);
        println!("Way Cooler IPC version {}", ipc::VERSION);
        return
    }
    println!("Launching way-cooler...");

    let sig_action = SigAction::new(SigHandler::Handler(sig_handle), SaFlags::empty(), SigSet::empty());
    unsafe {signal::sigaction(signal::SIGINT, &sig_action).unwrap() };

    // Start logging first
    init_logs();
    // Detect proprietary modules loaded, and warn about them.
    detect_proprietary();

    // Initialize callbacks
    callbacks::init();

    // Handle wlc logs
    rustwlc::log_set_rust_handler(log_handler);

    // Prepare to launch wlc
    let run_wlc = rustwlc::init2().expect("Unable to initialize wlc!");

    // (Future config initialization goes here)
    // Initialize commands
    commands::init();
    // Add API to registry
    registry::init();
    // Register Alt+Esc keybinding
    keys::init();
    // Start listening for clients
    ipc::init();

    // Hand control over to wlc's event loop
    info!("Running wlc...");
    run_wlc();
}
<commit_msg>Cleaned up main.rs<commit_after>//! Main module of way-cooler

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate dbus_macros;
#[cfg(not(test))]
extern crate rustwlc;
extern crate getopts;
#[cfg(test)]
extern crate dummy_rustwlc as rustwlc;
#[macro_use]
extern crate log;
extern crate env_logger;
#[macro_use]
extern crate hlua;
extern crate rustc_serialize;
#[macro_use]
extern crate json_macro;
extern crate nix;
extern crate petgraph;
extern crate uuid;
extern crate dbus;

#[macro_use]
mod macros;
mod convert;

mod callbacks;
mod keys;

mod lua;
mod registry;
mod commands;
mod ipc;

mod layout;

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

use getopts::Options;
use log::LogLevel;
use nix::sys::signal::{self, SigHandler, SigSet, SigAction, SaFlags};

use rustwlc::types::LogType;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const DRIVER_MOD_PATH: &'static str = "/proc/modules";

/// Callback to route wlc logs into env_logger
fn log_handler(level: LogType, message: &str) {
    match level {
        LogType::Info => info!("wlc: {}", message),
        LogType::Warn => warn!("wlc: {}", message),
        LogType::Error => error!("wlc: {}", message),
        LogType::Wayland => info!("wayland: {}", message)
    }
}

/// Formats the log strings properly
fn log_format(record: &log::LogRecord) -> String {
    let color = match record.level() {
        LogLevel::Info => "",
        LogLevel::Trace => "\x1B[37m",
        LogLevel::Debug => "\x1B[37m",
        LogLevel::Warn =>  "\x1B[33m",
        LogLevel::Error => "\x1B[31m",
    };
    let location = record.location();
    let file = location.file();
    let line = location.line();
    let mut module_path = location.module_path();
    if let Some(index) = module_path.find("way_cooler::") {
        let index = index + "way_cooler::".len();
        module_path = &module_path[index..];
    }
    format!("{} {} [{}] \x1B[37m{}:{}\x1B[0m{0} {} \x1B[0m",
            color, record.level(), module_path, file, line, record.args())
}

/// Checks the loaded modules, and reports any problematic proprietary ones
fn detect_proprietary() {
    // If DISPLAY is present, we are running embedded
    if env::var("DISPLAY").is_ok() {
        return
    }
    match File::open(Path::new(DRIVER_MOD_PATH)) {
        Ok(file) => {
            let reader = BufReader::new(&file);
            for line in reader.lines() {
                if let Ok(line) = line {
                    if line.contains("nvidia") {
                        error!("Warning: Proprietary nvidia graphics drivers are installed, \
                               but they are not compatible with Wayland. \
                               Consider using nouveau drivers for Wayland.");
                        break;
                    } else if line.contains("fglrx") {
                        error!("Warning: Proprietary AMD graphics drivers are installed, \
                                but they are not compatible with Wayland. \
                               Consider using radeon drivers for Waylad.");
                        break;
                    }
                }
            }
        },
        Err(err) => {
            warn!("Could not read proprietary modules at \"{}\", because: {:#?}",
                  DRIVER_MOD_PATH, err);
            warn!("If you are running proprietary AMD or Nvidia graphics drivers, \
                   Way Cooler may not work for you");
        }
    }
}

/// Initializes the logging system.
pub fn init_logs() {
    let mut builder = env_logger::LogBuilder::new();
    builder.format(log_format);
    builder.filter(None, log::LogLevelFilter::Trace);
    if env::var("WAY_COOLER_LOG").is_ok() {
        builder.parse(&env::var("WAY_COOLER_LOG")
                      .expect("WAY_COOLER_LOG not defined"));
    }
    builder.init().expect("Unable to initialize logging!");
    info!("Logger initialized, setting wlc handlers.");
}

/// Handler for signals
extern "C" fn sig_handle(_: nix::libc::c_int) {
    rustwlc::terminate();
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("", "version", "show version information");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("{}", f.to_string());
            std::process::exit(1);
        }
    };
    if matches.opt_present("version") {
        println!("Way Cooler {}", VERSION);
        println!("Way Cooler IPC version {}", ipc::VERSION);
        return
    }
    println!("Launching way-cooler...");

    let sig_action = SigAction::new(SigHandler::Handler(sig_handle), SaFlags::empty(),
                                    SigSet::empty());
    unsafe {signal::sigaction(signal::SIGINT, &sig_action).unwrap() };

    init_logs();
    detect_proprietary();
    // This prepares wlc, doesn't run main loop until run_wlc is called
    let run_wlc = rustwlc::init2().expect("Unable to initialize wlc!");
    rustwlc::log_set_rust_handler(log_handler);
    callbacks::init();
    commands::init();
    registry::init();
    keys::init();
    ipc::init();

    info!("Running wlc...");
    run_wlc();
}
<|endoftext|>


<commit_before>#![feature(std_misc, test)]

extern crate threadpool;
extern crate rand;
extern crate num_cpus;

extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate glutin_window;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow as Window;
use piston::window::{AdvancedWindow, WindowSettings};
use piston::input::{Key, Button};
use piston::event::*;

mod board;

const SCALE: f64 = 2.0;
const X_SZ: u32 = 800;
const Y_SZ: u32 = 600;

fn scale_dimension(x: u32) -> usize {
    (x as f64 / SCALE).floor() as usize
}

#[cfg(not(test))]
fn main() {
    let (rows, cols) = (scale_dimension(X_SZ), scale_dimension(Y_SZ));
    let mut brd = board::Board::new(rows, cols).random();
    let ref mut worker_pool = board::WorkerPool::new_with_default_size();

    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings::new("Life", [X_SZ, Y_SZ])
        .exit_on_esc(true)
    );
    let ref mut gl = GlGraphics::new(opengl);
    let rect = graphics::Rectangle::new([1.0; 4]);
    let mut running = true;

    for e in window.events() {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::R     => brd = brd.random(),
                Key::Space => running = !running,
                _          => {}
            };
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, g| {
                graphics::clear([0.0; 4], g);
                for (x, y, val) in brd.cells() {
                    if !val { continue; }
                    rect.draw(
                        [y as f64 * SCALE, x as f64 * SCALE, SCALE, SCALE],
                        &c.draw_state, c.transform, g
                    );
                }
            });
        }

        if let Some(args) = e.update_args() {
            if running {
                brd = brd.parallel_next_generation(worker_pool);
            }
        }
    }
}
<commit_msg>Add 'single step' operation<commit_after>#![feature(std_misc, test)]

extern crate threadpool;
extern crate rand;
extern crate num_cpus;

extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate glutin_window;

use opengl_graphics::{GlGraphics, OpenGL};
use glutin_window::GlutinWindow as Window;
use piston::window::{AdvancedWindow, WindowSettings};
use piston::input::{Key, Button};
use piston::event::*;

mod board;

const SCALE: f64 = 2.0;
const X_SZ: u32 = 800;
const Y_SZ: u32 = 600;

fn scale_dimension(x: u32) -> usize {
    (x as f64 / SCALE).floor() as usize
}

#[cfg(not(test))]
fn main() {
    let (rows, cols) = (scale_dimension(X_SZ), scale_dimension(Y_SZ));
    let mut brd = board::Board::new(rows, cols).random();
    let ref mut worker_pool = board::WorkerPool::new_with_default_size();

    let opengl = OpenGL::_3_2;
    let window = Window::new(
        opengl,
        WindowSettings::new("Life", [X_SZ, Y_SZ])
        .exit_on_esc(true)
    );
    let ref mut gl = GlGraphics::new(opengl);
    let rect = graphics::Rectangle::new([1.0; 4]);
    let mut running = true;

    for e in window.events() {
        if let Some(Button::Keyboard(key)) = e.press_args() {
            match key {
                Key::R     => brd = brd.random(),
                Key::S     => brd = brd.parallel_next_generation(worker_pool),
                Key::Space => running = !running,
                _          => {}
            };
        }

        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, g| {
                graphics::clear([0.0; 4], g);
                for (x, y, val) in brd.cells() {
                    if !val { continue; }
                    rect.draw(
                        [y as f64 * SCALE, x as f64 * SCALE, SCALE, SCALE],
                        &c.draw_state, c.transform, g
                    );
                }
            });
        }

        if let Some(args) = e.update_args() {
            if running {
                brd = brd.parallel_next_generation(worker_pool);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::process::{Command, Output};
use walkdir::WalkDirIterator;

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;
    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let cwd = env::current_dir().unwrap();
    for _ in walkdir::WalkDir::new(cwd)
                   .min_depth(MIN_DEPTH)
                   .max_depth(MAX_DEPTH)
                   .into_iter()
                   .filter_entry(|e| e.path().join("Cargo.toml").exists())
                   .map(|e| e.ok().unwrap().path().to_path_buf())
                   .map(|p| {println!("{}:", p.display()); cmd.current_dir(p).output().unwrap()})
                   .map(|o| report_output(o)) {}
}
<commit_msg>rustfmt<commit_after>extern crate walkdir;

use std::ffi::OsString;
use std::env;
use std::process::{Command, Output};
use walkdir::WalkDirIterator;

fn announce(banner: &str) {
    let mut line = String::new();
    for _ in 0..banner.len() {
        line.push('-');
    }
    println!("{}", line);
    println!("{}", banner);
    println!("{}", line);
}

fn print_ident(buf: Vec<u8>) {
    for line in String::from_utf8_lossy(&buf[..]).lines() {
        println!("        {}", line);
    }
}

fn report_output(output: Output) {
    if output.status.success() {
        print_ident(output.stdout);
    } else {
        print_ident(output.stderr);
    }
    println!("");
}

const CARGO: &'static str = "cargo";
const MIN_DEPTH: usize = 1;
const MAX_DEPTH: usize = 1;

fn main() {
    let mut cmd = Command::new(CARGO);
    let mut banner = String::from("Executing ") + CARGO;
    for arg in env::args().skip(2) {
        cmd.arg(OsString::from(&arg));
        banner = banner + " " + &arg;
    }

    announce(&banner);

    let cwd = env::current_dir().unwrap();
    for _ in walkdir::WalkDir::new(cwd)
                 .min_depth(MIN_DEPTH)
                 .max_depth(MAX_DEPTH)
                 .into_iter()
                 .filter_entry(|e| e.path().join("Cargo.toml").exists())
                 .map(|e| e.ok().unwrap().path().to_path_buf())
                 .map(|p| {
                     println!("{}:", p.display());
                     cmd.current_dir(p).output().unwrap()
                 })
                 .map(|o| report_output(o)) {}
}
<|endoftext|>


<commit_before>/*
* rust-clean - Copyright (c) 2014 Gomez Guillaume.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim
*    that you wrote the original software. If you use this software in a product,
*    an acknowledgment in the product documentation would be appreciated but is
*    not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/

use std::io::fs;
use std::os;
use std::path::posix::Path;
use std::io::fs::PathExtensions;

struct CleanOptions {
    recursive: bool,
    verbose: bool,
    confirmation: bool
}

fn ask_confirmation(file: &Path) -> bool {
    loop {
        print!("clean: remove \x1b[37;1m'{}'\x1b[0m (y/n) ? ", file.as_str().unwrap());
        match std::io::stdio::stdin().read_line() {
            Ok(s) => {
                let tmp_s = s.replace("\r\n", "").replace("\n", "");

                if tmp_s.as_slice() == "y" || tmp_s.as_slice() == "yes" {
                    return true;
                } else if tmp_s.as_slice() == "n" || tmp_s.as_slice() == "no" {
                    return false;
                }
            }
            Err(_) => {}
        }
    }
}

fn start_clean(options: &CleanOptions, entry: &Path) {
    if entry.exists() {
        if entry.is_dir() {
            if options.recursive || entry.as_str().unwrap() == "." {
                match fs::readdir(entry) {
                    Ok(res) => {
                        if options.verbose {
                            println!("\x1b[36;1m-> Entering {}\x1b[0m", entry.as_str().unwrap());
                        }
                        for tmp in res.iter() {
                            start_clean(options, tmp);
                        }
                        if options.verbose {
                            println!("\x1b[34;1m<- Leaving {}\x1b[0m", entry.as_str().unwrap());
                        }
                    }
                    Err(e) => {
                        println!("\x1b[31;1mProblem with this directory: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                    }
                }
            }
        } else {
            match entry.filename() {
                Some(s) => {
                    if s.last().unwrap() == &('~' as u8) {
                        if !options.confirmation || ask_confirmation(&Path::new(s)) {
                            match fs::unlink(entry) {
                                Ok(_) => {
                                    if options.verbose {
                                        println!("\x1b[32;1m{} deleted\x1b[0m", entry.as_str().unwrap());
                                    }
                                }
                                Err(e) => {
                                    println!("\x1b[31;1mProblem with this file: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                                }
                            }
                        }
                    }
                }
                None => {
                    println!("\x1b[31;1mProblem with this file: {}\x1b[0m", entry.as_str().unwrap());
                }
            }
        }
    } else {
        println!("\x1b[31;1mProblem with this entry: {}\x1b[0m", entry.as_str().unwrap());
    }
}

fn print_help() {
    println!("./clean [options] [files | dirs]");
    println!("    -r : recursive mode");
    println!("    -v : verbose mode");
    println!("    -i : prompt before every removal");
    println!("--help : print this help");
}

fn main() {
    let mut args = os::args().clone();
    let mut options = CleanOptions{recursive: false, verbose: false, confirmation: false};
    let mut files = Vec::new();

    args.remove(0);
    for tmp in args.iter() {
        if tmp.clone().into_bytes()[0] == '-' as u8 {
            let mut tmp_arg = String::from_str(tmp.as_slice());

            tmp_arg.remove(0);
            if tmp_arg.len() > 0 {
                for character in tmp_arg.into_bytes().iter() {
                    match *character as char {
                        '-' => {
                            if tmp.as_slice() == "--help" {
                                print_help();
                                return;
                            }
                        }
                        'r' => {
                            options.recursive = true;
                        }
                        'v' => {
                            options.verbose = true;
                        }
                        'i' => {
                            options.confirmation = true;
                        }
                        _ => {
                            fail!("Unknown option: '{}', to have the options list, please launch with '-h' option\n", character);
                        }
                    }
                }
            } else {
                files.push(Path::new(tmp.as_slice()));
            }
        }
    }
    if files.len() == 0 {
        files.push(Path::new(String::from_str(".").as_slice()));
    }
    if options.verbose {
        println!("\x1b[33;1m=== VERBOSE MODE ===\x1b[0m");
    }
    for tmp in files.iter() {
        start_clean(&options, tmp);
    }
    if options.verbose {
        println!("\x1b[33;1mEnd of execution\x1b[0m");
    }
}<commit_msg>Update to last rust compiler version<commit_after>/*
* rust-clean - Copyright (c) 2014 Gomez Guillaume.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim
*    that you wrote the original software. If you use this software in a product,
*    an acknowledgment in the product documentation would be appreciated but is
*    not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/

use std::io::fs;
use std::os;
use std::path::posix::Path;
use std::io::fs::PathExtensions;

struct CleanOptions {
    recursive: bool,
    verbose: bool,
    confirmation: bool
}

fn ask_confirmation(file: &Path) -> bool {
    loop {
        print!("clean: remove \x1b[37;1m'{}'\x1b[0m (y/n) ? ", file.as_str().unwrap());
        match std::io::stdio::stdin().read_line() {
            Ok(s) => {
                let tmp_s = s.replace("\r\n", "").replace("\n", "");

                if tmp_s.as_slice() == "y" || tmp_s.as_slice() == "yes" {
                    return true;
                } else if tmp_s.as_slice() == "n" || tmp_s.as_slice() == "no" {
                    return false;
                }
            }
            Err(_) => {}
        }
    }
}

fn start_clean(options: &CleanOptions, entry: &Path) {
    if entry.exists() {
        if entry.is_dir() {
            if options.recursive || entry.as_str().unwrap() == "." {
                match fs::readdir(entry) {
                    Ok(res) => {
                        if options.verbose {
                            println!("\x1b[36;1m-> Entering {}\x1b[0m", entry.as_str().unwrap());
                        }
                        for tmp in res.iter() {
                            start_clean(options, tmp);
                        }
                        if options.verbose {
                            println!("\x1b[34;1m<- Leaving {}\x1b[0m", entry.as_str().unwrap());
                        }
                    }
                    Err(e) => {
                        println!("\x1b[31;1mProblem with this directory: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                    }
                }
            }
        } else {
            match entry.filename() {
                Some(s) => {
                    if s.last().unwrap() == &('~' as u8) {
                        if !options.confirmation || ask_confirmation(&Path::new(s)) {
                            match fs::unlink(entry) {
                                Ok(_) => {
                                    if options.verbose {
                                        println!("\x1b[32;1m{} deleted\x1b[0m", entry.as_str().unwrap());
                                    }
                                }
                                Err(e) => {
                                    println!("\x1b[31;1mProblem with this file: {} -> {}\x1b[0m", entry.as_str().unwrap(), e);
                                }
                            }
                        }
                    }
                }
                None => {
                    println!("\x1b[31;1mProblem with this file: {}\x1b[0m", entry.as_str().unwrap());
                }
            }
        }
    } else {
        println!("\x1b[31;1mProblem with this entry: {}\x1b[0m", entry.as_str().unwrap());
    }
}

fn print_help() {
    println!("./clean [options] [files | dirs]");
    println!("    -r : recursive mode");
    println!("    -v : verbose mode");
    println!("    -i : prompt before every removal");
    println!("--help : print this help");
}

fn main() {
    let mut args = os::args().clone();
    let mut options = CleanOptions{recursive: false, verbose: false, confirmation: false};
    let mut files = Vec::new();

    args.remove(0);
    for tmp in args.iter() {
        if tmp.clone().into_bytes()[0] == '-' as u8 {
            let mut tmp_arg = String::from_str(tmp.as_slice());

            tmp_arg.remove(0);
            if tmp_arg.len() > 0 {
                for character in tmp_arg.into_bytes().iter() {
                    match *character as char {
                        '-' => {
                            if tmp.as_slice() == "--help" {
                                print_help();
                                return;
                            }
                        }
                        'r' => {
                            options.recursive = true;
                        }
                        'v' => {
                            options.verbose = true;
                        }
                        'i' => {
                            options.confirmation = true;
                        }
                        _ => {
                            panic!("Unknown option: '{}', to have the options list, please launch with '-h' option\n", character);
                        }
                    }
                }
            } else {
                files.push(Path::new(tmp.as_slice()));
            }
        }
    }
    if files.len() == 0 {
        files.push(Path::new(String::from_str(".").as_slice()));
    }
    if options.verbose {
        println!("\x1b[33;1m=== VERBOSE MODE ===\x1b[0m");
    }
    for tmp in files.iter() {
        start_clean(&options, tmp);
    }
    if options.verbose {
        println!("\x1b[33;1mEnd of execution\x1b[0m");
    }
}<|endoftext|>