<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process;

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean {
        all: bool,
    },
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(1);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            "clean" => { opts.optflag("", "all", "clean all build artifacts"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else {
            extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
                     subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean takes no arguments\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }

                Subcommand::Clean {
                    all: matches.opt_present("all"),
                }
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        let cwd = t!(env::current_dir());
        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd);

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            src,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<commit_msg>Do not show "available paths" help in ./x.py clean<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process;

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean {
        all: bool,
    },
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(1);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            "clean" => { opts.optflag("", "all", "clean all build artifacts"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands except `clean` can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else if subcommand.as_str() != "clean" {
            extra_help.push_str(format!(
                "Run `./x.py {} -h -v` to see a list of available paths.",
                subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean does not take a path argument\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }

                Subcommand::Clean {
                    all: matches.opt_present("all"),
                }
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        let cwd = t!(env::current_dir());
        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd);

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            src,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<|endoftext|>


<commit_before><commit_msg>Add xfailed test for #3707<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
struct Obj {
    member: uint
}

impl Obj {
    static pure fn boom() -> bool {
        return 1+1 == 2
    }
    pure fn chirp() {
        self.boom(); //~ ERROR wat
    }
}

fn main() {
    let o = Obj { member: 0 };
    o.chirp();
    1 + 1;
}
<|endoftext|>


<commit_before>extern crate cards;
extern crate libthyme;
extern crate ncurses;

use super::{Action,UI};
use libthyme::board::{Position,HPosition,VPosition};
use libthyme::game::Game;
use libthyme::score::Scorer;

const CARD_WIDTH: i32 = 7;
const CARD_HEIGHT: i32 = 5;
const CARD_MARGIN: i32 = 2;
const BOARD_MARGIN: i32 = 2;
const STATUS_HEIGHT: i32 = 2;

const CARD_COLOR_BLACK: i16 = 1; // black on white
const CARD_COLOR_RED: i16 = 2; // red on white
const CARD_COLOR_EMPTY: i16 = 4; // white on black
const SELECTED_COLOR: i16 = 5; // yellow on black
const CURSOR_INFO_COLOR: i16 = 6; // cyan on black
const GAME_INFO_COLOR: i16 = 7; // green on black
const BG_COLOR: i16 = ncurses::COLOR_BLACK;
const CARD_BG_COLOR: i16 = ncurses::COLOR_WHITE;

/// Set up the UI
pub fn initialize_screen() {
    ncurses::setlocale(ncurses::LcCategory::ctype, "");
    ncurses::initscr();
    ncurses::noecho();
    ncurses::start_color();
    ncurses::keypad(ncurses::stdscr, true);
    ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE);
    ncurses::init_pair(CARD_COLOR_BLACK, ncurses::COLOR_BLACK, CARD_BG_COLOR);
    ncurses::init_pair(CARD_COLOR_RED, ncurses::COLOR_RED, CARD_BG_COLOR);
    ncurses::init_pair(CARD_COLOR_EMPTY, ncurses::COLOR_WHITE, BG_COLOR);
    ncurses::init_pair(SELECTED_COLOR, ncurses::COLOR_YELLOW, BG_COLOR);
    ncurses::init_pair(CURSOR_INFO_COLOR, ncurses::COLOR_CYAN, BG_COLOR);
    ncurses::init_pair(GAME_INFO_COLOR, ncurses::COLOR_GREEN, BG_COLOR);
}

/// Redraw a UI in the current screen
pub fn redraw<T: Scorer>(ui: &UI, game: &mut Game<T>, refresh: bool) {
    if refresh {
        ncurses::clear();
        ncurses::bkgd(ncurses::COLOR_PAIR(CARD_COLOR_EMPTY));
    }
    if validate_screen_size() {
        write_title(game);
        draw_cards(ui, game);
        write_cursor_message(ui, game);
        write_message(&ui.message);
    }
    ncurses::refresh();
}

/// Tear down the UI
pub fn cleanup() {
    ncurses::endwin();
}

/// Process input from the user
///
/// Known inputs:
/// - Arrow keys: Move cursor between various positions on the board
/// - Q: Quit game
/// - H: Hint (unimplemented)
/// - ?: Help
/// - Space: Toggle position selection
/// - Return: Play move, clear selection
pub fn get_action() -> Action {
    return match ncurses::getch() {
        ncurses::KEY_LEFT => Action::CursorLeft,
        ncurses::KEY_RIGHT => Action::CursorRight,
        ncurses::KEY_UP => Action::CursorUp,
        ncurses::KEY_DOWN => Action::CursorDown,
        ncurses::KEY_RESIZE => Action::Resize,
        ncurses::KEY_ENTER | 13 | 10 => Action::Play,
        32 =>  Action::ToggleSelection, // Space
        113 => Action::Quit, // Q
        104 => Action::Hint, // H
        63 =>  Action::Help, // ?
        _ =>   Action::Unknown
    }
}

/// Check that the content can fit
fn validate_screen_size() -> bool {
    let min_height = BOARD_MARGIN*2 + CARD_MARGIN*4 + STATUS_HEIGHT + CARD_HEIGHT*3;
    if ncurses::LINES < min_height || ncurses::COLS < 50 {
        write_message(&format!(
                "Please resize your terminal to be at least 50x{}",
                min_height));
        return false
    }
    return true
}

/// Print the game title and status info
fn write_title<T: Scorer>(game: &mut Game<T>) {
    printw_margin(0, 0);
    ncurses::attron(ncurses::A_BOLD());
    ncurses::printw("Thyme");
    ncurses::attroff(ncurses::A_BOLD());
    ncurses::printw(&format!(" - Score: {}", game.score()));
    printw_margin(0, 1);
    let (_, suit) = layout_suit(game.board.lucky_card);
    let info = ncurses::COLOR_PAIR(GAME_INFO_COLOR);
    ncurses::attron(info);
    ncurses::printw(&format!("Lucky Suit: {}  Discards Left: {}/{}", suit,
                             game.discards_allowed, game.discards_allowed_max));
    ncurses::clrtoeol();
    ncurses::attroff(info);
}

/// Print the message at the bottom of the window
fn write_message(message: &str) {
    printw_margin(0, ncurses::LINES - 1);
    ncurses::printw(message);
    ncurses::clrtoeol();
}

fn write_cursor_message<T: Scorer>(ui: &UI, game: &Game<T>) {
    let stacked_cards = game.board.count_cards(ui.cursor_position);
    let all_cards = game.board.count_all_cards();
    let message = format!("*{}/{} cards in the stack", stacked_cards, all_cards);
    let color = ncurses::COLOR_PAIR(CURSOR_INFO_COLOR);
    printw_margin(0, ncurses::LINES - 2);
    ncurses::attron(color);
    ncurses::printw(&message);
    ncurses::clrtoeol();
    ncurses::attroff(color);
}

fn printw_margin(x: i32, y: i32) {
    ncurses::mv(y, x);
    printw_repeat(" ", BOARD_MARGIN, ncurses::COLOR_PAIR(CARD_COLOR_EMPTY));
}

fn draw_cards<T: Scorer>(ui: &UI, game: &mut Game<T>) {
    for position in game.board.positions() {
        let card = game.board.top(position);
        if card.is_some() {
            draw_card(position, card.unwrap());
        } else {
            draw_empty(position);
        }
        let (x, y) = card_location(position);
        toggle_highlight_card(x, y, ui.selection.contains(&position));
        if position == ui.cursor_position {
            let offset = (CARD_WIDTH as f32 /2.0).floor() as i32;
            ncurses::mvprintw(y + CARD_HEIGHT, x + offset, "*");
        }
    }
}

/// Draw a card on the board at a position
fn draw_card(position: Position, card: cards::card::Card) {
    let (x, y) = card_location(position);
    let (color, suit) = layout_suit(card);
    let value = layout_value(card);
    let black = ncurses::COLOR_PAIR(CARD_COLOR_BLACK);
    ncurses::attron(black);
    ncurses::mvprintw(y, x, &value);
    ncurses::attroff(black);
    ncurses::attron(color);
    ncurses::mvprintw(y, x + value.len() as i32, &suit);
    ncurses::attroff(color);
    let spacing = CARD_WIDTH - value.len() as i32 - 1;
    printw_repeat(" ", spacing, black);
    for i in 1..CARD_HEIGHT - 1 {
        ncurses::mv(y + i, x);
        printw_repeat(" ", CARD_WIDTH, black);
    }
    ncurses::mv(y + CARD_HEIGHT - 1, x);
    printw_repeat(" ", spacing, black);
    ncurses::attron(black);
    ncurses::printw(&value);
    ncurses::attroff(black);
    ncurses::attron(color);
    ncurses::printw(&suit);
    ncurses::attroff(color);
}

/// Draw empty slot for a card
fn draw_empty(position: Position) {
    let color = ncurses::COLOR_PAIR(CARD_COLOR_EMPTY);
    let (x, y) = card_location(position);
    ncurses::attron(color);
    ncurses::mvprintw(y, x, "┌");
    printw_repeat("─", CARD_WIDTH - 2, color);
    ncurses::mvprintw(y, x + CARD_WIDTH - 1, "┐");
    ncurses::attroff(color);
    for i in 1..CARD_HEIGHT - 1 {
        ncurses::attron(color);
        ncurses::mvprintw(y + i, x , "│");
        printw_repeat(" ", CARD_WIDTH - 2, color);
        ncurses::attroff(color);
        ncurses::attron(color);
        ncurses::mvprintw(y + i, x + CARD_WIDTH - 1, "│");
        ncurses::attroff(color);
    }
    ncurses::attron(color);
    ncurses::mvprintw(y + CARD_HEIGHT - 1, x, "└");
    printw_repeat("─", CARD_WIDTH - 2, color);
    ncurses::mvprintw(y + CARD_HEIGHT - 1, x + CARD_WIDTH - 1, "┘");
    ncurses::attroff(color);
}

fn printw_repeat(content: &str, len: i32, color: u64) {
    ncurses::attron(color);
    for _ in 0..len {
       ncurses::printw(content);
    }
    ncurses::attroff(color);
}

fn toggle_highlight_card(x: i32, y: i32, on: bool) {
    let color = ncurses::COLOR_PAIR(SELECTED_COLOR);
    ncurses::attron(color);
    ncurses::mvprintw(y - 1, x - 1, if on {"┌"} else {" "});
    ncurses::attroff(color);
    ncurses::mv(y - 1, x);
    printw_repeat(if on {"─"} else {" "}, CARD_WIDTH, color);
    ncurses::mv(y + CARD_HEIGHT, x);
    printw_repeat(if on {"─"} else {" "}, CARD_WIDTH, color);
    ncurses::attron(color);
    ncurses::mvprintw(y - 1, x + CARD_WIDTH, if on {"┐"} else {" "});
    for i in 0..CARD_HEIGHT {
        ncurses::mvprintw(y + i, x - 1, if on {"│"} else {" "});
        ncurses::mvprintw(y + i, x + CARD_WIDTH, if on {"│"} else {" "});
    }
    ncurses::mvprintw(y + CARD_HEIGHT, x - 1, if on {"└"} else {" "});
    ncurses::mvprintw(y + CARD_HEIGHT, x + CARD_WIDTH, if on {"┘"} else {" "});
    ncurses::attroff(color);
}

fn layout_suit(card: cards::card::Card) -> (u64, String) {
    let black = ncurses::COLOR_PAIR(CARD_COLOR_BLACK);
    let red = ncurses::COLOR_PAIR(CARD_COLOR_RED);
    return match card.suit {
        cards::card::Suit::Diamonds => (red, "\u{2666}".to_string()),
        cards::card::Suit::Clubs => (black, "\u{2663}".to_string()),
        cards::card::Suit::Spades => (black, "\u{2660}".to_string()),
        cards::card::Suit::Hearts => (red, "\u{2665}".to_string()),
    }
}

fn layout_value(card: cards::card::Card) -> String {
    return match card.value {
        cards::card::Value::Ace => "A",
        cards::card::Value::Two => "2",
        cards::card::Value::Three => "3",
        cards::card::Value::Four => "4",
        cards::card::Value::Five => "5",
        cards::card::Value::Six => "6",
        cards::card::Value::Seven => "7",
        cards::card::Value::Eight => "8",
        cards::card::Value::Nine => "9",
        cards::card::Value::Ten => "10",
        cards::card::Value::Jack => "J",
        cards::card::Value::Queen => "Q",
        cards::card::Value::King => "K",
    }.to_string()
}

/// Location (x, y) for a card position
fn card_location(position: Position) -> (i32, i32) {
    let left = BOARD_MARGIN + CARD_MARGIN;
    let center = BOARD_MARGIN + CARD_MARGIN*2 + CARD_WIDTH;
    let right = BOARD_MARGIN + CARD_MARGIN*3 + CARD_WIDTH*2;
    let top = BOARD_MARGIN + CARD_MARGIN;
    let middle = BOARD_MARGIN + CARD_MARGIN*2 + CARD_HEIGHT;
    let bottom = BOARD_MARGIN + CARD_MARGIN*3 + CARD_HEIGHT*2;
    match (position.x, position.y) {
        (HPosition::Left, VPosition::Top) => (left, top),
        (HPosition::Left, VPosition::Middle) => (left, middle),
        (HPosition::Left, VPosition::Bottom) => (left, bottom),
        (HPosition::Center, VPosition::Top) => (center, top),
        (HPosition::Center, VPosition::Middle) => (center, middle),
        (HPosition::Center, VPosition::Bottom) => (center, bottom),
        (HPosition::Right, VPosition::Top) => (right, top),
        (HPosition::Right, VPosition::Middle) => (right, middle),
        (HPosition::Right, VPosition::Bottom) => (right, bottom),
    }
}
<commit_msg>Print clear bonuses in empty stacks<commit_after>extern crate cards;
extern crate libthyme;
extern crate ncurses;

use super::{Action,UI};
use libthyme::board::{Position,HPosition,VPosition};
use libthyme::game::Game;
use libthyme::score::Scorer;
use std::cmp;

const CARD_WIDTH: i32 = 7;
const CARD_HEIGHT: i32 = 5;
const CARD_MARGIN: i32 = 2;
const BOARD_MARGIN: i32 = 2;
const STATUS_HEIGHT: i32 = 2;

const CARD_COLOR_BLACK: i16 = 1; // black on white
const CARD_COLOR_RED: i16 = 2; // red on white
const CARD_COLOR_EMPTY: i16 = 4; // white on black
const SELECTED_COLOR: i16 = 5; // yellow on black
const CURSOR_INFO_COLOR: i16 = 6; // cyan on black
const GAME_INFO_COLOR: i16 = 7; // green on black
const BG_COLOR: i16 = ncurses::COLOR_BLACK;
const CARD_BG_COLOR: i16 = ncurses::COLOR_WHITE;

/// Set up the UI
pub fn initialize_screen() {
    ncurses::setlocale(ncurses::LcCategory::ctype, "");
    ncurses::initscr();
    ncurses::noecho();
    ncurses::start_color();
    ncurses::keypad(ncurses::stdscr, true);
    ncurses::curs_set(ncurses::CURSOR_VISIBILITY::CURSOR_INVISIBLE);
    ncurses::init_pair(CARD_COLOR_BLACK, ncurses::COLOR_BLACK, CARD_BG_COLOR);
    ncurses::init_pair(CARD_COLOR_RED, ncurses::COLOR_RED, CARD_BG_COLOR);
    ncurses::init_pair(CARD_COLOR_EMPTY, ncurses::COLOR_WHITE, BG_COLOR);
    ncurses::init_pair(SELECTED_COLOR, ncurses::COLOR_YELLOW, BG_COLOR);
    ncurses::init_pair(CURSOR_INFO_COLOR, ncurses::COLOR_CYAN, BG_COLOR);
    ncurses::init_pair(GAME_INFO_COLOR, ncurses::COLOR_GREEN, BG_COLOR);
}

/// Redraw a UI in the current screen
pub fn redraw<T: Scorer>(ui: &UI, game: &mut Game<T>, refresh: bool) {
    if refresh {
        ncurses::clear();
        ncurses::bkgd(ncurses::COLOR_PAIR(CARD_COLOR_EMPTY));
    }
    if validate_screen_size() {
        write_title(game);
        draw_cards(ui, game);
        write_cursor_message(ui, game);
        write_message(&ui.message);
    }
    ncurses::refresh();
}

/// Tear down the UI
pub fn cleanup() {
    ncurses::endwin();
}

/// Process input from the user
///
/// Known inputs:
/// - Arrow keys: Move cursor between various positions on the board
/// - Q: Quit game
/// - H: Hint (unimplemented)
/// - ?: Help
/// - Space: Toggle position selection
/// - Return: Play move, clear selection
pub fn get_action() -> Action {
    return match ncurses::getch() {
        ncurses::KEY_LEFT => Action::CursorLeft,
        ncurses::KEY_RIGHT => Action::CursorRight,
        ncurses::KEY_UP => Action::CursorUp,
        ncurses::KEY_DOWN => Action::CursorDown,
        ncurses::KEY_RESIZE => Action::Resize,
        ncurses::KEY_ENTER | 13 | 10 => Action::Play,
        32 =>  Action::ToggleSelection, // Space
        113 => Action::Quit, // Q
        104 => Action::Hint, // H
        63 =>  Action::Help, // ?
        _ =>   Action::Unknown
    }
}

/// Check that the content can fit
fn validate_screen_size() -> bool {
    let min_height = BOARD_MARGIN*2 + CARD_MARGIN*4 + STATUS_HEIGHT + CARD_HEIGHT*3;
    if ncurses::LINES < min_height || ncurses::COLS < 50 {
        write_message(&format!(
                "Please resize your terminal to be at least 50x{}",
                min_height));
        return false
    }
    return true
}

/// Print the game title and status info
fn write_title<T: Scorer>(game: &mut Game<T>) {
    printw_margin(0, 0);
    ncurses::attron(ncurses::A_BOLD());
    ncurses::printw("Thyme");
    ncurses::attroff(ncurses::A_BOLD());
    ncurses::printw(&format!(" - Score: {}", game.score()));
    printw_margin(0, 1);
    let (_, suit) = layout_suit(game.board.lucky_card);
    let info = ncurses::COLOR_PAIR(GAME_INFO_COLOR);
    ncurses::attron(info);
    ncurses::printw(&format!("Lucky Suit: {}  Discards Left: {}/{}", suit,
                             game.discards_allowed, game.discards_allowed_max));
    ncurses::clrtoeol();
    ncurses::attroff(info);
}

/// Print the message at the bottom of the window
fn write_message(message: &str) {
    printw_margin(0, ncurses::LINES - 1);
    ncurses::printw(message);
    ncurses::clrtoeol();
}

fn write_cursor_message<T: Scorer>(ui: &UI, game: &Game<T>) {
    let stacked_cards = game.board.count_cards(ui.cursor_position);
    let all_cards = game.board.count_all_cards();
    let message = format!("*{}/{} cards in the stack", stacked_cards, all_cards);
    let color = ncurses::COLOR_PAIR(CURSOR_INFO_COLOR);
    printw_margin(0, ncurses::LINES - 2);
    ncurses::attron(color);
    ncurses::printw(&message);
    ncurses::clrtoeol();
    ncurses::attroff(color);
}

fn printw_margin(x: i32, y: i32) {
    ncurses::mv(y, x);
    printw_repeat(" ", BOARD_MARGIN, ncurses::COLOR_PAIR(CARD_COLOR_EMPTY));
}

fn draw_cards<T: Scorer>(ui: &UI, game: &mut Game<T>) {
    for position in game.board.positions() {
        let card = game.board.top(position);
        if card.is_some() {
            draw_card(position, card.unwrap());
        } else {
            draw_empty(game, position);
        }
        let (x, y) = card_location(position);
        toggle_highlight_card(x, y, ui.selection.contains(&position));
        if position == ui.cursor_position {
            let offset = (CARD_WIDTH as f32 /2.0).floor() as i32;
            ncurses::mvprintw(y + CARD_HEIGHT, x + offset, "*");
        }
    }
}

/// Draw a card on the board at a position
fn draw_card(position: Position, card: cards::card::Card) {
    let (x, y) = card_location(position);
    let (color, suit) = layout_suit(card);
    let value = layout_value(card);
    let black = ncurses::COLOR_PAIR(CARD_COLOR_BLACK);
    ncurses::attron(black);
    ncurses::mvprintw(y, x, &value);
    ncurses::attroff(black);
    ncurses::attron(color);
    ncurses::mvprintw(y, x + value.len() as i32, &suit);
    ncurses::attroff(color);
    let spacing = CARD_WIDTH - value.len() as i32 - 1;
    printw_repeat(" ", spacing, black);
    for i in 1..CARD_HEIGHT - 1 {
        ncurses::mv(y + i, x);
        printw_repeat(" ", CARD_WIDTH, black);
    }
    ncurses::mv(y + CARD_HEIGHT - 1, x);
    printw_repeat(" ", spacing, black);
    ncurses::attron(black);
    ncurses::printw(&value);
    ncurses::attroff(black);
    ncurses::attron(color);
    ncurses::printw(&suit);
    ncurses::attroff(color);
}

/// Draw empty slot for a card
fn draw_empty<T: Scorer>(game: &Game<T>, position: Position) {
    let color = ncurses::COLOR_PAIR(CARD_COLOR_EMPTY);
    let (x, y) = card_location(position);
    ncurses::attron(color);
    ncurses::mvprintw(y, x, "┌");
    printw_repeat("─", CARD_WIDTH - 2, color);
    ncurses::mvprintw(y, x + CARD_WIDTH - 1, "┐");
    ncurses::attroff(color);
    let gap_height = CARD_HEIGHT - 1;
    let bonus_height = gap_height/2;
    for i in 1..gap_height {
        ncurses::attron(color);
        ncurses::mvprintw(y + i, x , "│");
        if i == bonus_height {
            let bonus = format!("{}", game.scorer.bonus(position));
            let available_width = cmp::max(0, CARD_WIDTH - 2 - bonus.len() as i32);
            let lede = available_width/2;
            printw_repeat(" ", lede, color);
            ncurses::printw(&bonus);
            printw_repeat(" ", lede, color);
        } else {
            printw_repeat(" ", CARD_WIDTH - 2, color);
        }
        ncurses::attroff(color);
        ncurses::attron(color);
        ncurses::mvprintw(y + i, x + CARD_WIDTH - 1, "│");
        ncurses::attroff(color);
    }
    ncurses::attron(color);
    ncurses::mvprintw(y + CARD_HEIGHT - 1, x, "└");
    printw_repeat("─", CARD_WIDTH - 2, color);
    ncurses::mvprintw(y + CARD_HEIGHT - 1, x + CARD_WIDTH - 1, "┘");
    ncurses::attroff(color);
}

fn printw_repeat(content: &str, len: i32, color: u64) {
    ncurses::attron(color);
    for _ in 0..len {
       ncurses::printw(content);
    }
    ncurses::attroff(color);
}

fn toggle_highlight_card(x: i32, y: i32, on: bool) {
    let color = ncurses::COLOR_PAIR(SELECTED_COLOR);
    ncurses::attron(color);
    ncurses::mvprintw(y - 1, x - 1, if on {"┌"} else {" "});
    ncurses::attroff(color);
    ncurses::mv(y - 1, x);
    printw_repeat(if on {"─"} else {" "}, CARD_WIDTH, color);
    ncurses::mv(y + CARD_HEIGHT, x);
    printw_repeat(if on {"─"} else {" "}, CARD_WIDTH, color);
    ncurses::attron(color);
    ncurses::mvprintw(y - 1, x + CARD_WIDTH, if on {"┐"} else {" "});
    for i in 0..CARD_HEIGHT {
        ncurses::mvprintw(y + i, x - 1, if on {"│"} else {" "});
        ncurses::mvprintw(y + i, x + CARD_WIDTH, if on {"│"} else {" "});
    }
    ncurses::mvprintw(y + CARD_HEIGHT, x - 1, if on {"└"} else {" "});
    ncurses::mvprintw(y + CARD_HEIGHT, x + CARD_WIDTH, if on {"┘"} else {" "});
    ncurses::attroff(color);
}

fn layout_suit(card: cards::card::Card) -> (u64, String) {
    let black = ncurses::COLOR_PAIR(CARD_COLOR_BLACK);
    let red = ncurses::COLOR_PAIR(CARD_COLOR_RED);
    return match card.suit {
        cards::card::Suit::Diamonds => (red, "\u{2666}".to_string()),
        cards::card::Suit::Clubs => (black, "\u{2663}".to_string()),
        cards::card::Suit::Spades => (black, "\u{2660}".to_string()),
        cards::card::Suit::Hearts => (red, "\u{2665}".to_string()),
    }
}

fn layout_value(card: cards::card::Card) -> String {
    return match card.value {
        cards::card::Value::Ace => "A",
        cards::card::Value::Two => "2",
        cards::card::Value::Three => "3",
        cards::card::Value::Four => "4",
        cards::card::Value::Five => "5",
        cards::card::Value::Six => "6",
        cards::card::Value::Seven => "7",
        cards::card::Value::Eight => "8",
        cards::card::Value::Nine => "9",
        cards::card::Value::Ten => "10",
        cards::card::Value::Jack => "J",
        cards::card::Value::Queen => "Q",
        cards::card::Value::King => "K",
    }.to_string()
}

/// Location (x, y) for a card position
fn card_location(position: Position) -> (i32, i32) {
    let left = BOARD_MARGIN + CARD_MARGIN;
    let center = BOARD_MARGIN + CARD_MARGIN*2 + CARD_WIDTH;
    let right = BOARD_MARGIN + CARD_MARGIN*3 + CARD_WIDTH*2;
    let top = BOARD_MARGIN + CARD_MARGIN;
    let middle = BOARD_MARGIN + CARD_MARGIN*2 + CARD_HEIGHT;
    let bottom = BOARD_MARGIN + CARD_MARGIN*3 + CARD_HEIGHT*2;
    match (position.x, position.y) {
        (HPosition::Left, VPosition::Top) => (left, top),
        (HPosition::Left, VPosition::Middle) => (left, middle),
        (HPosition::Left, VPosition::Bottom) => (left, bottom),
        (HPosition::Center, VPosition::Top) => (center, top),
        (HPosition::Center, VPosition::Middle) => (center, middle),
        (HPosition::Center, VPosition::Bottom) => (center, bottom),
        (HPosition::Right, VPosition::Top) => (right, top),
        (HPosition::Right, VPosition::Middle) => (right, middle),
        (HPosition::Right, VPosition::Bottom) => (right, bottom),
    }
}
<|endoftext|>


<commit_before><commit_msg>Initialise package_version.rs<commit_after><|endoftext|>


<commit_before><commit_msg>easage-pack: Make kind optional and BIGF default<commit_after><|endoftext|>


<commit_before><commit_msg>stops2mimir added<commit_after>extern crate rustc_serialize;
extern crate docopt;
extern crate csv;
extern crate mimir;
use mimir::rubber::Rubber;
#[macro_use]
extern crate log;

use docopt::Docopt;

const USAGE: &'static str =
    "
Usage:
    stops2mimir --help
    stops2mimir --input=<file> \
     [--connection-string=<connection-string>] [--dataset=<dataset>]

Options:
    -h, --help              \
     Show this message.
    -i, --input=<file>      NTFS stops.txt file.
    -c, \
     --connection-string=<connection-string>
                            Elasticsearch \
     parameters, [default: http://localhost:9200/munin]
    -d, --dataset=<dataset>
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_input: String,
    flag_dataset: String,
    flag_connection_string: String,
}

struct StopPointIter<'a, R: std::io::Read + 'a> {
    iter: csv::StringRecords<'a, R>,
    stop_id_pos: usize,
    stop_lat_pos: usize,
    stop_lon_pos: usize,
    stop_name_pos: usize,
    location_type_pos: Option<usize>,
    stop_visible_pos: Option<usize>,
}
impl<'a, R: std::io::Read + 'a> StopPointIter<'a, R> {
    fn new(r: &'a mut csv::Reader<R>) -> Option<Self> {
        let headers = if let Ok(hs) = r.headers() {
            hs
        } else {
            return None;
        };
        let get = |name| headers.iter().position(|s| s == name);
        let stop_id_pos = if let Some(pos) = get("stop_id") {
            pos
        } else {
            return None;
        };
        let stop_lat_pos = if let Some(pos) = get("stop_lat") {
            pos
        } else {
            return None;
        };
        let stop_lon_pos = if let Some(pos) = get("stop_lon") {
            pos
        } else {
            return None;
        };
        let stop_name_pos = if let Some(pos) = get("stop_name") {
            pos
        } else {
            return None;
        };

        Some(StopPointIter {
            iter: r.records(),
            stop_id_pos: stop_id_pos,
            stop_lat_pos: stop_lat_pos,
            stop_lon_pos: stop_lon_pos,
            stop_name_pos: stop_name_pos,
            location_type_pos: get("location_type"),
            stop_visible_pos: get("visible"),
        })
    }
    fn get_location_type(&self, record: &[String]) -> Option<u8> {
        self.location_type_pos.and_then(|pos| record.get(pos).and_then(|s| s.parse().ok()))
    }
    fn get_visible(&self, record: &[String]) -> Option<u8> {
        self.stop_visible_pos.and_then(|pos| record.get(pos).and_then(|s| s.parse().ok()))
    }
}
impl<'a, R: std::io::Read + 'a> Iterator for StopPointIter<'a, R> {
    type Item = csv::Result<mimir::Stop>;
    fn next(&mut self) -> Option<Self::Item> {
        fn get(record: &[String], pos: usize) -> csv::Result<&str> {
            match record.get(pos) {
                Some(s) => Ok(&s),
                None => Err(csv::Error::Decode(format!("Failed accessing record '{}'.", pos))),
            }
        }
        fn parse_f64(s: &str) -> csv::Result<f64> {
            s.parse()
                .map_err(|_| csv::Error::Decode(format!("Failed converting '{}' from str.", s)))
        }
        fn is_stop_area(location_type: &Option<u8>, visible: &Option<u8>) -> csv::Result<bool> {
            if (*location_type == Some(1)) && (*visible == Some(0)) {
                Ok(true)
            } else {
                Err(csv::Error::Decode("Not stop_area.".to_string()))
            }
        }
        self.iter.next().map(|r| {
            r.and_then(|r| {
                let stop_id = try!(get(&r, self.stop_id_pos));
                let stop_lat = try!(get(&r, self.stop_lat_pos));
                let stop_lat = try!(parse_f64(stop_lat));
                let stop_lon = try!(get(&r, self.stop_lon_pos));
                let stop_lon = try!(parse_f64(stop_lon));
                let stop_name = try!(get(&r, self.stop_name_pos));
                let location_type = self.get_location_type(&r);
                let visible = self.get_visible(&r);
                try!(is_stop_area(&location_type, &visible));
                Ok(mimir::Stop {
                    id: stop_id.to_string(),
                    coord: mimir::Coord::new(stop_lat, stop_lon),
                    label: stop_name.to_string(),
                    weight: 1,
                    zip_codes: vec![],
                    administrative_regions: vec![],
                    name: stop_name.to_string(),
                })
            })
        })
    }
}

fn main() {
    println!("Launching stops2mimir...");

    let args: Args = Docopt::new(USAGE)
        .and_then(|dopt| dopt.decode())
        .unwrap_or_else(|e| e.exit());
	println!("args: {:?}", args);
    println!("creation of indexes");
    let mut rubber = Rubber::new(&args.flag_connection_string);

    let mut rdr = csv::Reader::from_file(args.flag_input)
        .unwrap()
        .double_quote(true);

    let stops: Vec<mimir::Stop> = StopPointIter::new(&mut rdr)
        .expect("Can't find needed fields in the header.")
        .filter_map(|rc| {
            rc.map_err(|e| println!("error at csv line decoding : {}", e))
                .ok()
        })
        .collect();

    println!("Importing stops into Mimir");
    let nb_stops = rubber.index("stops", &args.flag_dataset, stops.iter())
        .unwrap();

    println!("Nb of indexed stops: {}", nb_stops);

}
<|endoftext|>


<commit_before><commit_msg>rm unneeded macro<commit_after><|endoftext|>


<commit_before><commit_msg>Added constants from prctl.h<commit_after><|endoftext|>


<commit_before><commit_msg>multi bytes<commit_after><|endoftext|>


<commit_before><commit_msg>Fix #557 Closes #557<commit_after><|endoftext|>


<commit_before><commit_msg>added TPCH Q17-like query<commit_after>extern crate rand;
extern crate time;
extern crate columnar;
extern crate timely;
extern crate differential_dataflow;

extern crate docopt;
use docopt::Docopt;

use std::thread;
use std::fs::File;
use std::io::{BufRead, BufReader};

use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::*;
use timely::networking::initialize_networking;
use timely::networking::initialize_networking_from_file;

use timely::drain::DrainExt;

// use differential_dataflow::collection_trace::lookup::UnsignedInt;
// use differential_dataflow::collection_trace::LeastUpperBound;

use differential_dataflow::operators::*;

// The typical differential dataflow vertex receives updates of the form (key, time, value, update),
// where the data are logically partitioned by key, and are then subject to various aggregations by time,
// accumulating for each value the update integers. The resulting multiset is the subjected to computation.

// The implementation I am currently most comfortable with is *conservative* in the sense that it will defer updates
// until it has received all updates for a time, at which point it commits these updates permanently. This is done
// to avoid issues with running logic on partially formed data, but should also simplify our data management story.
// Rather than requiring random access to diffs, we can store them as flat arrays (possibly sorted) and integrate
// them using merge techniques. Updating cached accumulations seems maybe harder w/o hashmaps, but we'll see...

static USAGE: &'static str = "
Usage: tpch17 [options] [<arguments>...]

Options:
    -w <arg>, --workers <arg>    number of workers per process [default: 1]
    -p <arg>, --processid <arg>  identity of this process      [default: 0]
    -n <arg>, --processes <arg>  number of processes involved  [default: 1]
    -h <arg>, --hosts <arg>      list of host:port for workers
";

fn main() {

    let args = Docopt::new(USAGE).and_then(|dopt| dopt.parse()).unwrap_or_else(|e| e.exit());

    let workers: u64 = if let Ok(threads) = args.get_str("-w").parse() { threads }
                       else { panic!("invalid setting for --workers: {}", args.get_str("-t")) };
    let process_id: u64 = if let Ok(proc_id) = args.get_str("-p").parse() { proc_id }
                          else { panic!("invalid setting for --processid: {}", args.get_str("-p")) };
    let processes: u64 = if let Ok(processes) = args.get_str("-n").parse() { processes }
                         else { panic!("invalid setting for --processes: {}", args.get_str("-n")) };

    println!("Starting timely with");
    println!("\tworkers:\t{}", workers);
    println!("\tprocesses:\t{}", processes);
    println!("\tprocessid:\t{}", process_id);

    // vector holding communicators to use; one per local worker.
    if processes > 1 {
        println!("Initializing BinaryCommunicator");

        let hosts = args.get_str("-h");
        let communicators = if hosts != "" {
            initialize_networking_from_file(hosts, process_id, workers).ok().expect("error initializing networking")
        }
        else {
            let addresses = (0..processes).map(|index| format!("localhost:{}", 2101 + index).to_string()).collect();
            initialize_networking(addresses, process_id, workers).ok().expect("error initializing networking")
        };

        start_main(communicators);
    }
    else if workers > 1 {
        println!("Initializing ProcessCommunicator");
        start_main(ProcessCommunicator::new_vector(workers));
    }
    else {
        println!("Initializing ThreadCommunicator");
        start_main(vec![ThreadCommunicator]);
    };
}

fn start_main<C: Communicator+Send>(communicators: Vec<C>) {
    // let communicators = ProcessCommunicator::new_vector(1);
    let mut guards = Vec::new();
    for communicator in communicators.into_iter() {
        guards.push(thread::Builder::new().name(format!("worker thread {}", communicator.index()))
                                          .spawn(move || test_dataflow(communicator))
                                          .unwrap());
    }

    for guard in guards { guard.join().unwrap(); }
}

fn test_dataflow<C: Communicator>(communicator: C) {

    let start = time::precise_time_s();
    let mut computation = GraphRoot::new(communicator);

    let (mut parts, mut items) = computation.subcomputation(|builder| {

        let (part_input, parts) = builder.new_input::<((u32, String, String), i32)>();
        let (item_input, items) = builder.new_input::<((u32, u32, u64), i32)>();

        // compute the average quantities
        let average = items.group_by_u(|(x,y,_)| (x,y), |k,v| (*k,*v), |_,s,t| {
            let mut sum = 0;
            let mut cnt = 0;
            for &(val,wgt) in s.iter() {
                cnt += wgt;
                sum += val;
            }
            t.push((sum / cnt as u32, 1));
        });

        // filter parts by brand and container
        let parts = parts.filter(|x| (x.0).1 == "Brand#33" && (x.0).2 == "WRAP PACK")
                         .map(|((key, _, _), wgt)| (key, wgt));

        // join items against their averages, filter by quantity, remove filter coordinate
        let items = items.join_u(&average, |x| (x.0, (x.1, x.2)), |y| y, |k, x, f| (*k, x.0, x.1, *f))
                         .filter(|&((_, q, _, avg),_)| q < avg / 5)
                         .map(|((key,_,price,_), wgt)| ((key,price), wgt));

        // semi-join against the part keys we retained. think of a better way to produce sum ...
        parts.join_u(&items, |k| (k,()), |(k,p)| (k,p), |_,_,p| *p)
             .inspect_batch(|_t,x| println!("results: {:?}", x.len()));

        (part_input, item_input)
    });

    let mut parts_buffer = Vec::new();
    let parts_reader =  BufReader::new(File::open(format!("/Users/mcsherry/Desktop/tpch-sf-10/part-{}.tbl", computation.index())).unwrap());
    for line in parts_reader.lines() {
        let text = line.ok().expect("read error");
        let mut fields = text.split("|");

        let part_id = fields.next().unwrap().parse::<u32>().unwrap();
        fields.next();
        fields.next();
        let brand = fields.next().unwrap().to_owned();
        fields.next();
        fields.next();
        let container = fields.next().unwrap().to_owned();

        parts_buffer.push(((part_id, brand, container), 1));
        if parts_buffer.len() == 1024 {
            parts.send_at(0u64, parts_buffer.drain_temp());
            computation.step();

        }
    }

    parts.send_at(0u64, parts_buffer.drain_temp());
    computation.step();

    let mut items_buffer = Vec::new();
    let items_reader =  BufReader::new(File::open(format!("/Users/mcsherry/Desktop/tpch-sf-10/lineitem-{}.tbl", computation.index())).unwrap());
    for line in items_reader.lines() {
        let text = line.ok().expect("read error");
        let mut fields = text.split("|");

        fields.next();
        let item_id = fields.next().unwrap().parse::<u32>().unwrap();
        fields.next();
        fields.next();
        let quantity = fields.next().unwrap().parse::<u32>().unwrap();
        let extended_price = fields.next().unwrap().parse::<f64>().unwrap() as u64;

        items_buffer.push(((item_id, quantity, extended_price), 1));
        if items_buffer.len() == 1024 {
            items.send_at(0u64, items_buffer.drain_temp());
            computation.step();
        }
    }

    items.send_at(0u64, items_buffer.drain_temp());
    computation.step();

    println!("data loaded at {}", time::precise_time_s() - start);

    parts.close();
    items.close();

    while computation.step() { std::thread::yield_now(); }
    computation.step(); // shut down

    println!("computation finished at {}", time::precise_time_s() - start);
}
<|endoftext|>


<commit_before><commit_msg>set1 challenge5: added<commit_after>extern crate rustc_serialize;
use rustc_serialize::hex::ToHex;

fn main() {
	let string = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal".as_bytes();
	let key = "ICE".as_bytes();

	let mut encrypted: Vec<u8> = Vec::new();

	for i in 0..string.len() {
		encrypted.push(string[i] ^ key[i % 3])
	}

	println!("{}", encrypted.to_hex());
}
<|endoftext|>


<commit_before><commit_msg>docs(examples): SARSALambda|Fourier|MountainCar<commit_after>extern crate rsrl;
#[macro_use] extern crate slog;

use rsrl::{run, logging, Parameter, SerialExperiment, Evaluation};
use rsrl::agents::memory::Trace;
use rsrl::agents::control::td::SARSALambda;
use rsrl::domains::{Domain, MountainCar};
use rsrl::fa::{Linear, Projector};
use rsrl::fa::projection::Fourier;
use rsrl::geometry::Space;
use rsrl::policies::EpsilonGreedy;

fn main() {
    let domain = MountainCar::default();
    let mut agent = {
        let n_actions = domain.action_space().span().into();

        // Build the linear value function using a fourier basis projection and the appropriate
        // eligibility trace.
        let bases = Fourier::from_space(3, domain.state_space());
        let trace = Trace::replacing(0.7, bases.activation());
        let q_func = Linear::new(bases, n_actions);

        // Build a stochastic behaviour policy with exponential epsilon.
        let eps = Parameter::exponential(0.99, 0.05, 0.99);
        let policy = EpsilonGreedy::new(eps);

        SARSALambda::new(trace, q_func, policy, 0.1, 0.99)
    };

    let logger = logging::root(logging::stdout());
    let domain_builder = Box::new(MountainCar::default);

    // Training phase:
    let _training_result = {
        // Start a serial learning experiment up to 1000 steps per episode.
        let e = SerialExperiment::new(&mut agent, domain_builder.clone(), 1000);

        // Realise 1000 episodes of the experiment generator.
        run(e, 1000, Some(logger.clone()))
    };

    // Testing phase:
    let testing_result =
        Evaluation::new(&mut agent, domain_builder).next().unwrap();

    info!(logger, "solution"; testing_result);
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::{fmt, env};

use mir;
use ty::{FnSig, Ty, layout};

use super::{
    MemoryPointer, Lock, AccessKind
};

use rustc_const_math::ConstMathErr;
use syntax::codemap::Span;
use backtrace::Backtrace;

#[derive(Debug, Clone)]
pub struct EvalError<'tcx> {
    pub kind: EvalErrorKind<'tcx>,
    pub backtrace: Option<Backtrace>,
}

impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
    fn from(kind: EvalErrorKind<'tcx>) -> Self {
        let backtrace = match env::var("RUST_BACKTRACE") {
            Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
            _ => None
        };
        EvalError {
            kind,
            backtrace,
        }
    }
}

#[derive(Debug, Clone)]
pub enum EvalErrorKind<'tcx> {
    /// This variant is used by machines to signal their own errors that do not
    /// match an existing variant
    MachineError(String),
    FunctionPointerTyMismatch(FnSig<'tcx>, FnSig<'tcx>),
    NoMirFor(String),
    UnterminatedCString(MemoryPointer),
    DanglingPointerDeref,
    DoubleFree,
    InvalidMemoryAccess,
    InvalidFunctionPointer,
    InvalidBool,
    InvalidDiscriminant,
    PointerOutOfBounds {
        ptr: MemoryPointer,
        access: bool,
        allocation_size: u64,
    },
    InvalidNullPointerUsage,
    ReadPointerAsBytes,
    ReadBytesAsPointer,
    InvalidPointerMath,
    ReadUndefBytes,
    DeadLocal,
    InvalidBoolOp(mir::BinOp),
    Unimplemented(String),
    DerefFunctionPointer,
    ExecuteMemory,
    ArrayIndexOutOfBounds(Span, u64, u64),
    Math(Span, ConstMathErr),
    Intrinsic(String),
    OverflowingMath,
    InvalidChar(u128),
    ExecutionTimeLimitReached,
    StackFrameLimitReached,
    OutOfTls,
    TlsOutOfBounds,
    AbiViolation(String),
    AlignmentCheckFailed {
        required: u64,
        has: u64,
    },
    MemoryLockViolation {
        ptr: MemoryPointer,
        len: u64,
        frame: usize,
        access: AccessKind,
        lock: Lock,
    },
    MemoryAcquireConflict {
        ptr: MemoryPointer,
        len: u64,
        kind: AccessKind,
        lock: Lock,
    },
    InvalidMemoryLockRelease {
        ptr: MemoryPointer,
        len: u64,
        frame: usize,
        lock: Lock,
    },
    DeallocatedLockedMemory {
        ptr: MemoryPointer,
        lock: Lock,
    },
    ValidationFailure(String),
    CalledClosureAsFunction,
    VtableForArgumentlessMethod,
    ModifiedConstantMemory,
    AssumptionNotHeld,
    InlineAsm,
    TypeNotPrimitive(Ty<'tcx>),
    ReallocatedWrongMemoryKind(String, String),
    DeallocatedWrongMemoryKind(String, String),
    ReallocateNonBasePtr,
    DeallocateNonBasePtr,
    IncorrectAllocationInformation(u64, usize, u64, u64),
    Layout(layout::LayoutError<'tcx>),
    HeapAllocZeroBytes,
    HeapAllocNonPowerOfTwoAlignment(u64),
    Unreachable,
    Panic,
    ReadFromReturnPointer,
    PathNotFound(Vec<String>),
    UnimplementedTraitSelection,
    /// Abort in case type errors are reached
    TypeckError,
    /// Cannot compute this constant because it depends on another one
    /// which already produced an error
    ReferencedConstant,
}

pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;

impl<'tcx> Error for EvalError<'tcx> {
    fn description(&self) -> &str {
        use self::EvalErrorKind::*;
        match self.kind {
            MachineError(ref inner) => inner,
            FunctionPointerTyMismatch(..) =>
                "tried to call a function through a function pointer of a different type",
            InvalidMemoryAccess =>
                "tried to access memory through an invalid pointer",
            DanglingPointerDeref =>
                "dangling pointer was dereferenced",
            DoubleFree =>
                "tried to deallocate dangling pointer",
            InvalidFunctionPointer =>
                "tried to use a function pointer after offsetting it",
            InvalidBool =>
                "invalid boolean value read",
            InvalidDiscriminant =>
                "invalid enum discriminant value read",
            PointerOutOfBounds { .. } =>
                "pointer offset outside bounds of allocation",
            InvalidNullPointerUsage =>
                "invalid use of NULL pointer",
            MemoryLockViolation { .. } =>
                "memory access conflicts with lock",
            MemoryAcquireConflict { .. } =>
                "new memory lock conflicts with existing lock",
            ValidationFailure(..) =>
                "type validation failed",
            InvalidMemoryLockRelease { .. } =>
                "invalid attempt to release write lock",
            DeallocatedLockedMemory { .. } =>
                "tried to deallocate memory in conflict with a lock",
            ReadPointerAsBytes =>
                "a raw memory access tried to access part of a pointer value as raw bytes",
            ReadBytesAsPointer =>
                "a memory access tried to interpret some bytes as a pointer",
            InvalidPointerMath =>
                "attempted to do invalid arithmetic on pointers that would leak base addresses, e.g. comparing pointers into different allocations",
            ReadUndefBytes =>
                "attempted to read undefined bytes",
            DeadLocal =>
                "tried to access a dead local variable",
            InvalidBoolOp(_) =>
                "invalid boolean operation",
            Unimplemented(ref msg) => msg,
            DerefFunctionPointer =>
                "tried to dereference a function pointer",
            ExecuteMemory =>
                "tried to treat a memory pointer as a function pointer",
            ArrayIndexOutOfBounds(..) =>
                "array index out of bounds",
            Math(..) =>
                "mathematical operation failed",
            Intrinsic(..) =>
                "intrinsic failed",
            OverflowingMath =>
                "attempted to do overflowing math",
            NoMirFor(..) =>
                "mir not found",
            InvalidChar(..) =>
                "tried to interpret an invalid 32-bit value as a char",
            ExecutionTimeLimitReached =>
                "the expression was too complex to be evaluated or resulted in an infinite loop",
            StackFrameLimitReached =>
                "reached the configured maximum number of stack frames",
            OutOfTls =>
                "reached the maximum number of representable TLS keys",
            TlsOutOfBounds =>
                "accessed an invalid (unallocated) TLS key",
            AbiViolation(ref msg) => msg,
            AlignmentCheckFailed{..} =>
                "tried to execute a misaligned read or write",
            CalledClosureAsFunction =>
                "tried to call a closure through a function pointer",
            VtableForArgumentlessMethod =>
                "tried to call a vtable function without arguments",
            ModifiedConstantMemory =>
                "tried to modify constant memory",
            AssumptionNotHeld =>
                "`assume` argument was false",
            InlineAsm =>
                "miri does not support inline assembly",
            TypeNotPrimitive(_) =>
                "expected primitive type, got nonprimitive",
            ReallocatedWrongMemoryKind(_, _) =>
                "tried to reallocate memory from one kind to another",
            DeallocatedWrongMemoryKind(_, _) =>
                "tried to deallocate memory of the wrong kind",
            ReallocateNonBasePtr =>
                "tried to reallocate with a pointer not to the beginning of an existing object",
            DeallocateNonBasePtr =>
                "tried to deallocate with a pointer not to the beginning of an existing object",
            IncorrectAllocationInformation(..) =>
                "tried to deallocate or reallocate using incorrect alignment or size",
            Layout(_) =>
                "rustc layout computation failed",
            UnterminatedCString(_) =>
                "attempted to get length of a null terminated string, but no null found before end of allocation",
            HeapAllocZeroBytes =>
                "tried to re-, de- or allocate zero bytes on the heap",
            HeapAllocNonPowerOfTwoAlignment(_) =>
                "tried to re-, de-, or allocate heap memory with alignment that is not a power of two",
            Unreachable =>
                "entered unreachable code",
            Panic =>
                "the evaluated program panicked",
            ReadFromReturnPointer =>
                "tried to read from the return pointer",
            EvalErrorKind::PathNotFound(_) =>
                "a path could not be resolved, maybe the crate is not loaded",
            UnimplementedTraitSelection =>
                "there were unresolved type arguments during trait selection",
            TypeckError =>
                "encountered constants with type errors, stopping evaluation",
            ReferencedConstant =>
                "referenced constant has errors",
        }
    }
}

impl<'tcx> fmt::Display for EvalError<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::EvalErrorKind::*;
        match self.kind {
            PointerOutOfBounds { ptr, access, allocation_size } => {
                write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
                       if access { "memory access" } else { "pointer computed" },
                       ptr.offset, ptr.alloc_id, allocation_size)
            },
            MemoryLockViolation { ptr, len, frame, access, ref lock } => {
                write!(f, "{:?} access by frame {} at {:?}, size {}, is in conflict with lock {:?}",
                       access, frame, ptr, len, lock)
            }
            MemoryAcquireConflict { ptr, len, kind, ref lock } => {
                write!(f, "new {:?} lock at {:?}, size {}, is in conflict with lock {:?}",
                       kind, ptr, len, lock)
            }
            InvalidMemoryLockRelease { ptr, len, frame, ref lock } => {
                write!(f, "frame {} tried to release memory write lock at {:?}, size {}, but cannot release lock {:?}",
                       frame, ptr, len, lock)
            }
            DeallocatedLockedMemory { ptr, ref lock } => {
                write!(f, "tried to deallocate memory at {:?} in conflict with lock {:?}",
                       ptr, lock)
            }
            ValidationFailure(ref err) => {
                write!(f, "type validation failed: {}", err)
            }
            NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
            FunctionPointerTyMismatch(sig, got) =>
                write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
            ArrayIndexOutOfBounds(span, len, index) =>
                write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
            ReallocatedWrongMemoryKind(ref old, ref new) =>
                write!(f, "tried to reallocate memory from {} to {}", old, new),
            DeallocatedWrongMemoryKind(ref old, ref new) =>
                write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
            Math(_, ref err) =>
                write!(f, "{}", err.description()),
            Intrinsic(ref err) =>
                write!(f, "{}", err),
            InvalidChar(c) =>
                write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
            AlignmentCheckFailed { required, has } =>
               write!(f, "tried to access memory with alignment {}, but alignment {} is required",
                      has, required),
            TypeNotPrimitive(ty) =>
                write!(f, "expected primitive type, got {}", ty),
            Layout(ref err) =>
                write!(f, "rustc layout computation failed: {:?}", err),
            PathNotFound(ref path) =>
                write!(f, "Cannot find path {:?}", path),
            MachineError(ref inner) =>
                write!(f, "{}", inner),
            IncorrectAllocationInformation(size, size2, align, align2) =>
                write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
            _ => write!(f, "{}", self.description()),
        }
    }
}
<commit_msg>Rollup merge of #49083 - oli-obk:mopsgeschwindigkeit, r=michaelwoerister<commit_after>use std::error::Error;
use std::{fmt, env};

use mir;
use ty::{FnSig, Ty, layout};

use super::{
    MemoryPointer, Lock, AccessKind
};

use rustc_const_math::ConstMathErr;
use syntax::codemap::Span;
use backtrace::Backtrace;

#[derive(Debug, Clone)]
pub struct EvalError<'tcx> {
    pub kind: EvalErrorKind<'tcx>,
    pub backtrace: Option<Backtrace>,
}

impl<'tcx> From<EvalErrorKind<'tcx>> for EvalError<'tcx> {
    fn from(kind: EvalErrorKind<'tcx>) -> Self {
        let backtrace = match env::var("MIRI_BACKTRACE") {
            Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
            _ => None
        };
        EvalError {
            kind,
            backtrace,
        }
    }
}

#[derive(Debug, Clone)]
pub enum EvalErrorKind<'tcx> {
    /// This variant is used by machines to signal their own errors that do not
    /// match an existing variant
    MachineError(String),
    FunctionPointerTyMismatch(FnSig<'tcx>, FnSig<'tcx>),
    NoMirFor(String),
    UnterminatedCString(MemoryPointer),
    DanglingPointerDeref,
    DoubleFree,
    InvalidMemoryAccess,
    InvalidFunctionPointer,
    InvalidBool,
    InvalidDiscriminant,
    PointerOutOfBounds {
        ptr: MemoryPointer,
        access: bool,
        allocation_size: u64,
    },
    InvalidNullPointerUsage,
    ReadPointerAsBytes,
    ReadBytesAsPointer,
    InvalidPointerMath,
    ReadUndefBytes,
    DeadLocal,
    InvalidBoolOp(mir::BinOp),
    Unimplemented(String),
    DerefFunctionPointer,
    ExecuteMemory,
    ArrayIndexOutOfBounds(Span, u64, u64),
    Math(Span, ConstMathErr),
    Intrinsic(String),
    OverflowingMath,
    InvalidChar(u128),
    ExecutionTimeLimitReached,
    StackFrameLimitReached,
    OutOfTls,
    TlsOutOfBounds,
    AbiViolation(String),
    AlignmentCheckFailed {
        required: u64,
        has: u64,
    },
    MemoryLockViolation {
        ptr: MemoryPointer,
        len: u64,
        frame: usize,
        access: AccessKind,
        lock: Lock,
    },
    MemoryAcquireConflict {
        ptr: MemoryPointer,
        len: u64,
        kind: AccessKind,
        lock: Lock,
    },
    InvalidMemoryLockRelease {
        ptr: MemoryPointer,
        len: u64,
        frame: usize,
        lock: Lock,
    },
    DeallocatedLockedMemory {
        ptr: MemoryPointer,
        lock: Lock,
    },
    ValidationFailure(String),
    CalledClosureAsFunction,
    VtableForArgumentlessMethod,
    ModifiedConstantMemory,
    AssumptionNotHeld,
    InlineAsm,
    TypeNotPrimitive(Ty<'tcx>),
    ReallocatedWrongMemoryKind(String, String),
    DeallocatedWrongMemoryKind(String, String),
    ReallocateNonBasePtr,
    DeallocateNonBasePtr,
    IncorrectAllocationInformation(u64, usize, u64, u64),
    Layout(layout::LayoutError<'tcx>),
    HeapAllocZeroBytes,
    HeapAllocNonPowerOfTwoAlignment(u64),
    Unreachable,
    Panic,
    ReadFromReturnPointer,
    PathNotFound(Vec<String>),
    UnimplementedTraitSelection,
    /// Abort in case type errors are reached
    TypeckError,
    /// Cannot compute this constant because it depends on another one
    /// which already produced an error
    ReferencedConstant,
}

pub type EvalResult<'tcx, T = ()> = Result<T, EvalError<'tcx>>;

impl<'tcx> Error for EvalError<'tcx> {
    fn description(&self) -> &str {
        use self::EvalErrorKind::*;
        match self.kind {
            MachineError(ref inner) => inner,
            FunctionPointerTyMismatch(..) =>
                "tried to call a function through a function pointer of a different type",
            InvalidMemoryAccess =>
                "tried to access memory through an invalid pointer",
            DanglingPointerDeref =>
                "dangling pointer was dereferenced",
            DoubleFree =>
                "tried to deallocate dangling pointer",
            InvalidFunctionPointer =>
                "tried to use a function pointer after offsetting it",
            InvalidBool =>
                "invalid boolean value read",
            InvalidDiscriminant =>
                "invalid enum discriminant value read",
            PointerOutOfBounds { .. } =>
                "pointer offset outside bounds of allocation",
            InvalidNullPointerUsage =>
                "invalid use of NULL pointer",
            MemoryLockViolation { .. } =>
                "memory access conflicts with lock",
            MemoryAcquireConflict { .. } =>
                "new memory lock conflicts with existing lock",
            ValidationFailure(..) =>
                "type validation failed",
            InvalidMemoryLockRelease { .. } =>
                "invalid attempt to release write lock",
            DeallocatedLockedMemory { .. } =>
                "tried to deallocate memory in conflict with a lock",
            ReadPointerAsBytes =>
                "a raw memory access tried to access part of a pointer value as raw bytes",
            ReadBytesAsPointer =>
                "a memory access tried to interpret some bytes as a pointer",
            InvalidPointerMath =>
                "attempted to do invalid arithmetic on pointers that would leak base addresses, e.g. comparing pointers into different allocations",
            ReadUndefBytes =>
                "attempted to read undefined bytes",
            DeadLocal =>
                "tried to access a dead local variable",
            InvalidBoolOp(_) =>
                "invalid boolean operation",
            Unimplemented(ref msg) => msg,
            DerefFunctionPointer =>
                "tried to dereference a function pointer",
            ExecuteMemory =>
                "tried to treat a memory pointer as a function pointer",
            ArrayIndexOutOfBounds(..) =>
                "array index out of bounds",
            Math(..) =>
                "mathematical operation failed",
            Intrinsic(..) =>
                "intrinsic failed",
            OverflowingMath =>
                "attempted to do overflowing math",
            NoMirFor(..) =>
                "mir not found",
            InvalidChar(..) =>
                "tried to interpret an invalid 32-bit value as a char",
            ExecutionTimeLimitReached =>
                "the expression was too complex to be evaluated or resulted in an infinite loop",
            StackFrameLimitReached =>
                "reached the configured maximum number of stack frames",
            OutOfTls =>
                "reached the maximum number of representable TLS keys",
            TlsOutOfBounds =>
                "accessed an invalid (unallocated) TLS key",
            AbiViolation(ref msg) => msg,
            AlignmentCheckFailed{..} =>
                "tried to execute a misaligned read or write",
            CalledClosureAsFunction =>
                "tried to call a closure through a function pointer",
            VtableForArgumentlessMethod =>
                "tried to call a vtable function without arguments",
            ModifiedConstantMemory =>
                "tried to modify constant memory",
            AssumptionNotHeld =>
                "`assume` argument was false",
            InlineAsm =>
                "miri does not support inline assembly",
            TypeNotPrimitive(_) =>
                "expected primitive type, got nonprimitive",
            ReallocatedWrongMemoryKind(_, _) =>
                "tried to reallocate memory from one kind to another",
            DeallocatedWrongMemoryKind(_, _) =>
                "tried to deallocate memory of the wrong kind",
            ReallocateNonBasePtr =>
                "tried to reallocate with a pointer not to the beginning of an existing object",
            DeallocateNonBasePtr =>
                "tried to deallocate with a pointer not to the beginning of an existing object",
            IncorrectAllocationInformation(..) =>
                "tried to deallocate or reallocate using incorrect alignment or size",
            Layout(_) =>
                "rustc layout computation failed",
            UnterminatedCString(_) =>
                "attempted to get length of a null terminated string, but no null found before end of allocation",
            HeapAllocZeroBytes =>
                "tried to re-, de- or allocate zero bytes on the heap",
            HeapAllocNonPowerOfTwoAlignment(_) =>
                "tried to re-, de-, or allocate heap memory with alignment that is not a power of two",
            Unreachable =>
                "entered unreachable code",
            Panic =>
                "the evaluated program panicked",
            ReadFromReturnPointer =>
                "tried to read from the return pointer",
            EvalErrorKind::PathNotFound(_) =>
                "a path could not be resolved, maybe the crate is not loaded",
            UnimplementedTraitSelection =>
                "there were unresolved type arguments during trait selection",
            TypeckError =>
                "encountered constants with type errors, stopping evaluation",
            ReferencedConstant =>
                "referenced constant has errors",
        }
    }
}

impl<'tcx> fmt::Display for EvalError<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::EvalErrorKind::*;
        match self.kind {
            PointerOutOfBounds { ptr, access, allocation_size } => {
                write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
                       if access { "memory access" } else { "pointer computed" },
                       ptr.offset, ptr.alloc_id, allocation_size)
            },
            MemoryLockViolation { ptr, len, frame, access, ref lock } => {
                write!(f, "{:?} access by frame {} at {:?}, size {}, is in conflict with lock {:?}",
                       access, frame, ptr, len, lock)
            }
            MemoryAcquireConflict { ptr, len, kind, ref lock } => {
                write!(f, "new {:?} lock at {:?}, size {}, is in conflict with lock {:?}",
                       kind, ptr, len, lock)
            }
            InvalidMemoryLockRelease { ptr, len, frame, ref lock } => {
                write!(f, "frame {} tried to release memory write lock at {:?}, size {}, but cannot release lock {:?}",
                       frame, ptr, len, lock)
            }
            DeallocatedLockedMemory { ptr, ref lock } => {
                write!(f, "tried to deallocate memory at {:?} in conflict with lock {:?}",
                       ptr, lock)
            }
            ValidationFailure(ref err) => {
                write!(f, "type validation failed: {}", err)
            }
            NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
            FunctionPointerTyMismatch(sig, got) =>
                write!(f, "tried to call a function with sig {} through a function pointer of type {}", sig, got),
            ArrayIndexOutOfBounds(span, len, index) =>
                write!(f, "index out of bounds: the len is {} but the index is {} at {:?}", len, index, span),
            ReallocatedWrongMemoryKind(ref old, ref new) =>
                write!(f, "tried to reallocate memory from {} to {}", old, new),
            DeallocatedWrongMemoryKind(ref old, ref new) =>
                write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
            Math(_, ref err) =>
                write!(f, "{}", err.description()),
            Intrinsic(ref err) =>
                write!(f, "{}", err),
            InvalidChar(c) =>
                write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
            AlignmentCheckFailed { required, has } =>
               write!(f, "tried to access memory with alignment {}, but alignment {} is required",
                      has, required),
            TypeNotPrimitive(ty) =>
                write!(f, "expected primitive type, got {}", ty),
            Layout(ref err) =>
                write!(f, "rustc layout computation failed: {:?}", err),
            PathNotFound(ref path) =>
                write!(f, "Cannot find path {:?}", path),
            MachineError(ref inner) =>
                write!(f, "{}", inner),
            IncorrectAllocationInformation(size, size2, align, align2) =>
                write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
            _ => write!(f, "{}", self.description()),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>We now check stuff inside struct literals.<commit_after><|endoftext|>


<commit_before><commit_msg>Test format hygiene<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub const arg0: u8 = 1;

pub fn main() {
    format!("{}", 1);
}
<|endoftext|>


<commit_before><commit_msg>Create regex_cache.rs<commit_after><|endoftext|>