<commit_before>#![warn(unused_results)]

// TODO: Instead of --base <base> and --decode, maybe use --from <base> and --to <base>
// With <base> in 2, 4, 8, 16, hex, 32, 32hex, 64, 64url, raw, <custom>
//      <custom> is <pad><symbols>

extern crate getopts;
extern crate data_encoding;

use std::fs::File;
use std::io::Write;

use getopts::Options;

#[macro_use]
mod tool;
mod base;
mod error;
mod io;

use base::{Base, lookup};
use error::Error;
use io::{ReadShift, Operation, Skip, Wrap, repeat};

fn main() {
    let (program, args): (_, Vec<_>) = {
        let mut i = std::env::args();
        match i.next() {
            None => ("encode".into(), vec![]),
            Some(p) => (p, i.collect()),
        }
    };
    let program = program.rsplit('/').next().unwrap_or(&program);

    if let Err(e) = wrapped_main(program, args) {
        let _ = writeln!(&mut std::io::stderr(), "{}: {}", program, e);
        std::process::exit(1)
    }
}

fn wrapped_main(program: &str, args: Vec<String>) -> Result<(), Error> {
    // Define options.
    let mut opts = Options::new();
    let opts = opts
        .optopt("b", "base", "select base 2, 4, 8, 16 (or hex), 32, 32hex, 64, or 64url if <name> matches. Otherwise, build base using the first character of <name> as padding and the remaining characters as symbols in value order. Default is 64.", "<name>")
        .optflag("d", "decode", "decode data. Default is to encode data.")
        .optopt("i", "input", "use <file> as input. Default is to use standard input.", "<file>")
        .optopt("o", "output", "use <file> as output. Default is to use standard output.", "<file>")
        .optflag("s", "skip", "when decoding, skip newlines. Default is to accept only well-formed input.")
        .optopt("w", "wrap", "when encoding, add newlines every <cols> characters and at the end. Default is to produce well-formed output.", "<cols>")
        ;

    // Deal with --help.
    if args.len() == 1 && (args[0] == "--help" || args[0] == "-h") {
        let brief = format!("Usage: {} [<options>]", program);
        print!("{}", opts.usage(&brief));
        println!("\nExamples:");
        println!("    {}", program);
        println!("    {} -d", program);
        println!("    {} -b32 -d -s", program);
        println!("    {} -b=0123456789abcdef -w76", program);
        return Ok(());
    }

    // Parse options.
    let matches = try!(opts.parse(&args).map_err(Error::ParseOpts));
    check!(matches.free.len() == 0, Error::ExtraArgs);

    // Deal with --base.
    let name = matches.opt_str("b").unwrap_or("64".into());
    let base = try!(base::lookup(name));

    // Deal with --input.
    let mut input: Box<ReadShift>;
    if let Some(file) = matches.opt_str("i") {
        input = Box::new(try!(File::open(&file).map_err(|e| Error::Open(file, e))));
    } else {
        input = Box::new(std::io::stdin());
    };

    // Deal with --output.
    let mut output: Box<Write>;
    if let Some(file) = matches.opt_str("o") {
        output = Box::new(try!(File::create(&file).map_err(|e| Error::Create(file, e))));
    } else {
        // TODO: Change the following lines when Stdout does not go
        // through a LineWriter anymore.
        output = Box::new(unsafe { <File as std::os::unix::io::FromRawFd>::from_raw_fd(1) });
        // output = Box::new(std::io::stdout());
    }
    output = Box::new(std::io::BufWriter::new(output));

    // Deal with --decode, --wrap, and --skip.
    let operation: Operation;
    let size = 8192;
    let imod;
    let omod;
    if matches.opt_present("d") {
        check!(!matches.opt_present("w"), Error::WrapDecode);
        imod = base.encode_len(1);
        omod = base.decode_len(1);
        operation = Box::new(move |i, o| Ok(try!(base.decode_mut(i, o))));
        if matches.opt_present("s") {
            input = Box::new(Skip::new(input));
        }
    } else {
        check!(!matches.opt_present("s"), Error::SkipEncode);
        imod = base.decode_len(1);
        omod = base.encode_len(1);
        operation = Box::new(move |i, o| { base.encode_mut(i, o); Ok(o.len()) });
        let cols = matches.opt_str("w").unwrap_or("0".into());
        let cols = try!(cols.parse().map_err(Error::ParseWrap));
        if cols > 0 {
            output = Box::new(Wrap::new(output, cols));
        }
    }

    // Do the real work.
    repeat(input, output, operation, size, imod, omod)
}
<commit_msg>Add todo in encode example<commit_after>#![warn(unused_results)]

// TODO: Test if we really need custom, or if it's not easier and
// faster to "tr | baseN | tr".

// TODO: Instead of --base <base> and --decode, maybe use --from <base> and --to <base>
// With <base> in 2, 4, 8, 16, hex, 32, 32hex, 64, 64url, raw, <custom>
//      <custom> is <pad><symbols>

extern crate getopts;
extern crate data_encoding;

use std::fs::File;
use std::io::Write;

use getopts::Options;

#[macro_use]
mod tool;
mod base;
mod error;
mod io;

use base::{Base, lookup};
use error::Error;
use io::{ReadShift, Operation, Skip, Wrap, repeat};

fn main() {
    let (program, args): (_, Vec<_>) = {
        let mut i = std::env::args();
        match i.next() {
            None => ("encode".into(), vec![]),
            Some(p) => (p, i.collect()),
        }
    };
    let program = program.rsplit('/').next().unwrap_or(&program);

    if let Err(e) = wrapped_main(program, args) {
        let _ = writeln!(&mut std::io::stderr(), "{}: {}", program, e);
        std::process::exit(1)
    }
}

fn wrapped_main(program: &str, args: Vec<String>) -> Result<(), Error> {
    // Define options.
    let mut opts = Options::new();
    let opts = opts
        .optopt("b", "base", "select base 2, 4, 8, 16 (or hex), 32, 32hex, 64, or 64url if <name> matches. Otherwise, build base using the first character of <name> as padding and the remaining characters as symbols in value order. Default is 64.", "<name>")
        .optflag("d", "decode", "decode data. Default is to encode data.")
        .optopt("i", "input", "use <file> as input. Default is to use standard input.", "<file>")
        .optopt("o", "output", "use <file> as output. Default is to use standard output.", "<file>")
        .optflag("s", "skip", "when decoding, skip newlines. Default is to accept only well-formed input.")
        .optopt("w", "wrap", "when encoding, add newlines every <cols> characters and at the end. Default is to produce well-formed output.", "<cols>")
        ;

    // Deal with --help.
    if args.len() == 1 && (args[0] == "--help" || args[0] == "-h") {
        let brief = format!("Usage: {} [<options>]", program);
        print!("{}", opts.usage(&brief));
        println!("\nExamples:");
        println!("    {}", program);
        println!("    {} -d", program);
        println!("    {} -b32 -d -s", program);
        println!("    {} -b=0123456789abcdef -w76", program);
        return Ok(());
    }

    // Parse options.
    let matches = try!(opts.parse(&args).map_err(Error::ParseOpts));
    check!(matches.free.len() == 0, Error::ExtraArgs);

    // Deal with --base.
    let name = matches.opt_str("b").unwrap_or("64".into());
    let base = try!(base::lookup(name));

    // Deal with --input.
    let mut input: Box<ReadShift>;
    if let Some(file) = matches.opt_str("i") {
        input = Box::new(try!(File::open(&file).map_err(|e| Error::Open(file, e))));
    } else {
        input = Box::new(std::io::stdin());
    };

    // Deal with --output.
    let mut output: Box<Write>;
    if let Some(file) = matches.opt_str("o") {
        output = Box::new(try!(File::create(&file).map_err(|e| Error::Create(file, e))));
    } else {
        // TODO: Change the following lines when Stdout does not go
        // through a LineWriter anymore.
        output = Box::new(unsafe { <File as std::os::unix::io::FromRawFd>::from_raw_fd(1) });
        // output = Box::new(std::io::stdout());
    }
    output = Box::new(std::io::BufWriter::new(output));

    // Deal with --decode, --wrap, and --skip.
    let operation: Operation;
    let size = 8192;
    let imod;
    let omod;
    if matches.opt_present("d") {
        check!(!matches.opt_present("w"), Error::WrapDecode);
        imod = base.encode_len(1);
        omod = base.decode_len(1);
        operation = Box::new(move |i, o| Ok(try!(base.decode_mut(i, o))));
        if matches.opt_present("s") {
            input = Box::new(Skip::new(input));
        }
    } else {
        check!(!matches.opt_present("s"), Error::SkipEncode);
        imod = base.decode_len(1);
        omod = base.encode_len(1);
        operation = Box::new(move |i, o| { base.encode_mut(i, o); Ok(o.len()) });
        let cols = matches.opt_str("w").unwrap_or("0".into());
        let cols = try!(cols.parse().map_err(Error::ParseWrap));
        if cols > 0 {
            output = Box::new(Wrap::new(output, cols));
        }
    }

    // Do the real work.
    repeat(input, output, operation, size, imod, omod)
}
<|endoftext|>


<commit_before>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::in_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyS;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Checks for no-op uses of Option::{as_deref,as_deref_mut},
    /// for example, `Option<&T>::as_deref()` returns the same type.
    ///
    /// ### Why is this bad?
    /// Redundant code and improving readability.
    ///
    /// ### Example
    /// ```rust
    /// let a = Some(&1);
    /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
    /// ```
    /// Could be written as:
    /// ```rust
    /// let a = Some(&1);
    /// let b = a;
    /// ```
    pub NEEDLESS_OPTION_AS_DEREF,
    complexity,
    "no-op use of `deref` or `deref_mut` method to `Option`."
}

declare_lint_pass!(OptionNeedlessDeref=> [
    NEEDLESS_OPTION_AS_DEREF,
]);

impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if expr.span.from_expansion() {
            return;
        }
        if in_macro(expr.span) {
            return;
        }
        let typeck = cx.typeck_results();
        let outer_ty = typeck.expr_ty(expr);

        if_chain! {
            if is_type_diagnostic_item(cx,outer_ty,sym::option_type);
            if let ExprKind::MethodCall(path, _, [sub_expr], _) = expr.kind;
            let symbol = path.ident.as_str();
            if symbol=="as_deref" || symbol=="as_deref_mut";
            if TyS::same_type( outer_ty, typeck.expr_ty(sub_expr) );
            then{
                span_lint_and_sugg(
                    cx,
                    NEEDLESS_OPTION_AS_DEREF,
                    expr.span,
                    "derefed type is same as origin",
                    "try this",
                    snippet_opt(cx,sub_expr.span).unwrap(),
                    Applicability::MachineApplicable
                );
            }
        }
    }
}
<commit_msg>Update clippy_lints/src/needless_option_as_deref.rs<commit_after>use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::in_macro;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyS;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::sym;

declare_clippy_lint! {
    /// ### What it does
    /// Checks for no-op uses of Option::{as_deref,as_deref_mut},
    /// for example, `Option<&T>::as_deref()` returns the same type.
    ///
    /// ### Why is this bad?
    /// Redundant code and improving readability.
    ///
    /// ### Example
    /// ```rust
    /// let a = Some(&1);
    /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
    /// ```
    /// Could be written as:
    /// ```rust
    /// let a = Some(&1);
    /// let b = a;
    /// ```
    pub NEEDLESS_OPTION_AS_DEREF,
    complexity,
    "no-op use of `deref` or `deref_mut` method to `Option`."
}

declare_lint_pass!(OptionNeedlessDeref=> [
    NEEDLESS_OPTION_AS_DEREF,
]);

impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
        if expr.span.from_expansion() || in_macro(expr.span) {
            return;
        }
        let typeck = cx.typeck_results();
        let outer_ty = typeck.expr_ty(expr);

        if_chain! {
            if is_type_diagnostic_item(cx,outer_ty,sym::option_type);
            if let ExprKind::MethodCall(path, _, [sub_expr], _) = expr.kind;
            let symbol = path.ident.as_str();
            if symbol=="as_deref" || symbol=="as_deref_mut";
            if TyS::same_type( outer_ty, typeck.expr_ty(sub_expr) );
            then{
                span_lint_and_sugg(
                    cx,
                    NEEDLESS_OPTION_AS_DEREF,
                    expr.span,
                    "derefed type is same as origin",
                    "try this",
                    snippet_opt(cx,sub_expr.span).unwrap(),
                    Applicability::MachineApplicable
                );
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate "cargo-registry" as cargo_registry;
extern crate civet;
extern crate green;
extern crate rustuv;
extern crate git2;

use std::os;
use std::sync::Arc;
use std::io::{mod, fs, File};
use civet::Server;

fn main() {
    let url = env("GIT_REPO_URL");
    let checkout = Path::new(env("GIT_REPO_CHECKOUT"));

    let repo = match git2::Repository::open(&checkout) {
        Ok(r) => r,
        Err(..) => {
            let _ = fs::rmdir_recursive(&checkout);
            fs::mkdir_recursive(&checkout, io::UserDir).unwrap();
            let config = git2::Config::open_default().unwrap();
            let url = url.as_slice();
            cargo_registry::git::with_authentication(url, &config, |f| {
                let cb = git2::RemoteCallbacks::new().credentials(f);
                git2::build::RepoBuilder::new()
                                         .remote_callbacks(cb)
                                         .clone(url, &checkout)
            }).unwrap()
        }
    };
    let mut cfg = repo.config().unwrap();
    cfg.set_str("user.name", "bors").unwrap();
    cfg.set_str("user.email", "bors@rust-lang.org").unwrap();

    let heroku = os::getenv("HEROKU").is_some();
    let cargo_env = if heroku {
        cargo_registry::Production
    } else {
        cargo_registry::Development
    };
    let config = cargo_registry::Config {
        s3_bucket: env("S3_BUCKET"),
        s3_access_key: env("S3_ACCESS_KEY"),
        s3_secret_key: env("S3_SECRET_KEY"),
        s3_proxy: None,
        session_key: env("SESSION_KEY"),
        git_repo_checkout: checkout,
        gh_client_id: env("GH_CLIENT_ID"),
        gh_client_secret: env("GH_CLIENT_SECRET"),
        db_url: env("DATABASE_URL"),
        env: cargo_env,
        max_upload_size: 2 * 1024 * 1024,
    };
    let app = cargo_registry::App::new(&config);
    let app = cargo_registry::middleware(Arc::new(app));

    let port = if heroku {
        8888
    } else {
        os::getenv("PORT").and_then(|s| from_str(s.as_slice()))
                          .unwrap_or(8888)
    };
    let _a = Server::start(civet::Config { port: port, threads: 8 }, app);
    println!("listening on port {}", port);
    if heroku {
        File::create(&Path::new("/tmp/app-initialized")).unwrap();
    }
    wait_for_sigint();
}

fn env(s: &str) -> String {
    match os::getenv(s) {
        Some(s) => s,
        None => fail!("must have `{}` defined", s),
    }
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use green::{SchedPool, PoolConfig, GreenTaskBuilder};
    use std::io::signal::{Listener, Interrupt};
    use std::task::TaskBuilder;

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;

    let mut pool = SchedPool::new(config);
    TaskBuilder::new().green(&mut pool).spawn(proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}
<commit_msg>Bump limit to 10MB for now<commit_after>extern crate "cargo-registry" as cargo_registry;
extern crate civet;
extern crate green;
extern crate rustuv;
extern crate git2;

use std::os;
use std::sync::Arc;
use std::io::{mod, fs, File};
use civet::Server;

fn main() {
    let url = env("GIT_REPO_URL");
    let checkout = Path::new(env("GIT_REPO_CHECKOUT"));

    let repo = match git2::Repository::open(&checkout) {
        Ok(r) => r,
        Err(..) => {
            let _ = fs::rmdir_recursive(&checkout);
            fs::mkdir_recursive(&checkout, io::UserDir).unwrap();
            let config = git2::Config::open_default().unwrap();
            let url = url.as_slice();
            cargo_registry::git::with_authentication(url, &config, |f| {
                let cb = git2::RemoteCallbacks::new().credentials(f);
                git2::build::RepoBuilder::new()
                                         .remote_callbacks(cb)
                                         .clone(url, &checkout)
            }).unwrap()
        }
    };
    let mut cfg = repo.config().unwrap();
    cfg.set_str("user.name", "bors").unwrap();
    cfg.set_str("user.email", "bors@rust-lang.org").unwrap();

    let heroku = os::getenv("HEROKU").is_some();
    let cargo_env = if heroku {
        cargo_registry::Production
    } else {
        cargo_registry::Development
    };
    let config = cargo_registry::Config {
        s3_bucket: env("S3_BUCKET"),
        s3_access_key: env("S3_ACCESS_KEY"),
        s3_secret_key: env("S3_SECRET_KEY"),
        s3_proxy: None,
        session_key: env("SESSION_KEY"),
        git_repo_checkout: checkout,
        gh_client_id: env("GH_CLIENT_ID"),
        gh_client_secret: env("GH_CLIENT_SECRET"),
        db_url: env("DATABASE_URL"),
        env: cargo_env,
        max_upload_size: 10 * 1024 * 1024,
    };
    let app = cargo_registry::App::new(&config);
    let app = cargo_registry::middleware(Arc::new(app));

    let port = if heroku {
        8888
    } else {
        os::getenv("PORT").and_then(|s| from_str(s.as_slice()))
                          .unwrap_or(8888)
    };
    let _a = Server::start(civet::Config { port: port, threads: 8 }, app);
    println!("listening on port {}", port);
    if heroku {
        File::create(&Path::new("/tmp/app-initialized")).unwrap();
    }
    wait_for_sigint();
}

fn env(s: &str) -> String {
    match os::getenv(s) {
        Some(s) => s,
        None => fail!("must have `{}` defined", s),
    }
}

// libnative doesn't have signal handling yet
fn wait_for_sigint() {
    use green::{SchedPool, PoolConfig, GreenTaskBuilder};
    use std::io::signal::{Listener, Interrupt};
    use std::task::TaskBuilder;

    let mut config = PoolConfig::new();
    config.event_loop_factory = rustuv::event_loop;

    let mut pool = SchedPool::new(config);
    TaskBuilder::new().green(&mut pool).spawn(proc() {
        let mut l = Listener::new();
        l.register(Interrupt).unwrap();
        l.rx.recv();
    });
    pool.shutdown();
}
<|endoftext|>


<commit_before>extern crate zwreec;
extern crate getopts;
extern crate libc;
#[macro_use] extern crate log;
extern crate time;
extern crate term;

use std::env;
use std::vec::Vec;
use std::error::Error;
use std::fs::File;
use std::io::{Read,Write};
use std::path::Path;
use std::process::exit;

use zwreec::config;

mod logger;

// found in:
// http://stackoverflow.com/a/27590832
macro_rules! print_stderr(
    ($($arg:tt)*) => (
        match write!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

/// Returns the primary options for zwreec. It is e.g. used to generate the
/// usage information.
fn short_options() -> getopts::Options {
    let mut opts = getopts::Options::new();
    opts.optflagmulti("v", "verbose", "be more verbose. Can be used multiple times.");
    opts.optflag("q", "quiet", "be quiet");
    opts.optflagopt("l", "logfile", "specify log file (default zwreec.log)", "LOGFILE");
    opts.optopt("o", "", "name of the output file", "FILE");
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "display version");

    opts
}

/// Prints usage information
/// The verbose flag signals if all options should be shown.
/// NOTE: This is similar to librustc_driver's usage function.
fn usage(verbose: bool) {
    let options = if verbose {
        config::zwreec_options(short_options())
    } else {
        short_options()
    };

    let brief = format!("Usage: zwreec [-hV] [-vq] [-l [LOGFILE]] [-o OUTPUT] INPUT");

    println!("{}\n
Additional help:
    --help -v           Print the full set of options zwreec accepts",
        options.usage(&brief));
}

/// Parse command line arguments
///
/// Parses command line arguments to set up the logger and extract input and
/// output parameters. Will display the usage and exit depending on arguments.
///
/// Returns `getopts::Matches` and a `std::fs::File` for the input and output
/// file. The `getopts::Matches` can be used to
///
/// # Examples
///
/// ```
/// let mut opts = getopts::Options::new();
/// opts.optflag("h", "help", "display this help and exit");
///
/// let (matches, mut input, mut output) = parse_arguments(
///     env::args().collect(),
///     opts
/// );
/// ```
///
/// # Failures
///
/// Depending on encountered arguments or parsing errors this function will
/// print the usage and/or call `exit(1)`.
///
/// NOTE: This is similar to librustc_driver's handle_options function.
fn parse_arguments(args: Vec<String>, opts: getopts::Options) -> (getopts::Matches, config::Config) {
    let mut loggers: Vec<Box<logger::SharedLogger>> = vec![];

    if args.is_empty() {
        // No options provided, print usage and exit
        usage(false);
        exit(1);
    }

    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(f) => {
            // parsing error
            // display usage and return
            print_stderr!("{}\n", f.to_string());
            exit(1);
        }
    };

    if matches.opt_present("help") {
        usage(matches.opt_present("verbose"));
        exit(1);
    }

    if matches.opt_present("version") {
        println!("zwreec {}", match option_env!("CFG_VERSION") {
            Some(s) => s.to_string(),
            None => format!("{}.{}.{}{}",
                            env!("CARGO_PKG_VERSION_MAJOR"),
                            env!("CARGO_PKG_VERSION_MINOR"),
                            env!("CARGO_PKG_VERSION_PATCH"),
                            option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
        });
        exit(0);
    }

    if matches.opt_present("verbose") {
        // set log level to verbose
        loggers.push(logger::TermLogger::new(
                match matches.opt_count("v") {
                    1 => logger::LogLevelFilter::Info,
                    2 => logger::LogLevelFilter::Debug,
                    _ => logger::LogLevelFilter::Trace,
                }));
    } else if matches.opt_present("quiet") {
        // set log level to error
        loggers.push(logger::TermLogger::new(logger::LogLevelFilter::Error));
    } else {
        // set log level to warn
        loggers.push(logger::TermLogger::new(logger::LogLevelFilter::Warn));
    }

    if matches.opt_present("logfile") {
        // sets a logger to output to logfile
        let name = if let Some(n) = matches.opt_str("logfile") {
            n
        } else {
            "zwreec.log".to_string()
        };
        loggers.push(logger::FileLogger::new(
                        logger::LogLevelFilter::Trace,
                        File::create(name).unwrap())
            );
    }

    // TODO: This might not belong in a function called parse_arguments
    // activate logger
    let _ = logger::CombinedLogger::init(loggers);

    let cfg = config::parse_matches(&matches);
    (matches, cfg)
}

fn parse_input(matches: &getopts::Matches) -> Option<Box<Read>> {
    if matches.free.len() == 1 {
        let path = Path::new(&matches.free[0]);
        match File::open(path) {
            Err(why) => {
                error!("Couldn't open {}: {}",
                    path.display(), Error::description(&why));
                None
            },
            Ok(file) => {
                info!("Opened input: {}", path.display());
                Some(Box::new(file))
            }
        }
    } else if unsafe { libc::isatty(libc::STDIN_FILENO as i32) } == 0 {
        // Not connected to a terminal, assuming safe to read from stdin
        info!("Reading input from stdin");
        Some(Box::new(std::io::stdin()))
    } else {
        None
    }
}

fn parse_output(matches: &getopts::Matches) -> Option<Box<Write>> {
    let name = matches.opt_str("o").unwrap_or("-".to_string());

    if name == "-" {
        // no name specified
        if unsafe { libc::isatty(libc::STDOUT_FILENO as i32)  } == 0 {
            // Not connected to a terminal, assuming safe to write to stdin
            // NOTE: this should be considered unsafe, as the library is *not*
            // guaranteed to only print to stderr
            warn!("Writing to stdout can lead to unusable output! You should specify an output name using -o 'FILE'");
            info!("Writing output to stdout");
            Some(Box::new(std::io::stdout()))
        } else {
            // assume default name
            let path = Path::new("a.z8");
            match File::create(path) {
                Err(why) => {
                    error!("Couldn't open {}: {}",
                           path.display(), Error::description(&why));
                    None
                },
                Ok(file) => {
                    debug!("No output file specified, assuming default");
                    info!("Opened output: {}", path.display());
                    Some(Box::new(file))
                }
            }
        }
    } else {
        // try to open FILE
        let path = Path::new(&name);
        match File::create(path) {
            Err(why) => {
                error!("Couldn't open {}: {}",
                       path.display(), Error::description(&why));
                None
            },
            Ok(file) => {
                info!("Opened output: {}", path.display());
                Some(Box::new(file))
            }
        }
    }
}

fn main() {
    // handle command line parameters
    let (matches, cfg) = parse_arguments(
        env::args().collect(),
        config::zwreec_options(short_options())
    );

    let mut input = parse_input(&matches);
    let mut output = parse_output(&matches);

    debug!("Parsed command line options");
    info!("Main started");

    // call library
    if !cfg.test_cases.is_empty() {
        zwreec::test_library(cfg, &mut input, &mut output);
    } else {
        // unwrap input and output
        let mut _input = match input {
            Some(i) => i,
            None => panic!("Missing input file! Compile aborted")
        };
        let mut _output = match output {
            Some(o) => o,
            None => panic!("Missing output file! Compile aborted")
        };
        zwreec::compile(cfg, &mut _input, &mut _output);
    }

    info!("Main finished");
}
<commit_msg>Prevent overwriting files without -f<commit_after>extern crate zwreec;
extern crate getopts;
extern crate libc;
#[macro_use] extern crate log;
extern crate time;
extern crate term;

use std::env;
use std::vec::Vec;
use std::error::Error;
use std::fs::File;
use std::io::{Read,Write};
use std::path::Path;
use std::process::exit;

use zwreec::config;

mod logger;

// found in:
// http://stackoverflow.com/a/27590832
macro_rules! print_stderr(
    ($($arg:tt)*) => (
        match write!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

/// Returns the primary options for zwreec. It is e.g. used to generate the
/// usage information.
fn short_options() -> getopts::Options {
    let mut opts = getopts::Options::new();
    opts.optflagmulti("v", "verbose", "be more verbose. Can be used multiple times.");
    opts.optflag("q", "quiet", "be quiet");
    opts.optflagopt("l", "logfile", "specify log file (default zwreec.log)", "LOGFILE");
    opts.optopt("o", "", "name of the output file", "FILE");
    opts.optflag("f", "force", "force opening of output file");
    opts.optflag("h", "help", "display this help and exit");
    opts.optflag("V", "version", "display version");

    opts
}

/// Prints usage information
/// The verbose flag signals if all options should be shown.
/// NOTE: This is similar to librustc_driver's usage function.
fn usage(verbose: bool) {
    let options = if verbose {
        config::zwreec_options(short_options())
    } else {
        short_options()
    };

    let brief = format!("Usage: zwreec [-hV] [-vq] [-l [LOGFILE]] [-o OUTPUT] INPUT");

    println!("{}\n
Additional help:
    --help -v           Print the full set of options zwreec accepts",
        options.usage(&brief));
}

/// Parse command line arguments
///
/// Parses command line arguments to set up the logger and extract input and
/// output parameters. Will display the usage and exit depending on arguments.
///
/// Returns `getopts::Matches` and a `std::fs::File` for the input and output
/// file. The `getopts::Matches` can be used to
///
/// # Examples
///
/// ```
/// let mut opts = getopts::Options::new();
/// opts.optflag("h", "help", "display this help and exit");
///
/// let (matches, mut input, mut output) = parse_arguments(
///     env::args().collect(),
///     opts
/// );
/// ```
///
/// # Failures
///
/// Depending on encountered arguments or parsing errors this function will
/// print the usage and/or call `exit(1)`.
///
/// NOTE: This is similar to librustc_driver's handle_options function.
fn parse_arguments(args: Vec<String>, opts: getopts::Options) -> (getopts::Matches, config::Config) {
    let mut loggers: Vec<Box<logger::SharedLogger>> = vec![];

    if args.is_empty() {
        // No options provided, print usage and exit
        usage(false);
        exit(1);
    }

    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(f) => {
            // parsing error
            // display usage and return
            print_stderr!("{}\n", f.to_string());
            exit(1);
        }
    };

    if matches.opt_present("help") {
        usage(matches.opt_present("verbose"));
        exit(1);
    }

    if matches.opt_present("version") {
        println!("zwreec {}", match option_env!("CFG_VERSION") {
            Some(s) => s.to_string(),
            None => format!("{}.{}.{}{}",
                            env!("CARGO_PKG_VERSION_MAJOR"),
                            env!("CARGO_PKG_VERSION_MINOR"),
                            env!("CARGO_PKG_VERSION_PATCH"),
                            option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""))
        });
        exit(0);
    }

    if matches.opt_present("verbose") {
        // set log level to verbose
        loggers.push(logger::TermLogger::new(
                match matches.opt_count("v") {
                    1 => logger::LogLevelFilter::Info,
                    2 => logger::LogLevelFilter::Debug,
                    _ => logger::LogLevelFilter::Trace,
                }));
    } else if matches.opt_present("quiet") {
        // set log level to error
        loggers.push(logger::TermLogger::new(logger::LogLevelFilter::Error));
    } else {
        // set log level to warn
        loggers.push(logger::TermLogger::new(logger::LogLevelFilter::Warn));
    }

    if matches.opt_present("logfile") {
        // sets a logger to output to logfile
        let name = if let Some(n) = matches.opt_str("logfile") {
            n
        } else {
            "zwreec.log".to_string()
        };
        loggers.push(logger::FileLogger::new(
                        logger::LogLevelFilter::Trace,
                        File::create(name).unwrap())
            );
    }

    // TODO: This might not belong in a function called parse_arguments
    // activate logger
    let _ = logger::CombinedLogger::init(loggers);

    let cfg = config::parse_matches(&matches);
    (matches, cfg)
}

fn parse_input(matches: &getopts::Matches) -> Option<Box<Read>> {
    if matches.free.len() == 1 {
        let path = Path::new(&matches.free[0]);
        match File::open(path) {
            Err(why) => {
                error!("Couldn't open {}: {}",
                    path.display(), Error::description(&why));
                None
            },
            Ok(file) => {
                info!("Opened input: {}", path.display());
                Some(Box::new(file))
            }
        }
    } else if unsafe { libc::isatty(libc::STDIN_FILENO as i32) } == 0 {
        // Not connected to a terminal, assuming safe to read from stdin
        info!("Reading input from stdin");
        Some(Box::new(std::io::stdin()))
    } else {
        None
    }
}

fn parse_output(matches: &getopts::Matches) -> Option<Box<Write>> {
    let name = matches.opt_str("o").unwrap_or("a.z8".to_string());

    if name == "-" {
        // tty requested
        if unsafe { libc::isatty(libc::STDOUT_FILENO as i32)  } == 0 {
            // Not connected to a terminal, assuming safe to write to stdin
            // NOTE: this should be considered unsafe, as the library is *not*
            // guaranteed to only print to stderr
            warn!("Writing to stdout can lead to unusable output!");
            warn!("You should specify an output name using -o 'FILE'");
            info!("Writing output to stdout");
            Some(Box::new(std::io::stdout()))
        } else {
            error!("stdout is connected to a terminal.");
            error!("Zcode is a binary format and should not be printed to a tty.");
            None
        }
    } else {
        // opening file
        let path = Path::new(&name);

        if name == "a.z8" {
            debug!("No output file specified, using {}", path.display());
        }

        // Check if FILE exists and issue warning.
        if File::open(path).is_ok() {
            if !matches.opt_present("f") {
                error!("Output file {} already exists. Use '-f' to overwrite!",
                       path.display());
                return None;
            } else {
                warn!("Output file {} already exists", path.display());
            }
        }

        match File::create(path) {
            Err(why) => {
                error!("Couldn't open {}: {}",
                       path.display(), Error::description(&why));
                None
            },
            Ok(file) => {
                info!("Opened output: {}", path.display());
                Some(Box::new(file))
            }
        }
    }
}

fn main() {
    // handle command line parameters
    let (matches, cfg) = parse_arguments(
        env::args().collect(),
        config::zwreec_options(short_options())
    );

    let mut input = parse_input(&matches);
    let mut output = parse_output(&matches);

    debug!("Parsed command line options");
    info!("Main started");

    // call library
    if !cfg.test_cases.is_empty() {
        zwreec::test_library(cfg, &mut input, &mut output);
    } else {
        // unwrap input and output
        let mut _input = match input {
            Some(i) => i,
            None => panic!("Missing input file! Compile aborted")
        };
        let mut _output = match output {
            Some(o) => o,
            None => panic!("Missing output file! Compile aborted")
        };
        zwreec::compile(cfg, &mut _input, &mut _output);
    }

    info!("Main finished");
}
<|endoftext|>


<commit_before>//! A splittable pseudorandom generator based on the [Chaskey
//! MAC](http://mouha.be/chaskey/).  **This is not intended to be a
//! cryptographically secure PRNG.**
//!
//! Like `SipRng`, this is broadly modeled after Claessen and Pałka's
//! splittable PRNGs, but with a different choice of cryptographic
//! primitive.
//!
//! ## References
//!
//! * Mouha, Nicky, Bart Mennik, Anthony Van Herrewege, Dai Watanabe,
//!   Bart Preneet and Ingrid Verbauwhede.  2014.  ["Chaskey: An
//!   Efficient MAC Algorithm for 32-bit
//!   Microcontrollers."](https://eprint.iacr.org/2014/386.pdf)
//!   Cryptology ePrint Archive, Report 2014/386.

//! * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
//!   Pseudorandom Number Generators using Cryptographic
//!   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
//!   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium on
//!   Haskell*, pp. 47-58.

use rand::{Rand, Rng, SeedableRng};
use super::{SplitRng, SplitPrf};
use std::u32;

/// A splittable pseudorandom generator based on Chaskey.
pub struct ChaskeyRng {
    // The state of the splittable RNG, properly speaking.
      v: [u32; 4],
     k1: [u32; 4],
    ctr: u64,

    // We buffer the 128-bit raw outputs of the RNG to speed it up a bit.
    buf: [u32; 4],
    i: usize
}

/// A PRF taken off a `ChaskeyRng`.
pub struct ChaskeyPrf(ChaskeyRng);

macro_rules! round {
    ($v0: expr, $v1: expr, $v2: expr, $v3: expr) => {
        $v0 = $v0.wrapping_add($v1); $v2 = $v2.wrapping_add($v3);
        $v1 = $v1.rotate_left(5);    $v3 = $v3.rotate_left(8);
        $v1 ^= $v0;                  $v3 ^= $v2;
        $v0 = $v0.rotate_left(16);

        $v2 = $v2.wrapping_add($v1); $v0 = $v0.wrapping_add($v3);
        $v1 = $v1.rotate_left(7);    $v3 = $v3.rotate_left(13);
        $v1 ^= $v2;                  $v3 ^= $v0;
        $v2 = $v2.rotate_left(16);
    }
}

macro_rules! permute {
    ($v0: expr, $v1: expr, $v2: expr, $v3: expr) => {
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
        round!($v0, $v1, $v2, $v3);
    }
}

macro_rules! times_two {
    ($k: expr) => {
        [$k[0].wrapping_shl(1)
         ^ if $k[3] < 0x8000_0000 { 0 } else { 0x87 },
         $k[1].wrapping_shl(1) ^ 0,
         $k[2].wrapping_shl(1) ^ 0,
         $k[3].wrapping_shl(1) ^ 0]
    }
}

#[inline]
fn lsb32(n: u64) -> u32 {
    const MASK: u64 = 0xffff_ffff;
    (n & MASK) as u32
}

#[inline]
fn msb32(n: u64) -> u32 {
    lsb32(n.wrapping_shr(32))
}

impl ChaskeyRng {
    pub fn new(seed: [u32; 4]) -> ChaskeyRng {
        let mut result = ChaskeyRng {
              v: [0u32; 4],
             k1: [0u32; 4],
            ctr: 0,
            buf: [0u32; 4],
              i: 0
        };
        result.reseed(seed);
        result
    }

    fn reseed(&mut self, seed: [u32; 4]) {
        self.v = seed;
        self.k1 = times_two!(seed);
        self.ctr = 0;
        self.advance();
    }

    fn clone(&self) -> ChaskeyRng {
        ChaskeyRng {
              v: self.v,
             k1: self.k1,
            ctr: self.ctr,
            buf: self.buf,
              i: self.i
        }
    }

    #[inline]
    fn advance(&mut self) {
        self.buf[0] = self.v[0] ^ self.k1[0];
        self.buf[1] = self.v[0] ^ self.k1[1];
        self.buf[2] = self.v[0] ^ self.k1[2] ^ lsb32(self.ctr);
        self.buf[3] = self.v[0] ^ self.k1[3] ^ msb32(self.ctr);
        permute!(self.buf[0], self.buf[1], self.buf[2], self.buf[3]);
        self.buf[0] ^= self.k1[0];
        self.buf[1] ^= self.k1[1];
        self.buf[2] ^= self.k1[2];
        self.buf[3] ^= self.k1[3];
        self.ctr = self.ctr.wrapping_add(1);
        self.i = 0;
    }

    #[inline]
    fn descend(&mut self, i: u32) {
        self.v[0] ^= u32::MAX;
        self.v[1] ^= i;
        self.v[2] ^= lsb32(self.ctr);
        self.v[3] ^= msb32(self.ctr);
        permute!(self.v[0], self.v[1], self.v[2], self.v[3]);
        self.ctr = 0;
        self.advance();
    }

}

impl SplitPrf<ChaskeyRng> for ChaskeyPrf {
    fn call(&self, i: u32) -> ChaskeyRng {
        let mut r = self.0.clone();
        r.descend(i);
        r
    }
}

impl SplitRng for ChaskeyRng {
    type Prf = ChaskeyPrf;

    fn split(&mut self) -> Self {
        let mut child = self.clone();
        self.descend(0);
        child.descend(1);
        child
    }

    fn splitn(&mut self) -> ChaskeyPrf {
        ChaskeyPrf(self.split())
    }

}

impl Rng for ChaskeyRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        if self.i >= 4 {
            self.advance();
        }
        let result = self.buf[self.i];
        self.i += 1;
        result
    }
}

impl SeedableRng<[u32; 4]> for ChaskeyRng {

    fn reseed(&mut self, seed: [u32; 4]) {
        ChaskeyRng::reseed(self, seed);
    }

    fn from_seed(seed: [u32; 4]) -> ChaskeyRng {
        ChaskeyRng::new(seed)
    }
}

impl Rand for ChaskeyRng {
    fn rand<R: Rng>(other: &mut R) -> ChaskeyRng {
        ChaskeyRng::new(other.gen::<[u32; 4]>())
    }
}

#[cfg(test)]
mod tests {
    use rand::Rng;
    use rand::os::OsRng;
    use chaskeyrng::ChaskeyRng;

    fn gen_chaskeyrng() -> ChaskeyRng {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    #[test]
    fn test_split_rand_independence() {
        ::tests::test_split_rand_independence(&mut gen_chaskeyrng());
    }

    #[test]
    fn test_split_rand_closure() {
        ::tests::test_split_rand_closure(&mut gen_chaskeyrng());
    }

    #[test]
    fn test_split_rand_split() {
        ::tests::test_split_rand_split(&mut gen_chaskeyrng());
    }

    fn gen_seed() -> [u32; 4] {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    #[test]
    fn test_rng_rand_seeded() {
        let seed = gen_seed();
        ::tests::test_rng_rand_seeded::<ChaskeyRng, [u32; 4]>(seed);
    }

    #[test]
    fn test_rng_seeded() {
        let seed = gen_seed();
        ::tests::test_rng_seeded::<ChaskeyRng, [u32; 4]>(seed);
    }

    #[test]
    fn test_rng_reseed() {
        let seed = gen_seed();
        ::tests::test_rng_reseed::<ChaskeyRng, [u32; 4]>(seed);
    }
}
<commit_msg>Improvements to `ChaskeyRng`.<commit_after>//! A splittable pseudorandom generator based on the [Chaskey
//! MAC](http://mouha.be/chaskey/).  **This is not intended to be a
//! cryptographically secure PRNG.**
//!
//! Like `SipRng`, this is broadly modeled after Claessen and Pałka's
//! splittable PRNGs, but with a different choice of cryptographic
//! primitive.
//!
//! ## References
//!
//! * Mouha, Nicky, Bart Mennik, Anthony Van Herrewege, Dai Watanabe,
//!   Bart Preneet and Ingrid Verbauwhede.  2014.  ["Chaskey: An
//!   Efficient MAC Algorithm for 32-bit
//!   Microcontrollers."](https://eprint.iacr.org/2014/386.pdf)
//!   Cryptology ePrint Archive, Report 2014/386.

//! * Claessen, Koen and Michał H. Pałka.  2013.  ["Splittable
//!   Pseudorandom Number Generators using Cryptographic
//!   Hashing."](http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf)
//!   *Haskell '13: Proceedings of the 2013 ACM SIGPLAN symposium on
//!   Haskell*, pp. 47-58.

use rand::{Rand, Rng, SeedableRng};
use super::{SplitRng, SplitPrf};
use std::u32;

/// A splittable pseudorandom generator based on Chaskey.
pub struct ChaskeyRng {
    // The state of the splittable RNG, properly speaking.
      v: [u32; 4],
     k1: [u32; 4],
    ctr: u64,

    // We buffer the 128-bit raw outputs of the RNG to speed it up a bit.
    buf: [u32; 4],
    i: usize
}

/// A PRF taken off a `ChaskeyRng`.
pub struct ChaskeyPrf(ChaskeyRng);

impl ChaskeyRng {
    pub fn new(seed: [u32; 4]) -> ChaskeyRng {
        let mut result = ChaskeyRng {
              v: seed,
             k1: times_two(seed),
            ctr: 0,
            buf: [0u32; 4],
              i: 0
        };
        result.advance();
        result
    }

    fn reseed(&mut self, seed: [u32; 4]) {
        self.v = seed;
        self.k1 = times_two(seed);
        self.ctr = 0;
        self.buf = [0u32; 4];
        self.i = 0;
        self.advance();
    }

    fn clone(&self) -> ChaskeyRng {
        ChaskeyRng {
              v: self.v,
             k1: self.k1,
            ctr: self.ctr,
            buf: self.buf,
              i: self.i
        }
    }

    #[inline]
    fn advance(&mut self) {
        let block = [0, 0, lsb32(self.ctr), msb32(self.ctr)];
        xor_u32x4(&mut self.buf, &block);
        xor_u32x4(&mut self.buf, &self.k1);
        permute8(&mut self.buf);
        xor_u32x4(&mut self.buf, &self.k1);

        self.ctr = self.ctr.wrapping_add(1);
        self.i = 0;
    }

    #[inline]
    fn descend(&mut self, i: u32) {
        let block = [u32::MAX, i, lsb32(self.ctr), msb32(self.ctr)];
        xor_u32x4(&mut self.buf, &block);
        permute8(&mut self.v);

        self.ctr = 0;
        self.advance();
    }

}

impl SplitPrf<ChaskeyRng> for ChaskeyPrf {
    fn call(&self, i: u32) -> ChaskeyRng {
        let mut r = self.0.clone();
        r.descend(i);
        r
    }
}

impl SplitRng for ChaskeyRng {
    type Prf = ChaskeyPrf;

    fn split(&mut self) -> Self {
        let mut child = self.clone();
        self.descend(0);
        child.descend(1);
        child
    }

    fn splitn(&mut self) -> ChaskeyPrf {
        ChaskeyPrf(self.split())
    }

}

impl Rng for ChaskeyRng {
    #[inline]
    fn next_u32(&mut self) -> u32 {
        if self.i >= 4 {
            self.advance();
        }
        let result = self.buf[self.i];
        self.i += 1;
        result
    }
}

impl SeedableRng<[u32; 4]> for ChaskeyRng {

    fn reseed(&mut self, seed: [u32; 4]) {
        ChaskeyRng::reseed(self, seed);
    }

    fn from_seed(seed: [u32; 4]) -> ChaskeyRng {
        ChaskeyRng::new(seed)
    }
}

impl Rand for ChaskeyRng {
    fn rand<R: Rng>(other: &mut R) -> ChaskeyRng {
        ChaskeyRng::new(other.gen::<[u32; 4]>())
    }
}

/*
 * Chaskey's building blocks.
 */

/// Function used in the Chaskey key schedule.
#[inline(always)]
pub fn times_two(key: [u32; 4]) -> [u32; 4] {
    const C: [u32; 2] = [0x00, 0x87];
    [key[0].wrapping_shl(1) ^ C[key[3].wrapping_shr(31) as usize],
     key[1].wrapping_shl(1) ^ key[0].wrapping_shr(31),
     key[2].wrapping_shl(1) ^ key[1].wrapping_shr(31),
     key[3].wrapping_shl(1) ^ key[2].wrapping_shr(31)]
}

/// XOR a `[u32; 4]` value into the Chaskey state.
#[inline(always)]
pub fn xor_u32x4(state: &mut [u32; 4], block: &[u32; 4]) {
    state[0] ^= block[0];
    state[1] ^= block[1];
    state[2] ^= block[2];
    state[3] ^= block[3];
}

// The original Chaskey permutation (8 rounds).
#[inline(always)]
pub fn permute8(state: &mut [u32; 4]) {
    permute4(state); permute4(state);
}

#[inline(always)]
fn permute4(state: &mut [u32; 4]) {
    round(state); round(state);
    round(state); round(state);
}

/// The Chaskey round function.
#[inline(always)]
pub fn round(v: &mut [u32; 4]) {
    v[0]  = v[0].wrapping_add(v[1]); v[2]  = v[2].wrapping_add(v[3]);
    v[1]  = v[1].rotate_left(5);     v[3]  = v[3].rotate_left(8);
    v[1] ^= v[0];                    v[3] ^= v[2];
    v[0]  = v[0].rotate_left(16);

    v[2]  = v[2].wrapping_add(v[1]); v[0]  = v[0].wrapping_add(v[3]);
    v[1]  = v[1].rotate_left(7);     v[3]  = v[3].rotate_left(13);
    v[1] ^= v[2];                    v[3] ^= v[0];
    v[2]  = v[2].rotate_left(16);
}

/*
 * Utility functions.
 */

/// Take the least 32 significant bits of an `u64`.
#[inline(always)]
fn lsb32(n: u64) -> u32 {
    const MASK: u64 = 0xffff_ffff;
    (n & MASK) as u32
}

/// Take the most 32 significant bits of an `u64`.
#[inline(always)]
fn msb32(n: u64) -> u32 {
    lsb32(n.wrapping_shr(32))
}

#[cfg(test)]
mod tests {
    use rand::Rng;
    use rand::os::OsRng;
    use chaskeyrng::ChaskeyRng;

    fn gen_chaskeyrng() -> ChaskeyRng {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    #[test]
    fn test_split_rand_independence() {
        ::tests::test_split_rand_independence(&mut gen_chaskeyrng());
    }

    #[test]
    fn test_split_rand_closure() {
        ::tests::test_split_rand_closure(&mut gen_chaskeyrng());
    }

    #[test]
    fn test_split_rand_split() {
        ::tests::test_split_rand_split(&mut gen_chaskeyrng());
    }

    fn gen_seed() -> [u32; 4] {
        let mut osrng = OsRng::new().ok().expect("Could not create OsRng");
        osrng.gen()
    }

    #[test]
    fn test_rng_rand_seeded() {
        let seed = gen_seed();
        ::tests::test_rng_rand_seeded::<ChaskeyRng, [u32; 4]>(seed);
    }

    #[test]
    fn test_rng_seeded() {
        let seed = gen_seed();
        ::tests::test_rng_seeded::<ChaskeyRng, [u32; 4]>(seed);
    }

    #[test]
    fn test_rng_reseed() {
        let seed = gen_seed();
        ::tests::test_rng_reseed::<ChaskeyRng, [u32; 4]>(seed);
    }
}
<|endoftext|>


<commit_before>pub mod messages;

use address::Address;
use mio;
use network;
use self::messages::{CommMessage, TextMessage, MessageAcknowledgement};
use std::collections::{HashMap, HashSet};
use std::io;
use std::sync::mpsc;
use std::thread;

#[derive(Debug)]
pub enum Task {
    HandleNetworkEvent(network::Event),
    ScheduleMessageDelivery(Address, CommMessage)
}

#[derive(Debug)]
pub enum ScheduledTask {
    DeliverMessage(Address, CommMessage),
}

pub struct Client {
    address: Address,
    network_commands: Option<network::TaskSender>,
    received: HashSet<Address>,
    pending_deliveries: HashMap<Address, mio::Timeout>,
    delivered: HashMap<Address, usize>,
    acknowledgements: HashMap<Address, CommMessage>
}

impl Client {
    pub fn new(address: Address) -> Client {
        Client {
            address: address,
            network_commands: None,
            received: HashSet::new(),
            pending_deliveries: HashMap::new(),
            delivered: HashMap::new(),
            acknowledgements: HashMap::new()
        }
    }

    pub fn run(mut self, mut network: network::Network, headless: bool) {
        let mut event_loop = mio::EventLoop::new().unwrap();
        let (event_sender, event_receiver) = mpsc::channel();
        network.register_event_listener(event_sender);
        let notify_channel = event_loop.channel();
        let sender = self.address;

        thread::spawn(move|| {
            for event in event_receiver.iter() {
                notify_channel
                    .send(Task::HandleNetworkEvent(event))
                    .unwrap_or_else(|err| info!("Couldn't handle network event: {:?}", err));
            }
        });

        self.network_commands = Some(network.run());

        let notify_channel = event_loop.channel();
        thread::spawn(move || event_loop.run(&mut self).unwrap());

        info!("Running client at {}", sender);

        if headless {
            loop { thread::park(); }
        } else {
            loop {
                let mut line = String::new();
                io::stdin().read_line(&mut line).unwrap();
                let parts: Vec<&str> = line.splitn(2, ' ').collect();
                let recipient = Address::from_str(parts[0]);
                let message_text = parts[1].trim().to_string();

                let message = messages::create_text_message(recipient, sender, message_text);
                notify_channel
                    .send(Task::ScheduleMessageDelivery(recipient, message))
                    .unwrap_or_else(|err| info!("Couldn't schedule message delivery: {:?}", err));
            }
        }
    }

    fn handle_networking_event(&mut self, event: network::Event, event_loop: &mut mio::EventLoop<Client>) {
        match event {
            network::Event::ReceivedPacket(data) => {
                let comm_message = messages::decode(data);
                let CommMessage { recipient, .. } = comm_message.clone();

                if let Some(ref text_message) = comm_message.text_message {
                    if !self.received.contains(&text_message.id) {
                        self.received.insert(text_message.id);
                        if recipient == self.address {
                            println!("{}: {}", text_message.sender, text_message.text);
                            let ack = messages::create_message_acknowledgement(text_message.sender, text_message.id);
                            self.schedule_message_delivery(text_message.sender, ack, event_loop);
                        } else {
                            if let Some(ack) = self.acknowledgements.remove(&text_message.id) {
                                self.schedule_message_delivery(recipient, ack.clone(), event_loop);
                                self.acknowledgements.insert(text_message.id, ack);
                            } else {
                                self.schedule_message_delivery(recipient, comm_message.clone(), event_loop);
                            }
                        }
                    }
                }

                if let Some(ref ack) = comm_message.message_acknowledgement {
                    if let None = self.acknowledgements.insert(ack.id, comm_message.clone()) {
                        self.pending_deliveries.remove(&ack.id).map(|p| event_loop.clear_timeout(p));
                        if recipient == self.address {
                            debug!("ack {}", ack.id);
                        } else {
                            self.schedule_message_delivery(recipient, comm_message.clone(), event_loop);
                        }
                    }
                }
            }
        }
    }

    fn schedule_message_delivery(&mut self, recipient: Address, message: CommMessage, event_loop: &mut mio::EventLoop<Client>) {
        if let Some(ref text_message) = message.text_message {
            if !self.pending_deliveries.contains_key(&text_message.id) {
                let delivered = self.delivered.entry(text_message.id).or_insert(0);
                let delay = (2u64.pow(*delivered as u32) - 1) * 1000;
                debug!("Delivery with delay {:?}", delay);
                let timeout = event_loop.timeout_ms(ScheduledTask::DeliverMessage(recipient, message.clone()), delay).unwrap();
                self.pending_deliveries.insert(text_message.id, timeout);
                *delivered += 1;
            }
        }

        if let Some(ref ack) = message.message_acknowledgement {
            event_loop.timeout_ms(ScheduledTask::DeliverMessage(recipient, message.clone()), 0).unwrap();
        }
    }

    fn deliver_message(&mut self, recipient: Address, message: CommMessage) {
        if let Some(ref commands) = self.network_commands {
            if let Some(ref text_message) = message.text_message {
                self.pending_deliveries.remove(&text_message.id);
            }
            commands.send(network::OneshotTask::SendPacket(recipient, message.encode())).unwrap();
        }
    }
}

impl mio::Handler for Client {
    type Timeout = ScheduledTask;
    type Message = Task;

    fn notify(&mut self, event_loop: &mut mio::EventLoop<Client>, task: Task) {
        match task {
            Task::HandleNetworkEvent(event) => self.handle_networking_event(event, event_loop),
            Task::ScheduleMessageDelivery(recipient, message) => self.schedule_message_delivery(recipient, message, event_loop)
        }
    }

    fn timeout(&mut self, _event_loop: &mut mio::EventLoop<Client>, task: ScheduledTask) {
        match task {
            ScheduledTask::DeliverMessage(recipient, message) => self.deliver_message(recipient, message)
        }
    }
}
<commit_msg>Remove unused identifiers<commit_after>pub mod messages;

use address::Address;
use mio;
use network;
use self::messages::{CommMessage};
use std::collections::{HashMap, HashSet};
use std::io;
use std::sync::mpsc;
use std::thread;

#[derive(Debug)]
pub enum Task {
    HandleNetworkEvent(network::Event),
    ScheduleMessageDelivery(Address, CommMessage)
}

#[derive(Debug)]
pub enum ScheduledTask {
    DeliverMessage(Address, CommMessage),
}

pub struct Client {
    address: Address,
    network_commands: Option<network::TaskSender>,
    received: HashSet<Address>,
    pending_deliveries: HashMap<Address, mio::Timeout>,
    delivered: HashMap<Address, usize>,
    acknowledgements: HashMap<Address, CommMessage>
}

impl Client {
    pub fn new(address: Address) -> Client {
        Client {
            address: address,
            network_commands: None,
            received: HashSet::new(),
            pending_deliveries: HashMap::new(),
            delivered: HashMap::new(),
            acknowledgements: HashMap::new()
        }
    }

    pub fn run(mut self, mut network: network::Network, headless: bool) {
        let mut event_loop = mio::EventLoop::new().unwrap();
        let (event_sender, event_receiver) = mpsc::channel();
        network.register_event_listener(event_sender);
        let notify_channel = event_loop.channel();
        let sender = self.address;

        thread::spawn(move|| {
            for event in event_receiver.iter() {
                notify_channel
                    .send(Task::HandleNetworkEvent(event))
                    .unwrap_or_else(|err| info!("Couldn't handle network event: {:?}", err));
            }
        });

        self.network_commands = Some(network.run());

        let notify_channel = event_loop.channel();
        thread::spawn(move || event_loop.run(&mut self).unwrap());

        info!("Running client at {}", sender);

        if headless {
            loop { thread::park(); }
        } else {
            loop {
                let mut line = String::new();
                io::stdin().read_line(&mut line).unwrap();
                let parts: Vec<&str> = line.splitn(2, ' ').collect();
                let recipient = Address::from_str(parts[0]);
                let message_text = parts[1].trim().to_string();

                let message = messages::create_text_message(recipient, sender, message_text);
                notify_channel
                    .send(Task::ScheduleMessageDelivery(recipient, message))
                    .unwrap_or_else(|err| info!("Couldn't schedule message delivery: {:?}", err));
            }
        }
    }

    fn handle_networking_event(&mut self, event: network::Event, event_loop: &mut mio::EventLoop<Client>) {
        match event {
            network::Event::ReceivedPacket(data) => {
                let comm_message = messages::decode(data);
                let CommMessage { recipient, .. } = comm_message.clone();

                if let Some(ref text_message) = comm_message.text_message {
                    if !self.received.contains(&text_message.id) {
                        self.received.insert(text_message.id);
                        if recipient == self.address {
                            println!("{}: {}", text_message.sender, text_message.text);
                            let ack = messages::create_message_acknowledgement(text_message.sender, text_message.id);
                            self.schedule_message_delivery(text_message.sender, ack, event_loop);
                        } else {
                            if let Some(ack) = self.acknowledgements.remove(&text_message.id) {
                                self.schedule_message_delivery(recipient, ack.clone(), event_loop);
                                self.acknowledgements.insert(text_message.id, ack);
                            } else {
                                self.schedule_message_delivery(recipient, comm_message.clone(), event_loop);
                            }
                        }
                    }
                }

                if let Some(ref ack) = comm_message.message_acknowledgement {
                    if let None = self.acknowledgements.insert(ack.id, comm_message.clone()) {
                        self.pending_deliveries.remove(&ack.id).map(|p| event_loop.clear_timeout(p));
                        if recipient == self.address {
                            debug!("ack {}", ack.id);
                        } else {
                            self.schedule_message_delivery(recipient, comm_message.clone(), event_loop);
                        }
                    }
                }
            }
        }
    }

    fn schedule_message_delivery(&mut self, recipient: Address, message: CommMessage, event_loop: &mut mio::EventLoop<Client>) {
        if let Some(ref text_message) = message.text_message {
            if !self.pending_deliveries.contains_key(&text_message.id) {
                let delivered = self.delivered.entry(text_message.id).or_insert(0);
                let delay = (2u64.pow(*delivered as u32) - 1) * 1000;
                debug!("Delivery with delay {:?}", delay);
                let timeout = event_loop.timeout_ms(ScheduledTask::DeliverMessage(recipient, message.clone()), delay).unwrap();
                self.pending_deliveries.insert(text_message.id, timeout);
                *delivered += 1;
            }
        }

        if let Some(_) = message.message_acknowledgement {
            event_loop.timeout_ms(ScheduledTask::DeliverMessage(recipient, message.clone()), 0).unwrap();
        }
    }

    fn deliver_message(&mut self, recipient: Address, message: CommMessage) {
        if let Some(ref commands) = self.network_commands {
            if let Some(ref text_message) = message.text_message {
                self.pending_deliveries.remove(&text_message.id);
            }
            commands.send(network::OneshotTask::SendPacket(recipient, message.encode())).unwrap();
        }
    }
}

impl mio::Handler for Client {
    type Timeout = ScheduledTask;
    type Message = Task;

    fn notify(&mut self, event_loop: &mut mio::EventLoop<Client>, task: Task) {
        match task {
            Task::HandleNetworkEvent(event) => self.handle_networking_event(event, event_loop),
            Task::ScheduleMessageDelivery(recipient, message) => self.schedule_message_delivery(recipient, message, event_loop)
        }
    }

    fn timeout(&mut self, _event_loop: &mut mio::EventLoop<Client>, task: ScheduledTask) {
        match task {
            ScheduledTask::DeliverMessage(recipient, message) => self.deliver_message(recipient, message)
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use bifrost::conshash::{ConsistentHashing, CHError};
use bifrost::raft::client::{RaftClient, ClientError};
use bifrost::raft;

use server::{transactions as txn_server};
use ram::types::Id;
use ram::cell::{Cell, ReadError, WriteError};
use self::transaction::*;

static TRANSACTION_MAX_RETRY: u32 = 50;

pub mod transaction;
pub mod plain;

pub enum NebClientError {
    RaftClientError(ClientError),
    ConsistentHashtableError(CHError)
}

pub struct Client {
    pub conshash: Arc<ConsistentHashing>,
}

impl Client {
    pub fn new(meta_servers: &Vec<String>, group: &String) -> Result<Client, NebClientError> {
        match RaftClient::new(meta_servers, raft::DEFAULT_SERVICE_ID) {
            Ok(raft_client) => {
                match ConsistentHashing::new_client(group, &raft_client) {
                    Ok(chash) => Ok(Client {conshash: chash}),
                    Err(err) => Err(NebClientError::ConsistentHashtableError(err))
                }
            },
            Err(err) => Err(NebClientError::RaftClientError(err))
        }
    }
    pub fn read_cell(&self, key: &Id) -> Result<Cell, ReadError> {
        unimplemented!()
    }
    fn write_cell(&self, cell: &Cell) -> Result<Cell, WriteError> {
         unimplemented!()
    }
    fn update_cell(&self, cell: &Cell) -> Result<Cell, WriteError> {
        unimplemented!()
    }
    fn remove_cell(&self, key: &Id) -> Result<(), WriteError> {
        unimplemented!()
    }
    fn transaction<TFN>(&self, mut func: TFN) -> Result<(), TxnError>
        where TFN: FnMut(&mut Transaction) -> Result<(), TxnError> {
        let server_name = match self.conshash.rand_server() {
            Some(name) => name,
            None => return Err(TxnError::CannotFindAServer)
        };
        let txn_client = match txn_server::new_client(&server_name) {
            Ok(client) => client,
            Err(e) => return Err(TxnError::IoError(e))
        };
        let mut txn_id: txn_server::TxnId;
        let mut retried = 0;
        while retried < TRANSACTION_MAX_RETRY {
            txn_id = match txn_client.begin() {
                Ok(Ok(id)) => id,
                _ => return Err(TxnError::CannotBegin)
            };
            let mut txn = Transaction{
                tid: txn_id,
                state: txn_server::TxnState::Started,
                client: txn_client.clone()
            };
            let mut exec_result = func(&mut txn);
            if exec_result.is_ok() && txn.state == txn_server::TxnState::Started {
                exec_result = txn.prepare();
            }
            if exec_result.is_ok() && txn.state == txn_server::TxnState::Prepared {
                exec_result = txn.commit();
            }
            match exec_result {
                Ok(()) => {
                    return Ok(());
                },
                Err(TxnError::NotRealizable) =>{
                    txn.abort();
                },
                Err(e) => {
                    txn.abort()?; // abort will always be an error to achieve early break
                }
            }
            retried += 1;
        }
        Err(TxnError::TooManyRetry)
    }
}<commit_msg>plain client<commit_after>use std::sync::Arc;
use std::io;
use bifrost::conshash::{ConsistentHashing, CHError};
use bifrost::raft::client::{RaftClient, ClientError};
use bifrost::raft;
use bifrost::rpc::{RPCError, DEFAULT_CLIENT_POOL};

use server::{transactions as txn_server, cell_rpc as plain_server};
use ram::types::Id;
use ram::cell::{Cell, ReadError, WriteError};
use self::transaction::*;

static TRANSACTION_MAX_RETRY: u32 = 50;

pub mod transaction;
pub mod plain;

pub enum NebClientError {
    RaftClientError(ClientError),
    ConsistentHashtableError(CHError)
}

pub struct Client {
    pub conshash: Arc<ConsistentHashing>,
}

impl Client {
    pub fn new(meta_servers: &Vec<String>, group: &String) -> Result<Client, NebClientError> {
        match RaftClient::new(meta_servers, raft::DEFAULT_SERVICE_ID) {
            Ok(raft_client) => {
                match ConsistentHashing::new_client(group, &raft_client) {
                    Ok(chash) => Ok(Client {conshash: chash}),
                    Err(err) => Err(NebClientError::ConsistentHashtableError(err))
                }
            },
            Err(err) => Err(NebClientError::RaftClientError(err))
        }
    }
    pub fn locate_server_address(&self, id: &Id) -> Result<String, RPCError> {
        match self.conshash.get_server(id.higher) {
            Some(n) => Ok(n),
            None => Err(RPCError::IOError(io::Error::new(io::ErrorKind::NotFound, "cannot locate")))
        }
    }
    pub fn locate_plain_server(&self, id: &Id) -> Result<Arc<plain_server::SyncServiceClient>, RPCError> {
        let address = self.locate_server_address(id)?;
        let client = match DEFAULT_CLIENT_POOL.get(&address) {
            Ok(c) => c,
            Err(e) => return Err(RPCError::IOError(e))
        };
        Ok(plain_server::SyncServiceClient::new(plain_server::DEFAULT_SERVICE_ID, &client))
    }
    pub fn read_cell(&self, id: &Id) -> Result<Result<Cell, ReadError>, RPCError> {
        let client = self.locate_plain_server(id)?;
        client.read_cell(id)
    }
    fn write_cell(&self, cell: &Cell) -> Result<Result<Cell, WriteError>, RPCError> {
        let client = self.locate_plain_server(&cell.id())?;
        client.write_cell(cell)
    }
    fn update_cell(&self, cell: &Cell) -> Result<Result<Cell, WriteError>, RPCError> {
        let client = self.locate_plain_server(&cell.id())?;
        client.update_cell(cell)
    }
    fn remove_cell(&self, id: &Id) -> Result<Result<(), WriteError>, RPCError> {
        let client = self.locate_plain_server(id)?;
        client.remove_cell(id)
    }
    fn transaction<TFN>(&self, mut func: TFN) -> Result<(), TxnError>
        where TFN: FnMut(&mut Transaction) -> Result<(), TxnError> {
        let server_name = match self.conshash.rand_server() {
            Some(name) => name,
            None => return Err(TxnError::CannotFindAServer)
        };
        let txn_client = match txn_server::new_client(&server_name) {
            Ok(client) => client,
            Err(e) => return Err(TxnError::IoError(e))
        };
        let mut txn_id: txn_server::TxnId;
        let mut retried = 0;
        while retried < TRANSACTION_MAX_RETRY {
            txn_id = match txn_client.begin() {
                Ok(Ok(id)) => id,
                _ => return Err(TxnError::CannotBegin)
            };
            let mut txn = Transaction{
                tid: txn_id,
                state: txn_server::TxnState::Started,
                client: txn_client.clone()
            };
            let mut exec_result = func(&mut txn);
            if exec_result.is_ok() && txn.state == txn_server::TxnState::Started {
                exec_result = txn.prepare();
            }
            if exec_result.is_ok() && txn.state == txn_server::TxnState::Prepared {
                exec_result = txn.commit();
            }
            match exec_result {
                Ok(()) => {
                    return Ok(());
                },
                Err(TxnError::NotRealizable) =>{
                    txn.abort();  // continue the loop to retry
                },
                Err(e) => {
                    txn.abort()?; // abort will always be an error to achieve early break
                }
            }
            retried += 1;
        }
        Err(TxnError::TooManyRetry)
    }
}<|endoftext|>


<commit_before>extern crate vst;

use std::sync::{Arc, Mutex};
use std::path::Path;
use std::error::Error;

use vst::host::{Host, PluginLoader};
use vst::plugin::Plugin;

#[allow(dead_code)]
struct SampleHost;

impl Host for SampleHost {
    fn automate(&mut self, index: i32, value: f32) {
        println!("Parameter {} had its value changed to {}", index, value);
    }
}

fn main() {
    // This is an example of a plugin being loaded. Change this to the appropriate path.
    let path = Path::new(
        "/Library/Audio/Plug-Ins/VST/beyerdynamicVS.vst/Contents/MacOS/beyerdynamicVS",
    );

    // Create the host
    let host = Arc::new(Mutex::new(SampleHost));

    println!("Loading {}...", path.to_str().unwrap());

    // Load the plugin
    let mut loader = PluginLoader::load(path, Arc::clone(&host)).unwrap_or_else(
        |e| {
            panic!("Failed to load plugin: {}", e.description())
        },
    );

    // Create an instance of the plugin
    let mut instance = loader.instance().unwrap();

    // Get the plugin information
    let info = instance.get_info();

    println!(
        "Loaded '{}':\n\t\
              Vendor: {}\n\t\
              Presets: {}\n\t\
              Parameters: {}\n\t\
              VST ID: {}\n\t\
              Version: {}\n\t\
              Initial Delay: {} samples",
        info.name,
        info.vendor,
        info.presets,
        info.parameters,
        info.unique_id,
        info.version,
        info.initial_delay
    );

    // Initialize the instance
    instance.init();
    println!("Initialized instance!");

    println!("Closing instance...");
    // Close the instance. This is not necessary as the instance is shut down when
    // it is dropped as it goes out of scope.
    // drop(instance);
}
<commit_msg>Add command line option for simple_host<commit_after>extern crate vst;

use std::sync::{Arc, Mutex};
use std::path::Path;
use std::error::Error;
use std::env;
use std::process;

use vst::host::{Host, PluginLoader};
use vst::plugin::Plugin;

#[allow(dead_code)]
struct SampleHost;

impl Host for SampleHost {
    fn automate(&mut self, index: i32, value: f32) {
        println!("Parameter {} had its value changed to {}", index, value);
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        println!("usage: simple_host path/to/vst");
        process::exit(1);
    }

    let path = Path::new(&args[1]);

    // Create the host
    let host = Arc::new(Mutex::new(SampleHost));

    println!("Loading {}...", path.to_str().unwrap());

    // Load the plugin
    let mut loader = PluginLoader::load(path, Arc::clone(&host)).unwrap_or_else(
        |e| {
            panic!("Failed to load plugin: {}", e.description())
        },
    );

    // Create an instance of the plugin
    let mut instance = loader.instance().unwrap();

    // Get the plugin information
    let info = instance.get_info();

    println!(
        "Loaded '{}':\n\t\
              Vendor: {}\n\t\
              Presets: {}\n\t\
              Parameters: {}\n\t\
              VST ID: {}\n\t\
              Version: {}\n\t\
              Initial Delay: {} samples",
        info.name,
        info.vendor,
        info.presets,
        info.parameters,
        info.unique_id,
        info.version,
        info.initial_delay
    );

    // Initialize the instance
    instance.init();
    println!("Initialized instance!");

    println!("Closing instance...");
    // Close the instance. This is not necessary as the instance is shut down when
    // it is dropped as it goes out of scope.
    // drop(instance);
}
<|endoftext|>


<commit_before>use super::expr::Expression;
use super::{CompileError};
use super::scope::Scope;

#[cfg(test)]
use super::lexer;

// Something that can be called with arguments given in the scope
pub trait Function {
	fn call(&self, scope: &Scope) -> Result<f32, CompileError>;
}

macro_rules! bind_function(
    ( $name:ident, $func:ident ( $($arg:ident),* ) ) => (
		struct $name;
		impl $name {
			fn new() -> $name {
				$name
			}
		}
		impl Function for $name {
			#[allow(unused_variables)] // Compiler complains that scope is not used on functions with no args.
			fn call(&self, scope: &Scope) -> Result<f32, CompileError> {
				Ok($func($(
					// Insert each argument from the scope
					match scope.var_id(stringify!($arg)) {
						Some(id) => scope.get_var(id).unwrap(),

						None => return Err(CompileError {
							msg: format!("function requires argument `{}` but not passed or defined in scope", stringify!($arg)),
							pos: None }),
					}
				),*))
			}
		}
    );
)

fn sin(a: f32) -> f32 {
	a.sin()
}

bind_function!(SinFunction, sin(a))

// Always returns a specific constant
struct ConstFunction {
	val: f32,
}
impl ConstFunction {
	fn new(val: f32) -> ConstFunction {
		ConstFunction {
			val: val,
		}
	}
}
impl Function for ConstFunction {
	fn call(&self, _: &Scope) -> Result<f32, CompileError> {
		Ok(self.val)
	}
}

// Wraps an expression from the expr module.
struct ExprFunction<'a> {
	expr: &'a Expression<'a>,
}
impl<'a> ExprFunction<'a> {
	fn new(expr: &'a Expression<'a>) -> ExprFunction<'a> {
		ExprFunction {
			expr: expr,
		}
	}
}
impl<'a> Function for ExprFunction<'a> {
	fn call(&self, scope: &Scope) -> Result<f32, CompileError> {
		self.expr.eval(scope)
	}
}

#[test]
fn const_function_test() {
	let f = ConstFunction::new(42_f32);
	assert!(f.call(&Scope::new()).unwrap() == 42_f32);
}

#[test]
fn expr_function_test() {
	let mut s = Scope::new();
	s.define("a", 9_f32);
	let e = Expression::new(lexer::tokenize("5*3+a").unwrap().as_slice(), &s).unwrap();
	let f = ExprFunction::new(&e);
	assert!(f.call(&s).unwrap() == 24_f32);
}

#[test]
fn sin_test() {
	let a = 2_f32;
	let mut s = Scope::new();
	s.define("a", a);
	let f = SinFunction::new();
	assert!(f.call(&s).unwrap() == a.sin());
}
<commit_msg>Add CondFunction and make the tests pass.<commit_after>use super::expr::Expression;
use super::{CompileError, is_truthy};
use super::scope::Scope;

#[cfg(test)]
use super::lexer;
#[cfg(test)]
use super::{TRUE, FALSE};

// Something that can be called with arguments given in the scope
pub trait Function {
	fn call(&self, scope: &Scope) -> Result<f32, CompileError>;
}

macro_rules! bind_function(
    ( $name:ident, $func:ident ( $($arg:ident),* ) ) => (
		struct $name;
		impl $name {
			fn new() -> $name {
				$name
			}
		}
		impl Function for $name {
			#[allow(unused_variables)] // Compiler complains that scope is not used on functions with no args.
			fn call(&self, scope: &Scope) -> Result<f32, CompileError> {
				Ok($func($(
					// Insert each argument from the scope
					match scope.var_id(stringify!($arg)) {
						Some(id) => scope.get_var(id).unwrap(),

						None => return Err(CompileError {
							msg: format!("function requires argument `{}` but not passed or defined in scope", stringify!($arg)),
							pos: None }),
					}
				),*))
			}
		}
    );
)

fn sin(a: f32) -> f32 {
	a.sin()
}

bind_function!(SinFunction, sin(a))

// Always returns a specific constant
struct ConstFunction {
	val: f32,
}
impl ConstFunction {
	fn new(val: f32) -> ConstFunction {
		ConstFunction {
			val: val,
		}
	}
}
impl Function for ConstFunction {
	fn call(&self, _: &Scope) -> Result<f32, CompileError> {
		Ok(self.val)
	}
}

// Wraps an expression from the expr module.
struct ExprFunction<'a> {
	expr: &'a Expression<'a>,
}
impl<'a> ExprFunction<'a> {
	fn new(expr: &'a Expression<'a>) -> ExprFunction<'a> {
		ExprFunction {
			expr: expr,
		}
	}
}
impl<'a> Function for ExprFunction<'a> {
	fn call(&self, scope: &Scope) -> Result<f32, CompileError> {
		self.expr.eval(scope)
	}
}

// Returns the result of calling the function if the condition is truthy, else 0
struct CondFunction<'a> {
	cond: Box<Function + 'a>,
	func: Box<Function + 'a>,
}
impl<'a> CondFunction<'a> {
	fn new(cond: Box<Function + 'a>, func: Box<Function + 'a>) -> CondFunction<'a> {
		CondFunction {
			cond: cond,
			func: func,
		}
	}
}
impl<'a> Function for CondFunction<'a> {
	fn call(&self, scope: &Scope) -> Result<f32, CompileError> {
		if is_truthy(try!(self.cond.call(scope))) {
			self.func.call(scope)
		} else {
			Ok(0_f32)
		}
	}
}

#[test]
fn const_function_test() {
	let f = ConstFunction::new(42_f32);
	assert!(f.call(&Scope::new()).unwrap() == 42_f32);
}

#[test]
fn expr_function_test() {
	let mut s = Scope::new();
	s.define_var("a", 9_f32);
	let e = Expression::new(lexer::tokenize("5*3+a").unwrap().as_slice(), &s).unwrap();
	let f = ExprFunction::new(&e);
	assert!(f.call(&s).unwrap() == 24_f32);
}

#[test]
fn sin_test() {
	let a = 2_f32;
	let mut s = Scope::new();
	s.define_var("a", a);
	let f = SinFunction::new();
	assert!(f.call(&s).unwrap() == a.sin());
}

#[test]
fn cond_test() {
	let cond_truthy = ConstFunction::new(TRUE);
	let cond_falsey = ConstFunction::new(FALSE);
	let expr = ConstFunction::new(42_f32);
	let f_truthy = CondFunction::new(box cond_truthy, box expr);
	let f_falsey = CondFunction::new(box cond_falsey, box expr);
	let s = Scope::new();
	assert!(f_truthy.call(&s).unwrap() == 42_f32);
	assert!(f_falsey.call(&s).unwrap() == 0_f32);
}
<|endoftext|>


<commit_before>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (ReadStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (pos, mut vel, actor, _) in (&pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector { x: pos.x, y: pos.y };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        let angle = angle(&own, &other);
        if angle > 270.0 || angle < 90.0 {
            vel.x = -vel.x.abs();
        } else {
            vel.x = vel.x.abs();
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        // Score and respawn
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<commit_msg>Core: Implement bounce and reset<commit_after>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (WriteStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (mut pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (mut pos, mut vel, actor, _) in (&mut pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, &mut pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &mut Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector { x: pos.x, y: pos.y };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        let angle = angle(&own, &other);
        if angle < 270.0 || angle > 90.0 {
            vel.x = -vel.x.abs();
        } else {
            vel.x = vel.x.abs();
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        pos.x = 500;
        pos.y = 500;
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<|endoftext|>


<commit_before>//! Module for working with derivatives.
//!
//! This module has functions for estimating and evaluating
//! derivatives of functions with one or more variables.

pub use super::func::*;

/// The value used for `h` in derivative estimates.
///
/// This value is chosen so as to offer the best accuracy,
/// it is a compromise between the increase in accuracy caused
/// by having an `h` closer to zero, and the decrease decrease
/// in accuracy caused by floating point imprecision with very
/// small values.
pub const EPSILON: f64 = 10.0e-7;

/// Return a `Function` estimating the `n`th derivative of `f`.
///
/// This function will return a `Function` that estimates the
/// `n`th derivative of `f` using the limit definition of the
/// derivative:
///
/// ```text
///                     f(x + h) - f(x)
/// f'(x) = lim         ---------------
///         h -> 0             h
/// ```
///
/// Where `h` is equal to `EPSILON`. See the documentation for
/// `EPSILON` for more information.
///
/// This function will use recursion to provide derivatives for `n > 1`.
///
/// It is important to note that the inaccuracy of the derivative
/// estimates compound each other, the higher `n` is, the less precise
/// the resulting function will be!
///
/// If `n = 0`, then a `clone()` of `f` is returned.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = nth_derivative(1, &f);
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f'(5)  = {}", first_deriv(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// f''(5) = 2.000177801164682
/// ```
pub fn nth_derivative(n: u64, f: &Function) -> Function {

    let f_copy = f.clone();
    let deriv: Function = func!(
        move |x: f64| {
            (f_copy(x + EPSILON) - f_copy(x)) / EPSILON
    });

    match n {
        0 => f.clone(),
        1 => deriv,
        _ => nth_derivative(n - 1, & deriv),
    }
}

/// Return a function estimating the first derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(1, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = derivative(&f);
///
/// println!("f(5)  = {}", f(5.0));
/// println!("f'(5) = {}", first_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// ```
pub fn derivative(f: &Function) -> Function {
    nth_derivative(1, &f)
}

/// Return a function estimating the second derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(2, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f''(5) = 2.000177801164682
/// ```
pub fn second_derivative(f: &Function) -> Function {
    nth_derivative(2, &f)
}

/// Estimate the value of the derivative of `f` at `x`
///
/// This is a helper function that calls `derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f'(-4.0) = {}", slope_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f'(-4.0) = 0.000001000000000279556
/// ```
pub fn slope_at(f: &Function, x: f64) -> f64 {
    derivative(f)(x)
}

/// Estimate the value of the second derivative of `f` at `x`
///
/// This is a helper function that calls `second_derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f''(-4.0) = {}", concavity_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f''(-4.0) = 2.0000000005591114
/// ```
pub fn concavity_at(f: &Function, x: f64) -> f64 {
    second_derivative(f)(x)
}

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

#[test]
    fn t_nth_derivative() {
        let f = func!(|x: f64| x * x * x + 5.0);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);

        assert_fp!(f(0.0), 5.0, 0.001);
        assert_fp!(f(4.0), 69.0, 0.001);
        assert_fp!(f(-2.0), -3.0, 0.001);

        assert_fp!(f_deriv(0.0), 0.0, 0.01);
        assert_fp!(f_deriv(4.0), 48.0, 0.01);
        assert_fp!(f_deriv(-2.0), 12.0, 0.01);

        assert_fp!(f_s_deriv(0.0), 0.0, 0.1);
        assert_fp!(f_s_deriv(4.0), 24.0, 0.1);
        assert_fp!(f_s_deriv(-2.0), -12.0, 0.1);

    }

#[test]
    fn t_helpers() {
        let f = func!(|x: f64| x * x);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);
        let f_deriv_2 = nth_derivative(1, &f);
        let f_s_deriv_2 = nth_derivative(2, &f);

        assert_eq!(f_deriv(0.0), f_deriv_2(0.0));
        assert_eq!(f_deriv(10.4), f_deriv_2(10.4));
        assert_eq!(f_deriv(56.8), f_deriv_2(56.8));

        assert_eq!(f_s_deriv(0.0), f_s_deriv_2(0.0));
        assert_eq!(f_s_deriv(40.4), f_s_deriv_2(40.4));
        assert_eq!(f_s_deriv(12.3), f_s_deriv_2(12.3));

        assert_eq!(f_deriv(0.0), slope_at(&f, 0.0));
        assert_eq!(f_deriv(10.4), slope_at(&f, 10.4));
        assert_eq!(f_deriv(56.8), slope_at(&f, 56.8));

        assert_eq!(f_s_deriv(0.0), concavity_at(&f, 0.0));
        assert_eq!(f_s_deriv(40.4), concavity_at(&f, 40.4));
        assert_eq!(f_s_deriv(12.3), concavity_at(&f, 12.3));
    }
}
<commit_msg>change derivative estimate to be on both sides of target point<commit_after>//! Module for working with derivatives.
//!
//! This module has functions for estimating and evaluating
//! derivatives of functions with one or more variables.

pub use super::func::*;

/// The value used for `h` in derivative estimates.
///
/// This value is chosen so as to offer the best accuracy,
/// it is a compromise between the increase in accuracy caused
/// by having an `h` closer to zero, and the decrease decrease
/// in accuracy caused by floating point imprecision with very
/// small values.
pub const EPSILON: f64 = 5.0e-7;

/// Return a `Function` estimating the `n`th derivative of `f`.
///
/// This function will return a `Function` that estimates the
/// `n`th derivative of `f` using the limit definition of the
/// derivative:
///
/// ```text
///                     f(x + h) - f(x)
/// f'(x) = lim         ---------------
///         h -> 0             h
/// ```
///
/// Where `h` is equal to `EPSILON`. See the documentation for
/// `EPSILON` for more information.
///
/// This function will use recursion to provide derivatives for `n > 1`.
///
/// It is important to note that the inaccuracy of the derivative
/// estimates compound each other, the higher `n` is, the less precise
/// the resulting function will be!
///
/// If `n = 0`, then a `clone()` of `f` is returned.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = nth_derivative(1, &f);
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f'(5)  = {}", first_deriv(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// f''(5) = 2.000177801164682
/// ```
pub fn nth_derivative(n: u64, f: &Function) -> Function {

    let f_copy = f.clone();
    let deriv: Function = func!(
        move |x: f64| {
            (f_copy(x + EPSILON) - f_copy(x - EPSILON)) / (EPSILON * 2.0)
    });

    match n {
        0 => f.clone(),
        1 => deriv,
        _ => nth_derivative(n - 1, &deriv),
    }
}

/// Return a function estimating the first derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(1, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let first_deriv = derivative(&f);
///
/// println!("f(5)  = {}", f(5.0));
/// println!("f'(5) = {}", first_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f'(5)  = 10.00000100148668
/// ```
pub fn derivative(f: &Function) -> Function {
    nth_derivative(1, &f)
}

/// Return a function estimating the second derivative of `f`.
///
/// This is a helper function and is equivalent to calling
/// `nth_derivative(2, f)`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| x * x];
///
/// let second_deriv = nth_derivative(2, &f);
///
/// println!("f(5)   = {}", f(5.0));
/// println!("f''(5) = {}", second_deriv(5.0));
/// # }
///
/// ```
///
/// Outputs:
///
/// ``` text
/// f(5)   = 25
/// f''(5) = 2.000177801164682
/// ```
pub fn second_derivative(f: &Function) -> Function {
    nth_derivative(2, &f)
}

/// Estimate the value of the derivative of `f` at `x`
///
/// This is a helper function that calls `derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f'(-4.0) = {}", slope_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f'(-4.0) = 0.000001000000000279556
/// ```
pub fn slope_at(f: &Function, x: f64) -> f64 {
    derivative(f)(x)
}

/// Estimate the value of the second derivative of `f` at `x`
///
/// This is a helper function that calls `second_derivative` and
/// then calls the resulting function with `x`.
///
/// Examples
///
/// ```
/// #[macro_use] extern crate reikna;
/// # fn main() {
/// use reikna::derivative::*;
///
/// let f = func![|x| (x + 4.0) * (x + 4.0)];
/// println!("f''(-4.0) = {}", concavity_at(&f, -4.0));
/// # }
///
/// ```
/// Outputs:
///
/// ```text
/// f''(-4.0) = 2.0000000005591114
/// ```
pub fn concavity_at(f: &Function, x: f64) -> f64 {
    second_derivative(f)(x)
}

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

#[test]
    fn t_nth_derivative() {
        let f = func!(|x: f64| x * x * x + 5.0);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);

        assert_fp!(f(0.0), 5.0, 0.0001);
        assert_fp!(f(4.0), 69.0, 0.0001);
        assert_fp!(f(-2.0), -3.0, 0.0001);

        assert_fp!(f_deriv(0.0), 0.0, 0.001);
        assert_fp!(f_deriv(4.0), 48.0, 0.001);
        assert_fp!(f_deriv(-2.0), 12.0, 0.001);

        assert_fp!(f_s_deriv(0.0), 0.0, 0.1);
        assert_fp!(f_s_deriv(4.0), 24.0, 0.1);
        assert_fp!(f_s_deriv(-2.0), -12.0, 0.1);

    }

#[test]
    fn t_helpers() {
        let f = func!(|x: f64| x * x);
        let f_deriv = derivative(&f);
        let f_s_deriv = second_derivative(&f);
        let f_deriv_2 = nth_derivative(1, &f);
        let f_s_deriv_2 = nth_derivative(2, &f);

        assert_eq!(f_deriv(0.0), f_deriv_2(0.0));
        assert_eq!(f_deriv(10.4), f_deriv_2(10.4));
        assert_eq!(f_deriv(56.8), f_deriv_2(56.8));

        assert_eq!(f_s_deriv(0.0), f_s_deriv_2(0.0));
        assert_eq!(f_s_deriv(40.4), f_s_deriv_2(40.4));
        assert_eq!(f_s_deriv(12.3), f_s_deriv_2(12.3));

        assert_eq!(f_deriv(0.0), slope_at(&f, 0.0));
        assert_eq!(f_deriv(10.4), slope_at(&f, 10.4));
        assert_eq!(f_deriv(56.8), slope_at(&f, 56.8));

        assert_eq!(f_s_deriv(0.0), concavity_at(&f, 0.0));
        assert_eq!(f_s_deriv(40.4), concavity_at(&f, 40.4));
        assert_eq!(f_s_deriv(12.3), concavity_at(&f, 12.3));
    }
}
<|endoftext|>