<commit_before>use std::process::{Command};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    //Rewrite to Main is needed.
    // This is needed for the end user to know what is happening.
    let keys:Vec<String> =
        vec!["AEFB411B072836CD48FF0381AE252C284B5DBA5D".to_string(),
             "9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0".to_string(),
             "35F52A02854DCCAEC9DD5CC410443C7F54B00041".to_string()];
    let mut keys_clone:Vec<String> = vec![];
    keys_clone = keys.clone();
    let mut holder:Vec<String> = vec![];
    let mut hold:Vec<String> = vec![];
    /*let pass = "PASS!";
    let fail = "FAIL!";
    let key_one = gpg_import_key_one();
    let key_two = gpg_import_key_two();
    let key_three = gpg_import_key_three();

    if key_one && key_two && key_three{
        println!("1st Key Import {}", pass);
        println!("2nd Key Import {}", pass);
        println!("3rd Key Import {}", pass);
    }else if !key_one {
        println!("1st Key Import {}", fail);
        exit(1);
    }else if key_one &! key_two{
        println!("2nd Key Import {}", fail);
        exit(1);
    }else if key_one && key_two &!key_three {
        println!("3rd Key Import {}", fail);
        exit(1);
    }

    let init_check = gpg_init();

    if init_check {
        println!("Pacman Key Init {}", pass);
    }else {
        println!("Pacman Key Init {}", fail);
    }*/
    //modify_pacman_conf();
    //holder =  check_pacman_conf();
    //check_pacman_conf();
    //let check_one = create_pacman_conf_old();
    //println!("Created backup of \"/etc/pacman.conf:\" {}", check_one);
    //create_new_pacman_conf(holder);
    //hold = pacman_conf_final();
    //create_new_pacman_conf(hold);
    gpg_import_keys(keys);
    gpg_remove_keys(keys_clone);
}

fn gpg_import_keys(k:Vec<String>) {

    let mut keys:String = String::new();
    let mut check:i8 = 0;
    for item in k.iter(){
        keys = item.to_string();

        let output = Command::new("gpg")
            .arg("--receive-keys")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");
        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not imported");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were imported successfully.");
    }
}

fn gpg_init() -> bool{
    let check:bool = true;
    let output = Command::new("pacman-key")
        .arg("--init")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        print!("Success: ");
        println!("{}", String::from_utf8(output.stdout).unwrap());
    }else {
        print!("Error: ");
        println!("{}", String::from_utf8(output.stderr).unwrap());
    }
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn gpg_remove_keys(k:Vec<String>) {

    let mut keys:String = String::new();
    let mut check:i8 = 0;
    for item in k.iter() {
        keys = item.to_string();

        let output =
            Command::new("pacman-key")
            .arg("-r")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");

        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not removed!");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were removed successfully.");
    }
}

fn create_pacman_conf_old() -> bool{
    let check:bool = true;
    let output = Command::new("mv")
        .arg("out/pacman.conf")
        .arg("out/pacman.conf.old")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}
//This function will be called on two separate iterations
fn create_new_pacman_conf(x:Vec<String>) {
    let path = Path::new("out/pacman.conf");
    let display = path.display();
    // Open a file in write-only mode, returns `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(file) => file,
    };

    let mut f = OpenOptions::new()
        .write(true)
        .append(true)
        .open("out/pacman.conf")
        .unwrap();
    for item in x.iter(){
        if let Err(e) =
        writeln!(f, "{}",item.to_string()){
            println!("{}", e);
        }
    }
}

fn check_pacman_conf() ->Vec<String> {

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "#[archlabs_repo]".to_string();
    let check_str_two:String =
        "[archlabs_repo]".to_string();
    let check_str_three:String =
        "#SigLevel = Never".to_string();
    let check_str_four:String =
        "SigLevel = Never".to_string();
    let check_str_five:String =
        "#Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_six:String =
        "Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_seven:String =
        "#Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();
    let check_str_eight:String =
        "Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();

    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_two);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_three) {
                let str_replace =
                    line.replace(&check_str_three, &check_str_four);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_five) {
                let str_replace =
                    line.replace(&check_str_five, &check_str_six);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_seven) {
                let str_replace =
                    line.replace(&check_str_seven, &check_str_eight);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}

fn archlabs_keyring() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn key_populate() -> bool {
    let check:bool = true;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        return check;
    }else {
        return !check;
    }
}

fn pacman_conf_final() -> Vec<String>{

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "[archlabs_repo]".to_string();
    let check_str_two:String =
        "SigLevel = Never".to_string();
    let check_str_three:String =
        "SigLevel = Optional TrustAll".to_string();
    let filename = r"/etc/pacman.conf";
    let mut f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_one);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_two) {
                let str_replace =
                    line.replace(&check_str_two, &check_str_three);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}<commit_msg>FNs changes, and process adjustment.<commit_after>use std::process::{Command, exit};
use std::fs::{OpenOptions, File};
use std::io::prelude::*;
use std::io::{BufReader,BufRead};
use std::error::Error;
use std::path::Path;

fn main() {
    let keys:Vec<String> =
        vec!["AEFB411B072836CD48FF0381AE252C284B5DBA5D".to_string(),
             "9E4F11C6A072942A7B3FD3B0B81EB14A09A25EB0".to_string(),
             "35F52A02854DCCAEC9DD5CC410443C7F54B00041".to_string()];
    let keys_clone:Vec<String> = keys.clone();
    //let mut contents:Vec<String> = vec![];
    gpg_import_keys(keys);
    let init_check:bool = gpg_init();
    if !init_check{
        println!("Update has failed, after gpg keys have been imported.");
        println!("Ensure you run update with \"sudo\", or super user privileges");
        exit(1);
    }else {
        println!("GPG Init: Task Completed Successfully!");
    }
    gpg_remove_keys(keys_clone);
    let mut contents:Vec<String> = check_pacman_conf();
    let confold:bool = create_pacman_conf_old();
    create_new_pacman_conf(contents);
    let keyring:bool = archlabs_keyring();
    let populate:bool = key_populate();
    contents = pacman_conf_final();
    create_new_pacman_conf(contents);
    println!("The automated update portion of the process has completed!");
    println!("Please visit the ArchLABs Forums:");
    println!("https://www.tapatalk.com/groups/archlabs\
    /upgrade-guide-for-existing-installations-t432.html");
    println!("To continue with the manual steps in the process...");
}

fn gpg_import_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter(){
        let keys:String =
            item.to_string();

        let output = Command::new("gpg")
            .arg("--receive-keys")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");
        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not imported");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were imported successfully.");
    }
}

fn gpg_init() -> bool{
    let check:bool;
    let output = Command::new("pacman-key")
        .arg("--init")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        print!("Success: ");
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        print!("Error: ");
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}

fn gpg_remove_keys(k:Vec<String>) {

    let mut check:i8 = 0;
    for item in k.iter() {
        let keys:String =
            item.to_string();

        let output =
            Command::new("pacman-key")
            .arg("-r")
            .arg(keys.to_string())
            .output()
            .expect("Process Failed to Execute!");

        if output.stderr.is_empty(){
            println!("{}", String::from_utf8(output.stdout).unwrap());
            check +=1 ; //or default of true
        }else {
            println!("{}", String::from_utf8(output.stderr).unwrap());
            check -= 1;
        }
    }
    if check != 3{
        // One or more keys were not imported.
        print!("{} ", (check*-1));
        println!("keys were not removed!");
    }else if check == 3 {
        print!("{} ", (check));
        println!("keys were removed successfully.");
    }
}

fn create_pacman_conf_old() -> bool{
    let check:bool;
    let output = Command::new("mv")
        .arg("out/pacman.conf")
        .arg("out/pacman.conf.old")
        .output()
        .expect("Process Failed to Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        println!("Back up of \"pacman.conf\" complete!");
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}
//This function will be called on two separate iterations
fn create_new_pacman_conf(x:Vec<String>) {
    let path = Path::new("out/pacman.conf");
    let display = path.display();
    // Open a file in write-only mode, returns `io::Result<File>`
    let _file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}",
                           display,
                           why.description()),
        Ok(_file) => _file,
    };

    let mut f = OpenOptions::new()
        .write(true)
        .append(true)
        .open("out/pacman.conf")
        .unwrap();
    for item in x.iter(){
        if let Err(e) =
        writeln!(f, "{}",item.to_string()){
            println!("{}", e);
        }
    }
}

fn check_pacman_conf() ->Vec<String> {

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "#[archlabs_repo]".to_string();
    let check_str_two:String =
        "[archlabs_repo]".to_string();
    let check_str_three:String =
        "#SigLevel = Never".to_string();
    let check_str_four:String =
        "SigLevel = Never".to_string();
    let check_str_five:String =
        "#Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_six:String =
        "Server = https://archlabs.github.io/archlabs_repo/$arch".to_string();
    let check_str_seven:String =
        "#Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();
    let check_str_eight:String =
        "Server = https://downloads.sourceforge.net/project/\
        archlabs-repo/archlabs_repo/$arch".to_string();

    let filename = r"/etc/pacman.conf";
    let f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_two);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_three) {
                let str_replace =
                    line.replace(&check_str_three, &check_str_four);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_five) {
                let str_replace =
                    line.replace(&check_str_five, &check_str_six);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_seven) {
                let str_replace =
                    line.replace(&check_str_seven, &check_str_eight);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}

fn archlabs_keyring() -> bool {
    let check:bool;
    let output =
        Command::new("pacman")
            .arg("-S")
            .arg("archlabs-keyring")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = false;
    }
    return check;
}

fn key_populate() -> bool {
    let check:bool;
    let output =
        Command::new("pacman-key")
            .arg("--populate")
            .arg("archlabs")
            .output()
            .expect("Process Failed To Execute!");
    if output.stderr.is_empty(){
        println!("{}", String::from_utf8(output.stdout).unwrap());
        check = true;
    }else {
        println!("{}", String::from_utf8(output.stderr).unwrap());
        check = false;
    }
    return check;
}

fn pacman_conf_final() -> Vec<String>{

    let mut contents:Vec<String> = vec![];
    let check_str_one:String =
        "[archlabs_repo]".to_string();
    let check_str_two:String =
        "SigLevel = Never".to_string();
    let check_str_three:String =
        "SigLevel = Optional TrustAll".to_string();
    let filename = r"/etc/pacman.conf";
    let f =
        BufReader::new(File::open(filename).unwrap());
    for line in f.lines() {
        match line {
            Ok(line) => if line.contains(&check_str_one) {
                let str_replace =
                    line.replace(&check_str_one, &check_str_one);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else if line.contains(&check_str_two) {
                let str_replace =
                    line.replace(&check_str_two, &check_str_three);
                contents.push(str_replace.to_string());
                //println!("{}", str_replace);
            } else {
                contents.push(line.to_string());
                //println!("{}", line.to_string());
            }
            //Error logic is flawed.. need to workout error check
            //to determine if pacman.conf needs to be modified.
            Err(_) => if check_str_two.eq(line.unwrap().as_str()) {
                println!("No change needed");
            } else {
                println!("Something Happened");
            }
        };
    };
    return contents;
}<|endoftext|>


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

fn sc_do(do_matches: &clap::ArgMatches) {
    let mut verbose = false;
    if do_matches.is_present("verbose") {
        verbose = true;
    }
    if let Some(create_droplet_matches) = do_matches.subcommand_matches("create_droplet") {
        if let Some(name) = create_droplet_matches.value_of("name") {
            breezyvps::digitalocean::create_droplet_by_name(name);
        } else {
            println!("Missing required name parameter!");
        }
        return;
    }
    if let Some(destroy_droplet_matches) = do_matches.subcommand_matches("destroy_droplet") {
        if let Some(name) = destroy_droplet_matches.value_of("name") {
            breezyvps::digitalocean::destroy_droplet_by_name(name);
        } else {
            println!("Missing required name parameter!");
        }
        return;
    }
}

fn main() {
    let matches = clap_app!(myapp =>
        (version: "0.0.1")
        (author: "Michael Xu <michaeljxu11@gmail.com>")
        (about: "One stop shop for common command line goodness")
        (@arg verbose: -v ... "Enable verbose output")
        (@subcommand do =>
            (about: "Doctl wrapper")
            (version: "0.0.0")
            (author: "Michael Xu <michaeljxu11@gmail.com>")
            (@arg verbose: -v --verbose "Print test information verbosely")
            (@subcommand create_droplet =>
                (about: "Create a new droplet")
                (@arg name: +required "Name of the droplet, must be unique")
                (@arg config: -c "Which configuration to use [small|medium|large]")
            )
            (@subcommand destroy_droplet =>
                (about: "Destroy a droplet by name")
                (@arg name: +required "Name of the droplet to destroy completely")
            )
        )
    ).get_matches();

    // Vary the output based on how many times the user used the "verbose" flag
    // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
    match matches.occurrences_of("v") {
        0 => println!("No verbose info"),
        1 => println!("Some verbose info"),
        2 => println!("Tons of verbose info"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can handle information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("do") {
	sc_do(matches);
    }
}
<commit_msg>return early<commit_after>#[macro_use]
extern crate clap;
extern crate breezyvps;

fn sc_do(do_matches: &clap::ArgMatches) {
    let mut verbose = false;
    if do_matches.is_present("verbose") {
        verbose = true;
    }
    if let Some(create_droplet_matches) = do_matches.subcommand_matches("create_droplet") {
        if let Some(name) = create_droplet_matches.value_of("name") {
            breezyvps::digitalocean::create_droplet_by_name(name);
        } else {
            println!("Missing required name parameter!");
        }
        return;
    }
    if let Some(destroy_droplet_matches) = do_matches.subcommand_matches("destroy_droplet") {
        if let Some(name) = destroy_droplet_matches.value_of("name") {
            breezyvps::digitalocean::destroy_droplet_by_name(name);
        } else {
            println!("Missing required name parameter!");
        }
        return;
    }
}

fn main() {
    let matches = clap_app!(myapp =>
        (version: "0.0.1")
        (author: "Michael Xu <michaeljxu11@gmail.com>")
        (about: "One stop shop for common command line goodness")
        (@arg verbose: -v ... "Enable verbose output")
        (@subcommand do =>
            (about: "Doctl wrapper")
            (version: "0.0.0")
            (author: "Michael Xu <michaeljxu11@gmail.com>")
            (@arg verbose: -v --verbose "Print test information verbosely")
            (@subcommand create_droplet =>
                (about: "Create a new droplet")
                (@arg name: +required "Name of the droplet, must be unique")
                (@arg config: -c "Which configuration to use [small|medium|large]")
            )
            (@subcommand destroy_droplet =>
                (about: "Destroy a droplet by name")
                (@arg name: +required "Name of the droplet to destroy completely")
            )
        )
    ).get_matches();

    // Vary the output based on how many times the user used the "verbose" flag
    // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
    match matches.occurrences_of("v") {
        0 => println!("No verbose info"),
        1 => println!("Some verbose info"),
        2 => println!("Tons of verbose info"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can handle information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("do") {
        sc_do(matches);
        return;
    }
}
<|endoftext|>


<commit_before>#![deny(missing_debug_implementations, missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unsafe_code, unstable_features,
    unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_bunyan;
extern crate slog_stream;
extern crate slog_term;
#[macro_use]
extern crate clap;
extern crate regex;
extern crate notify;
extern crate bincode;
extern crate rustc_serialize;
extern crate byteorder;
extern crate filetime;
extern crate time;

use clap::{App, ArgMatches};
use shared::helpers;
use slog::{Level, LevelFilter, Logger, Duplicate, DrainExt};
use std::fs::{self, File};
use std::path::Path;

mod master;
mod slave;
mod shared;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

fn main() {
    let yaml = load_yaml!("cli.yml");
    let m = App::from_yaml(yaml)
        .version(VERSION)
        .get_matches();

    if let Some(ref m) = m.subcommand_matches("master") {
        run_master(m);
    } else if let Some(ref m) = m.subcommand_matches("slave") {
        run_slave(m);
    }
}

fn run_master(m: &ArgMatches) {
    let base_dir = get_base_dir(m.value_of("base_dir").unwrap());
    let remote_dir = m.value_of("remote_dir").unwrap();
    let remote_port = m.value_of("port");
    let verbose_mode = m.is_present("verbose");
    let mut ignore_strings = get_ignore_strings(m);

    let log = setup_log(&base_dir, verbose_mode, true);
    info!(log, "Starting BindRS");

    master::run(&log,
                &base_dir,
                remote_dir,
                remote_port,
                &mut ignore_strings,
                verbose_mode)
}

fn run_slave(m: &ArgMatches) {
    let base_dir = get_base_dir(m.value_of("base_dir").unwrap());
    let mut ignore_strings = get_ignore_strings(m);
    let verbose_mode = m.is_present("verbose");

    let log = setup_log(&base_dir, verbose_mode, false);
    info!(log, "Starting BindRS");

    slave::run(&log, &base_dir, &mut ignore_strings)
}

fn get_ignore_strings(m: &ArgMatches) -> Vec<String> {
    match m.values_of("ignore") {
        Some(i) => i.into_iter().map(|str| str.to_owned()).collect(),
        None => vec![],
    }
}

fn get_base_dir(base_dir: &str) -> String {
    match helpers::resolve_path(base_dir) {
        Some(dir) => dir,
        None => {
            helpers::print_error_and_exit("failed to find base directory");
            "".to_owned()
        }
    }
}

fn setup_log(base_dir: &str, verbose_mode: bool, master_mode: bool) -> Logger {
    let mut path_buf = Path::new(base_dir).to_path_buf();
    path_buf.push(".bindrs");
    fs::create_dir_all(path_buf.as_path()).unwrap();

    path_buf.push("bindrs");
    path_buf.set_extension("log");

    let file = File::create(path_buf.as_path()).unwrap();
    let stream = slog_stream::stream(file, slog_bunyan::new().build());

    let level = match verbose_mode {
        true => Level::Debug,
        false => Level::Info,
    };

    if master_mode {
        let termlog = slog_term::streamer().async().full().build();
        Logger::root(Duplicate::new(LevelFilter::new(stream, level),
                                    LevelFilter::new(termlog, level))
                         .fuse(),
                     o!("version" => VERSION, "mode" => "master"))
    } else {
        Logger::root(LevelFilter::new(stream, level).fuse(),
                     o!("version" => VERSION, "mode" => "slave"))
    }
}
<commit_msg>Remove unwraps in main.rs<commit_after>#![deny(missing_debug_implementations, missing_copy_implementations,
    trivial_casts, trivial_numeric_casts,
    unsafe_code, unstable_features,
    unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_bunyan;
extern crate slog_stream;
extern crate slog_term;
#[macro_use]
extern crate clap;
extern crate regex;
extern crate notify;
extern crate bincode;
extern crate rustc_serialize;
extern crate byteorder;
extern crate filetime;
extern crate time;

use clap::{App, ArgMatches};
use shared::helpers;
use slog::{Level, LevelFilter, Logger, Duplicate, DrainExt};
use std::fs::{self, File};
use std::path::Path;
use std::process::exit;

mod master;
mod slave;
mod shared;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");

fn main() {
    let yaml = load_yaml!("cli.yml");
    let m = App::from_yaml(yaml)
        .version(VERSION)
        .get_matches();

    if let Some(ref m) = m.subcommand_matches("master") {
        run_master(m);
    } else if let Some(ref m) = m.subcommand_matches("slave") {
        run_slave(m);
    }
}

fn run_master(m: &ArgMatches) {
    let base_dir = get_base_dir(m.value_of("base_dir").unwrap()); // Unwrap is safe - required by clap
    let remote_dir = m.value_of("remote_dir").unwrap(); // Unwrap is safe - required by clap
    let remote_port = m.value_of("port");
    let verbose_mode = m.is_present("verbose");
    let mut ignore_strings = get_ignore_strings(m);

    let log = setup_log(&base_dir, verbose_mode, true);
    info!(log, "Starting BindRS");

    master::run(&log,
                &base_dir,
                remote_dir,
                remote_port,
                &mut ignore_strings,
                verbose_mode)
}

fn run_slave(m: &ArgMatches) {
    let base_dir = get_base_dir(m.value_of("base_dir").unwrap()); // Unwrap is safe - required by clap
    let mut ignore_strings = get_ignore_strings(m);
    let verbose_mode = m.is_present("verbose");

    let log = setup_log(&base_dir, verbose_mode, false);
    info!(log, "Starting BindRS");

    slave::run(&log, &base_dir, &mut ignore_strings)
}

fn get_ignore_strings(m: &ArgMatches) -> Vec<String> {
    match m.values_of("ignore") {
        Some(i) => i.into_iter().map(|str| str.to_owned()).collect(),
        None => vec![],
    }
}

fn get_base_dir(base_dir: &str) -> String {
    match helpers::resolve_path(base_dir) {
        Some(dir) => dir,
        None => {
            helpers::print_error_and_exit("failed to find base directory");
            "".to_owned()
        }
    }
}

fn setup_log(base_dir: &str, verbose_mode: bool, master_mode: bool) -> Logger {
    let mut path_buf = Path::new(base_dir).to_path_buf();
    path_buf.push(".bindrs");

    match fs::create_dir_all(path_buf.as_path()) {
        Ok(_) => (),
        Err(_) => helpers::print_error_and_exit("Failed to create .bindrs directory!"),
    }

    path_buf.push("bindrs");
    path_buf.set_extension("log");

    let file = match File::create(path_buf.as_path()) {
        Ok(f) => f,
        Err(_) => {
            helpers::print_error_and_exit("Failed to create log file.");
            exit(1); // For compilation
        }
    };
    let stream = slog_stream::stream(file, slog_bunyan::new().build());

    let level = match verbose_mode {
        true => Level::Debug,
        false => Level::Info,
    };

    if master_mode {
        let termlog = slog_term::streamer().async().full().build();
        Logger::root(Duplicate::new(LevelFilter::new(stream, level),
                                    LevelFilter::new(termlog, level))
                         .fuse(),
                     o!("version" => VERSION, "mode" => "master"))
    } else {
        Logger::root(LevelFilter::new(stream, level).fuse(),
                     o!("version" => VERSION, "mode" => "slave"))
    }
}
<|endoftext|>


<commit_before>#![crate_id="TicTacToe#0.1"]

extern crate sdl2;

use sdl2::video::Window;
use sdl2::video::PosCentered;
use sdl2::video::OpenGL;

use sdl2::render::Renderer;
use sdl2::render::DriverAuto;
use sdl2::render::Accelerated;

use sdl2::rect::Point;
use sdl2::pixels::RGB;

use sdl2::mouse::Mouse;

/// Draws a player X mark at a given location.
fn draw_x(r: &Renderer, x: i32, y: i32, w: i32, h: i32) {
  r.draw_line(Point::new(x, y), Point::new(x + w, y + h));
  r.draw_line(Point::new(x + w, y), Point::new(x, y + h));
}

/// Draws a player O mark at a given location.
fn draw_o(r: &Renderer, x: i32, y: i32, w: i32, h: i32) {
  use std::f32::consts::PI;

  let segs = 16;
  let segr: f32 = 2f32 * PI / segs as f32;

  let cx: f32 = x as f32 + w as f32 / 2f32;
  let cy: f32 = y as f32 + h as f32 / 2f32;
  // technically we have to support oval shapes because the field is dynamically sized
  let rx: f32 = w as f32 / 2f32;
  let ry: f32 = h as f32 / 2f32;

  for i in range(0, segs) {
    let a = i as f32;
    let b = a + 1f32;
    let pt1 = Point::new(
      (cx + (a * segr).cos() * rx) as i32,
      (cy + (a * segr).sin() * ry) as i32);
    let pt2 = Point::new(
      (cx + (b * segr).cos() * rx) as i32,
      (cy + (b * segr).sin() * ry) as i32);
    r.draw_line(pt1, pt2);
  }
}

/// Specifies a set of methods that all game states should implement.
trait GameState {
  fn render(&self, r: &Renderer) {
  }

  fn on_mouse_down(&mut self, mouse: Mouse, x: int, y: int) {
  }
}

/// Represents the players in a Tic-tac-toe game.
#[deriving(Clone, Show)]
enum Mark {
  X, O
}

impl Mark {
  /// Returns the opposite mark.
  fn opposite(self) -> Mark {
    match self {
      X => O,
      O => X
    }
  }
}

/// Represents the winner in a game of Tic-tac-toe.
enum WinState {
  Win(Mark),
  Draw,
  Neither
}

/// Stores the board data associated with a game of Tic-tac-toe.
struct PlayField {
  cells: [Option<Mark>, ..9]
}

/// Represents a line of the Tic-tac-toe board. A line consists of three cells.
struct PlayLine {
  cells: [Option<Mark>, ..3]
}

impl PlayLine {
  /// Determines if this line counts as a win. Returns the winner wrapped in an
  /// Option, with None meaning that this line is not a winning one.
  fn is_win(&self) -> Option<Mark> {
    let (xs, os) = self.cells.iter().fold((0, 0), |(xs, os), &place| {
      match place {
        Some(X) => (xs + 1, os),
        Some(O) => (xs, os + 1),
        None    => (xs, os)
      }
    });
    if xs == 3 {
      Some(X)
    } else if os == 3 {
      Some(O)
    } else {
      None
    }
  }
}

enum LineIterState {
  Row(uint),
  Column(uint),
  LtrDiagonal,
  RtlDiagonal,
  Finished
}

struct LineIter<'a> {
  field: &'a PlayField,
  state: LineIterState
}

impl<'a> LineIter<'a> {
  fn from_field<'a>(f: &'a PlayField) -> LineIter<'a> {
    LineIter {
      field: f,
      state: Row(0)
    }
  }
}

impl<'a> Iterator<PlayLine> for LineIter<'a> {
  fn next(&mut self) -> Option<PlayLine> {
    match self.state {
      Row(place) => {
        self.state = if place + 1 < 3 {
          Row(place + 1)
        } else {
          Column(0)
        };
        self.field.horizontal_line(place)
      },
      Column(place) => {
        self.state = if place + 1 < 3 {
          Column(place + 1)
        } else {
          LtrDiagonal
        };
        self.field.vertical_line(place)
      },
      LtrDiagonal => {
        self.state = RtlDiagonal;
        Some(self.field.ltr_diagonal_line())
      },
      RtlDiagonal => {
        self.state = Finished;
        Some(self.field.rtl_diagonal_line())
      },
      Finished => None
    }
  }
}

impl PlayField {
  fn new() -> PlayField {
    PlayField {
      cells: [None, ..9]
    }
  }

  /// Returns the number of occupied cells.
  fn occupied_count(&self) -> int {
    self.cells.iter().fold(0, |s, mark| if mark.is_some() { s + 1 } else { s })
  }

  /// Returns an iterator over the `PlayLine`s in this field.
  fn lines<'a>(&'a self) -> LineIter<'a> {
    LineIter::from_field(self)
  }

  fn horizontal_line(&self, row: uint) -> Option<PlayLine> {
    PlayField::map_xy(0, row).map(|ix| PlayLine {
      // there's probably a trick to do this with a slice
      cells: [self.cells[ix], self.cells[ix + 1], self.cells[ix + 2]]
    })
  }

  fn vertical_line(&self, col: uint) -> Option<PlayLine> {
    PlayField::map_xy(col, 0).map(|ix| PlayLine {
      cells: [self.cells[ix], self.cells[ix + 3], self.cells[ix + 6]]
    })
  }

  fn ltr_diagonal_line(&self) -> PlayLine {
    PlayLine {
      cells: [self.cells[0], self.cells[4], self.cells[8]]
    }
  }

  fn rtl_diagonal_line(&self) -> PlayLine {
    PlayLine {
      cells: [self.cells[2], self.cells[4], self.cells[6]]
    }
  }

  fn map_xy(x: uint, y: uint) -> Option<uint> {
    if y < 3 && y < 3 {
      Some(y * 3 + x)
    } else {
      None
    }
  }

  fn get_cell_xy(&self, x: uint, y: uint) -> Option< Option<Mark> > {
    PlayField::map_xy(x, y).map(|ix| self.cells[ix])
  }

  fn get_mut_cell_xy<'a>(&'a mut self, x: uint, y: uint) -> Option< &'a mut Option<Mark> > {
    match PlayField::map_xy(x, y) {
      Some(ix) => Some(&mut self.cells[ix]),
      None     => None
    }
  }
}

/// Represents an on-screen area where a Tic-tac-toe board can be interacted
/// with.
struct FieldArea {
  x: int, y: int,
  w: int, h: int
}

impl FieldArea {
  /// Returns the width of an individual cell.
  fn cell_width(&self) -> int {
    self.w / 3
  }

  /// Returns the height of an individual cell.
  fn cell_height(&self) -> int {
    self.h / 3
  }

  /// Computes the row at a given on-screen Y-coordinate.
  fn unproject_row(&self, y: int) -> Option<int> {
    if y >= self.y {
      match (y - self.y) / self.cell_height() {
        ix if ix > 2 => None,
        ix           => Some(ix)
      }
    } else {
      None
    }
  }

  /// Computes the column at a given on-screen X-coordinate.
  fn unproject_col(&self, x: int) -> Option<int> {
    if x >= self.x {
      match (x - self.x) / self.cell_width() {
        ix if ix > 2 => None,
        ix           => Some(ix)
      }
    } else {
      None
    }
  }

  /// Computes the given row and column given on-screen X and Y coordinates.
  fn unproject(&self, x: int, y: int) -> Option<(int, int)> {
    let row = match self.unproject_row(y) {
      Some(row) => row,
      None      => return None
    };
    let col = match self.unproject_col(x) {
      Some(col) => col,
      None      => return None
    };
    Some((row, col))
  }

  /// Computes the on-screen X and Y coordinates for a given row and column.
  fn project(&self, row: int, col: int) -> Point {
    let x = (self.x + col * self.cell_width()) as i32;
    let y = (self.y + row * self.cell_height()) as i32;
    Point::new(x, y)
  }
}

struct PlayState {
  field: PlayField,
  area: FieldArea,
  turn: Mark,
  winner: WinState
}
impl PlayState {
  fn new() -> ~PlayState {
    ~PlayState {
      field: PlayField::new(),
      area: FieldArea {
        x: 100, y: 0, w: 600, h: 600
      },
      turn: X,
      winner: Neither
    }
  }
}
impl GameState for PlayState {
  fn render(&self, renderer: &Renderer) {
    renderer.set_draw_color(RGB(0, 0, 0));
    renderer.clear();

    renderer.set_draw_color(RGB(255, 0, 0));

    for i in range(1, 3) {
      let x1 = self.area.x as i32;
      let y1 = (self.area.y + self.area.cell_height() * i) as i32;
      let x2 = (self.area.x + self.area.w) as i32;
      let y2 = (self.area.y + self.area.cell_height() * i) as i32;
      renderer.draw_line(Point::new(x1, y1), Point::new(x2, y2));
    }
    for i in range(1, 3) {
      let x1 = (self.area.x + self.area.cell_width() * i) as i32;
      let y1 = self.area.y as i32;
      let x2 = (self.area.x + self.area.cell_width() * i) as i32;
      let y2 = (self.area.y + self.area.h) as i32;
      renderer.draw_line(Point::new(x1, y1), Point::new(x2, y2));
    }

    renderer.set_draw_color(RGB(0, 255, 0));

    for row in range(0, 3) {
      for col in range(0, 3) {
        let pt = self.area.project(row, col);

        self.field.get_cell_xy(col as uint, row as uint).map(|mark| {
          match mark {
            Some(X) => draw_x(renderer, pt.x, pt.y, self.area.cell_width() as i32, self.area.cell_height() as i32),
            Some(O) => draw_o(renderer, pt.x, pt.y, self.area.cell_width() as i32, self.area.cell_height() as i32),
            _ => {}
          }
        });
      }
    }
  }

  fn on_mouse_down(&mut self, button: Mouse, x: int, y: int) {
    match self.winner {
      Neither => {},
      _ => {
        self.field = PlayField::new();
        self.winner = Neither;
      }
    }

    match self.area.unproject(x, y) {
      Some((row,col)) => {
        match self.field.get_mut_cell_xy(col as uint, row as uint) {
          Some(r) => match *r {
            None => {
              *r = Some(self.turn);
              self.turn = self.turn.opposite();
            },
            _ => println!("space already occupied")
          },
          None => fail!("invalid coords! this should never happen!")
        }
      },
      None => println!("clicked out of bounds")
    }

    self.winner = self.check_winner();
    match self.winner {
      Win(mark) => {
        println!("{} wins!", mark);
      },
      Draw => {
        println!("draw")
      },
      Neither => {}
    }
  }
}

impl PlayState {
  fn check_winner(&self) -> WinState {
    for line in self.field.lines() {
      match line.is_win() {
        Some(mark) => {
          return Win(mark)
        },
        None => {}
      };
    };

    if self.field.occupied_count() == 9 {
      return Draw
    };

    return Neither
  }
}

fn main() {
  sdl2::init(sdl2::InitVideo);

  // TODO: since we're going to fail! anyways these could be converted to .unwrap()
  let window = match Window::new("Tic Tac Toe: The Rustening", PosCentered, PosCentered, 800, 600, OpenGL) {
    Ok(window) => window,
    Err(err)   => fail!("failed to create window: {}", err)
  };

  let renderer = match Renderer::from_window(window, DriverAuto, Accelerated) {
    Ok(renderer) => renderer,
    Err(err)     => fail!("failed to create renderer: {}", err)
  };

  // TODO: state machine
  let mut state = PlayState::new();

  loop {
    use sdl2::event::poll_event;
    use sdl2::event::{QuitEvent, MouseButtonDownEvent};

    match poll_event() {
      QuitEvent(..) => break,
      MouseButtonDownEvent(_, _, _, button, x, y) => state.on_mouse_down(button, x, y),
      _ => {}
    }

    state.render(renderer);
    renderer.present();
  }

  sdl2::quit();
}
<commit_msg>Rename LineIter to LineIterator for stdlib consistency<commit_after>#![crate_id="TicTacToe#0.1"]

extern crate sdl2;

use sdl2::video::Window;
use sdl2::video::PosCentered;
use sdl2::video::OpenGL;

use sdl2::render::Renderer;
use sdl2::render::DriverAuto;
use sdl2::render::Accelerated;

use sdl2::rect::Point;
use sdl2::pixels::RGB;

use sdl2::mouse::Mouse;

/// Draws a player X mark at a given location.
fn draw_x(r: &Renderer, x: i32, y: i32, w: i32, h: i32) {
  r.draw_line(Point::new(x, y), Point::new(x + w, y + h));
  r.draw_line(Point::new(x + w, y), Point::new(x, y + h));
}

/// Draws a player O mark at a given location.
fn draw_o(r: &Renderer, x: i32, y: i32, w: i32, h: i32) {
  use std::f32::consts::PI;

  let segs = 16;
  let segr: f32 = 2f32 * PI / segs as f32;

  let cx: f32 = x as f32 + w as f32 / 2f32;
  let cy: f32 = y as f32 + h as f32 / 2f32;
  // technically we have to support oval shapes because the field is dynamically sized
  let rx: f32 = w as f32 / 2f32;
  let ry: f32 = h as f32 / 2f32;

  for i in range(0, segs) {
    let a = i as f32;
    let b = a + 1f32;
    let pt1 = Point::new(
      (cx + (a * segr).cos() * rx) as i32,
      (cy + (a * segr).sin() * ry) as i32);
    let pt2 = Point::new(
      (cx + (b * segr).cos() * rx) as i32,
      (cy + (b * segr).sin() * ry) as i32);
    r.draw_line(pt1, pt2);
  }
}

/// Specifies a set of methods that all game states should implement.
trait GameState {
  fn render(&self, r: &Renderer) {
  }

  fn on_mouse_down(&mut self, mouse: Mouse, x: int, y: int) {
  }
}

/// Represents the players in a Tic-tac-toe game.
#[deriving(Clone, Show)]
enum Mark {
  X, O
}

impl Mark {
  /// Returns the opposite mark.
  fn opposite(self) -> Mark {
    match self {
      X => O,
      O => X
    }
  }
}

/// Represents the winner in a game of Tic-tac-toe.
enum WinState {
  Win(Mark),
  Draw,
  Neither
}

/// Stores the board data associated with a game of Tic-tac-toe.
struct PlayField {
  cells: [Option<Mark>, ..9]
}

/// Represents a line of the Tic-tac-toe board. A line consists of three cells.
struct PlayLine {
  cells: [Option<Mark>, ..3]
}

impl PlayLine {
  /// Determines if this line counts as a win. Returns the winner wrapped in an
  /// Option, with None meaning that this line is not a winning one.
  fn is_win(&self) -> Option<Mark> {
    let (xs, os) = self.cells.iter().fold((0, 0), |(xs, os), &place| {
      match place {
        Some(X) => (xs + 1, os),
        Some(O) => (xs, os + 1),
        None    => (xs, os)
      }
    });
    if xs == 3 {
      Some(X)
    } else if os == 3 {
      Some(O)
    } else {
      None
    }
  }
}

enum LineIteratorState {
  Row(uint),
  Column(uint),
  LtrDiagonal,
  RtlDiagonal,
  Finished
}

struct LineIterator<'a> {
  field: &'a PlayField,
  state: LineIteratorState
}

impl<'a> LineIterator<'a> {
  fn from_field<'a>(f: &'a PlayField) -> LineIterator<'a> {
    LineIterator {
      field: f,
      state: Row(0)
    }
  }
}

impl<'a> Iterator<PlayLine> for LineIterator<'a> {
  fn next(&mut self) -> Option<PlayLine> {
    match self.state {
      Row(place) => {
        self.state = if place + 1 < 3 {
          Row(place + 1)
        } else {
          Column(0)
        };
        self.field.horizontal_line(place)
      },
      Column(place) => {
        self.state = if place + 1 < 3 {
          Column(place + 1)
        } else {
          LtrDiagonal
        };
        self.field.vertical_line(place)
      },
      LtrDiagonal => {
        self.state = RtlDiagonal;
        Some(self.field.ltr_diagonal_line())
      },
      RtlDiagonal => {
        self.state = Finished;
        Some(self.field.rtl_diagonal_line())
      },
      Finished => None
    }
  }
}

impl PlayField {
  fn new() -> PlayField {
    PlayField {
      cells: [None, ..9]
    }
  }

  /// Returns the number of occupied cells.
  fn occupied_count(&self) -> int {
    self.cells.iter().fold(0, |s, mark| if mark.is_some() { s + 1 } else { s })
  }

  /// Returns an iterator over the `PlayLine`s in this field.
  fn lines<'a>(&'a self) -> LineIterator<'a> {
    LineIterator::from_field(self)
  }

  fn horizontal_line(&self, row: uint) -> Option<PlayLine> {
    PlayField::map_xy(0, row).map(|ix| PlayLine {
      // there's probably a trick to do this with a slice
      cells: [self.cells[ix], self.cells[ix + 1], self.cells[ix + 2]]
    })
  }

  fn vertical_line(&self, col: uint) -> Option<PlayLine> {
    PlayField::map_xy(col, 0).map(|ix| PlayLine {
      cells: [self.cells[ix], self.cells[ix + 3], self.cells[ix + 6]]
    })
  }

  fn ltr_diagonal_line(&self) -> PlayLine {
    PlayLine {
      cells: [self.cells[0], self.cells[4], self.cells[8]]
    }
  }

  fn rtl_diagonal_line(&self) -> PlayLine {
    PlayLine {
      cells: [self.cells[2], self.cells[4], self.cells[6]]
    }
  }

  fn map_xy(x: uint, y: uint) -> Option<uint> {
    if y < 3 && y < 3 {
      Some(y * 3 + x)
    } else {
      None
    }
  }

  fn get_cell_xy(&self, x: uint, y: uint) -> Option< Option<Mark> > {
    PlayField::map_xy(x, y).map(|ix| self.cells[ix])
  }

  fn get_mut_cell_xy<'a>(&'a mut self, x: uint, y: uint) -> Option< &'a mut Option<Mark> > {
    match PlayField::map_xy(x, y) {
      Some(ix) => Some(&mut self.cells[ix]),
      None     => None
    }
  }
}

/// Represents an on-screen area where a Tic-tac-toe board can be interacted
/// with.
struct FieldArea {
  x: int, y: int,
  w: int, h: int
}

impl FieldArea {
  /// Returns the width of an individual cell.
  fn cell_width(&self) -> int {
    self.w / 3
  }

  /// Returns the height of an individual cell.
  fn cell_height(&self) -> int {
    self.h / 3
  }

  /// Computes the row at a given on-screen Y-coordinate.
  fn unproject_row(&self, y: int) -> Option<int> {
    if y >= self.y {
      match (y - self.y) / self.cell_height() {
        ix if ix > 2 => None,
        ix           => Some(ix)
      }
    } else {
      None
    }
  }

  /// Computes the column at a given on-screen X-coordinate.
  fn unproject_col(&self, x: int) -> Option<int> {
    if x >= self.x {
      match (x - self.x) / self.cell_width() {
        ix if ix > 2 => None,
        ix           => Some(ix)
      }
    } else {
      None
    }
  }

  /// Computes the given row and column given on-screen X and Y coordinates.
  fn unproject(&self, x: int, y: int) -> Option<(int, int)> {
    let row = match self.unproject_row(y) {
      Some(row) => row,
      None      => return None
    };
    let col = match self.unproject_col(x) {
      Some(col) => col,
      None      => return None
    };
    Some((row, col))
  }

  /// Computes the on-screen X and Y coordinates for a given row and column.
  fn project(&self, row: int, col: int) -> Point {
    let x = (self.x + col * self.cell_width()) as i32;
    let y = (self.y + row * self.cell_height()) as i32;
    Point::new(x, y)
  }
}

struct PlayState {
  field: PlayField,
  area: FieldArea,
  turn: Mark,
  winner: WinState
}
impl PlayState {
  fn new() -> ~PlayState {
    ~PlayState {
      field: PlayField::new(),
      area: FieldArea {
        x: 100, y: 0, w: 600, h: 600
      },
      turn: X,
      winner: Neither
    }
  }
}
impl GameState for PlayState {
  fn render(&self, renderer: &Renderer) {
    renderer.set_draw_color(RGB(0, 0, 0));
    renderer.clear();

    renderer.set_draw_color(RGB(255, 0, 0));

    for i in range(1, 3) {
      let x1 = self.area.x as i32;
      let y1 = (self.area.y + self.area.cell_height() * i) as i32;
      let x2 = (self.area.x + self.area.w) as i32;
      let y2 = (self.area.y + self.area.cell_height() * i) as i32;
      renderer.draw_line(Point::new(x1, y1), Point::new(x2, y2));
    }
    for i in range(1, 3) {
      let x1 = (self.area.x + self.area.cell_width() * i) as i32;
      let y1 = self.area.y as i32;
      let x2 = (self.area.x + self.area.cell_width() * i) as i32;
      let y2 = (self.area.y + self.area.h) as i32;
      renderer.draw_line(Point::new(x1, y1), Point::new(x2, y2));
    }

    renderer.set_draw_color(RGB(0, 255, 0));

    for row in range(0, 3) {
      for col in range(0, 3) {
        let pt = self.area.project(row, col);

        self.field.get_cell_xy(col as uint, row as uint).map(|mark| {
          match mark {
            Some(X) => draw_x(renderer, pt.x, pt.y, self.area.cell_width() as i32, self.area.cell_height() as i32),
            Some(O) => draw_o(renderer, pt.x, pt.y, self.area.cell_width() as i32, self.area.cell_height() as i32),
            _ => {}
          }
        });
      }
    }
  }

  fn on_mouse_down(&mut self, button: Mouse, x: int, y: int) {
    match self.winner {
      Neither => {},
      _ => {
        self.field = PlayField::new();
        self.winner = Neither;
      }
    }

    match self.area.unproject(x, y) {
      Some((row,col)) => {
        match self.field.get_mut_cell_xy(col as uint, row as uint) {
          Some(r) => match *r {
            None => {
              *r = Some(self.turn);
              self.turn = self.turn.opposite();
            },
            _ => println!("space already occupied")
          },
          None => fail!("invalid coords! this should never happen!")
        }
      },
      None => println!("clicked out of bounds")
    }

    self.winner = self.check_winner();
    match self.winner {
      Win(mark) => {
        println!("{} wins!", mark);
      },
      Draw => {
        println!("draw")
      },
      Neither => {}
    }
  }
}

impl PlayState {
  fn check_winner(&self) -> WinState {
    for line in self.field.lines() {
      match line.is_win() {
        Some(mark) => {
          return Win(mark)
        },
        None => {}
      };
    };

    if self.field.occupied_count() == 9 {
      return Draw
    };

    return Neither
  }
}

fn main() {
  sdl2::init(sdl2::InitVideo);

  // TODO: since we're going to fail! anyways these could be converted to .unwrap()
  let window = match Window::new("Tic Tac Toe: The Rustening", PosCentered, PosCentered, 800, 600, OpenGL) {
    Ok(window) => window,
    Err(err)   => fail!("failed to create window: {}", err)
  };

  let renderer = match Renderer::from_window(window, DriverAuto, Accelerated) {
    Ok(renderer) => renderer,
    Err(err)     => fail!("failed to create renderer: {}", err)
  };

  // TODO: state machine
  let mut state = PlayState::new();

  loop {
    use sdl2::event::poll_event;
    use sdl2::event::{QuitEvent, MouseButtonDownEvent};

    match poll_event() {
      QuitEvent(..) => break,
      MouseButtonDownEvent(_, _, _, button, x, y) => state.on_mouse_down(button, x, y),
      _ => {}
    }

    state.render(renderer);
    renderer.present();
  }

  sdl2::quit();
}
<|endoftext|>


<commit_before>
mod stdout_writer;

extern crate clap;
extern crate xor_utils;
extern crate hex;
extern crate base64;

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

use log::LogLevel;
use clap::{App, Arg, ArgMatches};
use std::io;
use std::io::{Cursor};
use std::fs;
use std::path::Path;
use std::fs::{File, OpenOptions, DirEntry};
use std::io::{Write, Read};
use xor_utils::Xor;
use xor_utils::*;
use hex::{ToHex};

fn main() {
    env_logger::init().unwrap();

    // Parse arguments and provide help.
    let matches = App::new("xor")
        .version("1.3.0")
        .about("XORs input against a provided key")
        .author("Gavyn Riebau")
        .arg(Arg::with_name("key")
             .help("The file containing the key data, or a provided string, against which input will be XOR'd. This should be larger than the given input data or will need to be repeated to encode the input data.")
             .long("key")
             .short("k")
             .required(true)
             .value_name("KEY"))
        .arg(Arg::with_name("input")
             .help("The file / directory from which input data will be read, if omitted input will be read from stdin.\nIf a directory is specified, all files inside the directory will be encryted.")
             .long("input")
             .short("i")
             .required(false)
             .value_name("FILE"))
        .arg(Arg::with_name("recursive")
             .help("Recursively encrypt files and subfolders starting at the given directory")
             .long("recursive")
             .short("r")
             .conflicts_with("output")
             .value_name("DIRECTORY"))
        .arg(Arg::with_name("output")
             .help("The file to which encoded data will be written, if omitted output will be written to stdout.\nIt's recommended to write output to a file for cases where the encoded data contains non-unicode characters.")
             .long("output")
             .short("o")
             .required(false)
             .value_name("FILE"))
        .arg(Arg::with_name("verbose")
             .help("Increases the level of feedback given")
             .long("verbose")
             .short("v")
             .required(false))
         .get_matches();

    let key_bytes = get_key_bytes(&matches);

    if matches.is_present("recursive") {
        // Recursively encrypt files and folders in the specified directory.
        let starting_dir_name = matches.value_of("recursive").unwrap();
        let starting_dir = Path::new(starting_dir_name);

        encrypt_path(starting_dir, &key_bytes);
    } else {
        // If the "file" argument was supplied input will be read from the file, otherwise
        // input is read from stdin.
        let input : Box<Read> = if matches.is_present("input") {
            Box::new(File::open(matches.value_of("input").unwrap()).unwrap())
        } else {
            Box::new(io::stdin())
        };

        // If "output" argument was supplied output will be written to a file, otherwise
        // it's written to stdout.
        let output : Box<Write> = if matches.is_present("output") {
            Box::new(OpenOptions::new()
                .write(true)
                .create(true)
                .truncate(true)
                .open(matches.value_of("output").unwrap())
                .unwrap())
        } else {
            Box::new(stdout_writer::StdoutWriter{})
        };

        encrypt_reader(input, &key_bytes, output);
    }
}

fn encrypt_reader(mut input : Box<Read>, key : &Vec<u8>, mut output : Box<Write>) {
    let encoded_bytes = input.by_ref().xor(&key);
    let _ = output.write_all(encoded_bytes.as_slice());
    output.flush().unwrap();
}

fn encrypt_path(p : &Path, key : &Vec<u8>) {
    for item in fs::read_dir(p).unwrap() {
        let entry = item.unwrap();
        xor_entry(&entry, key);
    }
}

fn xor_entry(entry : &DirEntry, key : &Vec<u8>) {
    if let Ok(entry_type) = entry.file_type() {
        if entry_type.is_dir() {
            xor_dir(entry, key);
        } else if entry_type.is_file() {
            xor_file(entry, key);
        } else if entry_type.is_symlink() {
            xor_symlink(entry, key);
        }
    }
}

fn xor_file(entry : &DirEntry, key : &Vec<u8>) {
    info!("Encrypting file {:?}", entry);

    if let Ok(mut file) = File::open(entry.path()) {
        let mut reader = &mut file as &mut Read;
        let cypher_text = reader.xor(&key);

        let mut writer = OpenOptions::new()
            .write(true)
            .truncate(true)
            .open(entry.path())
            .unwrap();

        writer.write_all(cypher_text.as_slice()).unwrap();
    }

    //rename_entry(entry, key);
}

fn xor_symlink(entry : &DirEntry, key : &Vec<u8>) {
    info!("Encrypting symlink {:?}", entry);

    rename_entry(entry, key);
}

fn xor_dir(entry : &DirEntry, key : &Vec<u8>) {
    info!("Encrypting dir {:?}", entry);

    match fs::read_dir(entry.path()) {
        Ok(entries) => {
            for child in entries {
                if let Ok(child) = child {
                    xor_entry(&child, key);
                }
            }
        },
        Err(e) => {
            let mut stderr = io::stderr();
            let _ = stderr.write_fmt(format_args!("Failed to read directory: {}", e));
        }
    }

    rename_entry(entry, key);
}

fn rename_entry(entry : &DirEntry, key : &Vec<u8>) {
    // Encrypt the directory entry itself.
    let file_name = entry.file_name();

    if let Some(original_name) = file_name.to_str() {
        debug!("original_name: {}", original_name);

        let mut key_repeated = repeat_key(key, original_name.len());
        let mut encrypted = Vec::with_capacity(original_name.len());
        for (d, k) in original_name.as_bytes().iter().zip(key_repeated) {
            encrypted.push(d ^ k);
        }

        let encrypted_name = to_hex_string(encrypted);
        debug!("encrypted_name: {}", encrypted_name);

        let full_path_buf = entry.path();
        let full_path = full_path_buf.as_path();
        let parent_path = full_path.parent().unwrap();

        let src_file_path_buf = parent_path.join(original_name);
        let dst_file_path_buf = parent_path.join(encrypted_name);

        let src_file_path = src_file_path_buf.as_path();
        let dst_file_path = dst_file_path_buf.as_path();

        debug!("Moving {:?} to {:?}", src_file_path, dst_file_path);
        fs::rename(src_file_path, dst_file_path).unwrap();
    }
}

/// Create a vector of bytes equal in length to the name of the file.
/// If the key is too small it'll be repeated to make up the required length.
fn repeat_key(key : &Vec<u8>, required_len : usize) -> Vec<u8> {
    let mut key_repeated = Vec::with_capacity(required_len);

    while key_repeated.len() < required_len {
        for &b in key {
            key_repeated.push(b);

            if key_repeated.len() == required_len {
                break;
            }
        }
    }

    key_repeated
}

fn to_hex_string(bytes: Vec<u8>) -> String {

  let strings: Vec<String> = bytes.iter()
                               .map(|b| format!("{:02X}", b))
                               .collect();

  strings.join("")
}

fn get_key_bytes<'a>(matches: &'a ArgMatches<'a>) -> Vec<u8> {
    let mut key_bytes : Vec<u8> = Vec::new();

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

    // If the key is a file, read the contents of the file.
    // Otherwise if key is a string, use the string bytes.
    if Path::new(key).exists() {
        File::open(key).unwrap().read_to_end(&mut key_bytes).unwrap();
    } else {
        key_bytes = key.to_string().into_bytes();
    }

    key_bytes
}

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

    #[test]
    fn to_hex_string_works() {
        let input_string = String::from("hello");
        let input_bytes = input_string.into_bytes();

        let hex_string = to_hex_string(input_bytes);
        assert_eq!(hex_string, "68656C6C6F");
    }

}

<commit_msg>Working rename files and directories for recursive encrypt<commit_after>
mod stdout_writer;

extern crate clap;
extern crate xor_utils;
extern crate hex;
extern crate base64;

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

use log::LogLevel;
use clap::{App, Arg, ArgMatches};
use std::io;
use std::io::{Cursor};
use std::fs;
use std::path::Path;
use std::fs::{File, OpenOptions, DirEntry};
use std::io::{Write, Read};
use xor_utils::Xor;
use xor_utils::*;
use hex::{ToHex, FromHex};

enum Mode {
    Encrypt,
    Decrypt
}

fn main() {
    env_logger::init().unwrap();

    // Parse arguments and provide help.
    let matches = App::new("xor")
        .version("1.3.0")
        .about("XORs input against a provided key")
        .author("Gavyn Riebau")
        .arg(Arg::with_name("key")
             .help("The file containing the key data, or a provided string, against which input will be XOR'd.\nThis should be larger than the given input data or will need to be repeated to encode the input data.")
             .long("key")
             .short("k")
             .required(true)
             .value_name("KEY"))
        .arg(Arg::with_name("force")
             .help("Don't show warning prompt if the key size is too small and key bytes will have to be re-used.\nRe-using key bytes makes the encryption vulnerable to being decrypted.")
             .long("force")
             .short("f"))
        .arg(Arg::with_name("mode")
             .help("The operating mode (i.e. whether encrypting or decrypting).\nOnly applicable when encrypting directories and affects how the file will be renamed.\nWhen in encrypt mode, names are xor'd then converted to hex strings.\nWhen in decrypt mode, names are parsed from hex strings then xor'd to restore the original name.")
             .long("mode")
             .short("m")
             .possible_values(&["e", "d"])
             .default_value("e"))
        .arg(Arg::with_name("input")
             .help("The file from which input data will be read, if omitted input will be read from stdin.")
             .long("input")
             .short("i")
             .required(false)
             .value_name("FILE"))
        .arg(Arg::with_name("recursive")
             .help("Recursively encrypt / decrypt files and subfolders starting at the given directory.\nFiles and directory names will be encrypted / decrypted according to the \"mode\" argument.\nNames are xor encrypted then converted to a hex string.")
             .long("recursive")
             .short("r")
             .conflicts_with("output")
             .value_name("DIRECTORY")
             .conflicts_with("input")
             .conflicts_with("output"))
        .arg(Arg::with_name("output")
             .help("The file to which encoded data will be written, if omitted output will be written to stdout.\nIt's recommended to write output to a file for cases where the encoded data contains non-unicode characters which would otherwise not be printed to the console.")
             .long("output")
             .short("o")
             .required(false)
             .value_name("FILE"))
        .arg(Arg::with_name("verbose")
             .help("Increases the level of feedback given")
             .long("verbose")
             .short("v")
             .required(false))
         .get_matches();

    let mode = match matches.value_of("mode").unwrap() {
        "e" => Mode::Encrypt,
        "d" => Mode::Decrypt,
        _ => Mode::Encrypt
    };

    let key_bytes = get_key_bytes(&matches);

    if matches.is_present("recursive") {
        // Recursively encrypt files and folders in the specified directory.
        let starting_dir_name = matches.value_of("recursive").unwrap();
        let starting_dir = Path::new(starting_dir_name);

        encrypt_path(starting_dir, &key_bytes, &mode);
    } else {
        // If the "file" argument was supplied input will be read from the file, otherwise
        // input is read from stdin.
        let input : Box<Read> = if matches.is_present("input") {
            Box::new(File::open(matches.value_of("input").unwrap()).unwrap())
        } else {
            Box::new(io::stdin())
        };

        // If "output" argument was supplied output will be written to a file, otherwise
        // it's written to stdout.
        let output : Box<Write> = if matches.is_present("output") {
            Box::new(OpenOptions::new()
                .write(true)
                .create(true)
                .truncate(true)
                .open(matches.value_of("output").unwrap())
                .unwrap())
        } else {
            Box::new(stdout_writer::StdoutWriter{})
        };

        encrypt_reader(input, &key_bytes, output);
    }
}

fn encrypt_reader(mut input : Box<Read>, key : &Vec<u8>, mut output : Box<Write>) {
    let encoded_bytes = input.by_ref().xor(&key);
    let _ = output.write_all(encoded_bytes.as_slice());
    output.flush().unwrap();
}

fn encrypt_path(p : &Path, key : &Vec<u8>, mode : &Mode) {
    for item in fs::read_dir(p).unwrap() {
        let entry = item.unwrap();
        xor_entry(&entry, key, mode);
    }
}

fn xor_entry(entry : &DirEntry, key : &Vec<u8>, mode : &Mode) {
    if let Ok(entry_type) = entry.file_type() {
        if entry_type.is_dir() {
            xor_dir(entry, key, mode);
        } else if entry_type.is_file() {
            xor_file(entry, key, mode);
        } else if entry_type.is_symlink() {
            xor_symlink(entry, key, mode);
        }
    }
}

fn xor_file(entry : &DirEntry, key : &Vec<u8>, mode : &Mode) {
    info!("Encrypting file {:?}", entry);

    if let Ok(mut file) = File::open(entry.path()) {
        let mut reader = &mut file as &mut Read;
        let cypher_text = reader.xor(&key);

        let mut writer = OpenOptions::new()
            .write(true)
            .truncate(true)
            .open(entry.path())
            .unwrap();

        writer.write_all(cypher_text.as_slice()).unwrap();
    }

    rename_entry(entry, key, mode);
}

fn xor_symlink(entry : &DirEntry, key : &Vec<u8>, mode : &Mode) {
    info!("Encrypting symlink {:?}", entry);

    rename_entry(entry, key, mode);
}

fn xor_dir(entry : &DirEntry, key : &Vec<u8>, mode : &Mode) {
    info!("Encrypting dir {:?}", entry);

    match fs::read_dir(entry.path()) {
        Ok(entries) => {
            for child in entries {
                if let Ok(child) = child {
                    xor_entry(&child, key, mode);
                }
            }
        },
        Err(e) => {
            let mut stderr = io::stderr();
            let _ = stderr.write_fmt(format_args!("Failed to read directory: {}", e));
        }
    }

    rename_entry(entry, key, mode);
}

fn rename_entry(entry : &DirEntry, key : &Vec<u8>, mode : &Mode) {
    // Encrypt the directory entry itself.
    let file_name = entry.file_name();

    if let Some(original_name) = file_name.to_str() {
        debug!("original_name: {}", original_name);

        let mut key_repeated = repeat_key(key, original_name.len());

        let input_bytes = match *mode {
            Mode::Encrypt => original_name.to_string().into_bytes(),
            Mode::Decrypt => from_hex_string(String::from(original_name))
        };

        let mut encrypted = Vec::with_capacity(input_bytes.len());
        for (d, k) in input_bytes.iter().zip(key_repeated) {
            encrypted.push(d ^ k);
        }

        let replaced_name = match *mode {
            Mode::Encrypt => to_hex_string(encrypted),
            Mode::Decrypt => String::from_utf8(encrypted).unwrap()
        };
        debug!("replaced_name: {}", replaced_name);

        let full_path_buf = entry.path();
        let full_path = full_path_buf.as_path();
        let parent_path = full_path.parent().unwrap();

        let src_file_path_buf = parent_path.join(original_name);
        let dst_file_path_buf = parent_path.join(replaced_name);

        let src_file_path = src_file_path_buf.as_path();
        let dst_file_path = dst_file_path_buf.as_path();

        debug!("Moving {:?} to {:?}", src_file_path, dst_file_path);
        fs::rename(src_file_path, dst_file_path).unwrap();
    }
}

/// Create a vector of bytes equal in length to the name of the file.
/// If the key is too small it'll be repeated to make up the required length.
fn repeat_key(key : &Vec<u8>, required_len : usize) -> Vec<u8> {
    let mut key_repeated = Vec::with_capacity(required_len);

    while key_repeated.len() < required_len {
        for &b in key {
            key_repeated.push(b);

            if key_repeated.len() == required_len {
                break;
            }
        }
    }

    key_repeated
}

fn to_hex_string(bytes: Vec<u8>) -> String {
  let strings: Vec<String> = bytes.iter()
                               .map(|b| format!("{:02X}", b))
                               .collect();

  strings.join("")
}

fn from_hex_string(hex : String) -> Vec<u8> {
    hex::FromHex::from_hex(hex).unwrap()
}

fn get_key_bytes<'a>(matches: &'a ArgMatches<'a>) -> Vec<u8> {
    let mut key_bytes : Vec<u8> = Vec::new();

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

    // If the key is a file, read the contents of the file.
    // Otherwise if key is a string, use the string bytes.
    if Path::new(key).exists() {
        File::open(key).unwrap().read_to_end(&mut key_bytes).unwrap();
    } else {
        key_bytes = key.to_string().into_bytes();
    }

    key_bytes
}

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

    #[test]
    fn to_hex_string_works() {
        let input_string = String::from("hello");
        let input_bytes = input_string.into_bytes();

        let hex_string = to_hex_string(input_bytes);
        assert_eq!(hex_string, "68656C6C6F");
    }

    #[test]
    fn from_hex_string_works() {
        let input_string = String::from("68656C6C6F");
        let ascii_bytes = from_hex_string(input_string);
        let expected_bytes = vec![104, 101, 108, 108, 111];

        assert_eq!(expected_bytes, ascii_bytes);
    }

}

<|endoftext|>


<commit_before>#![feature(old_path)]
#![feature(io)]

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

fn main() {

    // get the arguments
    let arguments: Vec<String> = env::args().collect();

    // csv file path
    let path_string: String = arguments[1].clone();
    let csv_path: Path = Path::new(path_string);

    // let's open an csv file
    let mut csv_file = match File::open(&csv_path) {
        Err(why)     => panic!("error openning csv file: {}", why.description()),
        Ok(csv_file) => csv_file,
    };

    // reader
    let mut csv_reader = BufReader::new(csv_file);
    let mut line_buffer: String = String::new();

    loop {
        match csv_reader.read_line(&mut line_buffer) {
            Err(why) => panic!("error reading from file: {}", why.description()),
            Ok(lines_read) =>   {
                                  println!("file has been read, lines read = {:?}", lines_read);
                                }
        };
        println!("{}", line_buffer);
    };
}
<commit_msg>Write down the algorithm(this algorithm is similar to one I used before to compare two CSV files)<commit_after>use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::str::FromStr;

fn main() {

/*

1. Parse arguments
2. Open CSV files
3. Get columns (cols_N)
4. Get intersection of those two sets of columns(cols_to_compare)
5. Create {column name : column index in cols_N} dicts
6. Create {CSV_col_value : CSV row index in file} dicts, where CSV_col_value is a unique key made of the value of several CSV columns.
   For example, {Alex38 : 76}. In this example a name and age form a unique key for the 76th CSV row.
7. Get intersection of key sets of dicts from step 6 (row_keys_to_compare)
8. Loop through row_keys_to_compare, use dicts from step 6 to get line numbers for CSV files
    8.1 Loop through cols_to_compare, use dicts from step 5 to extract column values from CSV rows(step 8)
    8.2 Compare values

Input parameters: CSV paths, delimiters, quotes

For example, ./main file_1.csv "," "'" file_2.csv " " ""

*/

}
<|endoftext|>


<commit_before>extern crate time;

use std::cmp;
use std::mem;
use std::f64;

type StreamType = f64;

const HLINE: &'static str = "-------------------------------------------------------------\n";
const STREAM_ARRAY_SIZE: usize = 10000000;
const NTIMES: usize = 10;
const M: usize = 10;

static mut A: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];
static mut B: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];
static mut C: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];

fn main() {
    /* --- SETUP --- determine precision and check timing --- */
    println!("{}", HLINE);
    println!("STREAM version $Revision: 5.10 $");
    println!("{}", HLINE);
    let bytes_per_word = mem::size_of::<StreamType>();
    println!("This system uses {} bytes per array element.", bytes_per_word);

    println!("{}", HLINE);

    println!("Array size = {} (elements)", STREAM_ARRAY_SIZE);
    println!("Memory per array = {:.1} MiB (= {:.1} GiB).",
             bytes_per_word as f64 * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0),
             bytes_per_word as f64 * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0 / 1024.0));
    println!("Total memory required = {:.1} MiB (= {:.1} GiB).",
            (3.0 * bytes_per_word as f64) * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0),
            (3.0 * bytes_per_word as f64) * (STREAM_ARRAY_SIZE as f64 / 1024.0/1024./1024.0));
    println!("Each kernel will be executed {} times.", NTIMES);
    println!(" The *best* time for each kernel (excluding the first iteration)");
    println!(" will be used to compute the reported bandwidth.");

	println!("{}", HLINE);

    unsafe {
        for i in 0..STREAM_ARRAY_SIZE {
            A[i] = 1.0;
            B[i] = 2.0;
            C[i] = 0.0;
        }
    }

    let mut quantum = check_tick();
    if  quantum >= 1 {
        println!("Your clock granularity/precision appears to be {} microseconds.", quantum);
    } else {
	    println!("Your clock granularity appears to be less than one microsecond.");
	    quantum = 1;
    }

    let mut t = time::precise_time_s();
    unsafe {
        for i in 0..STREAM_ARRAY_SIZE {
            A[i] = 2.0 * A[i];
        }
    }
    t = 1.0E6 * (time::precise_time_s() - t);

    println!("Each test below will take on the order of {} microseconds.", t as i32);
    println!("   (= {} clock ticks)", (t / quantum as f64) as i32);
    println!("Increase the size of the arrays if this shows that");
    println!("you are not getting at least 20 clock ticks per test.");

    println!("{}", HLINE);

    println!("WARNING -- The above is only a rough guideline.");
    println!("For best results, please be sure you know the");
    println!("precision of your system timer.");
    println!("{}", HLINE);

    let mut times: [[f64; NTIMES]; 4] = [[0.0; NTIMES]; 4];

    /*	--- MAIN LOOP --- repeat test cases NTIMES times --- */

    let scalar:StreamType = 3.0;
    for k in 0..NTIMES {
        times[0][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                C[j] = A[j];
            }
        }
        times[0][k] = time::precise_time_s() - times[0][k];

        times[1][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                B[j] = scalar * C[j];
            }
        }
        times[1][k] = time::precise_time_s() - times[1][k];

        times[2][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                C[j] = A[j] + B[j];
            }
        }
        times[2][k] = time::precise_time_s() - times[2][k];

        times[3][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                A[j] = B[j] + scalar * C[j];
            }
        }
        times[3][k] = time::precise_time_s() - times[3][k];
    }

    let mut avg_time: [f64; 4] = [0.0; 4];
    let mut max_time: [f64; 4] = [0.0; 4];
    let mut min_time: [f64; 4] = [f64::MAX, f64::MAX, f64::MAX, f64::MAX];

    let label: [&'static str; 4] = ["Copy:      ", "Scale:     ",  "Add:       ", "Triad:     "];
    let bytes: [usize; 4] = [
        2 * bytes_per_word * STREAM_ARRAY_SIZE ,
        2 * bytes_per_word * STREAM_ARRAY_SIZE ,
        3 * bytes_per_word * STREAM_ARRAY_SIZE ,
        3 * bytes_per_word * STREAM_ARRAY_SIZE
    ];

    /*	--- SUMMARY --- */

    for k in 1..NTIMES /* note -- skip first iteration */
    {
        for j in 0..4
        {
            avg_time[j] = avg_time[j] + times[j][k];
            if min_time[j] > times[j][k] {
                min_time[j] = times[j][k];
            }
            if max_time[j] < times[j][k] {
                max_time[j] = times[j][k];
            }
        }
    }

    println!("Function    Best Rate MB/s  Avg time     Min time     Max time");
    for j in 0..4 {
        avg_time[j] = avg_time[j] / (NTIMES-1) as f64;

        println!("{}{:12.1}  {:11.6}  {:11.6}  {:11.6}", label[j],
            1.0E-06 * bytes[j] as f64 / min_time[j],
            avg_time[j],
            min_time[j],
            max_time[j]);
    }
    println!("{}", HLINE);

    check_stream_results();
    println!("{}", HLINE);
}

fn check_tick() -> i32 {
    let mut times_found: [f64; M] = [0.0; M];

    for i in 0..M {
        let t1 = time::precise_time_s();

        loop {
            let t2 = time::precise_time_s();
            if (t2 - t1) >= 1.0E-6 {
                times_found[i] = t2;
                break;
            }
        }
    }

    let mut min_delta = 1000000;
    for i in 1..M {
        let delta = (1.0E6 * (times_found[i] - times_found[i-1])) as i32;
        min_delta = cmp::min(min_delta, cmp::max(delta, 0));
    }

    min_delta

}

fn check_stream_results() {
    /* reproduce initialization */
    let mut aj: StreamType = 1.0;
    let mut bj: StreamType = 2.0;
    let mut cj: StreamType = 0.0;
    /* a[] is modified during timing check */
    aj = 2.0E0 * aj;
    /* now execute timing loop */
    let scalar: StreamType = 3.0;
    for _ in 0..NTIMES {
        cj = aj;
        bj = scalar * cj;
        cj = aj + bj;
        aj = bj + scalar * cj;
    }

    /* accumulate deltas between observed and expected results */
    let mut a_sum_err: StreamType = 0.0;
    let mut b_sum_err: StreamType = 0.0;
    let mut c_sum_err: StreamType = 0.0;
    for j in 0..STREAM_ARRAY_SIZE {
        unsafe {
            a_sum_err += (A[j] - aj).abs();
            b_sum_err += (B[j] - bj).abs();
            c_sum_err += (C[j] - cj).abs();
        }
    }
    let a_avg_err = a_sum_err / STREAM_ARRAY_SIZE as f64;
    let b_avg_err = b_sum_err / STREAM_ARRAY_SIZE as f64;
    let c_avg_err = c_sum_err / STREAM_ARRAY_SIZE as f64;

    let epsilon = 1.0E-13;

    let mut err = 0;
    let mut ierr = 0;

    if (a_avg_err / aj).abs() > epsilon {
        err = err + 1;
        println!("Failed Validation on array a[], AvgRelAbsErr > epsilon ({})", epsilon);
        println!("     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",aj, a_avg_err, a_avg_err.abs()/aj);
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (A[j] / aj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array a[], {} errors were found.", ierr);
    }

    if (b_avg_err / bj).abs() > epsilon {
        err = err + 1;
        println!("Failed Validation on array b[], AvgRelAbsErr > epsilon ({})", epsilon);
        println! ("     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",bj, b_avg_err, b_avg_err.abs()/bj);
        println! ("     AvgRelAbsErr > Epsilon {}", epsilon);
        ierr = 0;
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (B[j]/ bj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array b[], {} errors were found.", ierr);
    }

    if (c_avg_err / cj).abs() > epsilon {
        err = err + 1;
        println! ("Failed Validation on array c[], AvgRelAbsErr > epsilon ({})", epsilon);
        println! ("     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",cj, c_avg_err, c_avg_err.abs() / cj);
        println! ("     AvgRelAbsErr > Epsilon ({})",epsilon);
        ierr = 0;
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (C[j] / cj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array c[], {} errors were found.", ierr);
    }

    if err == 0 {
        println! ("Solution Validates: avg error less than {:e} on all three arrays", epsilon);
    }

}

<commit_msg>Format code.<commit_after>extern crate time;

use std::cmp;
use std::mem;
use std::f64;

type StreamType = f64;

const HLINE: &'static str = "-------------------------------------------------------------\n";
const STREAM_ARRAY_SIZE: usize = 10000000;
const NTIMES: usize = 10;
const M: usize = 10;

static mut A: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];
static mut B: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];
static mut C: [StreamType; STREAM_ARRAY_SIZE] = [0.0; STREAM_ARRAY_SIZE];

fn main() {
    /* --- SETUP --- determine precision and check timing --- */
    println!("{}", HLINE);
    println!("STREAM version $Revision: 5.10 $");
    println!("{}", HLINE);
    let bytes_per_word = mem::size_of::<StreamType>();
    println!(
        "This system uses {} bytes per array element.",
        bytes_per_word
    );

    println!("{}", HLINE);

    println!("Array size = {} (elements)", STREAM_ARRAY_SIZE);
    println!(
        "Memory per array = {:.1} MiB (= {:.1} GiB).",
        bytes_per_word as f64 * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0),
        bytes_per_word as f64 * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0 / 1024.0)
    );
    println!(
        "Total memory required = {:.1} MiB (= {:.1} GiB).",
        (3.0 * bytes_per_word as f64) * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024.0),
        (3.0 * bytes_per_word as f64) * (STREAM_ARRAY_SIZE as f64 / 1024.0 / 1024. / 1024.0)
    );
    println!("Each kernel will be executed {} times.", NTIMES);
    println!(" The *best* time for each kernel (excluding the first iteration)");
    println!(" will be used to compute the reported bandwidth.");

    println!("{}", HLINE);

    unsafe {
        for i in 0..STREAM_ARRAY_SIZE {
            A[i] = 1.0;
            B[i] = 2.0;
            C[i] = 0.0;
        }
    }

    let mut quantum = check_tick();
    if quantum >= 1 {
        println!(
            "Your clock granularity/precision appears to be {} microseconds.",
            quantum
        );
    } else {
        println!("Your clock granularity appears to be less than one microsecond.");
        quantum = 1;
    }

    let mut t = time::precise_time_s();
    unsafe {
        for i in 0..STREAM_ARRAY_SIZE {
            A[i] = 2.0 * A[i];
        }
    }
    t = 1.0E6 * (time::precise_time_s() - t);

    println!(
        "Each test below will take on the order of {} microseconds.",
        t as i32
    );
    println!("   (= {} clock ticks)", (t / quantum as f64) as i32);
    println!("Increase the size of the arrays if this shows that");
    println!("you are not getting at least 20 clock ticks per test.");

    println!("{}", HLINE);

    println!("WARNING -- The above is only a rough guideline.");
    println!("For best results, please be sure you know the");
    println!("precision of your system timer.");
    println!("{}", HLINE);

    let mut times: [[f64; NTIMES]; 4] = [[0.0; NTIMES]; 4];

    /*	--- MAIN LOOP --- repeat test cases NTIMES times --- */

    let scalar: StreamType = 3.0;
    for k in 0..NTIMES {
        times[0][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                C[j] = A[j];
            }
        }
        times[0][k] = time::precise_time_s() - times[0][k];

        times[1][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                B[j] = scalar * C[j];
            }
        }
        times[1][k] = time::precise_time_s() - times[1][k];

        times[2][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                C[j] = A[j] + B[j];
            }
        }
        times[2][k] = time::precise_time_s() - times[2][k];

        times[3][k] = time::precise_time_s();
        unsafe {
            for j in 0..STREAM_ARRAY_SIZE {
                A[j] = B[j] + scalar * C[j];
            }
        }
        times[3][k] = time::precise_time_s() - times[3][k];
    }

    let mut avg_time: [f64; 4] = [0.0; 4];
    let mut max_time: [f64; 4] = [0.0; 4];
    let mut min_time: [f64; 4] = [f64::MAX, f64::MAX, f64::MAX, f64::MAX];

    let label: [&'static str; 4] = ["Copy:      ", "Scale:     ", "Add:       ", "Triad:     "];
    let bytes: [usize; 4] = [
        2 * bytes_per_word * STREAM_ARRAY_SIZE,
        2 * bytes_per_word * STREAM_ARRAY_SIZE,
        3 * bytes_per_word * STREAM_ARRAY_SIZE,
        3 * bytes_per_word * STREAM_ARRAY_SIZE,
    ];

    /*	--- SUMMARY --- */

    for k in 1..NTIMES
    /* note -- skip first iteration */
    {
        for j in 0..4 {
            avg_time[j] = avg_time[j] + times[j][k];
            if min_time[j] > times[j][k] {
                min_time[j] = times[j][k];
            }
            if max_time[j] < times[j][k] {
                max_time[j] = times[j][k];
            }
        }
    }

    println!("Function    Best Rate MB/s  Avg time     Min time     Max time");
    for j in 0..4 {
        avg_time[j] = avg_time[j] / (NTIMES - 1) as f64;

        println!(
            "{}{:12.1}  {:11.6}  {:11.6}  {:11.6}",
            label[j],
            1.0E-06 * bytes[j] as f64 / min_time[j],
            avg_time[j],
            min_time[j],
            max_time[j]
        );
    }
    println!("{}", HLINE);

    check_stream_results();
    println!("{}", HLINE);
}

fn check_tick() -> i32 {
    let mut times_found: [f64; M] = [0.0; M];

    for i in 0..M {
        let t1 = time::precise_time_s();

        loop {
            let t2 = time::precise_time_s();
            if (t2 - t1) >= 1.0E-6 {
                times_found[i] = t2;
                break;
            }
        }
    }

    let mut min_delta = 1000000;
    for i in 1..M {
        let delta = (1.0E6 * (times_found[i] - times_found[i - 1])) as i32;
        min_delta = cmp::min(min_delta, cmp::max(delta, 0));
    }

    min_delta

}

fn check_stream_results() {
    /* reproduce initialization */
    let mut aj: StreamType = 1.0;
    let mut bj: StreamType = 2.0;
    let mut cj: StreamType = 0.0;
    /* a[] is modified during timing check */
    aj = 2.0E0 * aj;
    /* now execute timing loop */
    let scalar: StreamType = 3.0;
    for _ in 0..NTIMES {
        cj = aj;
        bj = scalar * cj;
        cj = aj + bj;
        aj = bj + scalar * cj;
    }

    /* accumulate deltas between observed and expected results */
    let mut a_sum_err: StreamType = 0.0;
    let mut b_sum_err: StreamType = 0.0;
    let mut c_sum_err: StreamType = 0.0;
    for j in 0..STREAM_ARRAY_SIZE {
        unsafe {
            a_sum_err += (A[j] - aj).abs();
            b_sum_err += (B[j] - bj).abs();
            c_sum_err += (C[j] - cj).abs();
        }
    }
    let a_avg_err = a_sum_err / STREAM_ARRAY_SIZE as f64;
    let b_avg_err = b_sum_err / STREAM_ARRAY_SIZE as f64;
    let c_avg_err = c_sum_err / STREAM_ARRAY_SIZE as f64;

    let epsilon = 1.0E-13;

    let mut err = 0;
    let mut ierr = 0;

    if (a_avg_err / aj).abs() > epsilon {
        err = err + 1;
        println!(
            "Failed Validation on array a[], AvgRelAbsErr > epsilon ({})",
            epsilon
        );
        println!(
            "     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",
            aj,
            a_avg_err,
            a_avg_err.abs() / aj
        );
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (A[j] / aj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array a[], {} errors were found.", ierr);
    }

    if (b_avg_err / bj).abs() > epsilon {
        err = err + 1;
        println!(
            "Failed Validation on array b[], AvgRelAbsErr > epsilon ({})",
            epsilon
        );
        println!(
            "     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",
            bj,
            b_avg_err,
            b_avg_err.abs() / bj
        );
        println!("     AvgRelAbsErr > Epsilon {}", epsilon);
        ierr = 0;
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (B[j] / bj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array b[], {} errors were found.", ierr);
    }

    if (c_avg_err / cj).abs() > epsilon {
        err = err + 1;
        println!(
            "Failed Validation on array c[], AvgRelAbsErr > epsilon ({})",
            epsilon
        );
        println!(
            "     Expected Value: {}, AvgAbsErr: {}, AvgRelAbsErr: {}",
            cj,
            c_avg_err,
            c_avg_err.abs() / cj
        );
        println!("     AvgRelAbsErr > Epsilon ({})", epsilon);
        ierr = 0;
        for j in 0..STREAM_ARRAY_SIZE {
            unsafe {
                if (C[j] / cj - 1.0).abs() > epsilon {
                    ierr = ierr + 1;
                }
            }
        }
        println!("     For array c[], {} errors were found.", ierr);
    }

    if err == 0 {
        println!(
            "Solution Validates: avg error less than {:e} on all three arrays",
            epsilon
        );
    }

}
<|endoftext|>


<commit_before>extern crate orbtk;

#[cfg(target_os = "redox")]
#[no_mangle]
pub fn main() {
    orbtk::example();
}

#[cfg(not(target_os = "redox"))]
fn main() {
    orbtk::example();
}
<commit_msg>Replace contents with big text box<commit_after>extern crate orbtk;

use orbtk::*;

fn real_main(){
    let mut window = Window::new(Rect::new(100, 100, 420, 420), "Editor");

    TextBox::new()
        .position(0, 0)
        .size(420, 420)
        .place(&mut window);

    window.exec();
}

#[cfg(target_os = "redox")]
#[no_mangle]
pub fn main() {
    real_main();
}

#[cfg(not(target_os = "redox"))]
fn main() {
    real_main();
}
<|endoftext|>