<commit_before>extern crate cargo_tarpaulin;
extern crate nix;
extern crate gimli;
extern crate object;
extern crate memmap;
extern crate fallible_iterator;
extern crate rustc_demangle;
#[macro_use]
extern crate clap;

use std::path::Path;
use clap::{App, Arg, SubCommand, ArgSettings};
use cargo_tarpaulin::run;
use cargo_tarpaulin::config::*;

fn is_dir(d: String) -> Result<(), String> {
    if Path::new(&d).is_dir() {
        Ok(())
    } else {
        Err(String::from("root must be a directory"))
    }
}

const CI_SERVER_HELP: &'static str =
"Name of service, supported services are:
travis-ci, travis-pro, circle-ci, semaphore, jenkins and codeship.
If you are interfacing with coveralls.io or another site you can \
also specify a name that they will recognise. Refer to their documentation for this.";

fn main() {
    let args = App::new("cargo-tarpaulin")
        .author("Daniel McKenna, <danielmckenna93@gmail.com>")
        .about("Tool to analyse test coverage of cargo projects")
        .version(concat!("version: ", crate_version!()))
        .bin_name("cargo")
        .subcommand(SubCommand::with_name("tarpaulin")
            .about("Tool to analyse test coverage of cargo projects")
            .version(concat!("version: ", crate_version!()))
            .args_from_usage(
                 "--verbose -v 'Show extra output'
                 --ignore-tests 'ignore lines of test functions when collecting coverage'
                 --no-count   'Disables counting line hits for a faster run'
                 --ignored -i 'Run ignored tests as well'
                 --line -l    'Line coverage'
                 --skip-clean 'Skips the clean stage to reduce build times, may affect coverage results'
                 --branch -b  'Branch coverage: NOT IMPLEMENTED'
                 --forward -f 'Forwards unexpected signals to test. Tarpaulin will still take signals it is expecting.'
                 --coveralls [KEY]  'Coveralls key, either the repo token, or if you're using travis use $TRAVIS_JOB_ID and specify travis-{ci|pro} in --ciserver'
                 --features [FEATURE]... 'Features to be included in the target project'
                 --all-features 'Build all available features'
                 --all        'Build all packages in the workspace'
                 --packages -p [PACKAGE]... 'Package id specifications for which package should be build. See cargo help pkgid for more info'
                 --exclude -e [PACKAGE]... 'Package id specifications to exclude from coverage. See cargo help pkgid for more info'
                 --exclude-files [FILE]... 'Exclude given files from coverage results has * wildcard'
                 --timeout -t [SECONDS] 'Integer for the maximum time in seconds without response from test before timeout (default is 1 minute).'")
            .args(&[
                Arg::from_usage("--out -o [FMT]   'Output path'")
                    .possible_values(&OutputFile::variants())
                    .multiple(true),
                Arg::from_usage("--root -r [DIR]  'Root directory containing Cargo.toml to use'")
                    .validator(is_dir),
                Arg::from_usage("--ciserver [SERVICE] 'CI server being used'")
                    .help(CI_SERVER_HELP),
                Arg::with_name("args")
                    .set(ArgSettings::Last)
                    .multiple(true)
            ]))
        .get_matches();

    let args = args.subcommand_matches("tarpaulin").unwrap_or(&args);
    let config = Config::from_args(args);
    match run(config) {
        Ok(()) => println!("Tarpaulin finished"),
        Err(e) => {
            println!("Error during run");
            std::process::exit(e);
        },
    }
}
<commit_msg>Add help for <args>...<commit_after>extern crate cargo_tarpaulin;
extern crate nix;
extern crate gimli;
extern crate object;
extern crate memmap;
extern crate fallible_iterator;
extern crate rustc_demangle;
#[macro_use]
extern crate clap;

use std::path::Path;
use clap::{App, Arg, SubCommand, ArgSettings};
use cargo_tarpaulin::run;
use cargo_tarpaulin::config::*;

fn is_dir(d: String) -> Result<(), String> {
    if Path::new(&d).is_dir() {
        Ok(())
    } else {
        Err(String::from("root must be a directory"))
    }
}

const CI_SERVER_HELP: &'static str =
"Name of service, supported services are:
travis-ci, travis-pro, circle-ci, semaphore, jenkins and codeship.
If you are interfacing with coveralls.io or another site you can \
also specify a name that they will recognise. Refer to their documentation for this.";

fn main() {
    let args = App::new("cargo-tarpaulin")
        .author("Daniel McKenna, <danielmckenna93@gmail.com>")
        .about("Tool to analyse test coverage of cargo projects")
        .version(concat!("version: ", crate_version!()))
        .bin_name("cargo")
        .subcommand(SubCommand::with_name("tarpaulin")
            .about("Tool to analyse test coverage of cargo projects")
            .version(concat!("version: ", crate_version!()))
            .args_from_usage(
                 "--verbose -v 'Show extra output'
                 --ignore-tests 'ignore lines of test functions when collecting coverage'
                 --no-count   'Disables counting line hits for a faster run'
                 --ignored -i 'Run ignored tests as well'
                 --line -l    'Line coverage'
                 --skip-clean 'Skips the clean stage to reduce build times, may affect coverage results'
                 --branch -b  'Branch coverage: NOT IMPLEMENTED'
                 --forward -f 'Forwards unexpected signals to test. Tarpaulin will still take signals it is expecting.'
                 --coveralls [KEY]  'Coveralls key, either the repo token, or if you're using travis use $TRAVIS_JOB_ID and specify travis-{ci|pro} in --ciserver'
                 --features [FEATURE]... 'Features to be included in the target project'
                 --all-features 'Build all available features'
                 --all        'Build all packages in the workspace'
                 --packages -p [PACKAGE]... 'Package id specifications for which package should be build. See cargo help pkgid for more info'
                 --exclude -e [PACKAGE]... 'Package id specifications to exclude from coverage. See cargo help pkgid for more info'
                 --exclude-files [FILE]... 'Exclude given files from coverage results has * wildcard'
                 --timeout -t [SECONDS] 'Integer for the maximum time in seconds without response from test before timeout (default is 1 minute).'")
            .args(&[
                Arg::from_usage("--out -o [FMT]   'Output path'")
                    .possible_values(&OutputFile::variants())
                    .multiple(true),
                Arg::from_usage("--root -r [DIR]  'Root directory containing Cargo.toml to use'")
                    .validator(is_dir),
                Arg::from_usage("--ciserver [SERVICE] 'CI server being used'")
                    .help(CI_SERVER_HELP),
                Arg::with_name("args")
                    .set(ArgSettings::Last)
                    .multiple(true)
                    .help("Arguments to be passed to the test executables can be used to filter or skip certain tests")
            ]))
        .get_matches();

    let args = args.subcommand_matches("tarpaulin").unwrap_or(&args);
    let config = Config::from_args(args);
    match run(config) {
        Ok(()) => println!("Tarpaulin finished"),
        Err(e) => {
            println!("Error during run");
            std::process::exit(e);
        },
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeSet;

const N: usize = 9;

fn row(linear_index: usize) -> usize {
    linear_index / N
}

fn col(linear_index: usize) -> usize {
    linear_index % N
}

struct SudokuBoard {
    /// Cells are represented by a linear vector of sets.
    /// Each set contains the possible values for a cell.
    /// - If the set for a cell is empty, the board, in its
    ///   current state, is unsolvable.
    /// - If the set is a singleton, we have found the solution
    ///   for the current cell.
    cells: Vec<BTreeSet<usize>>
}

impl SudokuBoard {
    fn from_str(descr: &str) -> Self {
        let mut v: Vec<BTreeSet<usize>> = Vec::with_capacity(N*N);
        for c in descr.chars() {
            match c {
                '.' => {
                    v.push((1..N+1).collect());
                }
                '1' ... '9' => {
                    // There ought to be a simpler way to create a singleton set.
                    let n = c.to_digit(10).unwrap() as usize;
                    let s = vec![n].into_iter().collect();
                    v.push(s);
                }
                _ => {
                    panic!("Not a valid string")
                }
            }
        }
        SudokuBoard { cells: v }
    }

    fn is_solved(&self) -> bool {
        self.cells.iter().all(|candidates| candidates.len() == 1)
    }

    fn cell_is_solved(&self, idx: usize) -> bool {
        self.cells[idx].len() == 1
    }

    /// Return the  indices of the neighbors of a cell, i.e.,
    /// the indices of the cells in the same row, same column and same
    /// square group.
    fn neighbors(&self, idx: usize) -> BTreeSet<usize> {
        let mut neighbor_indices = BTreeSet::new();

        // Row & column
        for i in 0..N {
            let row_idx = row(idx) + i;
            if row_idx != idx {
                neighbor_indices.insert(row_idx);
            }

            let col_idx = (N*i) + col(idx);
            if col_idx != idx {
                neighbor_indices.insert(col_idx);
            }
        }

        // Group
        let x = 3 * (row(idx) / 3);
        let y = 3 * (col(idx) / 3);
        for i in x .. x+3 {
            for j in y .. y+3 {
                let group_idx = (N*i) + j;
                if group_idx != idx {
                    neighbor_indices.insert(group_idx);
                }
            }
        }

        neighbor_indices
    }

    /*
    fn update_candidates(&mut self, row: usize, col: usize) {
        if self.cell_is_solved(linear_index(row, col)) {
            return;
        }

        // Put non-candidates in a vector, because we cannot
        // do self.cells[idx].remove(x) since self.cells is
        // already borrowed.
        let mut non_candidates: Vec<usize> = Vec::new();
        for n in self.neighbors(row, col) {
            if self.cell_is_solved(n) {
                for x in self.cells[n].iter() {
                    non_candidates.push(*x);
                }
            }
        }
        let idx = linear_index(row, col);
        for nc in non_candidates {
            self.cells[idx].remove(&nc);
        }
    }
    */
    fn print(&self) {
        for i in 0..N*N {
            if self.cell_is_solved(i) {
                for c in self.cells[i].iter() {
                    print!("{}", c);
                }
            } else {
                print!(".");
            }
        }
        println!("");
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(
        "............942.8.16.....29........89.6.....14..25......4.......2...8.9..5....7.."
    );
}
<commit_msg>Rework entire thing from scratch<commit_after>use std::char;
use std::collections::BTreeSet;

const NSQRT: usize = 3;
const N: usize = NSQRT * NSQRT;
const NSQ: usize = N*N;

/// Return the 0-based row index of `cell`.
fn row(cell: usize) -> usize {
    cell / N
}

/// Return the 0-based row index of `cell`.
fn col(cell: usize) -> usize {
    cell % N
}

/// Return the 0-based index of the upper-left cell of `cell`'s group.
fn group(cell: usize) -> usize {
    let r = row(cell);
    let c = col(cell);
    (N * (r - r % NSQRT)) + (c - c % NSQRT)
}

fn neighbors(cell: usize) -> BTreeSet<usize> {
    let mut all_neighbors: BTreeSet<usize> = BTreeSet::new();

    // Neighbors on row
    for col in 0..N {
        all_neighbors.insert((N * row(cell)) + col);
    }

    // Neighbors on column
    for row in 0..N {
        all_neighbors.insert((N * row) + col(cell));
    }

    // Neighbors in group
    let leader = group(cell);
    for r in row(leader) .. row(leader) + NSQRT {
        for c in col(leader) .. col(leader) + NSQRT {
            all_neighbors.insert(N * r + c);
        }
    }

    all_neighbors.remove(&cell);
    return all_neighbors;
}

#[derive(Debug)]
struct SudokuBoard(Vec<u8>);

impl SudokuBoard {
    fn from_str(digits: &str) -> Self {
        let mut v = Vec::with_capacity(NSQ);
        for d in digits.chars() {
            match d {
                '.' => { v.push(0); }
                '1' ... '9' => {
                    let n = d.to_digit(10).unwrap() as u8;
                    v.push(n);
                }
                _ => { panic!("invalid digit ({:?}) in string", d); }
            }
        }
        SudokuBoard(v)
    }

    fn to_str(&self) -> String {
        /*
        let mut s = String::with_capacity(NSQ);
        for n in self.0.iter() {
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
        }
        s
         */
        let mut s = String::with_capacity(N + NSQ);
        let mut i = 0;
        for n in self.0.iter() {
            if i % N == 0 {
                s.push('\n');
            }
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
            i += 1;
        }
        s
    }

    fn is_solved(&self, cell: usize) -> bool {
        self.0[cell] != 0
    }

    fn candidates(&self, cell: usize) -> BTreeSet<u8> {
        let mut non_candidates = BTreeSet::new();
        for n in neighbors(cell) {
            let x = self.0[n];
            if x != 0 {
                non_candidates.insert(x);
            }
        }
        let mut candidates: BTreeSet<u8> = (1_u8 .. (N+1) as u8).collect();
        for nc in non_candidates {
            candidates.remove(&nc);
        }
        candidates
    }

    fn solve(&mut self, cell: usize) -> bool {
        if cell >= NSQ {
            return true;
        }

        if self.is_solved(cell) {
            return self.solve(cell + 1);
        }

        for c in self.candidates(cell) {
            self.0[cell] = c;
            if self.solve(cell + 1) {
                return true;
            } else {
                self.0[cell] = 0;
            }
        }
        return false;
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(".94...13..............76..2.8..1.....32.........2...6.....5.4.......8..7..63.4..8");
    println!("{}", sb.to_str());
    sb.solve(0);
    println!("{}", sb.to_str());
}

#[test]
fn test_row_col() {
    assert_eq!(row(11), 1);
    assert_eq!(col(11), 2);
}

#[test]
fn test_group() {
    assert_eq!(group(0), 0);
    assert_eq!(group(1), 0);
    assert_eq!(group(2), 0);
    assert_eq!(group(9), 0);
    assert_eq!(group(10), 0);
    assert_eq!(group(11), 0);
    assert_eq!(group(18), 0);
    assert_eq!(group(19), 0);
    assert_eq!(group(20), 0);
    assert_eq!(group(60), 60);
    assert_eq!(group(61), 60);
    assert_eq!(group(62), 60);
    assert_eq!(group(69), 60);
    assert_eq!(group(70), 60);
    assert_eq!(group(71), 60);
    assert_eq!(group(78), 60);
    assert_eq!(group(79), 60);
    assert_eq!(group(80), 60);
}

#[test]
fn test_is_solved() {
    let sb = SudokuBoard(vec![0, 1]);
    assert!(!sb.is_solved(0));
    assert!(sb.is_solved(1));
}

#[test]
fn test_neighbors() {
    assert!(!neighbors(0).contains(&0));
    // Neighbors of 0 on the same row
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&3));
    assert!(neighbors(0).contains(&4));
    assert!(neighbors(0).contains(&5));
    assert!(neighbors(0).contains(&6));
    assert!(neighbors(0).contains(&7));
    assert!(neighbors(0).contains(&8));
    // Neighbors of 0 on the same col
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&27));
    assert!(neighbors(0).contains(&36));
    assert!(neighbors(0).contains(&45));
    assert!(neighbors(0).contains(&54));
    assert!(neighbors(0).contains(&63));
    assert!(neighbors(0).contains(&72));
    // Neighbors of 0 in the same group
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&10));
    assert!(neighbors(0).contains(&11));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&19));
    assert!(neighbors(0).contains(&20));
}

#[test]
fn test_candidates() {
    let sb = SudokuBoard::from_str(".2......34..........6...................................................5........");
    assert!(!sb.candidates(0).contains(&2));
    assert!(!sb.candidates(0).contains(&3));
    assert!(!sb.candidates(0).contains(&4));
    assert!(!sb.candidates(0).contains(&5));
    assert!(!sb.candidates(0).contains(&6));
    assert!(sb.candidates(0).contains(&1));
    assert!(sb.candidates(0).contains(&7));
    assert!(sb.candidates(0).contains(&8));
    assert!(sb.candidates(0).contains(&9));
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate toml;

#[macro_use]
extern crate clap;

use std::io::prelude::*;
use std::fs::File;
use std::collections::BTreeMap;

use clap::{App,Arg};

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String,String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?
        .read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or_else(|| std::io::Error::last_os_error().into())
}

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author("Koen Wilde <koen@chillheid.nl>")
        .about("Restricted Shell that only allows whitelisted aliases")
        .arg((Arg::with_name("command")
            .short("-c")
            .help("Alias of command to execute")
            .value_name("COMMAND")))
        .get_matches();

    let command_alias = match matches.value_of("command") {
        Some(cmd) => String::from(cmd),
        None => {
            match std::env::var("SSH_ORIGINAL_COMMAND") {
                Ok(cmd) => cmd,
                _ => die!("Usage: {} <command alias>", crate_name!()), }
        }
    };

    let config_file = std::env::var("RESH_CONFIG")
        .unwrap_or_else(|_| {"/etc/resh.toml".to_string()});

    let config: Config = read_config(&config_file).
        unwrap_or_else(|e| { die!("Failed to read {}: {}", config_file, e); });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => { die!("Undefined command alias: {}", command_alias) },
    };

    let exitcode = run_command(full_command)
        .unwrap_or(1);

    std::process::exit(exitcode);
}
<commit_msg>Cleanup (deprecation) warnings<commit_after>#[macro_use]
extern crate serde_derive;
extern crate toml;

#[macro_use]
extern crate clap;

use std::collections::BTreeMap;
use std::fs::File;
use std::io::prelude::*;

use clap::{App, Arg};

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String, String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<dyn std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?.read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<dyn std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or_else(|| std::io::Error::last_os_error().into())
}

fn main() {
    let matches = App::new(crate_name!())
        .version(crate_version!())
        .author("Koen Wilde <koen@chillheid.nl>")
        .about("Restricted Shell that only allows whitelisted aliases")
        .arg(
            Arg::with_name("command")
                .short("-c")
                .help("Alias of command to execute")
                .value_name("COMMAND"),
        )
        .get_matches();

    let command_alias = match matches.value_of("command") {
        Some(cmd) => String::from(cmd),
        None => match std::env::var("SSH_ORIGINAL_COMMAND") {
            Ok(cmd) => cmd,
            _ => die!("Usage: {} <command alias>", crate_name!()),
        },
    };

    let config_file = std::env::var("RESH_CONFIG").unwrap_or_else(|_| "/etc/resh.toml".to_string());

    let config: Config = read_config(&config_file).unwrap_or_else(|e| {
        die!("Failed to read {}: {}", config_file, e);
    });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => die!("Undefined command alias: {}", command_alias),
    };

    let exitcode = run_command(full_command).unwrap_or(1);

    std::process::exit(exitcode);
}
<|endoftext|>


<commit_before>use std::os;
use std::io;

#[allow(dead_code)]
use ast::Ast;

mod parser;
mod ast;

fn help() {
    println!("rust-scm: prog");
}

fn main() {
    let args = os::args();

    if args.len() < 2 {
        help();
        os::set_exit_status(1);
        return;
    }

    let program = args[0].as_slice();
    println!("args: {} program: {}", args, program);
    let code = match io::File::open(&Path::new(args[1].as_slice())) {
        Ok(mut file) => file.read_to_string().unwrap(),
        Err(_) => {
            os::set_exit_status(1);
            return
        }
    };
    let parser = parser::new();

    println!("parser: {}", parser);
    println!("code: {}", code);

    let int_node = ast::IntNode::new(3);
    int_node.print();
}
<commit_msg>more ast<commit_after>use std::os;
use std::io;

#[allow(dead_code)]
use ast::Ast;

mod parser;
mod ast;

fn help() {
    println!("rust-scm: prog");
}

fn main() {
    let args = os::args();

    if args.len() < 2 {
        help();
        os::set_exit_status(1);
        return;
    }

    let program = args[0].as_slice();
    println!("args: {} program: {}", args, program);
    let code = match io::File::open(&Path::new(args[1].as_slice())) {
        Ok(mut file) => file.read_to_string().unwrap(),
        Err(_) => {
            os::set_exit_status(1);
            return
        }
    };
    let parser = parser::new();

    println!("parser: {}", parser);
    println!("code: {}", code);

    let int_node = ast::IntNode::new(3);
    int_node.print();
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
#![cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]

extern crate docopt;
extern crate env_logger;
extern crate hprof;
extern crate libgir as gir;

use std::cell::RefCell;
use std::str::FromStr;

use gir::{Config, WorkMode};

use gir::Library;
use hprof::Profiler;

static USAGE: &'static str = "
Usage: gir [options] [<library> <version>]
       gir --help

Options:
    -h, --help              Show this message.
    -c CONFIG               Config file path (default: Gir.toml)
    -d GIRSPATH             Directory for girs
    -m MODE                 Work mode: doc, normal, sys or not_bound
    -o PATH                 Target path
    --doc-target-path PATH  Doc target path
    -b, --make-backup       Make backup before generating
    -s, --stats             Show statistics
";

fn build_config() -> Result<Config, String> {
    let args = match docopt::Docopt::new(USAGE).and_then(|dopt| dopt.parse()) {
        Ok(args) => args,
        Err(e) => return Err(format!("Failed to get arguments: {}", e)),
    };
    let work_mode = match args.get_str("-m") {
        "" => None,
        s => match WorkMode::from_str(s) {
            Ok(w) => Some(w),
            Err(e) => {
                eprintln!("Error (switching to default work mode): {}", e);
                None
            }
        },
    };

    Config::new(args.get_str("-c"), work_mode, args.get_str("-d"),
                args.get_str("<library>"), args.get_str("<version>"), args.get_str("-o"),
                args.get_str("--doc-target-path"), args.get_bool("-b"), args.get_bool("-s"))
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    if let Err(ref e) = do_main() {
        eprintln!("{}", e);

        ::std::process::exit(1);
    }
}

fn do_main() -> Result<(), String> {
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "gir=warn");
        std::env::set_var("RUST_LOG", "libgir=warn");
    }
    env_logger::init();

    let mut cfg = match build_config() {
        Ok(cfg) => cfg,
        Err(err) => return Err(err),
    };

    let statistics = Profiler::new("Gir");
    statistics.start_frame();

    let watcher_total = statistics.enter("Total");

    let mut library;

    {
        let _watcher = statistics.enter("Loading");

        library = Library::new(&cfg.library_name);
        try!(library.read_file(&cfg.girs_dir, &cfg.library_full_name()));
    }

    {
        let _watcher = statistics.enter("Preprocessing");
        library.preprocessing(cfg.work_mode);
    }

    {
        let _watcher = statistics.enter("Update library by config");
        gir::update_version::apply_config(&mut library, &cfg);
    }

    {
        let _watcher = statistics.enter("Postprocessing");
        library.postprocessing();
    }

    {
        let _watcher = statistics.enter("Resolving type ids");
        cfg.resolve_type_ids(&library);
    }

    {
        let _watcher = statistics.enter("Checking versions");
        gir::update_version::check_function_real_version(&mut library);
    }

    let mut env;

    {
        let _watcher = statistics.enter("Namespace/symbol/class analysis");

        let namespaces = gir::namespaces_run(&library);
        let symbols = gir::symbols_run(&library, &namespaces);
        let class_hierarchy = gir::class_hierarchy_run(&library);

        env = gir::Env {
            library,
            config: cfg,
            namespaces,
            symbols: RefCell::new(symbols),
            class_hierarchy,
            analysis: Default::default(),
        };
    }

    if env.config.work_mode != WorkMode::Sys {
        let _watcher = statistics.enter("Analysing");
        gir::analysis_run(&mut env);
    }

    if env.config.work_mode != WorkMode::DisplayNotBound {
        let _watcher = statistics.enter("Generating");
        gir::codegen_generate(&env);
    }

    drop(watcher_total);
    statistics.end_frame();

    if env.config.show_statistics {
        statistics.print_timing();
    }
    if env.config.work_mode == WorkMode::DisplayNotBound {
        env.library.show_non_bound_types(&env);
    }

    Ok(())
}
<commit_msg>Fix unneeded "Failed to get arguments" when run `gir --help`<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(match_same_arms))]
#![cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]

extern crate docopt;
extern crate env_logger;
extern crate hprof;
extern crate libgir as gir;

use std::cell::RefCell;
use std::str::FromStr;

use gir::{Config, WorkMode};

use gir::Library;
use hprof::Profiler;

static USAGE: &'static str = "
Usage: gir [options] [<library> <version>]
       gir (-h | --help)

Options:
    -h, --help              Show this message.
    -c CONFIG               Config file path (default: Gir.toml)
    -d GIRSPATH             Directory for girs
    -m MODE                 Work mode: doc, normal, sys or not_bound
    -o PATH                 Target path
    --doc-target-path PATH  Doc target path
    -b, --make-backup       Make backup before generating
    -s, --stats             Show statistics
";

fn build_config() -> Result<Config, String> {
    let args = match docopt::Docopt::new(USAGE).and_then(|dopt| dopt.parse()) {
        Ok(args) => args,
        Err(e) => return Err(e.to_string()),
    };
    let work_mode = match args.get_str("-m") {
        "" => None,
        s => match WorkMode::from_str(s) {
            Ok(w) => Some(w),
            Err(e) => {
                eprintln!("Error (switching to default work mode): {}", e);
                None
            }
        },
    };

    Config::new(args.get_str("-c"), work_mode, args.get_str("-d"),
                args.get_str("<library>"), args.get_str("<version>"), args.get_str("-o"),
                args.get_str("--doc-target-path"), args.get_bool("-b"), args.get_bool("-s"))
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    if let Err(ref e) = do_main() {
        eprintln!("{}", e);

        ::std::process::exit(1);
    }
}

fn do_main() -> Result<(), String> {
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "gir=warn");
        std::env::set_var("RUST_LOG", "libgir=warn");
    }
    env_logger::init();

    let mut cfg = match build_config() {
        Ok(cfg) => cfg,
        Err(err) => return Err(err),
    };

    let statistics = Profiler::new("Gir");
    statistics.start_frame();

    let watcher_total = statistics.enter("Total");

    let mut library;

    {
        let _watcher = statistics.enter("Loading");

        library = Library::new(&cfg.library_name);
        try!(library.read_file(&cfg.girs_dir, &cfg.library_full_name()));
    }

    {
        let _watcher = statistics.enter("Preprocessing");
        library.preprocessing(cfg.work_mode);
    }

    {
        let _watcher = statistics.enter("Update library by config");
        gir::update_version::apply_config(&mut library, &cfg);
    }

    {
        let _watcher = statistics.enter("Postprocessing");
        library.postprocessing();
    }

    {
        let _watcher = statistics.enter("Resolving type ids");
        cfg.resolve_type_ids(&library);
    }

    {
        let _watcher = statistics.enter("Checking versions");
        gir::update_version::check_function_real_version(&mut library);
    }

    let mut env;

    {
        let _watcher = statistics.enter("Namespace/symbol/class analysis");

        let namespaces = gir::namespaces_run(&library);
        let symbols = gir::symbols_run(&library, &namespaces);
        let class_hierarchy = gir::class_hierarchy_run(&library);

        env = gir::Env {
            library,
            config: cfg,
            namespaces,
            symbols: RefCell::new(symbols),
            class_hierarchy,
            analysis: Default::default(),
        };
    }

    if env.config.work_mode != WorkMode::Sys {
        let _watcher = statistics.enter("Analysing");
        gir::analysis_run(&mut env);
    }

    if env.config.work_mode != WorkMode::DisplayNotBound {
        let _watcher = statistics.enter("Generating");
        gir::codegen_generate(&env);
    }

    drop(watcher_total);
    statistics.end_frame();

    if env.config.show_statistics {
        statistics.print_timing();
    }
    if env.config.work_mode == WorkMode::DisplayNotBound {
        env.library.show_non_bound_types(&env);
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate image;
extern crate clap;
extern crate rand;
extern crate itertools;

use clap::*;

mod codec;

mod rgba;

mod utils;

fn main()
{
    let matches = App::new("stag")
        .version("0.0.1")
        .about("Image steganography")
        .subcommand(SubCommand::with_name("encode")
            .about("encodes a file")
            .arg(Arg::with_name("mode")
                 .short("m")
                 .long("mode")
                 .value_name("MODE")
                 .help("Set the encoding mode, default depends on SOURCE type")
                 .takes_value(true))
            .arg(Arg::with_name("SOURCE")
                 .help("The image source")
                 .index(1)
                 .required(true))
            .arg(Arg::with_name("OUTPUT")
                 .help("The output image")
                 .index(2)
                 .required(true)))
        .subcommand(SubCommand::with_name("decode")
            .about("decodes a file")
            .arg(Arg::with_name("mode")
                 .short("m")
                 .long("mode")
                 .value_name("MODE")
                 .help("Set the decoding mode, default depends on SOURCE type")
                 .takes_value(true))
            .arg(Arg::with_name("SOURCE")
                 .help("The image source")
                 .index(1)
                 .required(true))
            .arg(Arg::with_name("length")
                 .short("l")
                 .long("length")
                 .help("the amount of bytes to decode")
                 .required(true)))
        .get_matches();

    if let Some(matches) = matches.subcommand_matches("encode")
    {
        dispatch_encode(
            matches.value_of("mode"),
            matches.value_of("SOURCE").unwrap(),
            matches.value_of("OUTPUT").unwrap()
        );
    }

    if let Some(matches) = matches.subcommand_matches("decode")
    {
        dispatch_decode(
            matches.value_of("mode"),
            matches.value_of("SOURCE").unwrap(),
            matches.value_of("length").unwrap()
        );
    }
}

use std::io::{stdin, stdout, Read, Write};
use std::str::FromStr;

use image::{open, DynamicImage};
use rand::StdRng;

use codec::Codec;
use rgba::{RgbaCodec, RgbaMode};

fn dispatch_encode(mode: Option<&str>, source: &str, output: &str)
{
    let dyimage = match open(source)
    {
        Ok(di) => di,
        Err(_) => error_out("Error opening source image for encoding")
    };

    match dyimage
    {
        DynamicImage::ImageRgba8(image) =>
        {
            match encode::<RgbaCodec>(image, mode).save(output)
            {
                Ok(_) => {},
                Err(_) => error_out("Error saving encoded output file"),
            };
        },
        _ => error_out("Unsupported filetype"),
    }
}

fn dispatch_decode(mode: Option<&str>, source: &str, len: &str)
{
    let len = match len.parse::<usize>()
    {
        Ok(l) => l,
        Err(_) => error_out("len argument to decode is not a number"),
    };

    let dyimage = match open(source)
    {
        Ok(di) => di,
        Err(_) => error_out("Error opening source image for decoding"),
    };

    match dyimage
    {
        DynamicImage::ImageRgba8(image) =>
        {
            decode::<RgbaCodec>(image, mode, len);
        },
        _ => error_out("Unsupported filetype"),
    }
}

fn encode<C: Codec>(mut image: C::Input, mode: Option<&str>) -> C::Input
{
    let mode = if let Some(mode) = mode
    {
        match C::Mode::from_str(mode)
        {
            Ok(mode) => mode,
            Err(_) => error_out("Error parsing mode string"),
        }
    }
    else
    {
        C::Mode::default()
    };

    let rng = match StdRng::new()
    {
        Ok(r) => r,
        Err(_) => error_out("Error creating source of randomness"),
    };

    let mut payload = String::new();
    stdin().read_to_string(&mut payload).unwrap();

    C::encode(&mut image, payload.as_bytes(), mode, rng);

    image
}

fn decode<C: Codec>(mut image: C::Input, mode: Option<&str>, len: usize)
{
    let mode = if let Some(mode) = mode
    {
        match C::Mode::from_str(mode)
        {
            Ok(mode) => mode,
            Err(_) => error_out("Error parsing mode string"),
        }
    }
    else
    {
        C::Mode::default()
    };

    let mut buf = vec![0; len];

    C::decode(&image, &mut buf, len, mode);

    match stdout().write(&buf)
    {
        Ok(_) => {},
        Err(_) => error_out("Error writing decoded payload"),
    };
}

fn error_out(msg: &str) -> !
{
    eprintln!("{}", msg);
    ::std::process::exit(1)
}
<commit_msg>cleaned up some warnings<commit_after>extern crate image;
extern crate clap;
extern crate rand;
extern crate itertools;

use clap::*;

mod codec;

mod rgba;

mod utils;

fn main()
{
    let matches = App::new("stag")
        .version("0.0.1")
        .about("Image steganography")
        .subcommand(SubCommand::with_name("encode")
            .about("encodes a file")
            .arg(Arg::with_name("mode")
                 .short("m")
                 .long("mode")
                 .value_name("MODE")
                 .help("Set the encoding mode, default depends on SOURCE type")
                 .takes_value(true))
            .arg(Arg::with_name("SOURCE")
                 .help("The image source")
                 .index(1)
                 .required(true))
            .arg(Arg::with_name("OUTPUT")
                 .help("The output image")
                 .index(2)
                 .required(true)))
        .subcommand(SubCommand::with_name("decode")
            .about("decodes a file")
            .arg(Arg::with_name("mode")
                 .short("m")
                 .long("mode")
                 .value_name("MODE")
                 .help("Set the decoding mode, default depends on SOURCE type")
                 .takes_value(true))
            .arg(Arg::with_name("SOURCE")
                 .help("The image source")
                 .index(1)
                 .required(true))
            .arg(Arg::with_name("length")
                 .short("l")
                 .long("length")
                 .help("the amount of bytes to decode")
                 .required(true)))
        .get_matches();

    if let Some(matches) = matches.subcommand_matches("encode")
    {
        dispatch_encode(
            matches.value_of("mode"),
            matches.value_of("SOURCE").unwrap(),
            matches.value_of("OUTPUT").unwrap()
        );
    }

    if let Some(matches) = matches.subcommand_matches("decode")
    {
        dispatch_decode(
            matches.value_of("mode"),
            matches.value_of("SOURCE").unwrap(),
            matches.value_of("length").unwrap()
        );
    }
}

use std::io::{stdin, stdout, Read, Write};
use std::str::FromStr;

use image::{open, DynamicImage};
use rand::StdRng;

use codec::Codec;
use rgba::RgbaCodec;

fn dispatch_encode(mode: Option<&str>, source: &str, output: &str)
{
    let dyimage = match open(source)
    {
        Ok(di) => di,
        Err(_) => error_out("Error opening source image for encoding")
    };

    match dyimage
    {
        DynamicImage::ImageRgba8(image) =>
        {
            match encode::<RgbaCodec>(image, mode).save(output)
            {
                Ok(_) => {},
                Err(_) => error_out("Error saving encoded output file"),
            };
        },
        _ => error_out("Unsupported filetype"),
    }
}

fn dispatch_decode(mode: Option<&str>, source: &str, len: &str)
{
    let len = match len.parse::<usize>()
    {
        Ok(l) => l,
        Err(_) => error_out("len argument to decode is not a number"),
    };

    let dyimage = match open(source)
    {
        Ok(di) => di,
        Err(_) => error_out("Error opening source image for decoding"),
    };

    match dyimage
    {
        DynamicImage::ImageRgba8(image) =>
        {
            decode::<RgbaCodec>(image, mode, len);
        },
        _ => error_out("Unsupported filetype"),
    }
}

fn encode<C: Codec>(mut image: C::Input, mode: Option<&str>) -> C::Input
{
    let mode = if let Some(mode) = mode
    {
        match C::Mode::from_str(mode)
        {
            Ok(mode) => mode,
            Err(_) => error_out("Error parsing mode string"),
        }
    }
    else
    {
        C::Mode::default()
    };

    let rng = match StdRng::new()
    {
        Ok(r) => r,
        Err(_) => error_out("Error creating source of randomness"),
    };

    let mut payload = String::new();
    stdin().read_to_string(&mut payload).unwrap();

    C::encode(&mut image, payload.as_bytes(), mode, rng);

    image
}

fn decode<C: Codec>(image: C::Input, mode: Option<&str>, len: usize)
{
    let mode = if let Some(mode) = mode
    {
        match C::Mode::from_str(mode)
        {
            Ok(mode) => mode,
            Err(_) => error_out("Error parsing mode string"),
        }
    }
    else
    {
        C::Mode::default()
    };

    let mut buf = vec![0; len];

    C::decode(&image, &mut buf, len, mode);

    match stdout().write(&buf)
    {
        Ok(_) => {},
        Err(_) => error_out("Error writing decoded payload"),
    };
}

fn error_out(msg: &str) -> !
{
    eprintln!("{}", msg);
    ::std::process::exit(1)
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::io::Lines;

use CommandType::{A_COMMAND, C_COMMAND, L_COMMAND};

enum CommandType {
	A_COMMAND,
	C_COMMAND,
	L_COMMAND,
}

struct Parser {
	input_lines: Lines<BufReader<File>>,
	current_command: String,
}

impl Parser {
	/// Opens the input file/stream and gets ready to parse it.
	fn new(filename: &str) -> Parser {
		let path = Path::new(filename);
		let file = match File::open(&path) {
			Err(why) => panic!("couldn't open {}: {}", path.display(), Error::description(&why)),
			Ok(file) => file,
		};

		let lines = BufReader::new(file).lines(); // iterator
		Parser { input_lines: lines, current_command: String::new()}
	}

	/// Are there any more commands in the input?
	///
	/// NOTE: Not needed since input_lines is an iterator
	fn has_more_commands(&self) -> bool {
		false
	}

	/// Reads the next command from the input and makes it the current command.
	///
	/// Should be called only if hasMoreCommands() is true.
	/// Initally there is no current command
	///
	fn advance(&mut self) {
		// Lines.next() -> Option<Result<String>>. That is why we have two unwrap()
		let s = self.input_lines.next().unwrap().unwrap();
		let s_trimmed = s.trim();
		if s_trimmed.starts_with("//") {
			println!("{0}", s_trimmed);
		} else {
			println!("No comment");
		}
	}

	/// Encapsulates has_more_command and avance method from the proposed API.
	///
	fn parse(mut self) {
		for line in self.input_lines { // has_more_commands + advance
			// println!("{0}", line.unwrap().trim());
			self.current_command = line.unwrap().trim().to_string();
			match self.command_type() {
				A_COMMAND 	=> {println!("A_COMMAND: {0}", self.current_command);},
				C_COMMAND 	=> {println!("C_COMMAND: {0}", self.current_command);},
				L_COMMAND 	=> {println!("L_COMMAND: {0}", self.current_command);},
			}
		}
	}

	/// Returns the type of the current command.
	///
	/// * A_COMMAND: For @xxx where xxx is either a symbol or a decimal number
	/// * C_COMMAND: For dest=comp;jump
	/// * L_COMMAND: Pseudo-Command. for (xxx) where xxx is a symbol
	fn command_type(&self) -> CommandType {
		A_COMMAND
	}
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 2 {
		println!("Usage: assembler [PATH_TO_ASM_FILE]");
		return;
	}
	let path_to_asm = &args[1];
	let mut parser = Parser::new(path_to_asm);
	parser.parse();
}
<commit_msg>Fighting with the compiler<commit_after>use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::io::Lines;

use CommandType::{A_COMMAND, C_COMMAND, L_COMMAND};

enum CommandType {
	A_COMMAND,
	C_COMMAND,
	L_COMMAND,
}

struct Parser {
	input_lines: Lines<BufReader<File>>,
	current_command: String,
}

impl Parser {
	/// Opens the input file/stream and gets ready to parse it.
	fn new(filename: &str) -> Parser {
		let path = Path::new(filename);
		let file = match File::open(&path) {
			Err(why) => panic!("couldn't open {}: {}", path.display(), Error::description(&why)),
			Ok(file) => file,
		};

		let lines = BufReader::new(file).lines(); // iterator
		Parser { input_lines: lines, current_command: String::new()}
	}

	/// Encapsulates has_more_command and avance method from the proposed API.
	///
	///		Are there any more commands in the input?
	///			Reads the next command from the input and makes it the current command
	fn parse(mut self) {
		for line in self.input_lines { // has_more_commands + advance
			// println!("{0}", line.unwrap().trim());
			self.current_command = line.unwrap().trim().to_string();
			match self.command_type() {
				A_COMMAND 	=> {println!("A_COMMAND: {0}", self.current_command);},
				C_COMMAND 	=> {println!("C_COMMAND: {0}", self.current_command);},
				L_COMMAND 	=> {println!("L_COMMAND: {0}", self.current_command);},
			}
		}
	}

	/// Returns the type of the current command.
	///
	/// * A_COMMAND: For @xxx where xxx is either a symbol or a decimal number
	/// * C_COMMAND: For dest=comp;jump
	/// * L_COMMAND: Pseudo-Command. for (xxx) where xxx is a symbol
	fn command_type(&self) -> CommandType {
		A_COMMAND
	}
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 2 {
		println!("Usage: assembler [PATH_TO_ASM_FILE]");
		return;
	}
	let path_to_asm = &args[1];
	let mut parser = Parser::new(path_to_asm);
	parser.parse();
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Bytes;

#[derive(Debug)]
enum Mnemonic {
    Add, Call, Cls, Drw,
    Jp, Ld, Or, Ret,
    Rnd, Se, Shl, Shr,
    Sknp, Skp, Sne, Sub,
    Subn, Sys, Xor,
}

#[derive(Debug)]
enum Register {
    V0, V1, V2, V3,
    V4, V5, V6, V7,
    V8, V9, Va, Vb,
    Vc, Vd, Ve, Vf,
    Sp, Pc, I, St, Dt, IVal,
}

#[derive(Debug)]
enum Token {
    Opcode(Mnemonic),
    Reg(Register),
    ImmConst(u16),
}

struct Stream {
    input: Bytes<File>,
}

impl Stream {
    fn new(input: Bytes<File>) -> Stream {
        Stream {
            input: input,
        }
    }

    fn next_token(&mut self) -> Option<Token> {
        let mut buffer: Vec<u8> = vec![];

        loop {
            let bs = self.input.next().map_or(None, |bm| match bm {
                Ok(b) => Some(b),
                _ => None
            });

            match bs {
                Some(b) => {
                    if Stream::is_separator(b) {
                        return Stream::create_token(buffer);
                    }
                    buffer.push(b);
                },
                None => {
                    return Stream::create_token(buffer);
                }
            }
        }
    }

    fn create_token(input: Vec<u8>) -> Option<Token> {
        let token_str: String = String::from_utf8(input).unwrap_or_else(|err| {
            println!("Error: {:?}", err);
            "".to_owned()
        }).to_lowercase();

        let (numeric, radix) = Stream::is_numeric(&token_str);
        if numeric {
            return match radix {
                // base 10
                0 => Some(Token::ImmConst(token_str.parse::<u16>().unwrap())),
                // base 16
                1 => Some(Token::ImmConst(u16::from_str_radix(&token_str[2..], 16).unwrap())),
                _ => None,
            }

        }

        if Stream::is_register(&token_str) {
            return match token_str.as_str() {
                "v0"   => Some(Token::Reg(Register::V0)),
                "v1"   => Some(Token::Reg(Register::V1)),
                "v2"   => Some(Token::Reg(Register::V2)),
                "v3"   => Some(Token::Reg(Register::V3)),
                "v4"   => Some(Token::Reg(Register::V4)),
                "v5"   => Some(Token::Reg(Register::V5)),
                "v6"   => Some(Token::Reg(Register::V6)),
                "v7"   => Some(Token::Reg(Register::V7)),
                "v8"   => Some(Token::Reg(Register::V8)),
                "v9"   => Some(Token::Reg(Register::V9)),
                "va"   => Some(Token::Reg(Register::Va)),
                "vb"   => Some(Token::Reg(Register::Vb)),
                "vc"   => Some(Token::Reg(Register::Vc)),
                "vd"   => Some(Token::Reg(Register::Vd)),
                "ve"   => Some(Token::Reg(Register::Ve)),
                "vf"   => Some(Token::Reg(Register::Vf)),
                "sp"   => Some(Token::Reg(Register::Sp)),
                "st"   => Some(Token::Reg(Register::St)),
                "dt"   => Some(Token::Reg(Register::Dt)),
                "pc"   => Some(Token::Reg(Register::Pc)),
                "i"    => Some(Token::Reg(Register::I)),
                "[i]"  => Some(Token::Reg(Register::IVal)),
                _      => None
            }
        }

        match token_str.as_str() {
            "add"   => Some(Token::Opcode(Mnemonic::Add)),
            "call"  => Some(Token::Opcode(Mnemonic::Call)),
            "cls"   => Some(Token::Opcode(Mnemonic::Cls)),
            "drw"   => Some(Token::Opcode(Mnemonic::Drw)),
            "jp"    => Some(Token::Opcode(Mnemonic::Jp)),
            "ld"    => Some(Token::Opcode(Mnemonic::Ld)),
            "or"    => Some(Token::Opcode(Mnemonic::Or)),
            "ret"   => Some(Token::Opcode(Mnemonic::Ret)),
            "rnd"   => Some(Token::Opcode(Mnemonic::Rnd)),
            "se"    => Some(Token::Opcode(Mnemonic::Se)),
            "shl"   => Some(Token::Opcode(Mnemonic::Shl)),
            "shr"   => Some(Token::Opcode(Mnemonic::Shr)),
            "sknp"  => Some(Token::Opcode(Mnemonic::Sknp)),
            "skp"   => Some(Token::Opcode(Mnemonic::Skp)),
            "sne"   => Some(Token::Opcode(Mnemonic::Sne)),
            "sub"   => Some(Token::Opcode(Mnemonic::Sub)),
            "subn"  => Some(Token::Opcode(Mnemonic::Subn)),
            "sys"   => Some(Token::Opcode(Mnemonic::Sys)),
            "xor"   => Some(Token::Opcode(Mnemonic::Xor)),
            _       => None
        }
    }

    fn is_separator(b: u8) -> bool {
        match b as char {
            ','|' '|'\n' => { true }
            _ => { false }
        }
    }

    fn is_register(input: &str) -> bool {
        input == "v0" || input == "v1" || input == "v2" ||
        input == "v3" || input == "v4" || input == "v5" ||
        input == "v6" || input == "v7" || input == "v8" ||
        input == "v9" || input == "va" || input == "vb" ||
        input == "vc" || input == "vd" || input == "ve" ||
        input == "vf" || input == "sp" || input == "st" ||
        input == "dt" || input == "pc" || input == "i" ||
        input == "[i]"
    }

    // Returns a tuple of boolean and integer
    // The input is numeric if the boolean component of the result is true
    // Integer component of result:
    //   0 => base 10
    //   1 => base 16
    fn is_numeric(input: &str) -> (bool, u8) {
        if input.len() < 1 {
            return (false, std::u8::MAX);
        }

        let in_bytes = input.as_bytes();
        if !Stream::is_ascii_numeric(in_bytes[0]) {
            return (false, std::u8::MAX);
        }

        // hex
        if input.starts_with("0x") {
            for i in 2..(in_bytes.len()) {
                if !Stream::is_ascii_hex(in_bytes[i]) {
                    return (false, std::u8::MAX);
                }
                return (true, 1);
            }
        } else {
            for b in in_bytes {
                if !Stream::is_ascii_numeric(*b) {
                    return (false, std::u8::MAX);
                }
                return (true, 0);
            }
        }
        return (false, std::u8::MAX);
    }

    fn is_ascii_numeric(input: u8) -> bool {
        input >= 48 && input <= 57
    }

    fn is_ascii_hex(input: u8) -> bool {
        (input >= 48 && input <= 57) || ((input >= 97 && input <= 102) || (input >= 65 && input <= 70))
    }
}

fn main() {
}
<commit_msg>Add tab as a separator to look for<commit_after>use std::fs::File;
use std::io::Bytes;

#[derive(Debug)]
enum Mnemonic {
    Add, Call, Cls, Drw,
    Jp, Ld, Or, Ret,
    Rnd, Se, Shl, Shr,
    Sknp, Skp, Sne, Sub,
    Subn, Sys, Xor,
}

#[derive(Debug)]
enum Register {
    V0, V1, V2, V3,
    V4, V5, V6, V7,
    V8, V9, Va, Vb,
    Vc, Vd, Ve, Vf,
    Sp, Pc, I, St, Dt, IVal,
}

#[derive(Debug)]
enum Token {
    Opcode(Mnemonic),
    Reg(Register),
    ImmConst(u16),
}

struct Stream {
    input: Bytes<File>,
}

impl Stream {
    fn new(input: Bytes<File>) -> Stream {
        Stream {
            input: input,
        }
    }

    fn next_token(&mut self) -> Option<Token> {
        let mut buffer: Vec<u8> = vec![];

        loop {
            let bs = self.input.next().map_or(None, |bm| match bm {
                Ok(b) => Some(b),
                _ => None
            });

            match bs {
                Some(b) => {
                    if Stream::is_separator(b) {
                        if buffer.len() > 0 {
                            return Stream::create_token(buffer);
                        }
                    } else {
                        buffer.push(b);
                    }
                },
                None => {
                    return Stream::create_token(buffer);
                }
            }
        }
    }

    fn create_token(input: Vec<u8>) -> Option<Token> {
        let token_str: String = String::from_utf8(input).unwrap_or_else(|err| {
            println!("Error: {:?}", err);
            "".to_owned()
        }).to_lowercase();

        let (numeric, radix) = Stream::is_numeric(&token_str);
        if numeric {
            return match radix {
                // base 10
                0 => Some(Token::ImmConst(token_str.parse::<u16>().unwrap())),
                // base 16
                1 => Some(Token::ImmConst(u16::from_str_radix(&token_str[2..], 16).unwrap())),
                _ => None,
            }

        }

        if Stream::is_register(&token_str) {
            return match token_str.as_str() {
                "v0"   => Some(Token::Reg(Register::V0)),
                "v1"   => Some(Token::Reg(Register::V1)),
                "v2"   => Some(Token::Reg(Register::V2)),
                "v3"   => Some(Token::Reg(Register::V3)),
                "v4"   => Some(Token::Reg(Register::V4)),
                "v5"   => Some(Token::Reg(Register::V5)),
                "v6"   => Some(Token::Reg(Register::V6)),
                "v7"   => Some(Token::Reg(Register::V7)),
                "v8"   => Some(Token::Reg(Register::V8)),
                "v9"   => Some(Token::Reg(Register::V9)),
                "va"   => Some(Token::Reg(Register::Va)),
                "vb"   => Some(Token::Reg(Register::Vb)),
                "vc"   => Some(Token::Reg(Register::Vc)),
                "vd"   => Some(Token::Reg(Register::Vd)),
                "ve"   => Some(Token::Reg(Register::Ve)),
                "vf"   => Some(Token::Reg(Register::Vf)),
                "sp"   => Some(Token::Reg(Register::Sp)),
                "st"   => Some(Token::Reg(Register::St)),
                "dt"   => Some(Token::Reg(Register::Dt)),
                "pc"   => Some(Token::Reg(Register::Pc)),
                "i"    => Some(Token::Reg(Register::I)),
                "[i]"  => Some(Token::Reg(Register::IVal)),
                _      => None
            }
        }

        match token_str.as_str() {
            "add"   => Some(Token::Opcode(Mnemonic::Add)),
            "call"  => Some(Token::Opcode(Mnemonic::Call)),
            "cls"   => Some(Token::Opcode(Mnemonic::Cls)),
            "drw"   => Some(Token::Opcode(Mnemonic::Drw)),
            "jp"    => Some(Token::Opcode(Mnemonic::Jp)),
            "ld"    => Some(Token::Opcode(Mnemonic::Ld)),
            "or"    => Some(Token::Opcode(Mnemonic::Or)),
            "ret"   => Some(Token::Opcode(Mnemonic::Ret)),
            "rnd"   => Some(Token::Opcode(Mnemonic::Rnd)),
            "se"    => Some(Token::Opcode(Mnemonic::Se)),
            "shl"   => Some(Token::Opcode(Mnemonic::Shl)),
            "shr"   => Some(Token::Opcode(Mnemonic::Shr)),
            "sknp"  => Some(Token::Opcode(Mnemonic::Sknp)),
            "skp"   => Some(Token::Opcode(Mnemonic::Skp)),
            "sne"   => Some(Token::Opcode(Mnemonic::Sne)),
            "sub"   => Some(Token::Opcode(Mnemonic::Sub)),
            "subn"  => Some(Token::Opcode(Mnemonic::Subn)),
            "sys"   => Some(Token::Opcode(Mnemonic::Sys)),
            "xor"   => Some(Token::Opcode(Mnemonic::Xor)),
            _       => None
        }
    }

    fn is_separator(b: u8) -> bool {
        match b as char {
            ','|' '|'\n' | '\t' => { true }
            _ => { false }
        }
    }

    fn is_register(input: &str) -> bool {
        input == "v0" || input == "v1" || input == "v2" ||
        input == "v3" || input == "v4" || input == "v5" ||
        input == "v6" || input == "v7" || input == "v8" ||
        input == "v9" || input == "va" || input == "vb" ||
        input == "vc" || input == "vd" || input == "ve" ||
        input == "vf" || input == "sp" || input == "st" ||
        input == "dt" || input == "pc" || input == "i" ||
        input == "[i]"
    }

    // Returns a tuple of boolean and integer
    // The input is numeric if the boolean component of the result is true
    // Integer component of result:
    //   0 => base 10
    //   1 => base 16
    fn is_numeric(input: &str) -> (bool, u8) {
        if input.len() < 1 {
            return (false, std::u8::MAX);
        }

        let in_bytes = input.as_bytes();
        if !Stream::is_ascii_numeric(in_bytes[0]) {
            return (false, std::u8::MAX);
        }

        // hex
        if input.starts_with("0x") {
            for i in 2..(in_bytes.len()) {
                if !Stream::is_ascii_hex(in_bytes[i]) {
                    return (false, std::u8::MAX);
                }
                return (true, 1);
            }
        } else {
            for b in in_bytes {
                if !Stream::is_ascii_numeric(*b) {
                    return (false, std::u8::MAX);
                }
                return (true, 0);
            }
        }
        return (false, std::u8::MAX);
    }

    fn is_ascii_numeric(input: u8) -> bool {
        input >= 48 && input <= 57
    }

    fn is_ascii_hex(input: u8) -> bool {
        (input >= 48 && input <= 57) || ((input >= 97 && input <= 102) || (input >= 65 && input <= 70))
    }
}

fn main() {
}
<|endoftext|>


<commit_before>extern crate time;
use time::{Timespec, Duration};
use std::thread;
use std::ops::Add;
use std::io::{self, Write, Read};

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

macro_rules! kb_fmt {
    ($n: ident) => {{
        let kb = 1024f64;
        match $n {
            $n if $n > kb.powf(4_f64) => {format!("{:.*} TG", 2, $n / kb.powf(4_f64))},
            $n if $n > kb.powf(3_f64) => format!("{:.*} GB", 2, $n / kb.powf(3_f64)),
            $n if $n > kb => format!("{:.*} KB", 2, $n / kb),
            _ => format!("{:.*} B", 2, $n)
        }
    }}
}

macro_rules! repeat {
    ($s: expr, $n: expr) => {{
        &std::iter::repeat($s).take($n).collect::<String>()
    }}
}

static FORMAT: &'static str = "[=>-]";

pub struct ProgressBar {
    start_time: Timespec,
    total: usize,
    current: usize,
    is_finish: bool,
    show_bar: bool,
    show_speed: bool,
    show_percent: bool,
    show_counter: bool,
    show_time_left: bool,
    // Format
    bar_start: String,
    bar_current: String,
    bar_current_n: String,
    bar_remain: String,
    bar_end: String,
}

impl ProgressBar {
    pub fn new(total: usize) -> ProgressBar {
        let v: Vec<&str> = FORMAT.split("").collect();
        ProgressBar {
            total: total,
            current: 0,
            start_time: time::get_time(),
            is_finish: false,
            show_bar: true,
            show_speed: false,
            show_percent: true,
            show_counter: true,
            show_time_left: true,
            bar_start: v[1].to_string(),
            bar_current: v[2].to_string(),
            bar_current_n: v[3].to_string(),
            bar_remain: v[4].to_string(),
            bar_end: v[5].to_string(),
        }
    }

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

    fn draw(&self) {
        let width = 149;    // replace to -> get_tty_size()
        let mut base = String::new();
        let mut suffix = String::new();
        let mut prefix = String::new();
        let mut out;
        // precent box
        if self.show_percent {
            let percent = self.current as f64 / (self.total as f64 / 100f64);
            suffix = suffix + &format!(" {:.*} % ", 2, percent);
        }
        // speed box
        // TODO: ADD KB FORMAT
        if !self.show_speed {
            let from_start = (time::get_time() - self.start_time).num_nanoseconds().unwrap() as f64;
            let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as f64;
            let speed = self.current as f64 / (from_start / sec_nano);
            suffix = suffix + &format!("{}/s ", speed as usize);
        }
        // time left box
        if self.show_time_left {
            let from_start = time::get_time() - self.start_time;
            let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as i32;
            let per_entry = from_start / self.current as i32;
            let mut left = per_entry * (self.total - self.current) as i32;
            left = (left / sec_nano) * sec_nano;
            if left.num_seconds() > 0 {
                if left.num_seconds() < Duration::minutes(1).num_seconds() {
                    suffix = suffix + &format!("{}s", left.num_seconds());
                } else {
                    suffix = suffix + &format!("{}m", left.num_minutes());
                }
            }
        }
        // counter box
        if self.show_counter {
            prefix = format!("{} / {} ", self.current, self.total);
        }
        // bar box
        if self.show_bar {
            let size = width - (prefix.len() + suffix.len() + 3);
            if size > 0 {
                let curr_count =
                    ((self.current as f64 / self.total as f64) * size as f64).ceil() as usize;
                let rema_count = size - curr_count;
                base = self.bar_start.to_string();
                if rema_count > 0 {
                    base = base + repeat!(self.bar_current.as_ref(), curr_count - 1) + &self.bar_current_n;
                } else {
                    base = base + repeat!(self.bar_current.as_ref(), curr_count);
                }
                base = base + repeat!(self.bar_remain.as_ref(), rema_count) + &self.bar_end;
            }
        }
        out = prefix + &base + &suffix;
        // pad
        if out.len() < width {
            let gap = width - out.len();
            out = out + repeat!(" ", gap);
        }
        // print
        printfl!("\r{}", out);
    }

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

// Implement io::Writer
impl Write for ProgressBar {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let n = buf.len();
        self.add(n);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

// TODO: Implement io::Reader

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

    /*let name = "/usr/share/dict/words";
    let mut file = std::fs::File::open(name).unwrap();
    let bytes = std::fs::metadata(name).unwrap().len() as i64;
    let mut pb = ProgressBar::new(bytes);
    std::io::copy(&mut file, &mut pb).unwrap();
    println!("Done");
    // Create example that use multiWriter and decorateWriter example too
    */
}
<commit_msg>add format fn<commit_after>extern crate time;
use time::{Timespec, Duration};
use std::thread;
use std::ops::Add;
use std::io::{self, Write, Read};

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

macro_rules! kb_fmt {
    ($n: ident) => {{
        let kb = 1024f64;
        match $n {
            $n if $n > kb.powf(4_f64) => {format!("{:.*} TG", 2, $n / kb.powf(4_f64))},
            $n if $n > kb.powf(3_f64) => format!("{:.*} GB", 2, $n / kb.powf(3_f64)),
            $n if $n > kb => format!("{:.*} KB", 2, $n / kb),
            _ => format!("{:.*} B", 2, $n)
        }
    }}
}

macro_rules! repeat {
    ($s: expr, $n: expr) => {{
        &std::iter::repeat($s).take($n).collect::<String>()
    }}
}

static FORMAT: &'static str = "[=>-]";

pub struct ProgressBar {
    start_time: Timespec,
    total: usize,
    current: usize,
    is_finish: bool,
    show_bar: bool,
    show_speed: bool,
    show_percent: bool,
    show_counter: bool,
    show_time_left: bool,
    // Format
    bar_start: String,
    bar_current: String,
    bar_current_n: String,
    bar_remain: String,
    bar_end: String,
}

impl ProgressBar {
    pub fn new(total: usize) -> ProgressBar {
        let mut pb = ProgressBar {
            total: total,
            current: 0,
            start_time: time::get_time(),
            is_finish: false,
            show_bar: true,
            show_speed: false,
            show_percent: true,
            show_counter: true,
            show_time_left: true,
            bar_start: String::new(),
            bar_current: String::new(),
            bar_current_n: String::new(),
            bar_remain: String::new(),
            bar_end: String::new(),
        };
        pb.format(FORMAT);
        pb
    }

    fn format(&mut self, fmt: &str) {
        if fmt.len() >= 5 {
            let v: Vec<&str> = fmt.split("").collect();
            self.bar_start = v[1].to_string();
            self.bar_current = v[2].to_string();
            self.bar_current_n = v[3].to_string();
            self.bar_remain = v[4].to_string();
            self.bar_end = v[5].to_string();
        }
    }

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

    fn draw(&self) {
        let width = 149;    // replace to -> get_tty_size()
        let mut base = String::new();
        let mut suffix = String::new();
        let mut prefix = String::new();
        let mut out;
        // precent box
        if self.show_percent {
            let percent = self.current as f64 / (self.total as f64 / 100f64);
            suffix = suffix + &format!(" {:.*} % ", 2, percent);
        }
        // speed box
        // TODO: ADD KB FORMAT
        if !self.show_speed {
            let from_start = (time::get_time() - self.start_time).num_nanoseconds().unwrap() as f64;
            let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as f64;
            let speed = self.current as f64 / (from_start / sec_nano);
            suffix = suffix + &format!("{}/s ", speed as usize);
        }
        // time left box
        if self.show_time_left {
            let from_start = time::get_time() - self.start_time;
            let sec_nano = Duration::seconds(1).num_nanoseconds().unwrap() as i32;
            let per_entry = from_start / self.current as i32;
            let mut left = per_entry * (self.total - self.current) as i32;
            left = (left / sec_nano) * sec_nano;
            if left.num_seconds() > 0 {
                if left.num_seconds() < Duration::minutes(1).num_seconds() {
                    suffix = suffix + &format!("{}s", left.num_seconds());
                } else {
                    suffix = suffix + &format!("{}m", left.num_minutes());
                }
            }
        }
        // counter box
        if self.show_counter {
            prefix = format!("{} / {} ", self.current, self.total);
        }
        // bar box
        if self.show_bar {
            let size = width - (prefix.len() + suffix.len() + 3);
            if size > 0 {
                let curr_count =
                    ((self.current as f64 / self.total as f64) * size as f64).ceil() as usize;
                let rema_count = size - curr_count;
                base = self.bar_start.to_string();
                if rema_count > 0 {
                    base = base + repeat!(self.bar_current.as_ref(), curr_count - 1) + &self.bar_current_n;
                } else {
                    base = base + repeat!(self.bar_current.as_ref(), curr_count);
                }
                base = base + repeat!(self.bar_remain.as_ref(), rema_count) + &self.bar_end;
            }
        }
        out = prefix + &base + &suffix;
        // pad
        if out.len() < width {
            let gap = width - out.len();
            out = out + repeat!(" ", gap);
        }
        // print
        printfl!("\r{}", out);
    }

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

// Implement io::Writer
impl Write for ProgressBar {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let n = buf.len();
        self.add(n);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

// TODO: Implement io::Reader

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

    /*let name = "/usr/share/dict/words";
    let mut file = std::fs::File::open(name).unwrap();
    let bytes = std::fs::metadata(name).unwrap().len() as i64;
    let mut pb = ProgressBar::new(bytes);
    std::io::copy(&mut file, &mut pb).unwrap();
    println!("Done");
    // Create example that use multiWriter and decorateWriter example too
    */
}
<|endoftext|>


<commit_before>use std::char;
use std::collections::BTreeSet;

const NSQRT: usize = 3;
const N: usize = NSQRT * NSQRT;
const NSQ: usize = N*N;

/// Return the 0-based row index of `cell`.
fn row(cell: usize) -> usize {
    cell / N
}

/// Return the 0-based row index of `cell`.
fn col(cell: usize) -> usize {
    cell % N
}

/// Return the 0-based index of the upper-left cell of `cell`'s group.
fn group(cell: usize) -> usize {
    let r = row(cell);
    let c = col(cell);
    (N * (r - r % NSQRT)) + (c - c % NSQRT)
}

/// Return the neighbors of `cell`:
/// - The cells on the same row;
/// - The cells on the same column;
/// - The same in the same group.
/// Note: `cell` is not a neighbor of itself.
fn neighbors(cell: usize) -> BTreeSet<usize> {
    let mut all_neighbors: BTreeSet<usize> = BTreeSet::new();

    // Neighbors on row
    for col in 0..N {
        all_neighbors.insert((N * row(cell)) + col);
    }

    // Neighbors on column
    for row in 0..N {
        all_neighbors.insert((N * row) + col(cell));
    }

    // Neighbors in group
    let leader = group(cell);
    for r in row(leader) .. row(leader) + NSQRT {
        for c in col(leader) .. col(leader) + NSQRT {
            all_neighbors.insert(N * r + c);
        }
    }

    all_neighbors.remove(&cell);
    return all_neighbors;
}

/// A sudoku board is represented by a vector of bytes.
#[derive(Debug)]
struct SudokuBoard(Vec<u8>);

impl SudokuBoard {
    /// Create a new sudoku board from a string.
    /// A non-zero digit stands for itself,
    /// a dot stands for a blank cell,
    /// anything else is an error.
    // TODO(vfoley): more error handling (length check)
    fn from_str(digits: &str) -> Self {
        let mut v = Vec::with_capacity(NSQ);
        for d in digits.chars() {
            match d {
                '.' => { v.push(0); }
                '1' ... '9' => {
                    let n = d.to_digit(10).unwrap() as u8;
                    v.push(n);
                }
                _ => { panic!("invalid digit ({:?}) in string", d); }
            }
        }
        SudokuBoard(v)
    }

    /// Convert a sudoku board to a rough string representation.
    fn to_str(&self) -> String {
        let mut s = String::with_capacity(N + NSQ);
        let mut i = 0;
        for n in self.0.iter() {
            if i % N == 0 {
                s.push('\n');
            }
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
            i += 1;
        }
        s
    }

    /// A cell is solved if its content is non-zero.
    fn is_solved(&self, cell: usize) -> bool {
        self.0[cell] != 0
    }

    /// Return the list of candidates for a cell.
    /// The candidates are the digits from 1 to NSQ
    /// that are *not* solved in any of `cell`'s neighbors.
    fn candidates(&self, cell: usize) -> BTreeSet<u8> {
        let mut non_candidates = BTreeSet::new();
        for n in neighbors(cell) {
            let x = self.0[n];
            if x != 0 {
                non_candidates.insert(x);
            }
        }
        let mut candidates: BTreeSet<u8> = (1_u8 .. (N+1) as u8).collect();
        for nc in non_candidates {
            candidates.remove(&nc);
        }
        candidates
    }

    /// Solve a sudoku board by backtracking.
    /// Return true if the board is solved, false otherwise.
    fn solve(&mut self, cell: usize) -> bool {
        if cell >= NSQ {
            return true;
        }

        if self.is_solved(cell) {
            return self.solve(cell + 1);
        }

        for c in self.candidates(cell) {
            self.0[cell] = c;
            if self.solve(cell + 1) {
                return true;
            } else {
                self.0[cell] = 0;
            }
        }
        return false;
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(".94...13..............76..2.8..1.....32.........2...6.....5.4.......8..7..63.4..8");
    println!("{}", sb.to_str());
    sb.solve(0);
    println!("{}", sb.to_str());
}

#[test]
fn test_row_col() {
    assert_eq!(row(11), 1);
    assert_eq!(col(11), 2);
}

#[test]
fn test_group() {
    assert_eq!(group(0), 0);
    assert_eq!(group(1), 0);
    assert_eq!(group(2), 0);
    assert_eq!(group(9), 0);
    assert_eq!(group(10), 0);
    assert_eq!(group(11), 0);
    assert_eq!(group(18), 0);
    assert_eq!(group(19), 0);
    assert_eq!(group(20), 0);
    assert_eq!(group(60), 60);
    assert_eq!(group(61), 60);
    assert_eq!(group(62), 60);
    assert_eq!(group(69), 60);
    assert_eq!(group(70), 60);
    assert_eq!(group(71), 60);
    assert_eq!(group(78), 60);
    assert_eq!(group(79), 60);
    assert_eq!(group(80), 60);
}

#[test]
fn test_is_solved() {
    let sb = SudokuBoard(vec![0, 1]);
    assert!(!sb.is_solved(0));
    assert!(sb.is_solved(1));
}

#[test]
fn test_neighbors() {
    assert!(!neighbors(0).contains(&0));
    // Neighbors of 0 on the same row
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&3));
    assert!(neighbors(0).contains(&4));
    assert!(neighbors(0).contains(&5));
    assert!(neighbors(0).contains(&6));
    assert!(neighbors(0).contains(&7));
    assert!(neighbors(0).contains(&8));
    // Neighbors of 0 on the same col
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&27));
    assert!(neighbors(0).contains(&36));
    assert!(neighbors(0).contains(&45));
    assert!(neighbors(0).contains(&54));
    assert!(neighbors(0).contains(&63));
    assert!(neighbors(0).contains(&72));
    // Neighbors of 0 in the same group
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&10));
    assert!(neighbors(0).contains(&11));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&19));
    assert!(neighbors(0).contains(&20));
}

#[test]
fn test_candidates() {
    let sb = SudokuBoard::from_str(".2......34..........6...................................................5........");
    assert!(!sb.candidates(0).contains(&2));
    assert!(!sb.candidates(0).contains(&3));
    assert!(!sb.candidates(0).contains(&4));
    assert!(!sb.candidates(0).contains(&5));
    assert!(!sb.candidates(0).contains(&6));
    assert!(sb.candidates(0).contains(&1));
    assert!(sb.candidates(0).contains(&7));
    assert!(sb.candidates(0).contains(&8));
    assert!(sb.candidates(0).contains(&9));
}
<commit_msg>Add comments to solve()<commit_after>use std::char;
use std::collections::BTreeSet;

const NSQRT: usize = 3;
const N: usize = NSQRT * NSQRT;
const NSQ: usize = N*N;

/// Return the 0-based row index of `cell`.
fn row(cell: usize) -> usize {
    cell / N
}

/// Return the 0-based row index of `cell`.
fn col(cell: usize) -> usize {
    cell % N
}

/// Return the 0-based index of the upper-left cell of `cell`'s group.
fn group(cell: usize) -> usize {
    let r = row(cell);
    let c = col(cell);
    (N * (r - r % NSQRT)) + (c - c % NSQRT)
}

/// Return the neighbors of `cell`:
/// - The cells on the same row;
/// - The cells on the same column;
/// - The same in the same group.
/// Note: `cell` is not a neighbor of itself.
fn neighbors(cell: usize) -> BTreeSet<usize> {
    let mut all_neighbors: BTreeSet<usize> = BTreeSet::new();

    // Neighbors on row
    for col in 0..N {
        all_neighbors.insert((N * row(cell)) + col);
    }

    // Neighbors on column
    for row in 0..N {
        all_neighbors.insert((N * row) + col(cell));
    }

    // Neighbors in group
    let leader = group(cell);
    for r in row(leader) .. row(leader) + NSQRT {
        for c in col(leader) .. col(leader) + NSQRT {
            all_neighbors.insert(N * r + c);
        }
    }

    all_neighbors.remove(&cell);
    return all_neighbors;
}

/// A sudoku board is represented by a vector of bytes.
#[derive(Debug)]
struct SudokuBoard(Vec<u8>);

impl SudokuBoard {
    /// Create a new sudoku board from a string.
    /// A non-zero digit stands for itself,
    /// a dot stands for a blank cell,
    /// anything else is an error.
    // TODO(vfoley): more error handling (length check)
    fn from_str(digits: &str) -> Self {
        let mut v = Vec::with_capacity(NSQ);
        for d in digits.chars() {
            match d {
                '.' => { v.push(0); }
                '1' ... '9' => {
                    let n = d.to_digit(10).unwrap() as u8;
                    v.push(n);
                }
                _ => { panic!("invalid digit ({:?}) in string", d); }
            }
        }
        SudokuBoard(v)
    }

    /// Convert a sudoku board to a rough string representation.
    fn to_str(&self) -> String {
        let mut s = String::with_capacity(N + NSQ);
        let mut i = 0;
        for n in self.0.iter() {
            if i % N == 0 {
                s.push('\n');
            }
            if *n == 0 {
                s.push('.');
            } else {
                s.push(char::from_digit(*n as u32, 10).unwrap());
            }
            i += 1;
        }
        s
    }

    /// A cell is solved if its content is non-zero.
    fn is_solved(&self, cell: usize) -> bool {
        self.0[cell] != 0
    }

    /// Return the list of candidates for a cell.
    /// The candidates are the digits from 1 to NSQ
    /// that are *not* solved in any of `cell`'s neighbors.
    fn candidates(&self, cell: usize) -> BTreeSet<u8> {
        let mut non_candidates = BTreeSet::new();
        for n in neighbors(cell) {
            let x = self.0[n];
            if x != 0 {
                non_candidates.insert(x);
            }
        }
        let mut candidates: BTreeSet<u8> = (1_u8 .. (N+1) as u8).collect();
        for nc in non_candidates {
            candidates.remove(&nc);
        }
        candidates
    }

    /// Solve a sudoku board by backtracking.
    /// Return true if the board is solved, false otherwise.
    fn solve(&mut self, cell: usize) -> bool {
        // If we reach the end of the board (NSQ'th cell),
        // we have solved the board, i.e., put digits into
        // cells without backtracking.
        if cell >= NSQ {
            return true;
        }

        // Skip over already-solved cells (initial solutions)
        if self.is_solved(cell) {
            return self.solve(cell + 1);
        }

        // Try the candidates in order.
        // Loop invariant: self.0[cell] = 0
        // coming into the loop and exiting the loop.
        for c in self.candidates(cell) {
            self.0[cell] = c;
            if self.solve(cell + 1) {
                return true;
            } else {
                self.0[cell] = 0;
            }
        }
        // No candidate satisfied the constraints, backtrack.
        return false;
    }
}

fn main() {
    let mut sb = SudokuBoard::from_str(".94...13..............76..2.8..1.....32.........2...6.....5.4.......8..7..63.4..8");
    println!("{}", sb.to_str());
    sb.solve(0);
    println!("{}", sb.to_str());
}

#[test]
fn test_row_col() {
    assert_eq!(row(11), 1);
    assert_eq!(col(11), 2);
}

#[test]
fn test_group() {
    assert_eq!(group(0), 0);
    assert_eq!(group(1), 0);
    assert_eq!(group(2), 0);
    assert_eq!(group(9), 0);
    assert_eq!(group(10), 0);
    assert_eq!(group(11), 0);
    assert_eq!(group(18), 0);
    assert_eq!(group(19), 0);
    assert_eq!(group(20), 0);
    assert_eq!(group(60), 60);
    assert_eq!(group(61), 60);
    assert_eq!(group(62), 60);
    assert_eq!(group(69), 60);
    assert_eq!(group(70), 60);
    assert_eq!(group(71), 60);
    assert_eq!(group(78), 60);
    assert_eq!(group(79), 60);
    assert_eq!(group(80), 60);
}

#[test]
fn test_is_solved() {
    let sb = SudokuBoard(vec![0, 1]);
    assert!(!sb.is_solved(0));
    assert!(sb.is_solved(1));
}

#[test]
fn test_neighbors() {
    assert!(!neighbors(0).contains(&0));
    // Neighbors of 0 on the same row
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&3));
    assert!(neighbors(0).contains(&4));
    assert!(neighbors(0).contains(&5));
    assert!(neighbors(0).contains(&6));
    assert!(neighbors(0).contains(&7));
    assert!(neighbors(0).contains(&8));
    // Neighbors of 0 on the same col
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&27));
    assert!(neighbors(0).contains(&36));
    assert!(neighbors(0).contains(&45));
    assert!(neighbors(0).contains(&54));
    assert!(neighbors(0).contains(&63));
    assert!(neighbors(0).contains(&72));
    // Neighbors of 0 in the same group
    assert!(neighbors(0).contains(&1));
    assert!(neighbors(0).contains(&2));
    assert!(neighbors(0).contains(&9));
    assert!(neighbors(0).contains(&10));
    assert!(neighbors(0).contains(&11));
    assert!(neighbors(0).contains(&18));
    assert!(neighbors(0).contains(&19));
    assert!(neighbors(0).contains(&20));
}

#[test]
fn test_candidates() {
    let sb = SudokuBoard::from_str(".2......34..........6...................................................5........");
    assert!(!sb.candidates(0).contains(&2));
    assert!(!sb.candidates(0).contains(&3));
    assert!(!sb.candidates(0).contains(&4));
    assert!(!sb.candidates(0).contains(&5));
    assert!(!sb.candidates(0).contains(&6));
    assert!(sb.candidates(0).contains(&1));
    assert!(sb.candidates(0).contains(&7));
    assert!(sb.candidates(0).contains(&8));
    assert!(sb.candidates(0).contains(&9));
}
<|endoftext|>


<commit_before>#![feature(std_misc)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize as rustc_serialize;
extern crate threadpool;
extern crate num_cpus;
extern crate tray_rust;

use std::vec::Vec;
use std::sync::{Arc};
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver};
use std::time::duration::Duration;
use std::path::Path;

use threadpool::ThreadPool;
use rand::StdRng;
use docopt::Docopt;

use tray_rust::film;
use tray_rust::geometry::Geometry;
use tray_rust::sampler;
use tray_rust::sampler::{Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static WIDTH: usize = 800;
static HEIGHT: usize = 600;
static USAGE: &'static str = "
Usage: tray_rust [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    flag_o: Option<String>,
    flag_n: Option<usize>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<(f32, f32, film::Colorf)>, queue: Arc<sampler::BlockQueue>,
               scene: Arc<scene::Scene>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), 64);
    let mut samples = Vec::with_capacity(sampler.max_spp());
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            for s in sample_pos.iter() {
                let mut ray = scene.camera.generate_ray(s);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(&*scene, &ray, &hit, &mut sampler, &mut rng).clamp();
                    samples.push((s.0, s.1, c));
                }
            }
            for s in samples.iter() {
                if let Err(e) = tx.send(*s) {
                    println!("Worker thread exiting with send error {:?}", e);
                    return;
                }
            }
            samples.clear();
        }
    }
}

/// Spawn `n` worker threads to render the scene in parallel. Returns the receive end
/// of the channel where the threads will write their samples so that the receiver
/// can write these samples to the render target
fn spawn_workers(pool: &ThreadPool, n: usize, scene: Arc<scene::Scene>) -> Receiver<(f32, f32, film::Colorf)> {
    let (tx, rx) = mpsc::channel();
    let block_queue = Arc::new(sampler::BlockQueue::new((WIDTH as u32, HEIGHT as u32), (8, 8)));
    for _ in 0..n {
        let q = block_queue.clone();
        let t = tx.clone();
        let s = scene.clone();
        pool.execute(move || {
            thread_work(t, q, s);
        });
    }
    rx
}

/// Render the scene in parallel to the render target
fn render_parallel(rt: &mut film::RenderTarget, n: usize){
    let scene = Arc::new(scene::Scene::new(WIDTH, HEIGHT));
    let pool = ThreadPool::new(n);
    let rx = spawn_workers(&pool, n, scene);
    for m in rx.iter() {
        rt.write(m.0, m.1, &m.2);
    }
}

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

    let mut rt = film::RenderTarget::new(WIDTH, HEIGHT);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get(),
    };
    println!("Rendering using {} threads", n);
    let d = Duration::span(|| render_parallel(&mut rt, n));
    println!("Rendering took {}ms", d.num_milliseconds());
    let img = rt.get_render();
    let out_file = match args.flag_o {
        Some(f) => f,
        None => "out.png".to_string(),
    };
    match image::save_buffer(&Path::new(&out_file), &img[..], WIDTH as u32, HEIGHT as u32, image::RGB(8)) {
        Ok(_) => {},
        Err(e) => println!("Error saving image, {}", e),
    };
}

<commit_msg>Duration just had some big changes land so broken in nightly<commit_after>extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize as rustc_serialize;
extern crate threadpool;
extern crate num_cpus;
extern crate tray_rust;

use std::vec::Vec;
use std::sync::{Arc};
use std::sync::mpsc::{self, Sender, Receiver};
use std::path::Path;

use threadpool::ThreadPool;
use rand::StdRng;
use docopt::Docopt;

use tray_rust::film;
use tray_rust::geometry::Geometry;
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static WIDTH: usize = 800;
static HEIGHT: usize = 600;
static USAGE: &'static str = "
Usage: tray_rust [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    flag_o: Option<String>,
    flag_n: Option<usize>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<(f32, f32, film::Colorf)>, queue: Arc<sampler::BlockQueue>,
               scene: Arc<scene::Scene>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), 64);
    let mut samples = Vec::with_capacity(sampler.max_spp());
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            for s in sample_pos.iter() {
                let mut ray = scene.camera.generate_ray(s);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(&*scene, &ray, &hit, &mut sampler, &mut rng).clamp();
                    samples.push((s.0, s.1, c));
                }
            }
            for s in samples.iter() {
                if let Err(e) = tx.send(*s) {
                    println!("Worker thread exiting with send error {:?}", e);
                    return;
                }
            }
            samples.clear();
        }
    }
}

/// Spawn `n` worker threads to render the scene in parallel. Returns the receive end
/// of the channel where the threads will write their samples so that the receiver
/// can write these samples to the render target
fn spawn_workers(pool: &ThreadPool, n: usize, scene: Arc<scene::Scene>) -> Receiver<(f32, f32, film::Colorf)> {
    let (tx, rx) = mpsc::channel();
    let block_queue = Arc::new(sampler::BlockQueue::new((WIDTH as u32, HEIGHT as u32), (8, 8)));
    for _ in 0..n {
        let q = block_queue.clone();
        let t = tx.clone();
        let s = scene.clone();
        pool.execute(move || {
            thread_work(t, q, s);
        });
    }
    rx
}

/// Render the scene in parallel to the render target
fn render_parallel(rt: &mut film::RenderTarget, n: usize){
    let scene = Arc::new(scene::Scene::new(WIDTH, HEIGHT));
    let pool = ThreadPool::new(n);
    let rx = spawn_workers(&pool, n, scene);
    for m in rx.iter() {
        rt.write(m.0, m.1, &m.2);
    }
}

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

    let mut rt = film::RenderTarget::new(WIDTH, HEIGHT);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get(),
    };
    println!("Rendering using {} threads", n);
    render_parallel(&mut rt, n);
    // TODO: Migrate to the new duration API that landed
    // See: https://github.com/rust-lang/rust/pull/24920
    //let d = std::time::duration::Duration::span(|| render_parallel(&mut rt, n));
    //println!("Rendering took {}ms", d.num_milliseconds());
    let img = rt.get_render();
    let out_file = match args.flag_o {
        Some(f) => f,
        None => "out.png".to_string(),
    };
    match image::save_buffer(&Path::new(&out_file), &img[..], WIDTH as u32, HEIGHT as u32, image::RGB(8)) {
        Ok(_) => {},
        Err(e) => println!("Error saving image, {}", e),
    };
}

<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>binary read<commit_after>use std::env;
use std::fs;
use std::io::Read;
use std::path::Path;

fn main() {
    let pif_file_name = env::args().nth(1).unwrap();
    let rom_file_name = env::args().nth(2).unwrap();

    let pif = load_bin(pif_file_name);
    let rom = load_bin(rom_file_name);
}

fn load_bin<P: AsRef<Path>>(path: P) -> Vec<u8> {
    let mut file = fs::File::open(path).unwrap();
    let mut file_buf = Vec::new();
    file.read_to_end(&mut file_buf).unwrap();
    file_buf
}
<|endoftext|>