<commit_before>#![deny(warnings)]
#![feature(question_mark)]

extern crate extra;
extern crate pager;
extern crate termion;

use std::env::args;
use std::fs::File;
use std::io::{self, Write, Read, StdoutLock};
use std::path::Path;

use extra::option::OptionalExt;

static LONG_HELP: &'static str = /* @MANSTART{less} */ r#"
NAME
    less - view a text file.

SYNOPSIS
    less [-h | --help] [input]

DESCRIPTION
    This utility views text files. If no input file is specified as an argument, standard input is
    used.

OPTIONS
    --help, -h
        Print this manual page.

AUTHOR
    This program was written by MovingtoMars and Ticki for Redox OS. Bugs, issues, or feature
    requests should be reported in the Github repository, 'redox-os/extrautils'.

COPYRIGHT
    Copyright (c) 2016 MovingtoMars

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    and associated documentation files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"#; /* @MANEND */

fn main() {
    let mut args = args().skip(1).peekable();
    let stdout = io::stdout();
    let mut stdout = stdout.lock();
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut stderr = io::stderr();

    if let Some(x) = args.peek() {
        if x == "--help" || x == "-h" {
            // Print help.
            stdout.write(LONG_HELP.as_bytes()).try(&mut stderr);
            return;
        }
    } else {
        let mut terminal = termion::get_tty().try(&mut stderr);
        run("-", &mut terminal, &mut stdin, &mut stdout).try(&mut stderr);
    };

    while let Some(filename) = args.next() {
        let mut file = File::open(Path::new(filename.as_str())).try(&mut stderr);
        run(filename.as_str(), &mut file, &mut stdin, &mut stdout).try(&mut stderr);
    }
}

fn run<R: Read>(path: &str, file: &mut File, controls: &mut R, stdout: &mut StdoutLock) -> std::io::Result<()> {
    let mut string = String::new();
    file.read_to_string(&mut string)?;

    pager::start(controls, stdout, path, &string)
}
<commit_msg>Fix issue with order of stdin and terminal<commit_after>#![deny(warnings)]
#![feature(question_mark)]

extern crate extra;
extern crate pager;
extern crate termion;

use std::env::args;
use std::fs::File;
use std::io::{self, Write, Read, StdoutLock};
use std::path::Path;

use extra::option::OptionalExt;

static LONG_HELP: &'static str = /* @MANSTART{less} */ r#"
NAME
    less - view a text file.

SYNOPSIS
    less [-h | --help] [input]

DESCRIPTION
    This utility views text files. If no input file is specified as an argument, standard input is
    used.

OPTIONS
    --help, -h
        Print this manual page.

AUTHOR
    This program was written by MovingtoMars and Ticki for Redox OS. Bugs, issues, or feature
    requests should be reported in the Github repository, 'redox-os/extrautils'.

COPYRIGHT
    Copyright (c) 2016 MovingtoMars

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    and associated documentation files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or
    substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
    BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"#; /* @MANEND */

fn main() {
    let mut args = args().skip(1).peekable();
    let stdout = io::stdout();
    let mut stdout = stdout.lock();
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut stderr = io::stderr();

    if let Some(x) = args.peek() {
        if x == "--help" || x == "-h" {
            // Print help.
            stdout.write(LONG_HELP.as_bytes()).try(&mut stderr);
            return;
        }
    } else {
        let mut terminal = termion::get_tty().try(&mut stderr);
        run("-", &mut stdin, &mut terminal, &mut stdout).try(&mut stderr);
    };

    while let Some(filename) = args.next() {
        let mut file = File::open(Path::new(filename.as_str())).try(&mut stderr);
        run(filename.as_str(), &mut file, &mut stdin, &mut stdout).try(&mut stderr);
    }
}

fn run(path: &str, file: &mut Read, controls: &mut Read, stdout: &mut StdoutLock) -> std::io::Result<()> {
    let mut string = String::new();
    file.read_to_string(&mut string)?;

    pager::start(controls, stdout, path, &string)
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use]
extern crate clap;
extern crate config;
extern crate diesel;
#[macro_use]
extern crate failure;
extern crate r2d2;
extern crate r2d2_diesel;
// extern crate ring;
extern crate log;
extern crate rocket;
extern crate rocket_contrib;
extern crate serde;
extern crate yaml_rust;
extern crate rocket_i18n;

#[cfg(feature = "log-simple")]
extern crate simple_logging;
#[cfg(feature = "log-syslog")]
extern crate syslog;
#[cfg(feature = "use-systemd")]
extern crate systemd;

extern crate _aardwolf as aardwolf;

mod common;
use common::{configure, db_conn_string};

use failure::Error;
// use ring::rand::SystemRandom;
use clap::App;
use diesel::pg::PgConnection;
use log::LevelFilter;
use r2d2_diesel::ConnectionManager;
use rocket::Rocket;
//use rocket_contrib::Template;

type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

fn db_pool(rocket: &Rocket) -> Result<Pool, Error> {
    let database_url = rocket.config().get_str("database_url")?;
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    Ok(r2d2::Pool::builder().build(manager)?)
}

fn app(config: config::Config) -> Result<Rocket, Error> {
    let db_url = db_conn_string(&config)?;

    let c = rocket::Config::build(rocket::config::Environment::Development)
        .address(config.get_str("Web.Listen.address")?)
        .port(config.get::<u16>("Web.Listen.port")?)
        .extra("database_url", db_url.as_str())
        .unwrap();

    let mut routes = routes![
        aardwolf::routes::app::home,
        aardwolf::routes::app::home_redirect,
    ];

    #[cfg(debug_assertions)]
    routes.extend(routes![
        // webroot/favicon
        aardwolf::routes::app::webroot,
        // emoji
        aardwolf::routes::app::emoji,
        // themes
        aardwolf::routes::app::themes,
    ]);

    let auth = routes![
        aardwolf::routes::auth::sign_up_form,
        aardwolf::routes::auth::sign_up_form_with_error,
        aardwolf::routes::auth::sign_in_form,
        aardwolf::routes::auth::sign_in_form_with_error,
        aardwolf::routes::auth::sign_up,
        aardwolf::routes::auth::sign_in,
        aardwolf::routes::auth::confirm,
        aardwolf::routes::auth::sign_out,
    ];

    let personas = routes![
        aardwolf::routes::personas::new,
        aardwolf::routes::personas::create,
        aardwolf::routes::personas::delete,
        aardwolf::routes::personas::switch,
    ];

    let r = rocket::custom(c, true)
        .mount("/auth", auth)
        .mount("/personas", personas)
        .mount(
            "/api/v1",
            routes![aardwolf::routes::applications::register_application],
        )
        .mount("/", routes)
    //  .attach(Template::fairing());
    // .manage(SystemRandom::new());

        // Just for giggles, what happens if I put the rocket_i18n fairing here....

        // Eventually register the Tera filters (only works with the master branch of Rocket)
        .attach(rocket_contrib::Template::custom(|engines| {
                rocket_i18n::tera(&mut engines.tera);
        }));
        // Register the fairing. The parameter is the domain you want to use (the name of your app most of the time)
        .attach(rocket_i18n::I18n::new("aardwolf"))

    // we need an instance of the app to access the config values in Rocket.toml,
    // so we pass it to the db_pool function, get the pool, and _then_ return the instance
    let pool = db_pool(&r)?;
    Ok(r.manage(pool))
}

fn cli<'a, 'b>(yaml: &'a yaml_rust::yaml::Yaml) -> App<'a, 'b> {
    App::from_yaml(yaml)
        .name(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
}

#[cfg(feature = "log-simple")]
fn begin_log(config: &config::Config) {
    match config.get_str("log_file").unwrap().as_ref() {
        "_CONSOLE_" => (),
        l => simple_logging::log_to_file(l, LevelFilter::Info).unwrap(),
    }
}

#[cfg(feature = "log-syslog")]
fn begin_log(config: &config::Config) {
    // TODO: Implement log-syslog:begin_log()
}

#[cfg(feature = "use-systemd")]
fn begin_log(config: &config::Config) {
    // TODO: Implement use-systemd:begin_log()
}

fn main() {
    let yaml = load_yaml!("cli.yml");
    let cli = cli(&yaml);
    let config = configure(cli).unwrap();
    begin_log(&config);

    app(config).unwrap().launch();
}
<commit_msg>Updating from diff<commit_after>#![feature(plugin)]
#![feature(custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use]
extern crate clap;
extern crate config;
extern crate diesel;
#[macro_use]
extern crate failure;
extern crate r2d2;
extern crate r2d2_diesel;
// extern crate ring;
extern crate log;
extern crate rocket;
extern crate rocket_contrib;
extern crate serde;
extern crate yaml_rust;
extern crate rocket_i18n;

#[cfg(feature = "log-simple")]
extern crate simple_logging;
#[cfg(feature = "log-syslog")]
extern crate syslog;
#[cfg(feature = "use-systemd")]
extern crate systemd;

extern crate _aardwolf as aardwolf;

mod common;
use common::{configure, db_conn_string};

use failure::Error;
// use ring::rand::SystemRandom;
use clap::App;
use diesel::pg::PgConnection;
use log::LevelFilter;
use r2d2_diesel::ConnectionManager;
use rocket::Rocket;

type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;

fn db_pool(rocket: &Rocket) -> Result<Pool, Error> {
    let database_url = rocket.config().get_str("database_url")?;
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    Ok(r2d2::Pool::builder().build(manager)?)
}

fn app(config: config::Config) -> Result<Rocket, Error> {
    let db_url = db_conn_string(&config)?;

    let c = rocket::Config::build(rocket::config::Environment::Development)
        .address(config.get_str("Web.Listen.address")?)
        .port(config.get::<u16>("Web.Listen.port")?)
        .extra("database_url", db_url.as_str())
        .unwrap();

    let mut routes = routes![
        aardwolf::routes::app::home,
        aardwolf::routes::app::home_redirect,
    ];

    #[cfg(debug_assertions)]
    routes.extend(routes![
        // webroot/favicon
        aardwolf::routes::app::webroot,
        // emoji
        aardwolf::routes::app::emoji,
        // themes
        aardwolf::routes::app::themes,
    ]);

    let auth = routes![
        aardwolf::routes::auth::sign_up_form,
        aardwolf::routes::auth::sign_up_form_with_error,
        aardwolf::routes::auth::sign_in_form,
        aardwolf::routes::auth::sign_in_form_with_error,
        aardwolf::routes::auth::sign_up,
        aardwolf::routes::auth::sign_in,
        aardwolf::routes::auth::confirm,
        aardwolf::routes::auth::sign_out,
    ];

    let personas = routes![
        aardwolf::routes::personas::new,
        aardwolf::routes::personas::create,
        aardwolf::routes::personas::delete,
        aardwolf::routes::personas::switch,
    ];

    let r = rocket::custom(c, true)
        .mount("/auth", auth)
        .mount("/personas", personas)
        .mount(
            "/api/v1",
            routes![aardwolf::routes::applications::register_application],
        )
        .mount("/", routes)
    // .manage(SystemRandom::new());

        // Just for giggles, what happens if I put the rocket_i18n fairing here....

        // Register the fairing. The parameter is the domain you want to use (the name of your app most of the time)
        .attach(rocket_i18n::I18n::new("aardwolf"))
        // Eventually register the Tera filters (only works with the master branch of Rocket)
        .attach(rocket_contrib::Template::custom(|engines| {
                rocket_i18n::tera(&mut engines.tera);
        }));

    // we need an instance of the app to access the config values in Rocket.toml,
    // so we pass it to the db_pool function, get the pool, and _then_ return the instance
    let pool = db_pool(&r)?;
    Ok(r.manage(pool))
}

fn cli<'a, 'b>(yaml: &'a yaml_rust::yaml::Yaml) -> App<'a, 'b> {
    App::from_yaml(yaml)
        .name(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
}

#[cfg(feature = "log-simple")]
fn begin_log(config: &config::Config) {
    match config.get_str("log_file").unwrap().as_ref() {
        "_CONSOLE_" => (),
        l => simple_logging::log_to_file(l, LevelFilter::Info).unwrap(),
    }
}

#[cfg(feature = "log-syslog")]
fn begin_log(config: &config::Config) {
    // TODO: Implement log-syslog:begin_log()
}

#[cfg(feature = "use-systemd")]
fn begin_log(config: &config::Config) {
    // TODO: Implement use-systemd:begin_log()
}

fn main() {
    let yaml = load_yaml!("cli.yml");
    let cli = cli(&yaml);
    let config = configure(cli).unwrap();
    begin_log(&config);

    app(config).unwrap().launch();
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]

extern crate getopts;
extern crate miri;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_codegen_utils;
extern crate env_logger;
extern crate log_settings;
extern crate syntax;
extern crate log;

use rustc::session::Session;
use rustc::middle::cstore::CrateStore;
use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls};
use rustc_driver::driver::{CompileState, CompileController};
use rustc::session::config::{self, Input, ErrorOutputType};
use rustc::hir::{self, itemlikevisit};
use rustc::ty::TyCtxt;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use syntax::ast;
use std::path::PathBuf;

struct MiriCompilerCalls {
    default: Box<RustcDefaultCalls>,
    /// Whether to begin interpretation at the start_fn lang item or not
    ///
    /// If false, the interpretation begins at the `main` function
    start_fn: bool,
}

impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default.early_callback(
            matches,
            sopts,
            cfg,
            descriptions,
            output,
        )
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(
            matches,
            sopts,
            cfg,
            odir,
            ofile,
            descriptions,
        )
    }
    fn late_callback(
        &mut self,
        codegen_backend: &CodegenBackend,
        matches: &getopts::Matches,
        sess: &Session,
        cstore: &CrateStore,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default.late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile)
    }
    fn build_controller(
        self: Box<Self>,
        sess: &Session,
        matches: &getopts::Matches,
    ) -> CompileController<'a> {
        let this = *self;
        let mut control = this.default.build_controller(sess, matches);
        control.after_hir_lowering.callback = Box::new(after_hir_lowering);
        let start_fn = this.start_fn;
        control.after_analysis.callback = Box::new(move |state| after_analysis(state, start_fn));
        control.after_analysis.stop = Compilation::Stop;
        control
    }
}

fn after_hir_lowering(state: &mut CompileState) {
    let attr = (
        String::from("miri"),
        syntax::feature_gate::AttributeType::Whitelisted,
    );
    state.session.plugin_attributes.borrow_mut().push(attr);
}

fn after_analysis<'a, 'tcx>(state: &mut CompileState<'a, 'tcx>, use_start_fn: bool) {
    state.session.abort_if_errors();

    let tcx = state.tcx.unwrap();

    if std::env::args().any(|arg| arg == "--test") {
        struct Visitor<'a, 'tcx: 'a>(
            TyCtxt<'a, 'tcx, 'tcx>,
            &'a CompileState<'a, 'tcx>
        );
        impl<'a, 'tcx: 'a, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'a, 'tcx> {
            fn visit_item(&mut self, i: &'hir hir::Item) {
                if let hir::ItemKind::Fn(.., body_id) = i.node {
                    if i.attrs.iter().any(|attr| {
                        attr.name() == "test"
                    })
                    {
                        let did = self.0.hir.body_owner_def_id(body_id);
                        println!(
                            "running test: {}",
                            self.0.def_path_debug_str(did),
                        );
                        miri::eval_main(self.0, did, None);
                        self.1.session.abort_if_errors();
                    }
                }
            }
            fn visit_trait_item(&mut self, _trait_item: &'hir hir::TraitItem) {}
            fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {}
        }
        state.hir_crate.unwrap().visit_all_item_likes(
            &mut Visitor(tcx, state),
        );
    } else if let Some((entry_node_id, _, _)) = *state.session.entry_fn.borrow() {
        let entry_def_id = tcx.hir.local_def_id(entry_node_id);
        // Use start_fn lang item if we have -Zmiri-start-fn set
        let start_wrapper = if use_start_fn {
            Some(tcx.lang_items().start_fn().unwrap())
        } else {
            None
        };
        miri::eval_main(tcx, entry_def_id, start_wrapper);

        state.session.abort_if_errors();
    } else {
        println!("no main function found, assuming auxiliary build");
    }
}

fn init_logger() {
    let format = |formatter: &mut env_logger::fmt::Formatter, record: &log::Record| {
        use std::io::Write;
        if record.level() == log::Level::Trace {
            // prepend frame number
            let indentation = log_settings::settings().indentation;
            writeln!(
                formatter,
                "{indentation}:{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.module_path().unwrap_or("<unknown module>"),
                indentation = indentation,
                text = record.args(),
            )
        } else {
            writeln!(
                formatter,
                "{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.module_path().unwrap_or("<unknown_module>"),
                text = record.args(),
            )
        }
    };

    let mut builder = env_logger::Builder::new();
    builder.format(format).filter(
        None,
        log::LevelFilter::Info,
    );

    if std::env::var("MIRI_LOG").is_ok() {
        builder.parse(&std::env::var("MIRI_LOG").unwrap());
    }

    builder.init();
}

fn find_sysroot() -> String {
    if let Ok(sysroot) = std::env::var("MIRI_SYSROOT") {
        return sysroot;
    }

    // Taken from https://github.com/Manishearth/rust-clippy/pull/911.
    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => {
            option_env!("RUST_SYSROOT")
                .expect(
                    "need to specify RUST_SYSROOT env var or use rustup or multirust",
                )
                .to_owned()
        }
    }
}

fn main() {
    rustc_driver::init_rustc_env_logger();
    init_logger();
    let mut args: Vec<String> = std::env::args().collect();

    let sysroot_flag = String::from("--sysroot");
    if !args.contains(&sysroot_flag) {
        args.push(sysroot_flag);
        args.push(find_sysroot());
    }

    let mut start_fn = false;
    args.retain(|arg| {
        if arg == "-Zmiri-start-fn" {
            start_fn = true;
            false
        } else {
            true
        }
    });

    rustc_driver::run_compiler(&args, Box::new(MiriCompilerCalls {
        default: Box::new(RustcDefaultCalls),
        start_fn,
    }), None, None);
}
<commit_msg>Produce the exit codes that compiletest expects<commit_after>#![feature(rustc_private)]

extern crate getopts;
extern crate miri;
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_codegen_utils;
extern crate env_logger;
extern crate log_settings;
extern crate syntax;
extern crate log;

use rustc::session::Session;
use rustc::middle::cstore::CrateStore;
use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls};
use rustc_driver::driver::{CompileState, CompileController};
use rustc::session::config::{self, Input, ErrorOutputType};
use rustc::hir::{self, itemlikevisit};
use rustc::ty::TyCtxt;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use syntax::ast;
use std::path::PathBuf;

struct MiriCompilerCalls {
    default: Box<RustcDefaultCalls>,
    /// Whether to begin interpretation at the start_fn lang item or not
    ///
    /// If false, the interpretation begins at the `main` function
    start_fn: bool,
}

impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
    fn early_callback(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        descriptions: &rustc_errors::registry::Registry,
        output: ErrorOutputType,
    ) -> Compilation {
        self.default.early_callback(
            matches,
            sopts,
            cfg,
            descriptions,
            output,
        )
    }
    fn no_input(
        &mut self,
        matches: &getopts::Matches,
        sopts: &config::Options,
        cfg: &ast::CrateConfig,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
        descriptions: &rustc_errors::registry::Registry,
    ) -> Option<(Input, Option<PathBuf>)> {
        self.default.no_input(
            matches,
            sopts,
            cfg,
            odir,
            ofile,
            descriptions,
        )
    }
    fn late_callback(
        &mut self,
        codegen_backend: &CodegenBackend,
        matches: &getopts::Matches,
        sess: &Session,
        cstore: &CrateStore,
        input: &Input,
        odir: &Option<PathBuf>,
        ofile: &Option<PathBuf>,
    ) -> Compilation {
        self.default.late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile)
    }
    fn build_controller(
        self: Box<Self>,
        sess: &Session,
        matches: &getopts::Matches,
    ) -> CompileController<'a> {
        let this = *self;
        let mut control = this.default.build_controller(sess, matches);
        control.after_hir_lowering.callback = Box::new(after_hir_lowering);
        let start_fn = this.start_fn;
        control.after_analysis.callback = Box::new(move |state| after_analysis(state, start_fn));
        control.after_analysis.stop = Compilation::Stop;
        control
    }
}

fn after_hir_lowering(state: &mut CompileState) {
    let attr = (
        String::from("miri"),
        syntax::feature_gate::AttributeType::Whitelisted,
    );
    state.session.plugin_attributes.borrow_mut().push(attr);
}

fn after_analysis<'a, 'tcx>(state: &mut CompileState<'a, 'tcx>, use_start_fn: bool) {
    state.session.abort_if_errors();

    let tcx = state.tcx.unwrap();

    if std::env::args().any(|arg| arg == "--test") {
        struct Visitor<'a, 'tcx: 'a>(
            TyCtxt<'a, 'tcx, 'tcx>,
            &'a CompileState<'a, 'tcx>
        );
        impl<'a, 'tcx: 'a, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'a, 'tcx> {
            fn visit_item(&mut self, i: &'hir hir::Item) {
                if let hir::ItemKind::Fn(.., body_id) = i.node {
                    if i.attrs.iter().any(|attr| {
                        attr.name() == "test"
                    })
                    {
                        let did = self.0.hir.body_owner_def_id(body_id);
                        println!(
                            "running test: {}",
                            self.0.def_path_debug_str(did),
                        );
                        miri::eval_main(self.0, did, None);
                        self.1.session.abort_if_errors();
                    }
                }
            }
            fn visit_trait_item(&mut self, _trait_item: &'hir hir::TraitItem) {}
            fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {}
        }
        state.hir_crate.unwrap().visit_all_item_likes(
            &mut Visitor(tcx, state),
        );
    } else if let Some((entry_node_id, _, _)) = *state.session.entry_fn.borrow() {
        let entry_def_id = tcx.hir.local_def_id(entry_node_id);
        // Use start_fn lang item if we have -Zmiri-start-fn set
        let start_wrapper = if use_start_fn {
            Some(tcx.lang_items().start_fn().unwrap())
        } else {
            None
        };
        miri::eval_main(tcx, entry_def_id, start_wrapper);

        state.session.abort_if_errors();
    } else {
        println!("no main function found, assuming auxiliary build");
    }
}

fn init_logger() {
    let format = |formatter: &mut env_logger::fmt::Formatter, record: &log::Record| {
        use std::io::Write;
        if record.level() == log::Level::Trace {
            // prepend frame number
            let indentation = log_settings::settings().indentation;
            writeln!(
                formatter,
                "{indentation}:{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.module_path().unwrap_or("<unknown module>"),
                indentation = indentation,
                text = record.args(),
            )
        } else {
            writeln!(
                formatter,
                "{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.module_path().unwrap_or("<unknown_module>"),
                text = record.args(),
            )
        }
    };

    let mut builder = env_logger::Builder::new();
    builder.format(format).filter(
        None,
        log::LevelFilter::Info,
    );

    if std::env::var("MIRI_LOG").is_ok() {
        builder.parse(&std::env::var("MIRI_LOG").unwrap());
    }

    builder.init();
}

fn find_sysroot() -> String {
    if let Ok(sysroot) = std::env::var("MIRI_SYSROOT") {
        return sysroot;
    }

    // Taken from https://github.com/Manishearth/rust-clippy/pull/911.
    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => {
            option_env!("RUST_SYSROOT")
                .expect(
                    "need to specify RUST_SYSROOT env var or use rustup or multirust",
                )
                .to_owned()
        }
    }
}

fn main() {
    rustc_driver::init_rustc_env_logger();
    init_logger();
    let mut args: Vec<String> = std::env::args().collect();

    let sysroot_flag = String::from("--sysroot");
    if !args.contains(&sysroot_flag) {
        args.push(sysroot_flag);
        args.push(find_sysroot());
    }

    let mut start_fn = false;
    args.retain(|arg| {
        if arg == "-Zmiri-start-fn" {
            start_fn = true;
            false
        } else {
            true
        }
    });

    let result = rustc_driver::run(move || {
        rustc_driver::run_compiler(&args, Box::new(MiriCompilerCalls {
            default: Box::new(RustcDefaultCalls),
            start_fn,
        }), None, None)
    });
    std::process::exit(result as i32);
}
<|endoftext|>


<commit_before>// Copyright © 2017 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate gfx;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate richter;

use richter::console::CmdRegistry;
use richter::console::Console;
use richter::console::ConsoleInput;
use richter::console::CvarRegistry;
use richter::console::History;
use richter::input::InputFocus;

use glutin::ElementState;
use glutin::Event;
use glutin::KeyboardInput;
use glutin::WindowEvent;
use glutin::VirtualKeyCode;

type ColorFormat = gfx::format::Srgba8;
type DepthFormat = gfx::format::DepthStencil;

fn main() {
    let mut events_loop = glutin::EventsLoop::new();
    let window_builder = glutin::WindowBuilder::new().with_title("BSP renderer: gfx-rs backend");
    let context_builder = glutin::ContextBuilder::new()
        .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 3)))
        .with_vsync(true);

    let (window, mut device, mut factory, color, depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(
            window_builder,
            context_builder,
            &events_loop,
        );

    let mut cvars = CvarRegistry::new();
    let mut cmds = CmdRegistry::new();
    let mut con = Console::new();
    let mut cmdline = ConsoleInput::new();

    let mut input_focus = InputFocus::Console;

    let mut quit = false;
    loop {
        match input_focus {
            InputFocus::Console => {
                events_loop.poll_events(|event| match event {
                    Event::WindowEvent {
                        event: e,
                        ..
                    } => match e {
                        WindowEvent::Closed => quit = true,
                        WindowEvent::ReceivedCharacter('`') => input_focus = InputFocus::Game,
                        WindowEvent::ReceivedCharacter(c) => con.send_char(c).unwrap(),
                        WindowEvent::KeyboardInput {
                            input: KeyboardInput {
                                state: ElementState::Pressed,
                                virtual_keycode: Some(k),
                                ..
                            },
                            ..
                        } => con.send_key(k),
                        _ => (),
                    }
                    _ => (),
                });
            }

            InputFocus::Game => {
                events_loop.poll_events(|event| match event {
                    Event::WindowEvent {
                        event: e,
                        ..
                    } => match e {
                        WindowEvent::Closed => quit = true,
                        WindowEvent::KeyboardInput {
                            input: KeyboardInput {
                                virtual_keycode: Some(k),
                                ..
                            },
                            ..
                        } => match k {
                            _ => (),
                        }
                        _ => (),
                    }
                    _ => (),
                });
            }

            _ => (),
        }

        if quit {
            break;
        }
    }
}
<commit_msg>bin/qwcl.rs: allow toggling back to console<commit_after>// Copyright © 2017 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate gfx;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate richter;

use richter::console::CmdRegistry;
use richter::console::Console;
use richter::console::ConsoleInput;
use richter::console::CvarRegistry;
use richter::console::History;
use richter::input::InputFocus;

use glutin::ElementState;
use glutin::Event;
use glutin::KeyboardInput;
use glutin::WindowEvent;
use glutin::VirtualKeyCode;

type ColorFormat = gfx::format::Srgba8;
type DepthFormat = gfx::format::DepthStencil;

fn main() {
    let mut events_loop = glutin::EventsLoop::new();
    let window_builder = glutin::WindowBuilder::new().with_title("BSP renderer: gfx-rs backend");
    let context_builder = glutin::ContextBuilder::new()
        .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 3)))
        .with_vsync(true);

    let (window, mut device, mut factory, color, depth) =
        gfx_window_glutin::init::<ColorFormat, DepthFormat>(
            window_builder,
            context_builder,
            &events_loop,
        );

    let mut cvars = CvarRegistry::new();
    let mut cmds = CmdRegistry::new();
    let mut con = Console::new();
    let mut cmdline = ConsoleInput::new();

    let mut input_focus = InputFocus::Console;

    let mut quit = false;
    loop {
        match input_focus {
            InputFocus::Console => {
                events_loop.poll_events(|event| match event {
                    Event::WindowEvent {
                        event: e,
                        ..
                    } => match e {
                        WindowEvent::Closed => quit = true,
                        WindowEvent::ReceivedCharacter('`') => input_focus = InputFocus::Game,
                        WindowEvent::ReceivedCharacter(c) => con.send_char(c).unwrap(),
                        WindowEvent::KeyboardInput {
                            input: KeyboardInput {
                                state: ElementState::Pressed,
                                virtual_keycode: Some(k),
                                ..
                            },
                            ..
                        } => con.send_key(k),
                        _ => (),
                    }
                    _ => (),
                });
            }

            InputFocus::Game => {
                events_loop.poll_events(|event| match event {
                    Event::WindowEvent {
                        event: e,
                        ..
                    } => match e {
                        WindowEvent::Closed => quit = true,
                        WindowEvent::ReceivedCharacter('`') => input_focus = InputFocus::Console,
                        WindowEvent::KeyboardInput {
                            input: KeyboardInput {
                                virtual_keycode: Some(k),
                                ..
                            },
                            ..
                        } => match k {
                            _ => (),
                        }
                        _ => (),
                    }
                    _ => (),
                });
            }

            _ => (),
        }

        if quit {
            break;
        }
    }
}
<|endoftext|>


<commit_before>//! Streaming bodies for Requests and Responses
//!
//! For both [Clients](::client) and [Servers](::server), requests and
//! responses use streaming bodies, instead of complete buffering. This
//! allows applications to not use memory they don't need, and allows exerting
//! back-pressure on connections by only reading when asked.
//!
//! There are two pieces to this in hyper:
//!
//! - The [`HttpBody`](body::HttpBody) trait the describes all possible bodies.
//!   hyper allows any body type that implements `HttpBody`, allowing
//!   applications to have fine-grained control over their streaming.
//! - The [`Body`](Body) concrete type, which is an implementation of
//!   `HttpBody`, and returned by hyper as a "receive stream" (so, for server
//!   requests and client responses). It is also a decent default implementation
//!   if you don't have very custom needs of your send streams.

pub use bytes::{Buf, Bytes};
pub use http_body::Body as HttpBody;

pub use self::aggregate::aggregate;
pub use self::body::{Body, Sender};
pub use self::to_bytes::to_bytes;

pub(crate) use self::payload::Payload;

mod aggregate;
mod body;
mod payload;
mod to_bytes;

/// An optimization to try to take a full body if immediately available.
///
/// This is currently limited to *only* `hyper::Body`s.
pub(crate) fn take_full_data<T: Payload + 'static>(body: &mut T) -> Option<T::Data> {
    use std::any::{Any, TypeId};

    // This static type check can be optimized at compile-time.
    if TypeId::of::<T>() == TypeId::of::<Body>() {
        let mut full = (body as &mut dyn Any)
            .downcast_mut::<Body>()
            .expect("must be Body")
            .take_full_data();
        // This second cast is required to make the type system happy.
        // Without it, the compiler cannot reason that the type is actually
        // `T::Data`. Oh wells.
        //
        // It's still a measurable win!
        (&mut full as &mut dyn Any)
            .downcast_mut::<Option<T::Data>>()
            .expect("must be T::Data")
            .take()
    } else {
        None
    }
}

fn _assert_send_sync() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}

    _assert_send::<Body>();
    _assert_sync::<Body>();
}
<commit_msg>docs(body): small wording improvement to body module docs<commit_after>//! Streaming bodies for Requests and Responses
//!
//! For both [Clients](::client) and [Servers](::server), requests and
//! responses use streaming bodies, instead of complete buffering. This
//! allows applications to not use memory they don't need, and allows exerting
//! back-pressure on connections by only reading when asked.
//!
//! There are two pieces to this in hyper:
//!
//! - **The [`HttpBody`](body::HttpBody) trait** describes all possible bodies.
//!   hyper allows any body type that implements `HttpBody`, allowing
//!   applications to have fine-grained control over their streaming.
//! - **The [`Body`](Body) concrete type**, which is an implementation of
//!   `HttpBody`, and returned by hyper as a "receive stream" (so, for server
//!   requests and client responses). It is also a decent default implementation
//!   if you don't have very custom needs of your send streams.

pub use bytes::{Buf, Bytes};
pub use http_body::Body as HttpBody;

pub use self::aggregate::aggregate;
pub use self::body::{Body, Sender};
pub use self::to_bytes::to_bytes;

pub(crate) use self::payload::Payload;

mod aggregate;
mod body;
mod payload;
mod to_bytes;

/// An optimization to try to take a full body if immediately available.
///
/// This is currently limited to *only* `hyper::Body`s.
pub(crate) fn take_full_data<T: Payload + 'static>(body: &mut T) -> Option<T::Data> {
    use std::any::{Any, TypeId};

    // This static type check can be optimized at compile-time.
    if TypeId::of::<T>() == TypeId::of::<Body>() {
        let mut full = (body as &mut dyn Any)
            .downcast_mut::<Body>()
            .expect("must be Body")
            .take_full_data();
        // This second cast is required to make the type system happy.
        // Without it, the compiler cannot reason that the type is actually
        // `T::Data`. Oh wells.
        //
        // It's still a measurable win!
        (&mut full as &mut dyn Any)
            .downcast_mut::<Option<T::Data>>()
            .expect("must be T::Data")
            .take()
    } else {
        None
    }
}

fn _assert_send_sync() {
    fn _assert_send<T: Send>() {}
    fn _assert_sync<T: Sync>() {}

    _assert_send::<Body>();
    _assert_sync::<Body>();
}
<|endoftext|>


<commit_before>extern crate collections;

use collections::dlist::DList;
use collections::Deque;

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

use std::rc::{mod, Rc};

static CHB_MIN_SIZE:uint = 32u;

// TODO: move to utils
fn blit<T:Clone>(src: &[T], dst: &mut [T], dst_ofs: uint) {
    let len = src.len();
    let sd = dst.slice_mut(dst_ofs, dst_ofs + len);
    if len > sd.len() {
        fail!("blit: source larger than destination");
    }

    let _ = sd.clone_from_slice(src);
}

/// Chained buffer of bytes.
/// Consists of linked list of nodes.
pub struct Chain {
    head: DList<Node>,
    length: uint
}

impl Chain {
    pub fn new() -> Chain {
        Chain{
            head: DList::new(),
            length: 0
        }
    }

    pub fn from_foreign(src: Chain) -> Chain {
        let mut ch = Chain::new();
        ch.concat(src);
        ch
    }

    pub fn len(&self) -> uint {
        self.length
    }

    // XXX: maybe DEDUP append/prepend?
    pub fn append_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.back() {
            Some(nd) => {
                (nd.room() < size) || !rc::is_unique(&nd.dh)
            }
            None => {
                true
            }
        };
        // We either not the only owner of DH or don't have enough room
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let node = Node::new(DataHolder::new(nsize));
            self.add_node_tail(node);
        }
        // infailable: added node above
        let node = self.head.back_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        // XXX: we need additional var and scope only to fight borrow checker
        {
            let node_end = node.end;
            // we should be sole owner of data holder inside node here
            let dh = rc::get_mut(&mut node.dh).unwrap();
            dh.copy_data_from(data, node_end);
        }
        node.end += size;
        self.length += size;
    }

    pub fn prepend_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.front() {
            Some(nd) => {
                (size > nd.start || !rc::is_unique(&nd.dh))
            }
            None => {
                true
            }
        };
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let mut node = Node::new(DataHolder::new(nsize)); // Box<Node>
            let r = node.room();
            node.start = r;
            node.end = r;
            self.add_node_head(node);
        }
        // See comments in `append_bytes`
        let node = self.head.front_mut().unwrap();
        {
            let node_start = node.start;
            let dh = rc::get_mut(&mut node.dh).unwrap();
            dh.copy_data_from(data, node_start - size);
        }
        node.start -= size;
        self.length += size;
    }

    pub fn pullup(&mut self, size: uint) -> Option<&[u8]> {
        if size == 0 || size > self.len() {
            return None
        }
        // could not fail, because self.size() > 0 => has node
        if self.head.front().unwrap().size() >= size {
            let node = self.head.front().unwrap();
            return Some(node.data(size));
        }

        let mut newn = Node::new(DataHolder::new(size));
        // XXX: we need this scope to be able to move newn inside our list
        {
            let mut msize = size;
            while msize > 0 {
                {

                    let node = self.head.front_mut().unwrap();
                    let csize = cmp::min(node.size(), msize);
                    // XXX: we need this scope only to beat borrow checker
                    {
                        let node_end = newn.end;
                        // we just created new data holder, so we have unique ownership
                        let dh = rc::get_mut(&mut newn.dh).unwrap();
                        dh.copy_data_from(node.data(csize), node_end);
                    }
                    newn.end += csize;

                    if node.size() > msize {
                        node.start += msize;
                        self.length -= msize;
                        break
                    }
                }
                // infailable
                let n = self.head.pop_front().unwrap();
                self.length -= n.size();
                msize -= n.size();
            }
        }
        self.add_node_head(newn);
        // Now first node.size >= size, so we recurse
        return self.pullup(size)
    }

    pub fn concat(&mut self, src: Chain) {
        self.length += src.length;
        self.head.append(src.head);
        // No need to cleanup `src`, because it has moved and cannot be used
    }

    // XXX: chb_drop; `drop` is the sole method of built-in Drop trait,
    // so use another name
    pub fn reset(&mut self) {
        self.head = DList::new();
        self.length = 0;
    }

    pub fn append(&mut self, src: &Chain) {
        for node in src.head.iter() {
            self.add_node_tail(node.clone());
        }
    }

    // XXX: deprecated & experimental

    // TODO: maybe we do not need this method?
    // TODO: `concat` better express move semantics
    // XXX: to delete...
    pub fn concat_ptr(&mut self, src: &mut Chain) {
        self.length += src.length;
        let sh = mem::replace(&mut src.head, DList::new());
        self.head.append(sh);
        src.length = 0;
    }

    // XXX: private
    fn add_node_tail(&mut self, node: Node) {
        self.length += node.size();
        self.head.push(node);
    }

    fn add_node_head(&mut self, node: Node) {
        self.length += node.size();
        self.head.push_front(node);
    }
}

/// Node of chain buffer.
/// Owned by Chain.
struct Node {
    dh: Rc<DataHolder>,
    start: uint,
    end: uint
}

impl Node {
    fn new(dh: Rc<DataHolder>) -> Node {
        Node {
            dh: dh,
            start: 0,
            end: 0
        }
    }

    fn size(&self) -> uint {
        self.end - self.start
    }

    fn room(&self) -> uint {
        self.dh.size - self.end
    }

    fn data(&self, size:uint) -> &[u8] {
        self.dh.data.slice(self.start, self.start + size)
    }

}

impl Clone for Node {
    fn clone(&self) -> Node {
        let mut newn = Node::new(self.dh.clone());
        newn.start = self.start;
        newn.end = self.end;
        newn
    }
}

/// Refcounted data holder
/// TODO: can be shared among different chains
/// TODO: implement other storages: shmem, mmap
struct DataHolder{
    size: uint,
    data: Vec<u8>
}

impl DataHolder {
    fn new(size: uint) -> Rc<DataHolder> {
        Rc::new(DataHolder {
            size: size,
            data: Vec::from_elem(size, 0)
        })
    }

    fn copy_data_from(&mut self, src: &[u8], dst_offs: uint) {
        blit(src,
             self.data.as_mut_slice(), dst_offs);
    }
}

#[cfg(test)]
mod test {
    use super::Chain;
    use std::rand::{task_rng, Rng};

    #[test]
    fn test_append_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.append_bytes(s.as_bytes());
        assert_eq!(chain.len(), ls);
    }

    #[test]
    fn test_prepend_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.prepend_bytes(s);
        assert_eq!(chain.len(), ls);
    }

    #[test]
    fn test_from_foreign_moves_all_data() {
        let mut orig = Chain::new();
        orig.append_bytes("HelloWorld".as_bytes());
        let sz = orig.len();
        let new = Chain::from_foreign(orig);
        assert_eq!(new.len(), sz);
    }

    #[test]
    fn test_pullup_return_none_on_empty_chain() {
        let mut chain = Chain::new();
        assert!(chain.pullup(1).is_none());
    }

    #[test]
    fn test_pullup_return_what_has_been_appended() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.append_bytes(s);
        let res = chain.pullup(ls);
        assert!(res.is_some());
        assert_eq!(res.unwrap(), s);
    }

    #[test]
    fn test_pullup_does_not_change_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.append_bytes(s);
        let olds = chain.len();
        chain.pullup(ls / 2);
        assert_eq!(chain.len(), olds);
    }

    #[test]
    fn test_pullup_works_on_large_sequences() {
        let mut chain = Chain::new();
        let total = 2048u;
        let mut t = total;
        let one_seq = 128u;
        let mut buf = Vec::new();
        while t > 0 {
            let s:String = task_rng().gen_ascii_chars().take(one_seq).collect();
            let b = s.as_bytes();
            buf.extend(b.iter().map(|x| x.clone()));
            chain.append_bytes(b);
            t -= one_seq;
        }
        {
            let ret = chain.pullup(total);
            assert!(ret.is_some());
            assert_eq!(ret.unwrap(), buf.as_slice());
        }
        assert_eq!(chain.len(), total);
    }

    #[test]
    fn test_concat_increase_dst_length() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        chain1.append_bytes("HelloWorld".as_bytes());
        let l1 = chain1.len();
        chain2.append_bytes("HelloWorld".as_bytes());
        let l2 = chain2.len();
        chain1.concat(chain2);
        assert_eq!(chain1.len(), l1+l2);
    }

    #[test]
    fn test_concat_appends_content() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let b = "HelloWorld".as_bytes();
        let bl = b.len();
        chain2.append_bytes(b);
        chain1.concat(chain2);
        let res = chain1.pullup(bl);

        assert!(res.is_some());
        assert_eq!(res.unwrap(), b);
    }

    #[test]
    fn test_reset_empties_chain() {
        let mut chain = Chain::new();
        chain.append_bytes("HelloWorld".as_bytes());
        chain.reset();
        assert!(chain.pullup(1).is_none());
        assert_eq!(chain.len(), 0);
    }

    #[test]
    fn test_append_copies_data() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let s = "HelloWorld";
        let b = s.as_bytes();
        let lb = b.len();
        let mut ss = String::from_str(s);
        ss.push_str(s);
        chain1.append_bytes(b);
        chain2.append_bytes(b);
        chain1.append(&mut chain2);
        {
            let res = chain1.pullup(2 * lb);
            assert!(res.is_some());
            assert_eq!(res.unwrap(), ss.as_bytes());
        }
        assert_eq!(chain1.len(), 2 * lb);
    }

    // XXX: do not need to test it for `concat`, because it is done for us
    // XXX: by type-system.
    #[test]
    fn test_concat_ptr_destroy_src() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        chain2.append_bytes("HelloWorld".as_bytes());
        chain1.concat_ptr(&mut chain2);
        assert_eq!(chain2.len(), 0);
    }

}
<commit_msg>[add] add Chain.move_from<commit_after>extern crate collections;

use collections::dlist::DList;
use collections::Deque;

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

use std::rc::{mod, Rc};

static CHB_MIN_SIZE:uint = 32u;

// TODO: move to utils
fn blit<T:Clone>(src: &[T], dst: &mut [T], dst_ofs: uint) {
    let len = src.len();
    let sd = dst.slice_mut(dst_ofs, dst_ofs + len);
    if len > sd.len() {
        fail!("blit: source larger than destination");
    }

    let _ = sd.clone_from_slice(src);
}

/// Move at most n items from the front of src deque to thes back of
/// dst deque.
/// XXX: if we had access to DList impl, we could do this more effective
fn move_n<TT, T: Deque<TT>>(src: &mut T, dst: &mut T, n: uint) {
    let mut nc = n;
    while nc > 0 {
        match src.pop_front() {
            Some(el) => {
                dst.push(el);
                nc -= 1;
            }
            None => {
                break;
            }
        }
    }
}

/// Chained buffer of bytes.
/// Consists of linked list of nodes.
pub struct Chain {
    head: DList<Node>,
    length: uint
}

struct NodeAtPosInfo<'a> {
    node: &'a mut Node, // link to node
    pos: uint, // position of node in chain
    offset: uint // offset inside node
}

impl Chain {
    pub fn new() -> Chain {
        Chain{
            head: DList::new(),
            length: 0
        }
    }

    pub fn from_foreign(src: Chain) -> Chain {
        let mut ch = Chain::new();
        ch.concat(src);
        ch
    }

    pub fn len(&self) -> uint {
        self.length
    }

    // XXX: maybe DEDUP append/prepend?
    pub fn append_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.back() {
            Some(nd) => {
                (nd.room() < size) || !rc::is_unique(&nd.dh)
            }
            None => {
                true
            }
        };
        // We either not the only owner of DH or don't have enough room
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let node = Node::new(DataHolder::new(nsize));
            self.add_node_tail(node);
        }
        // infailable: added node above
        let node = self.head.back_mut().unwrap();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6268
        // XXX: we need additional var and scope only to fight borrow checker
        {
            let node_end = node.end;
            // we should be sole owner of data holder inside node here
            let dh = rc::get_mut(&mut node.dh).unwrap();
            dh.copy_data_from(data, node_end);
        }
        node.end += size;
        self.length += size;
    }

    pub fn prepend_bytes(&mut self, data: &[u8]) {
        let size = data.len();
        // XXX: Damn, https://github.com/rust-lang/rust/issues/6393
        let should_create = match self.head.front() {
            Some(nd) => {
                (size > nd.start || !rc::is_unique(&nd.dh))
            }
            None => {
                true
            }
        };
        if should_create {
            let nsize = if size < CHB_MIN_SIZE { size << 1 } else { size };
            let mut node = Node::new(DataHolder::new(nsize)); // Box<Node>
            let r = node.room();
            node.start = r;
            node.end = r;
            self.add_node_head(node);
        }
        // See comments in `append_bytes`
        let node = self.head.front_mut().unwrap();
        {
            let node_start = node.start;
            let dh = rc::get_mut(&mut node.dh).unwrap();
            dh.copy_data_from(data, node_start - size);
        }
        node.start -= size;
        self.length += size;
    }

    pub fn pullup(&mut self, size: uint) -> Option<&[u8]> {
        if size == 0 || size > self.len() {
            return None
        }
        // could not fail, because self.size() > 0 => has node
        if self.head.front().unwrap().size() >= size {
            let node = self.head.front().unwrap();
            return Some(node.data(size));
        }
        let mut newn = Node::new(DataHolder::new(size));
        // XXX: we need this scope to be able to move newn inside our list
        {
            let mut msize = size;
            while msize > 0 {
                {
                    let node = self.head.front_mut().unwrap();
                    let csize = cmp::min(node.size(), msize);
                    // XXX: we need this scope only to beat borrow checker
                    {
                        let node_end = newn.end;
                        // we just created new data holder, so we have unique ownership
                        let dh = rc::get_mut(&mut newn.dh).unwrap();
                        dh.copy_data_from(node.data(csize), node_end);
                    }
                    newn.end += csize;

                    if node.size() > msize {
                        node.start += msize;
                        self.length -= msize;
                        break
                    }
                }
                // infailable
                let n = self.head.pop_front().unwrap();
                self.length -= n.size();
                msize -= n.size();
            }
        }
        self.add_node_head(newn);
        // Now first node.size >= size, so we recurse
        return self.pullup(size)
    }

    pub fn concat(&mut self, src: Chain) {
        self.length += src.length;
        self.head.append(src.head);
        // No need to cleanup `src`, because it has moved and cannot be used
    }

    // XXX: chb_drop; `drop` is the sole method of built-in Drop trait,
    // so use another name
    pub fn reset(&mut self) {
        self.head = DList::new();
        self.length = 0;
    }

    pub fn append(&mut self, src: &Chain) {
        for node in src.head.iter() {
            self.add_node_tail(node.clone());
        }
    }

    pub fn move_from(&mut self, src: &mut Chain, size: uint) -> uint {
        if size == 0 {
            return 0;
        }
        if size >= src.len() {
            let sz = src.len();
            self.move_all_from(src);
            return sz;
        }

        let mut move_nodes;
        let mut newn = None;
        // We've done checks, so we cannot have None here
        {
            let node_info = src.node_at_pos(size).unwrap();
            if node_info.offset != 0 {
                // We requesting data in the middle of node, should split it then
                let mut nn = node_info.node.clone();
                nn.start += node_info.offset;
                node_info.node.end = nn.start;
                newn = Some(nn);
                move_nodes = node_info.pos + 1;
            } else {
                // Requested data right on the border of nodes, can move all nodes
                // before this one
                move_nodes = node_info.pos;
            }
        }
        move_n(&mut src.head, &mut self.head, move_nodes);
        if newn.is_some() {
            src.head.push_front(newn.unwrap());
        }

        self.length += size;
        src.length -= size;

        return size; }

    pub fn move_all_from(&mut self, src: &mut Chain) {
        self.length += src.length;
        let sh = mem::replace(&mut src.head, DList::new());
        self.head.append(sh);
        src.length = 0;
    }

    // XXX: private

    fn node_at_pos<'a>(&'a mut self, pos: uint) -> Option<NodeAtPosInfo<'a>> {
        if (pos << 1) > self.len() {
            // Find from tail
            let mut toff = self.len(); // tail offset
            for (i, n) in self.head.iter_mut().rev().enumerate() {
                let nsize = n.size();
                if (toff - pos) <= nsize {
                    return Some(NodeAtPosInfo {
                        node: n,
                        pos: i,
                        offset: (nsize - (toff - pos))
                    })
                }
                toff -= nsize;
            }
        } else {
            // Find from begining
            let mut hoff = 0; // head offset
            for (i, n) in self.head.iter_mut().enumerate() {
                let nsize = n.size();
                if (pos - hoff) < nsize {
                    return Some(NodeAtPosInfo {
                        node: n,
                        pos: i,
                        offset: pos - hoff
                    })
                }
                hoff += nsize;
            }
        }
        None
    }

    fn add_node_tail(&mut self, node: Node) {
        self.length += node.size();
        self.head.push(node);
    }

    fn add_node_head(&mut self, node: Node) {
        self.length += node.size();
        self.head.push_front(node);
    }
}

/// Node of chain buffer.
/// Owned by Chain.
struct Node {
    dh: Rc<DataHolder>,
    start: uint,
    end: uint
}

impl Node {
    fn new(dh: Rc<DataHolder>) -> Node {
        Node {
            dh: dh,
            start: 0,
            end: 0
        }
    }

    fn size(&self) -> uint {
        self.end - self.start
    }

    fn room(&self) -> uint {
        self.dh.size - self.end
    }

    fn data(&self, size:uint) -> &[u8] {
        self.dh.data.slice(self.start, self.start + size)
    }

}

impl Clone for Node {
    fn clone(&self) -> Node {
        let mut newn = Node::new(self.dh.clone());
        newn.start = self.start;
        newn.end = self.end;
        newn
    }
}

/// Refcounted data holder
/// TODO: can be shared among different chains
/// TODO: implement other storages: shmem, mmap
struct DataHolder{
    size: uint,
    data: Vec<u8>
}

impl DataHolder {
    fn new(size: uint) -> Rc<DataHolder> {
        Rc::new(DataHolder {
            size: size,
            data: Vec::from_elem(size, 0)
        })
    }

    fn copy_data_from(&mut self, src: &[u8], dst_offs: uint) {
        blit(src,
             self.data.as_mut_slice(), dst_offs);
    }
}

#[cfg(test)]
mod test {
    use super::Chain;
    use super::CHB_MIN_SIZE;
    use std::rand::{task_rng, Rng};

    #[test]
    fn test_append_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld";
        let ls = s.len();
        chain.append_bytes(s.as_bytes());
        assert_eq!(chain.len(), ls);
    }

    #[test]
    fn test_prepend_bytes_changes_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.prepend_bytes(s);
        assert_eq!(chain.len(), ls);
    }

    #[test]
    fn test_from_foreign_moves_all_data() {
        let mut orig = Chain::new();
        orig.append_bytes("HelloWorld".as_bytes());
        let sz = orig.len();
        let new = Chain::from_foreign(orig);
        assert_eq!(new.len(), sz);
    }

    #[test]
    fn test_pullup_return_none_on_empty_chain() {
        let mut chain = Chain::new();
        assert!(chain.pullup(1).is_none());
    }

    #[test]
    fn test_pullup_return_what_has_been_appended() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.append_bytes(s);
        let res = chain.pullup(ls);
        assert!(res.is_some());
        assert_eq!(res.unwrap(), s);
    }

    #[test]
    fn test_pullup_does_not_change_length() {
        let mut chain = Chain::new();
        let s = "HelloWorld".as_bytes();
        let ls = s.len();
        chain.append_bytes(s);
        let olds = chain.len();
        chain.pullup(ls / 2);
        assert_eq!(chain.len(), olds);
    }

    #[test]
    fn test_pullup_works_on_large_sequences() {
        let mut chain = Chain::new();
        let total = 2048u;
        let mut t = total;
        let one_seq = 128u;
        let mut buf = Vec::new();
        while t > 0 {
            let s:String = task_rng().gen_ascii_chars().take(one_seq).collect();
            let b = s.as_bytes();
            buf.extend(b.iter().map(|x| x.clone()));
            chain.append_bytes(b);
            t -= one_seq;
        }
        {
            let ret = chain.pullup(total);
            assert!(ret.is_some());
            assert_eq!(ret.unwrap(), buf.as_slice());
        }
        assert_eq!(chain.len(), total);
    }

    #[test]
    fn test_concat_increase_dst_length() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        chain1.append_bytes("HelloWorld".as_bytes());
        let l1 = chain1.len();
        chain2.append_bytes("HelloWorld".as_bytes());
        let l2 = chain2.len();
        chain1.concat(chain2);
        assert_eq!(chain1.len(), l1+l2);
    }

    #[test]
    fn test_concat_appends_content() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let b = "HelloWorld".as_bytes();
        let bl = b.len();
        chain2.append_bytes(b);
        chain1.concat(chain2);
        let res = chain1.pullup(bl);

        assert!(res.is_some());
        assert_eq!(res.unwrap(), b);
    }

    #[test]
    fn test_reset_empties_chain() {
        let mut chain = Chain::new();
        chain.append_bytes("HelloWorld".as_bytes());
        chain.reset();
        assert!(chain.pullup(1).is_none());
        assert_eq!(chain.len(), 0);
    }

    #[test]
    fn test_append_copies_data() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let s = "HelloWorld";
        let b = s.as_bytes();
        let lb = b.len();
        let mut ss = String::from_str(s);
        ss.push_str(s);
        chain1.append_bytes(b);
        chain2.append_bytes(b);
        chain1.append(&mut chain2);
        {
            let res = chain1.pullup(2 * lb);
            assert!(res.is_some());
            assert_eq!(res.unwrap(), ss.as_bytes());
        }
        assert_eq!(chain1.len(), 2 * lb);
    }

    #[test]
    fn test_move_from_moves_data() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let s = "HelloWorld";
        let b = s.as_bytes();
        let lb = b.len();
        let hlb = lb / 2;
        chain1.append_bytes(b);
        chain2.append_bytes(b);
        chain1.move_from(&mut chain2, hlb);
        assert_eq!(chain1.len(), lb + hlb);
        assert_eq!(chain2.len(), hlb);
        {
            let mut ss = String::from_str(s);
            ss.push_str(s.slice(0, hlb));
            let r = b.slice_from(hlb);
            let r1 = chain1.pullup(lb + hlb);
            let r2 = chain2.pullup(hlb);
            assert!(r1.is_some());
            assert!(r2.is_some());
            assert_eq!(r1.unwrap(), ss.as_bytes());
            assert_eq!(r2.unwrap(), r);
        }
    }

    #[test]
    fn test_move_from_move_on_node_edge() {
        let mut chain1 = Chain::new();
        let mut chain2 = Chain::new();
        let s:String = task_rng().gen_ascii_chars().take(CHB_MIN_SIZE).collect();
        let sb = s.as_bytes();
        chain2.append_bytes(sb);
        chain2.append_bytes(sb);
        chain2.append_bytes(sb);
        chain2.append_bytes(sb);
        chain1.move_from(&mut chain2, CHB_MIN_SIZE * 2);
        assert_eq!(chain1.len(), chain2.len());
    }

}
<|endoftext|>


<commit_before>// Copyright (c) 2019 Stefan Lankes, RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

#![allow(dead_code)]
#![allow(unused_imports)]

#[cfg(target_os = "hermit")]
extern crate hermit_sys;
extern crate rand;
extern crate rayon;

mod tests;

use tests::*;

fn test_result<T>(result: Result<(), T>) -> &'static str {
	match result {
		Ok(_) => "ok",
		Err(_) => "failed!",
	}
}

fn main() {
	println!("Test {} ... {}", stringify!(hello), test_result(hello()));
	println!(
		"Test {} ... {}",
		stringify!(print_argv),
		test_result(print_argv())
	);
	println!(
		"Test {} ... {}",
		stringify!(print_env),
		test_result(print_env())
	);
	println!(
		"Test {} ... {}",
		stringify!(read_file),
		test_result(read_file())
	);
	println!(
		"Test {} ... {}",
		stringify!(create_file),
		test_result(create_file())
	);
	println!(
		"Test {} ... {}",
		stringify!(threading),
		test_result(threading())
	);
	println!(
		"Test {} ... {}",
		stringify!(random_number),
		test_result(random_number())
	);
	println!(
		"Test {} ... {}",
		stringify!(pi_sequential),
		test_result(pi_sequential(5000000))
	);
	println!(
		"Test {} ... {}",
		stringify!(pi_parallel),
		test_result(pi_parallel(2, 5000000))
	);
	/*println!(
		"Test {} ... {}",
		stringify!(laplace),
		test_result(laplace(128, 128))
	);
	println!(
		"Test {} ... {}",
		stringify!(test_matmul_strassen),
		test_result(test_matmul_strassen())
	);*/
	/*println!(
		"Test {} ... {}",
		stringify!(thread_creation),
		test_result(thread_creation())
	);
	println!(
		"Test {} ... {}",
		stringify!(bench_sched_one_thread),
		test_result(bench_sched_one_thread())
	);
	println!(
		"Test {} ... {}",
		stringify!(bench_sched_two_threads),
		test_result(bench_sched_two_threads())
	);*/
	println!(
		"Test {} ... {}",
		stringify!(test_http_request),
		test_result(test_http_request())
	);
}
<commit_msg>disable temporary the random number test<commit_after>// Copyright (c) 2019 Stefan Lankes, RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

#![allow(dead_code)]
#![allow(unused_imports)]

#[cfg(target_os = "hermit")]
extern crate hermit_sys;
extern crate rand;
extern crate rayon;

mod tests;

use tests::*;

fn test_result<T>(result: Result<(), T>) -> &'static str {
	match result {
		Ok(_) => "ok",
		Err(_) => "failed!",
	}
}

fn main() {
	println!("Test {} ... {}", stringify!(hello), test_result(hello()));
	println!(
		"Test {} ... {}",
		stringify!(print_argv),
		test_result(print_argv())
	);
	println!(
		"Test {} ... {}",
		stringify!(print_env),
		test_result(print_env())
	);
	println!(
		"Test {} ... {}",
		stringify!(read_file),
		test_result(read_file())
	);
	println!(
		"Test {} ... {}",
		stringify!(create_file),
		test_result(create_file())
	);
	println!(
		"Test {} ... {}",
		stringify!(threading),
		test_result(threading())
	);
	/*println!(
		"Test {} ... {}",
		stringify!(random_number),
		test_result(random_number())
	);*/
	println!(
		"Test {} ... {}",
		stringify!(pi_sequential),
		test_result(pi_sequential(5000000))
	);
	println!(
		"Test {} ... {}",
		stringify!(pi_parallel),
		test_result(pi_parallel(2, 5000000))
	);
	/*println!(
		"Test {} ... {}",
		stringify!(laplace),
		test_result(laplace(128, 128))
	);
	println!(
		"Test {} ... {}",
		stringify!(test_matmul_strassen),
		test_result(test_matmul_strassen())
	);*/
	/*println!(
		"Test {} ... {}",
		stringify!(thread_creation),
		test_result(thread_creation())
	);
	println!(
		"Test {} ... {}",
		stringify!(bench_sched_one_thread),
		test_result(bench_sched_one_thread())
	);
	println!(
		"Test {} ... {}",
		stringify!(bench_sched_two_threads),
		test_result(bench_sched_two_threads())
	);*/
	println!(
		"Test {} ... {}",
		stringify!(test_http_request),
		test_result(test_http_request())
	);
}
<|endoftext|>


<commit_before>use {
    BackEnd,
    Borrowed,
    CanTransform,
    Clear,
    Color,
    Field,
    Fill,
    HasTransform,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity,
};
use triangulation::{
    with_polygon_tri_list_xy_f32_rgba_f32
};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> HasTransform<'a, Matrix2d> for PolygonColorContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, PolygonColorContext<'a>, Matrix2d> for PolygonColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for PolygonColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygon = self.polygon.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_polygon_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygon,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Clear for PolygonColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

<commit_msg>Implemented `HasColor` and `CanColor` for `PolygonColorContext`<commit_after>use {
    BackEnd,
    Borrowed,
    CanColor,
    CanTransform,
    Clear,
    Color,
    Field,
    Fill,
    HasColor,
    HasTransform,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity,
};
use triangulation::{
    with_polygon_tri_list_xy_f32_rgba_f32
};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> HasTransform<'a, Matrix2d> for PolygonColorContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, PolygonColorContext<'a>, Matrix2d> for PolygonColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> HasColor<'a, Color> for PolygonColorContext<'a> {
    #[inline(always)]
    fn get_color(&'a self) -> &'a Color {
        self.color.get()
    }
}

impl<'a> CanColor<'a, PolygonColorContext<'a>, Color> for PolygonColorContext<'a> {
    #[inline(always)]
    fn color(&'a self, value: Color) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            color: Value(value),
            polygon: Borrowed(self.polygon.get()),
        }
    }
}

impl<'a> Fill<'a> for PolygonColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygon = self.polygon.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_polygon_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygon,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Clear for PolygonColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

extern crate gtk;
extern crate libxdo;
#[macro_use]
extern crate mg;
extern crate mg_settings;
#[macro_use]
extern crate mg_settings_macros;

mod utils;

use std::thread;

use gtk::Label;
use libxdo::XDo;

use self::AppCommand::*;
use utils::XDoExt;

#[derive(Commands)]
enum AppCommand {
    #[help(text="Show the text in the label")]
    Show(String),
    Quit,
}

#[derive(Default, Settings)]
pub struct AppSettings {
    boolean: bool,
}

struct App {
    app: Box<Application<AppCommand, AppSettings>>,
    label: Label,
}

impl App {
    fn new() -> Box<Self> {
        let app = ApplicationBuilder::new()
            .settings(AppSettings::default())
            .build();

        let label = Label::new(Some("Label"));

        app.set_view(&label);

        let mut app = Box::new(App {
            app: app,
            label: label,
        });

        connect!(app.app, connect_command(command), app, handle_command(command));

        app
    }

    fn handle_command(&self, command: AppCommand) {
        match command {
            Show(text) => self.label.set_text(&format!("Showing text: {}", text)),
            Quit => gtk::main_quit(),
        }
    }
}

#[test]
fn test_basic_command() {
    gtk::init().unwrap();

    let app = App::new();

    assert_eq!(Some("Label".to_string()), app.label.get_text());

    thread::spawn(|| {
        let xdo = XDo::new(None).unwrap();
        xdo.enter_command("show test");
        xdo.enter_command("quit");
    });

    gtk::main();

    assert_eq!(Some("Showing text: test".to_string()), app.label.get_text());
}
<commit_msg>Fix tests<commit_after>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#![feature(proc_macro)]

extern crate gtk;
extern crate libxdo;
extern crate mg;
extern crate mg_settings;
#[macro_use]
extern crate mg_settings_macros;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

mod utils;

use std::thread;

use gtk::WidgetExt;
use libxdo::XDo;
use mg::{
    CustomCommand,
    Mg,
    Modes,
};
use relm::{Widget, init_test};
use relm_attributes::widget;

use self::AppCommand::*;
use self::Msg::*;
use utils::XDoExt;

#[derive(Commands)]
pub enum AppCommand {
    #[help(text="Show the text in the label")]
    Show(String),
    Quit,
}

#[derive(Default, Settings)]
pub struct AppSettings {
    boolean: bool,
}

pub struct Model {
    text: String,
}

#[derive(Msg)]
pub enum Msg {
    Command(AppCommand),
}

static MODES: Modes = &[
    ("i", "insert"),
];

#[widget]
impl Widget for Win {
    fn model() -> Model {
        Model {
            text: "Label".to_string(),
        }
    }

    fn update(&mut self, event: Msg) {
        match event {
            Command(command) => {
                match command {
                    Show(text) => self.model.text = format!("Showing text: {}", text),
                    Quit => gtk::main_quit(),
                }
            },
        }
    }

    view! {
        #[name="mg"]
        Mg<AppCommand, AppSettings>((MODES, "examples/main.conf")) {
            #[name="label"]
            gtk::Label {
                text: &self.model.text,
            },
            CustomCommand(command) => Command(command),
        }
    }
}

#[test]
fn test_basic_command() {
    gtk::init().unwrap();

    let win = init_test::<Win>(()).unwrap();

    assert_eq!(Some("Label".to_string()), win.widget().label.get_text());

    thread::spawn(|| {
        let xdo = XDo::new(None).unwrap();
        xdo.enter_command("show test");
        xdo.enter_command("quit");
    });

    gtk::main();

    assert_eq!(Some("Showing text: test".to_string()), win.widget().label.get_text());
}
<|endoftext|>


<commit_before>use super::*;

use graphics::text::Font;
use gfx_glyph::{FontId, Scale, Section};

/// Efficient drawable text using a `Font::GlyphFont`.
#[derive(Clone, Debug)]
pub struct TextCached {
    font_id: FontId,
    font_scale: Scale,
    contents: String,
    blend_mode: Option<BlendMode>,
}

impl TextCached {
    /// Creates a `TextCached` with given `Font::GlyphFont`.
    /// Can be relatively efficiently re-created every frame.
    pub fn new(context: &mut Context, text: &str, font: &Font) -> GameResult<TextCached> {
        if let &Font::GlyphFont { font_id, scale } = font {
            return Ok(TextCached {
                font_id,
                font_scale: scale,
                contents: text.to_string(),
                blend_mode: None,
            });
        }
        Err(GameError::FontError(
            "`TextCached` can only be used with a `Font::GlyphFont`!".into(),
        ))
    }
}

impl Drawable for TextCached {
    fn draw_ex(&self, ctx: &mut Context, param: DrawParam) -> GameResult<()> {
        let color = match param.color {
            Some(color) => color,
            None => get_color(ctx),
        };
        let (font_id, font_scale) = (self.font_id, self.font_scale);
        ctx.gfx_context.glyph_brush.queue(Section {
            text: &self.contents,
            //screen_position: (dest.x, dest.y),
            //bounds: (f32, f32),
            scale: font_scale,
            color: <[f32; 4]>::from(color),
            //z: f32,
            //layout: Layout<BuiltInLineBreaker>,
            font_id,
            ..Section::default()
        });

        type Mat4 = na::Matrix4<f32>;
        type Vec3 = na::Vector3<f32>;

        let (offset_x, offset_y) = (-1.0, 1.0);
        let (screen_w, screen_h) = (ctx.gfx_context.screen_rect.w, ctx.gfx_context.screen_rect.h);
        let (aspect, aspect_inv) = (screen_h / screen_w, screen_w / screen_h);
        let m_aspect = Mat4::new_nonuniform_scaling(&Vec3::new(1.0, aspect_inv, 1.0));
        let m_aspect_inv = Mat4::new_nonuniform_scaling(&Vec3::new(1.0, aspect, 1.0));
        let m_scale = Mat4::new_nonuniform_scaling(&Vec3::new(param.scale.x, param.scale.y, 1.0));
        let m_shear = Mat4::new(
            1.0,
            param.shear.x,
            0.0,
            0.0,
            param.shear.y,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
        );
        let m_rotation = Mat4::new_rotation(param.rotation * Vec3::z());
        let m_offset = Mat4::new_translation(&Vec3::new(offset_x, offset_y, 0.0));
        let m_offset_inv = Mat4::new_translation(&Vec3::new(-offset_x, -offset_y, 0.0));
        let m_translate = Mat4::new_translation(&Vec3::new(
            param.dest.x / screen_w,
            -param.dest.y / screen_h,
            0.0,
        ));

        let m_transform = m_translate * m_offset * m_aspect * m_rotation * m_scale * m_shear
            * m_aspect_inv * m_offset_inv;

        let (encoder, render_tgt, depth_view) = (
            &mut ctx.gfx_context.encoder,
            &ctx.gfx_context.screen_render_target,
            &ctx.gfx_context.depth_view,
        );

        ctx.gfx_context.glyph_brush.draw_queued_with_transform(
            m_transform.into(),
            encoder,
            render_tgt,
            depth_view,
        )?;
        Ok(())
    }

    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.blend_mode = mode;
    }

    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.blend_mode
    }
}
<commit_msg>Rearranged `TextCached`, now has `.queue()` and `::draw_queued()`.<commit_after>use super::*;

use graphics::text::Font;
use gfx_glyph::{FontId, Scale, Section};

/// Efficient drawable text using a `Font::GlyphFont`.
#[derive(Clone, Debug)]
pub struct TextCached {
    font_id: FontId,
    font_scale: Scale,
    contents: String,
    blend_mode: Option<BlendMode>,
}

impl TextCached {
    /// Creates a `TextCached` with given `Font::GlyphFont`.
    /// Can be relatively efficiently re-created every frame.
    pub fn new(context: &mut Context, text: &str, font: &Font) -> GameResult<TextCached> {
        if let &Font::GlyphFont { font_id, scale } = font {
            return Ok(TextCached {
                font_id,
                font_scale: scale,
                contents: text.to_string(),
                blend_mode: None,
            });
        }
        Err(GameError::FontError(
            "`TextCached` can only be used with a `Font::GlyphFont`!".into(),
        ))
    }

    /// Queues the `TextCached` to be drawn by `draw_queued()`.
    /// This is much more efficient than using `graphics::draw()` or equivalent.
    /// Note, any `TextCached` drawn via `graphics::draw()` will also draw the queue,
    /// if it hasn't been drawn by `draw_queued()` yet.
    pub fn queue(&self, context: &mut Context) {
        /*let color = match param.color {
            Some(color) => color,
            None => get_color(ctx),
        };*/
        let (font_id, font_scale) = (self.font_id, self.font_scale);
        context.gfx_context.glyph_brush.queue(Section {
            text: &self.contents,
            //screen_position: (dest.x, dest.y),
            //bounds: (f32, f32),
            scale: self.font_scale,
            //  color: <[f32; 4]>::from(color),
            //z: f32,
            //layout: Layout<BuiltInLineBreaker>,
            font_id: self.font_id,
            ..Section::default()
        });
    }

    /// Draws all of queued `TextCached`.
    /// This is much more efficient than using `graphics::draw()` or equivalent.
    pub fn draw_queued(context: &mut Context, param: DrawParam) -> GameResult<()> {
        type Mat4 = na::Matrix4<f32>;
        type Vec3 = na::Vector3<f32>;

        let (offset_x, offset_y) = (-1.0, 1.0);
        let (screen_w, screen_h) = (
            context.gfx_context.screen_rect.w,
            context.gfx_context.screen_rect.h,
        );
        let (aspect, aspect_inv) = (screen_h / screen_w, screen_w / screen_h);
        let m_aspect = Mat4::new_nonuniform_scaling(&Vec3::new(1.0, aspect_inv, 1.0));
        let m_aspect_inv = Mat4::new_nonuniform_scaling(&Vec3::new(1.0, aspect, 1.0));
        let m_scale = Mat4::new_nonuniform_scaling(&Vec3::new(param.scale.x, param.scale.y, 1.0));
        let m_shear = Mat4::new(
            1.0,
            param.shear.x,
            0.0,
            0.0,
            param.shear.y,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
        );
        let m_rotation = Mat4::new_rotation(param.rotation * Vec3::z());
        let m_offset = Mat4::new_translation(&Vec3::new(offset_x, offset_y, 0.0));
        let m_offset_inv = Mat4::new_translation(&Vec3::new(-offset_x, -offset_y, 0.0));
        let m_translate = Mat4::new_translation(&Vec3::new(
            param.dest.x / screen_w,
            -param.dest.y / screen_h,
            0.0,
        ));

        let m_transform = m_translate * m_offset * m_aspect * m_rotation * m_scale * m_shear
            * m_aspect_inv * m_offset_inv;

        let (encoder, render_tgt, depth_view) = (
            &mut context.gfx_context.encoder,
            &context.gfx_context.screen_render_target,
            &context.gfx_context.depth_view,
        );

        Ok(context.gfx_context.glyph_brush.draw_queued_with_transform(
            m_transform.into(),
            encoder,
            render_tgt,
            depth_view,
        )?)
    }
}

impl Drawable for TextCached {
    fn draw_ex(&self, ctx: &mut Context, param: DrawParam) -> GameResult<()> {
        self.queue(ctx);
        TextCached::draw_queued(ctx, param)
    }

    fn set_blend_mode(&mut self, mode: Option<BlendMode>) {
        self.blend_mode = mode;
    }

    fn get_blend_mode(&self) -> Option<BlendMode> {
        self.blend_mode
    }
}
<|endoftext|>