<commit_before>use rustc::mir;
use rustc::ty::{self, Ty};
use syntax::codemap::Span;

use error::EvalResult;
use eval_context::{EvalContext, StackPopCleanup};
use lvalue::{Lvalue, LvalueExtra};
use value::PrimVal;
use value::Value;

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    pub(crate) fn drop_lvalue(&mut self, lval: Lvalue<'tcx>, instance: ty::Instance<'tcx>, ty: Ty<'tcx>, span: Span) -> EvalResult<'tcx> {
        trace!("drop_lvalue: {:#?}", lval);
        // We take the address of the object.
        let val = match self.force_allocation(lval)? {
            Lvalue::Ptr { ptr, extra: LvalueExtra::Vtable(vtable), aligned: _ } => ptr.to_value_with_vtable(vtable),
            Lvalue::Ptr { ptr, extra: LvalueExtra::Length(len), aligned: _ } => ptr.to_value_with_len(len),
            Lvalue::Ptr { ptr, extra: LvalueExtra::None, aligned: _ } => ptr.to_value(),
            _ => bug!("force_allocation broken"),
        };
        self.drop(val, instance, ty, span)
    }
    pub(crate) fn drop(&mut self, arg: Value, mut instance: ty::Instance<'tcx>, ty: Ty<'tcx>, span: Span) -> EvalResult<'tcx> {
        trace!("drop: {:#?}, {:?}, {:?}", arg, ty.sty, instance.def);

        if let ty::InstanceDef::DropGlue(_, None) = instance.def {
            trace!("nothing to do, aborting");
            // we don't actually need to drop anything
            return Ok(());
        }
        let mir = match ty.sty {
            ty::TyDynamic(..) => {
                let vtable = match arg {
                    Value::ByValPair(_, PrimVal::Ptr(vtable)) => vtable,
                    _ => bug!("expected fat ptr, got {:?}", arg),
                };
                match self.read_drop_type_from_vtable(vtable)? {
                    Some(func) => {
                        instance = func;
                        self.load_mir(func.def)?
                    },
                    // no drop fn -> bail out
                    None => return Ok(()),
                }
            },
            _ => self.load_mir(instance.def)?,
        };

        self.push_stack_frame(
            instance,
            span,
            mir,
            Lvalue::undef(),
            StackPopCleanup::None,
        )?;

        let mut arg_locals = self.frame().mir.args_iter();
        assert_eq!(self.frame().mir.arg_count, 1);
        let arg_local = arg_locals.next().unwrap();
        let dest = self.eval_lvalue(&mir::Lvalue::Local(arg_local))?;
        let arg_ty = self.tcx.mk_mut_ptr(ty);
        self.write_value(arg, dest, arg_ty)
    }
}
<commit_msg>expand comment<commit_after>use rustc::mir;
use rustc::ty::{self, Ty};
use syntax::codemap::Span;

use error::EvalResult;
use eval_context::{EvalContext, StackPopCleanup};
use lvalue::{Lvalue, LvalueExtra};
use value::PrimVal;
use value::Value;

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
    pub(crate) fn drop_lvalue(&mut self, lval: Lvalue<'tcx>, instance: ty::Instance<'tcx>, ty: Ty<'tcx>, span: Span) -> EvalResult<'tcx> {
        trace!("drop_lvalue: {:#?}", lval);
        // We take the address of the object.  This may well be unaligned, which is fine for us here.
        // However, unaligned accesses will probably make the actual drop implementation fail -- a problem shared
        // by rustc.
        let val = match self.force_allocation(lval)? {
            Lvalue::Ptr { ptr, extra: LvalueExtra::Vtable(vtable), aligned: _ } => ptr.to_value_with_vtable(vtable),
            Lvalue::Ptr { ptr, extra: LvalueExtra::Length(len), aligned: _ } => ptr.to_value_with_len(len),
            Lvalue::Ptr { ptr, extra: LvalueExtra::None, aligned: _ } => ptr.to_value(),
            _ => bug!("force_allocation broken"),
        };
        self.drop(val, instance, ty, span)
    }
    pub(crate) fn drop(&mut self, arg: Value, mut instance: ty::Instance<'tcx>, ty: Ty<'tcx>, span: Span) -> EvalResult<'tcx> {
        trace!("drop: {:#?}, {:?}, {:?}", arg, ty.sty, instance.def);

        if let ty::InstanceDef::DropGlue(_, None) = instance.def {
            trace!("nothing to do, aborting");
            // we don't actually need to drop anything
            return Ok(());
        }
        let mir = match ty.sty {
            ty::TyDynamic(..) => {
                let vtable = match arg {
                    Value::ByValPair(_, PrimVal::Ptr(vtable)) => vtable,
                    _ => bug!("expected fat ptr, got {:?}", arg),
                };
                match self.read_drop_type_from_vtable(vtable)? {
                    Some(func) => {
                        instance = func;
                        self.load_mir(func.def)?
                    },
                    // no drop fn -> bail out
                    None => return Ok(()),
                }
            },
            _ => self.load_mir(instance.def)?,
        };

        self.push_stack_frame(
            instance,
            span,
            mir,
            Lvalue::undef(),
            StackPopCleanup::None,
        )?;

        let mut arg_locals = self.frame().mir.args_iter();
        assert_eq!(self.frame().mir.arg_count, 1);
        let arg_local = arg_locals.next().unwrap();
        let dest = self.eval_lvalue(&mir::Lvalue::Local(arg_local))?;
        let arg_ty = self.tcx.mk_mut_ptr(ty);
        self.write_value(arg, dest, arg_ty)
    }
}
<|endoftext|>


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

// ignore-android: FIXME (#20004)

#![feature(asm)]

use std::process::Command;
use std::env;

// lifted from the test module
// Inlining to avoid llvm turning the recursive functions into tail calls,
// which doesn't consume stack.
#[inline(always)]
pub fn black_box<T>(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } }

fn silent_recurse() {
    let buf = [0; 1000];
    black_box(buf);
    silent_recurse();
}

fn loud_recurse() {
    println!("hello!");
    loud_recurse();
    black_box(()); // don't optimize this into a tail call. please.
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "silent" {
        silent_recurse();
    } else if args.len() > 1 && args[1] == "loud" {
        loud_recurse();
    } else {
        let silent = Command::new(&args[0]).arg("silent").output().unwrap();
        assert!(!silent.status.success());
        let error = String::from_utf8_lossy(&silent.stderr);
        assert!(error.contains("has overflowed its stack"));

        let loud = Command::new(&args[0]).arg("loud").output().unwrap();
        assert!(!loud.status.success());
        let error = String::from_utf8_lossy(&silent.stderr);
        assert!(error.contains("has overflowed its stack"));
    }
}
<commit_msg>Auto merge of #25043 - alexcrichton:musl-out-of-stack, r=nikomatsakis<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-android: FIXME (#20004)
// ignore-musl

#![feature(asm)]

use std::process::Command;
use std::env;

// lifted from the test module
// Inlining to avoid llvm turning the recursive functions into tail calls,
// which doesn't consume stack.
#[inline(always)]
pub fn black_box<T>(dummy: T) { unsafe { asm!("" : : "r"(&dummy)) } }

fn silent_recurse() {
    let buf = [0; 1000];
    black_box(buf);
    silent_recurse();
}

fn loud_recurse() {
    println!("hello!");
    loud_recurse();
    black_box(()); // don't optimize this into a tail call. please.
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "silent" {
        silent_recurse();
    } else if args.len() > 1 && args[1] == "loud" {
        loud_recurse();
    } else {
        let silent = Command::new(&args[0]).arg("silent").output().unwrap();
        assert!(!silent.status.success());
        let error = String::from_utf8_lossy(&silent.stderr);
        assert!(error.contains("has overflowed its stack"));

        let loud = Command::new(&args[0]).arg("loud").output().unwrap();
        assert!(!loud.status.success());
        let error = String::from_utf8_lossy(&silent.stderr);
        assert!(error.contains("has overflowed its stack"));
    }
}
<|endoftext|>


<commit_before>#![crate_id = "chroot#1.0.0"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]
extern crate getopts;
extern crate libc;

use getopts::{optflag, optopt, getopts, usage};
use c_types::{get_pw_from_args, get_group};
use libc::funcs::posix88::unistd::{execvp, setuid, setgid};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

extern {
    fn chroot(path: *libc::c_char) -> libc::c_int;
    fn setgroups(size: libc::c_int, list: *libc::gid_t) -> libc::c_int;
}

static NAME: &'static str = "chroot";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main () { std::os::set_exit_status(uumain(std::os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optopt("u", "user", "User (ID or name) to switch before running the program", "USER"),
        optopt("g", "group", "Group (ID or name) to switch to", "GROUP"),
        optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2…"),
        optopt("", "userspec", "Colon-separated user and group to switch to. \
                                Same as -u USER -g GROUP. \
                                Userspec has higher preference than -u and/or -g", "USER:GROUP"),
        optflag("h", "help", "Show help"),
        optflag("V", "version", "Show program's version")
    ];

    let opts = match getopts(args.tail(), options) {
        Ok(m) => m,
        Err(f) => {
            show_error!("{}", f);
            help_menu(program.as_slice(), options);
            return 1
        }
    };

    if opts.opt_present("V") { version(); return 0 }
    if opts.opt_present("h") { help_menu(program.as_slice(), options); return 0 }

    if opts.free.len() == 0 {
        println!("Missing operand: NEWROOT");
        println!("Try `{:s} --help` for more information.", program.as_slice());
        return 1
    }

    let defaultShell: &'static str = "/bin/sh";
    let defaultOption: &'static str = "-i";
    let userShell = std::os::getenv("SHELL");

    let newroot = Path::new(opts.free.get(0).as_slice());
    if !newroot.is_dir() {
        crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display());
    }

    let command: Vec<&str> = match opts.free.len() {
        1 => {
            let shell: &str = match userShell {
                None => {defaultShell}
                Some(ref s) => {s.as_slice()}
            };
            vec!(shell, defaultOption)
        }
        _ => opts.free.slice(1, opts.free.len()).iter().map(|x| x.as_slice()).collect()
    };

    set_context(&newroot, &opts);

    unsafe {
        let executable = command.get(0).as_slice().to_c_str().unwrap();
        let mut commandParts: Vec<*i8> = command.iter().map(|x| x.to_c_str().unwrap()).collect();
        commandParts.push(std::ptr::null());
        execvp(executable as *libc::c_char, commandParts.as_ptr() as **libc::c_char) as int
    }
}

fn set_context(root: &Path, options: &getopts::Matches) {
    let userspecStr = options.opt_str("userspec");
    let userStr = options.opt_str("user").unwrap_or_default();
    let groupStr = options.opt_str("group").unwrap_or_default();
    let groupsStr = options.opt_str("groups").unwrap_or_default();
    let userspec = match userspecStr {
        Some(ref u) => {
            let s: Vec<&str> = u.as_slice().split(':').collect();
            if s.len() != 2 {
                crash!(1, "invalid userspec: `{:s}`", u.as_slice())
            };
            s
        }
        None => Vec::new()
    };
    let user = if userspec.is_empty() { userStr.as_slice() } else { userspec.get(0).as_slice() };
    let group = if userspec.is_empty() { groupStr.as_slice() } else { userspec.get(1).as_slice() };

    enter_chroot(root);

    set_groups(groupsStr.as_slice());
    set_main_group(group);
    set_user(user);
}

fn enter_chroot(root: &Path) {
    let rootStr = root.display();
    if !std::os::change_dir(root) {
        crash!(1, "cannot chdir to {}", rootStr)
    };
    let err = unsafe {
        chroot(".".to_c_str().unwrap() as *libc::c_char)
    };
    if err != 0 {
        crash!(1, "cannot chroot to {}: {:s}", rootStr, strerror(err).as_slice())
    };
}

fn set_main_group(group: &str) {
    if !group.is_empty() {
        let group_id = match get_group(group) {
            None => crash!(1, "no such group: {}", group),
            Some(g) => g.gr_gid
        };
        let err = unsafe { setgid(group_id) };
        if err != 0 {
            crash!(1, "cannot set gid to {:u}: {:s}", group_id, strerror(err).as_slice())
        }
    }
}

fn set_groups(groups: &str) {
    if !groups.is_empty() {
        let groupsVec: Vec<libc::gid_t> = FromIterator::from_iter(
            groups.split(',').map(
                |x| match get_group(x) {
                    None => crash!(1, "no such group: {}", x),
                    Some(g) => g.gr_gid
                })
            );
        let err = unsafe {
            setgroups(groupsVec.len() as libc::c_int,
                      groupsVec.as_slice().as_ptr() as *libc::gid_t)
        };
        if err != 0 {
            crash!(1, "cannot set groups: {:s}", strerror(err).as_slice())
        }
    }
}

fn set_user(user: &str) {
    if !user.is_empty() {
        let user_id = get_pw_from_args(&vec!(String::from_str(user))).unwrap().pw_uid;
        let err = unsafe { setuid(user_id as libc::uid_t) };
        if err != 0 {
            crash!(1, "cannot set user to {:s}: {:s}", user, strerror(err).as_slice())
        }
    }
}

fn strerror(errno: i32) -> String {
    unsafe {
        let err = libc::funcs::c95::string::strerror(errno);
        std::str::raw::from_c_str(err)
    }
}

fn version() {
    println!("{} v{}", NAME, VERSION)
}

fn help_menu(program: &str, options: &[getopts::OptGroup]) {
    version();
    println!("Usage:");
    println!("  {:s} [OPTION]… NEWROOT [COMMAND [ARG]…]", program);
    println!("");
    print!("{:s}", usage(
            "Run COMMAND with root directory set to NEWROOT.\n\
             If COMMAND is not specified, it defaults to '${SHELL} -i'. \
             If ${SHELL} is not set, /bin/sh is used.", options))
}
<commit_msg>chroot: remove a couple more braces<commit_after>#![crate_id = "chroot#1.0.0"]
/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Vsevolod Velichko <torkvemada@sorokdva.net>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]
extern crate getopts;
extern crate libc;

use getopts::{optflag, optopt, getopts, usage};
use c_types::{get_pw_from_args, get_group};
use libc::funcs::posix88::unistd::{execvp, setuid, setgid};

#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;

extern {
    fn chroot(path: *libc::c_char) -> libc::c_int;
    fn setgroups(size: libc::c_int, list: *libc::gid_t) -> libc::c_int;
}

static NAME: &'static str = "chroot";
static VERSION: &'static str = "1.0.0";

#[allow(dead_code)]
fn main () { std::os::set_exit_status(uumain(std::os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0);

    let options = [
        optopt("u", "user", "User (ID or name) to switch before running the program", "USER"),
        optopt("g", "group", "Group (ID or name) to switch to", "GROUP"),
        optopt("G", "groups", "Comma-separated list of groups to switch to", "GROUP1,GROUP2…"),
        optopt("", "userspec", "Colon-separated user and group to switch to. \
                                Same as -u USER -g GROUP. \
                                Userspec has higher preference than -u and/or -g", "USER:GROUP"),
        optflag("h", "help", "Show help"),
        optflag("V", "version", "Show program's version")
    ];

    let opts = match getopts(args.tail(), options) {
        Ok(m) => m,
        Err(f) => {
            show_error!("{}", f);
            help_menu(program.as_slice(), options);
            return 1
        }
    };

    if opts.opt_present("V") { version(); return 0 }
    if opts.opt_present("h") { help_menu(program.as_slice(), options); return 0 }

    if opts.free.len() == 0 {
        println!("Missing operand: NEWROOT");
        println!("Try `{:s} --help` for more information.", program.as_slice());
        return 1
    }

    let defaultShell: &'static str = "/bin/sh";
    let defaultOption: &'static str = "-i";
    let userShell = std::os::getenv("SHELL");

    let newroot = Path::new(opts.free.get(0).as_slice());
    if !newroot.is_dir() {
        crash!(1, "cannot change root directory to `{}`: no such directory", newroot.display());
    }

    let command: Vec<&str> = match opts.free.len() {
        1 => {
            let shell: &str = match userShell {
                None => defaultShell,
                Some(ref s) => s.as_slice()
            };
            vec!(shell, defaultOption)
        }
        _ => opts.free.slice(1, opts.free.len()).iter().map(|x| x.as_slice()).collect()
    };

    set_context(&newroot, &opts);

    unsafe {
        let executable = command.get(0).as_slice().to_c_str().unwrap();
        let mut commandParts: Vec<*i8> = command.iter().map(|x| x.to_c_str().unwrap()).collect();
        commandParts.push(std::ptr::null());
        execvp(executable as *libc::c_char, commandParts.as_ptr() as **libc::c_char) as int
    }
}

fn set_context(root: &Path, options: &getopts::Matches) {
    let userspecStr = options.opt_str("userspec");
    let userStr = options.opt_str("user").unwrap_or_default();
    let groupStr = options.opt_str("group").unwrap_or_default();
    let groupsStr = options.opt_str("groups").unwrap_or_default();
    let userspec = match userspecStr {
        Some(ref u) => {
            let s: Vec<&str> = u.as_slice().split(':').collect();
            if s.len() != 2 {
                crash!(1, "invalid userspec: `{:s}`", u.as_slice())
            };
            s
        }
        None => Vec::new()
    };
    let user = if userspec.is_empty() { userStr.as_slice() } else { userspec.get(0).as_slice() };
    let group = if userspec.is_empty() { groupStr.as_slice() } else { userspec.get(1).as_slice() };

    enter_chroot(root);

    set_groups(groupsStr.as_slice());
    set_main_group(group);
    set_user(user);
}

fn enter_chroot(root: &Path) {
    let rootStr = root.display();
    if !std::os::change_dir(root) {
        crash!(1, "cannot chdir to {}", rootStr)
    };
    let err = unsafe {
        chroot(".".to_c_str().unwrap() as *libc::c_char)
    };
    if err != 0 {
        crash!(1, "cannot chroot to {}: {:s}", rootStr, strerror(err).as_slice())
    };
}

fn set_main_group(group: &str) {
    if !group.is_empty() {
        let group_id = match get_group(group) {
            None => crash!(1, "no such group: {}", group),
            Some(g) => g.gr_gid
        };
        let err = unsafe { setgid(group_id) };
        if err != 0 {
            crash!(1, "cannot set gid to {:u}: {:s}", group_id, strerror(err).as_slice())
        }
    }
}

fn set_groups(groups: &str) {
    if !groups.is_empty() {
        let groupsVec: Vec<libc::gid_t> = FromIterator::from_iter(
            groups.split(',').map(
                |x| match get_group(x) {
                    None => crash!(1, "no such group: {}", x),
                    Some(g) => g.gr_gid
                })
            );
        let err = unsafe {
            setgroups(groupsVec.len() as libc::c_int,
                      groupsVec.as_slice().as_ptr() as *libc::gid_t)
        };
        if err != 0 {
            crash!(1, "cannot set groups: {:s}", strerror(err).as_slice())
        }
    }
}

fn set_user(user: &str) {
    if !user.is_empty() {
        let user_id = get_pw_from_args(&vec!(String::from_str(user))).unwrap().pw_uid;
        let err = unsafe { setuid(user_id as libc::uid_t) };
        if err != 0 {
            crash!(1, "cannot set user to {:s}: {:s}", user, strerror(err).as_slice())
        }
    }
}

fn strerror(errno: i32) -> String {
    unsafe {
        let err = libc::funcs::c95::string::strerror(errno);
        std::str::raw::from_c_str(err)
    }
}

fn version() {
    println!("{} v{}", NAME, VERSION)
}

fn help_menu(program: &str, options: &[getopts::OptGroup]) {
    version();
    println!("Usage:");
    println!("  {:s} [OPTION]… NEWROOT [COMMAND [ARG]…]", program);
    println!("");
    print!("{:s}", usage(
            "Run COMMAND with root directory set to NEWROOT.\n\
             If COMMAND is not specified, it defaults to '${SHELL} -i'. \
             If ${SHELL} is not set, /bin/sh is used.", options))
}
<|endoftext|>


<commit_before>extern crate libloading;
extern crate rand;
extern crate test_server;

use libloading::{Library, Symbol};
use std::{env, str};
use std::u16::MAX;
use test_server::hyper;

#[cfg(target_os = "windows")]
const LIB_PATH: &str = "../../target/debug/ctehxk2.dll";
#[cfg(target_os = "linux")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.so";
#[cfg(target_os = "macos")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.dylib";

#[test]
fn has_ct_api_functions() {
    let server = test_server::serve(Some(String::from("127.0.0.1:65432")));
    env::set_var("K2_BASE_URL", "http://127.0.0.1:65432");

    match Library::new(LIB_PATH) {
        Ok(lib) => {
            println!("before load init");
            let init: Symbol<unsafe extern "system" fn(u16, u16) -> i8> =
                unsafe { lib.get(b"CT_init").unwrap() };
            println!("before load data");
            let data: Symbol<
                unsafe extern "system" fn(u16, *mut u8, *mut u8, u16, *const u8, *mut u16, *mut u8)
                    -> i8,
            > = unsafe { lib.get(b"CT_data").unwrap() };
            println!("before load close");
            let close: Symbol<unsafe extern "system" fn(u16) -> i8> =
                unsafe { lib.get(b"CT_close").unwrap() };

            let ctn = rand::random::<u16>();
            println!("ctn: {}", ctn);
            let pn = rand::random::<u16>();
            println!("pn: {}", pn);
            let mut dad = rand::random::<u8>();
            println!("dad: {}", dad);
            let mut sad = rand::random::<u8>();
            println!("sad: {}", sad);

            let commands: [u8; 1] = [rand::random::<u8>(); 1];
            let commands_ptr: *const u8 = &commands[0];
            let lenc: u16 = commands.len() as u16;

            println!("command: {:?}", commands);
            println!("lenc: {}", lenc);

            let mut response: [u8; MAX as usize] = [rand::random::<u8>(); MAX as usize];
            let response_ptr: *mut u8 = &mut response[0];
            let mut lenr: u16 = response.len() as u16;

            println!("lenr: {}", lenr);

            unsafe {
                println!("before init server");
                server.reply().status(hyper::Ok).body("0");

                println!("before init");
                assert_eq!(0, init(ctn, pn));

                println!("before data server");
                server.reply().status(hyper::Ok).body(
                    "{\"dad\":1,\"sad\":1,\"lenr\":5,\"response\":\"AQIDBAU=\",\"responseCode\":0}",
                );

                println!("before data");
                assert_eq!(
                    0,
                    data(
                        ctn,
                        &mut dad,
                        &mut sad,
                        lenc,
                        commands_ptr,
                        &mut lenr,
                        response_ptr,
                    )
                );

                println!("before close server");
                server.reply().status(hyper::Ok).body("0");

                println!("before close");
                assert_eq!(0, close(ctn));
            }
        }
        _ => assert!(false, format!("loading library from {}", LIB_PATH)),
    }
}
<commit_msg>add more dubg output<commit_after>extern crate libloading;
extern crate rand;
extern crate test_server;

use libloading::{Library, Symbol};
use std::{env, str};
use std::u16::MAX;
use test_server::hyper;

#[cfg(target_os = "windows")]
const LIB_PATH: &str = "../../target/debug/ctehxk2.dll";
#[cfg(target_os = "linux")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.so";
#[cfg(target_os = "macos")]
const LIB_PATH: &str = "../../target/debug/libctehxk2.dylib";

#[test]
fn has_ct_api_functions() {
    let server = test_server::serve(Some(String::from("127.0.0.1:65432")));
    env::set_var("K2_BASE_URL", "http://127.0.0.1:65432");

    match Library::new(LIB_PATH) {
        Ok(lib) => {
            println!("before load init");
            let init: Symbol<unsafe extern "system" fn(u16, u16) -> i8> =
                unsafe { lib.get(b"CT_init").unwrap() };
            println!("before load data");
            let data: Symbol<
                unsafe extern "system" fn(u16, *mut u8, *mut u8, u16, *const u8, *mut u16, *mut u8)
                    -> i8,
            > = unsafe { lib.get(b"CT_data").unwrap() };
            println!("before load close");
            let close: Symbol<unsafe extern "system" fn(u16) -> i8> =
                unsafe { lib.get(b"CT_close").unwrap() };

            let ctn = rand::random::<u16>();
            println!("ctn: {}", ctn);
            let pn = rand::random::<u16>();
            println!("pn: {}", pn);
            let mut dad = rand::random::<u8>();
            println!("dad: {}", dad);
            let mut sad = rand::random::<u8>();
            println!("sad: {}", sad);

            let commands: [u8; 1] = [rand::random::<u8>(); 1];
            let commands_ptr: *const u8 = &commands[0];
            let lenc: u16 = commands.len() as u16;

            println!("command: {:?}", commands);
            println!("lenc: {}", lenc);

            let mut response: [u8; MAX as usize] = [rand::random::<u8>(); MAX as usize];
            let response_ptr: *mut u8 = &mut response[0];
            let mut lenr: u16 = response.len() as u16;

            println!("lenr: {}", lenr);

            unsafe {
                println!("before init server");
                server.reply().status(hyper::Ok).body("0");

                println!("before init");
                assert_eq!(0, init(ctn, pn));

                println!("before data server");
                server.reply().status(hyper::Ok).body(
                    "{\"dad\":1,\"sad\":1,\"lenr\":5,\"response\":\"AQIDBAU=\",\"responseCode\":0}",
                );

                println!("before data");
                assert_eq!(
                    0,
                    data(
                        ctn,
                        &mut dad,
                        &mut sad,
                        lenc,
                        commands_ptr,
                        &mut lenr,
                        response_ptr,
                    )
                );

                println!("before close server");
                server.reply().status(hyper::Ok).body("0");

                println!("before close");
                assert_eq!(0, close(ctn));
                println!("after close");
            }
        }
        _ => assert!(false, format!("loading library from {}", LIB_PATH)),
    }
    println!("end of test");
}
<|endoftext|>


<commit_before>extern crate openvr;
extern crate winit;
#[macro_use]
extern crate vulkano;
extern crate vulkano_win;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate libloading;

// Socket communication with language server
use std::net;

fn main() {
    // Initialize application state
    // @TODO - read from config files
    let state = 0;

    // Import and create descriptor tree of application
    let app = 0;

    // Start Coronal engine
    // @TODO - Pass state as props,
    let engine = 0;

    //while engine.update()
    {}
}
<commit_msg>Changed main.rs<commit_after>extern crate openvr;
extern crate winit;
#[macro_use]
extern crate vulkano;
extern crate vulkano_win;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate libloading;

// Socket communication with language server
use std::net;

fn main() {
    // Initialize application state
    // @TODO - read_config();
    let state = 0;

    // Import and create descriptor tree of application
    // @TODO - App::new();
    let app = 0;

    // Start Coronal engine
    // @TODO - Engine::new(state, app);
    let engine = 0;

    //while engine.update()
    {
        //engine.io();
        //engine.begin_update();
        //engine.update();
        //engine.render();
        //engine.end_update();
    }
}<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

//! This crate contains a GraphQL schema representation.

#![deny(warnings)]
#![deny(rust_2018_idioms)]
#![deny(clippy::all)]

pub mod definitions;
mod errors;
mod flatbuffer;
mod graphql_schema;
mod schema;
mod sdl;

use common::{DiagnosticsResult, SourceLocationKey};
pub use definitions::{
    Argument, ArgumentDefinitions, ArgumentValue, Directive, DirectiveValue, Enum, EnumID,
    EnumValue, Field, FieldID, InputObject, InputObjectID, Interface, InterfaceID, Object,
    ObjectID, Scalar, ScalarID, Type, TypeReference, TypeWithFields, Union, UnionID,
};
pub use errors::{Result, SchemaError};
use flatbuffer::FlatBufferSchema;
pub use graphql_schema::Schema;
pub use graphql_syntax::{DirectiveLocation, TypeSystemDefinition};
pub use schema::SDLSchema;
pub use sdl::SDLSchemaImpl;

const BUILTINS: &str = include_str!("./builtins.graphql");

pub use flatbuffer::serialize_as_fb;

pub fn build_schema(sdl: &str) -> DiagnosticsResult<SDLSchema> {
    build_schema_with_extensions::<_, &str>(&[sdl], &[])
}

pub fn build_schema_with_extensions<T: AsRef<str>, U: AsRef<str>>(
    server_sdls: &[T],
    extension_sdls: &[U],
) -> DiagnosticsResult<SDLSchema> {
    let mut server_definitions = builtins()?;
    let mut combined_sdl: String = String::new();
    for server_sdl in server_sdls {
        combined_sdl.push_str(server_sdl.as_ref());
        combined_sdl.push_str("\n");
    }
    server_definitions.extend(
        graphql_syntax::parse_schema_document(&combined_sdl, SourceLocationKey::generated())?
            .definitions,
    );

    let mut extension_definitions = Vec::new();
    for extension_sdl in extension_sdls {
        extension_definitions.extend(
            graphql_syntax::parse_schema_document(
                extension_sdl.as_ref(),
                SourceLocationKey::generated(),
            )?
            .definitions,
        );
    }

    SDLSchema::build(&server_definitions, &extension_definitions)
}

pub fn build_schema_from_flat_buffer(bytes: &[u8]) -> DiagnosticsResult<FlatBufferSchema<'_>> {
    Ok(FlatBufferSchema::build(bytes))
}

pub fn builtins() -> DiagnosticsResult<Vec<TypeSystemDefinition>> {
    Ok(
        graphql_syntax::parse_schema_document(BUILTINS, SourceLocationKey::generated())?
            .definitions,
    )
}
<commit_msg>Fix ambiguous `schema` doc-test failure<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

//! This crate contains a GraphQL schema representation.

#![deny(warnings)]
#![deny(rust_2018_idioms)]
#![deny(clippy::all)]

pub mod definitions;
mod errors;
mod flatbuffer;
mod graphql_schema;
mod schema;
mod sdl;

pub use crate::schema::SDLSchema;
use common::{DiagnosticsResult, SourceLocationKey};
pub use definitions::{
    Argument, ArgumentDefinitions, ArgumentValue, Directive, DirectiveValue, Enum, EnumID,
    EnumValue, Field, FieldID, InputObject, InputObjectID, Interface, InterfaceID, Object,
    ObjectID, Scalar, ScalarID, Type, TypeReference, TypeWithFields, Union, UnionID,
};
pub use errors::{Result, SchemaError};
use flatbuffer::FlatBufferSchema;
pub use graphql_schema::Schema;
pub use graphql_syntax::{DirectiveLocation, TypeSystemDefinition};
pub use sdl::SDLSchemaImpl;

const BUILTINS: &str = include_str!("./builtins.graphql");

pub use flatbuffer::serialize_as_fb;

pub fn build_schema(sdl: &str) -> DiagnosticsResult<SDLSchema> {
    build_schema_with_extensions::<_, &str>(&[sdl], &[])
}

pub fn build_schema_with_extensions<T: AsRef<str>, U: AsRef<str>>(
    server_sdls: &[T],
    extension_sdls: &[U],
) -> DiagnosticsResult<SDLSchema> {
    let mut server_definitions = builtins()?;
    let mut combined_sdl: String = String::new();
    for server_sdl in server_sdls {
        combined_sdl.push_str(server_sdl.as_ref());
        combined_sdl.push_str("\n");
    }
    server_definitions.extend(
        graphql_syntax::parse_schema_document(&combined_sdl, SourceLocationKey::generated())?
            .definitions,
    );

    let mut extension_definitions = Vec::new();
    for extension_sdl in extension_sdls {
        extension_definitions.extend(
            graphql_syntax::parse_schema_document(
                extension_sdl.as_ref(),
                SourceLocationKey::generated(),
            )?
            .definitions,
        );
    }

    SDLSchema::build(&server_definitions, &extension_definitions)
}

pub fn build_schema_from_flat_buffer(bytes: &[u8]) -> DiagnosticsResult<FlatBufferSchema<'_>> {
    Ok(FlatBufferSchema::build(bytes))
}

pub fn builtins() -> DiagnosticsResult<Vec<TypeSystemDefinition>> {
    Ok(
        graphql_syntax::parse_schema_document(BUILTINS, SourceLocationKey::generated())?
            .definitions,
    )
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::{File, IoResult};
use std::io::fs::PathExtensions;
use std::os;
use std::path::Path;

pub fn resources_dir_path() -> Path {
    // FIXME: Find a way to not rely on the executable being under `<servo source>/target`.
    let mut path = os::self_exe_path().expect("can't get exe path");
    path.pop();
    path.push("resources");
    if !path.is_dir() {
        path.pop();
        path.pop();
        path.push("resources");
    }
    path
}

pub fn read_resource_file(relative_path_components: &[&str]) -> IoResult<Vec<u8>> {
    let mut path = resources_dir_path();
    path.push_many(relative_path_components);
    let mut file = try!(File::open(&path));
    file.read_to_end()
}
<commit_msg>auto merge of #4013 : glennw/servo/android-resources, r=larsbergstrom<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::{File, IoResult};
use std::path::Path;

#[cfg(not(target_os = "android"))]
use std::io::fs::PathExtensions;
#[cfg(not(target_os = "android"))]
use std::os;

#[cfg(target_os = "android")]
pub fn resources_dir_path() -> Path {
    Path::new("/sdcard/servo/")
}

#[cfg(not(target_os = "android"))]
pub fn resources_dir_path() -> Path {
    // FIXME: Find a way to not rely on the executable being under `<servo source>/target`.
    let mut path = os::self_exe_path().expect("can't get exe path");
    path.pop();
    path.push("resources");
    if !path.is_dir() {
        path.pop();
        path.pop();
        path.push("resources");
    }
    path
}

pub fn read_resource_file(relative_path_components: &[&str]) -> IoResult<Vec<u8>> {
    let mut path = resources_dir_path();
    path.push_many(relative_path_components);
    let mut file = try!(File::open(&path));
    file.read_to_end()
}
<|endoftext|>


<commit_before>#![feature(try_trait)]

extern crate pgn_reader;
extern crate memmap;
extern crate madvise;
extern crate btoi;
extern crate rand;
extern crate reqwest;

use std::env;
use std::mem;
use std::cmp::min;
use std::fs::File;
use std::option::NoneError;
use std::io::Read;

use memmap::Mmap;
use madvise::{AccessPattern, AdviseMemory};
use pgn_reader::{Visitor, Skip, Reader, San};
use btoi::ParseIntegerError;
use rand::{random, Closed01};

const BATCH_SIZE: usize = 50;

const MAX_PLIES: usize = 50;

#[derive(Debug)]
enum TimeControl {
    UltraBullet,
    Bullet,
    Blitz,
    Rapid,
    Classical,
    Correspondence,
}

#[derive(Debug)]
struct TimeControlError;

impl From<NoneError> for TimeControlError {
    fn from(_: NoneError) -> TimeControlError {
        TimeControlError { }
    }
}

impl From<ParseIntegerError> for TimeControlError {
    fn from(_: ParseIntegerError) -> TimeControlError {
        TimeControlError { }
    }
}

impl TimeControl {
    fn from_seconds_and_increment(seconds: u64, increment: u64) -> TimeControl {
        let total = seconds + 40 * increment;

        if total < 30 {
            TimeControl::UltraBullet
        } else if total < 180 {
            TimeControl::Bullet
        } else if total < 480 {
            TimeControl::Blitz
        } else if total < 1500 {
            TimeControl::Rapid
        } else if total < 21_600 {
            TimeControl::Classical
        } else {
            TimeControl::Correspondence
        }
    }

    fn from_bytes(bytes: &[u8]) -> Result<TimeControl, TimeControlError> {
        if bytes == b"-" {
            return Ok(TimeControl::Correspondence);
        }

        let mut parts = bytes.splitn(2, |ch| *ch == b'+');
        let seconds = btoi::btou(parts.next()?)?;
        let increment = btoi::btou(parts.next()?)?;
        Ok(TimeControl::from_seconds_and_increment(seconds, increment))
    }
}

struct Indexer {
    context: String,

    white_elo: i16,
    black_elo: i16,
    time_control: TimeControl,
    skip: bool,

    current_game: Vec<u8>,
    plies: usize,
    standard: bool,

    batch: Vec<u8>,
    batch_size: usize,
}

impl Indexer {
    fn new(context: &str) -> Indexer {
        Indexer {
            context: context.into(),

            white_elo: 0,
            black_elo: 0,
            time_control: TimeControl::Correspondence,
            skip: true,

            current_game: Vec::new(),
            plies: 0,
            standard: true,

            batch: Vec::new(),
            batch_size: 0,
        }
    }

    fn send(&mut self) {
        if self.batch_size > 0 {
            self.batch_size = 0;

            let mut res = reqwest::Client::new()
                .put("http://localhost:9000/import/lichess")
                .body(mem::replace(&mut self.batch, Vec::new()))
                .send().expect("send batch");

            let mut answer = String::new();
            res.read_to_string(&mut answer).expect("decode response");
            println!("{}: {}", self.context, answer);
            assert!(res.status().is_success());
        }
    }
}

impl<'pgn> Visitor<'pgn> for Indexer {
    type Result = ();

    fn begin_game(&mut self) {
        self.current_game.clear();
        self.plies = 0;
    }

    fn begin_headers(&mut self) {
        self.white_elo = 0;
        self.black_elo = 0;
        self.time_control = TimeControl::Correspondence;
        self.standard = true;
    }

    fn header(&mut self, key: &'pgn [u8], value: &'pgn [u8]) {
        if key == b"WhiteElo" {
            self.white_elo = if value == b"?" { 0 } else { btoi::btoi(value).expect("WhiteElo") };
        } else if key == b"BlackElo" {
            self.black_elo = if value == b"?" { 0 } else { btoi::btoi(value).expect("BlackElo") };
        } else if key == b"TimeControl" {
            self.time_control = TimeControl::from_bytes(value).expect("TimeControl");
        } else if key == b"Variant" {
            self.standard = value == b"Standard";
            if self.standard {
                return; // we add this unconditionally later
            }
        }

        let (key, value) = if key == b"Site" {
            (&b"LichessID"[..], value.rsplitn(2, |ch| *ch == b'/').next().expect("Site"))
        } else {
            (key, value)
        };

        self.current_game.push(b'[');
        self.current_game.extend(key);
        self.current_game.extend(b" \"");
        self.current_game.extend(value);
        self.current_game.extend(b"\"]\n");
    }

    fn end_headers(&mut self) -> Skip {
        let rating = (self.white_elo + self.black_elo) / 2;

        let probability = if self.standard {
            self.current_game.extend(b"[Variant \"Standard\"]\n");

            match self.time_control {
                TimeControl::Correspondence | TimeControl::Classical => 1.0,
                TimeControl::Rapid if rating >= 2000 => 1.0,
                TimeControl::Rapid if rating >= 1800 => 2.0 / 5.0,
                TimeControl::Rapid => 1.0 / 8.0,
                TimeControl::Blitz if rating >= 2000 => 1.0,
                TimeControl::Blitz if rating >= 1800 => 1.0 / 4.0,
                TimeControl::Blitz => 1.0 / 15.0,
                TimeControl::Bullet if rating >= 2300 => 1.0,
                TimeControl::Bullet if rating >= 2200 => 4.0 / 5.0,
                TimeControl::Bullet if rating >= 2000 => 1.0 / 4.0,
                TimeControl::Bullet if rating >= 1800 => 1.0 / 7.0,
                _ => 1.0 / 20.0,
            }
        } else {
            1.0 // variant game
        };

        self.current_game.push(b'\n');

        let Closed01(rnd) = random::<Closed01<f64>>();
        let accept = min(self.white_elo, self.black_elo) >= 1500 && probability >= rnd;

        self.skip = !accept;
        Skip(self.skip)
    }

    fn san(&mut self, san: San) {
        if self.plies < MAX_PLIES {
            if self.plies > 0 {
                self.current_game.push(b' ');
            }

            self.current_game.extend(san.to_string().as_bytes());
            self.plies += 1;
        }
    }

    fn begin_variation(&mut self) -> Skip {
        Skip(true) // stay in the mainline
    }

    fn end_game(&mut self, _game: &'pgn [u8]) {
        if !self.skip && self.plies > 8 {
            if self.batch_size >= BATCH_SIZE {
                self.send();
            }

            if self.batch_size > 0 {
                self.batch.extend(b"\n\n\n");
            }

            self.batch.extend(&self.current_game);
            self.batch_size += 1;
        }
    }
}

fn main() {
    for arg in env::args().skip(1) {
        eprintln!("% indexing {} ...", arg);
        let file = File::open(&arg).expect("fopen");
        let pgn = unsafe { Mmap::map(&file).expect("mmap") };
        pgn.advise_memory_access(AccessPattern::Sequential).expect("madvise");

        let mut indexer = Indexer::new(&arg);
        Reader::new(&mut indexer, &pgn[..]).read_all();
        indexer.send(); // send last
    }
}
<commit_msg>index fewer noob variant games<commit_after>#![feature(try_trait)]

extern crate pgn_reader;
extern crate memmap;
extern crate madvise;
extern crate btoi;
extern crate rand;
extern crate reqwest;

use std::env;
use std::mem;
use std::cmp::min;
use std::fs::File;
use std::option::NoneError;
use std::io::Read;

use memmap::Mmap;
use madvise::{AccessPattern, AdviseMemory};
use pgn_reader::{Visitor, Skip, Reader, San};
use btoi::ParseIntegerError;
use rand::{random, Closed01};

const BATCH_SIZE: usize = 50;

const MAX_PLIES: usize = 50;

#[derive(Debug)]
enum TimeControl {
    UltraBullet,
    Bullet,
    Blitz,
    Rapid,
    Classical,
    Correspondence,
}

#[derive(Debug)]
struct TimeControlError;

impl From<NoneError> for TimeControlError {
    fn from(_: NoneError) -> TimeControlError {
        TimeControlError { }
    }
}

impl From<ParseIntegerError> for TimeControlError {
    fn from(_: ParseIntegerError) -> TimeControlError {
        TimeControlError { }
    }
}

impl TimeControl {
    fn from_seconds_and_increment(seconds: u64, increment: u64) -> TimeControl {
        let total = seconds + 40 * increment;

        if total < 30 {
            TimeControl::UltraBullet
        } else if total < 180 {
            TimeControl::Bullet
        } else if total < 480 {
            TimeControl::Blitz
        } else if total < 1500 {
            TimeControl::Rapid
        } else if total < 21_600 {
            TimeControl::Classical
        } else {
            TimeControl::Correspondence
        }
    }

    fn from_bytes(bytes: &[u8]) -> Result<TimeControl, TimeControlError> {
        if bytes == b"-" {
            return Ok(TimeControl::Correspondence);
        }

        let mut parts = bytes.splitn(2, |ch| *ch == b'+');
        let seconds = btoi::btou(parts.next()?)?;
        let increment = btoi::btou(parts.next()?)?;
        Ok(TimeControl::from_seconds_and_increment(seconds, increment))
    }
}

struct Indexer {
    context: String,

    white_elo: i16,
    black_elo: i16,
    time_control: TimeControl,
    skip: bool,

    current_game: Vec<u8>,
    plies: usize,
    standard: bool,

    batch: Vec<u8>,
    batch_size: usize,
}

impl Indexer {
    fn new(context: &str) -> Indexer {
        Indexer {
            context: context.into(),

            white_elo: 0,
            black_elo: 0,
            time_control: TimeControl::Correspondence,
            skip: true,

            current_game: Vec::new(),
            plies: 0,
            standard: true,

            batch: Vec::new(),
            batch_size: 0,
        }
    }

    fn send(&mut self) {
        if self.batch_size > 0 {
            self.batch_size = 0;

            let mut res = reqwest::Client::new()
                .put("http://localhost:9000/import/lichess")
                .body(mem::replace(&mut self.batch, Vec::new()))
                .send().expect("send batch");

            let mut answer = String::new();
            res.read_to_string(&mut answer).expect("decode response");
            println!("{}: {}", self.context, answer);
            assert!(res.status().is_success());
        }
    }
}

impl<'pgn> Visitor<'pgn> for Indexer {
    type Result = ();

    fn begin_game(&mut self) {
        self.current_game.clear();
        self.plies = 0;
    }

    fn begin_headers(&mut self) {
        self.white_elo = 0;
        self.black_elo = 0;
        self.time_control = TimeControl::Correspondence;
        self.standard = true;
    }

    fn header(&mut self, key: &'pgn [u8], value: &'pgn [u8]) {
        if key == b"WhiteElo" {
            self.white_elo = if value == b"?" { 0 } else { btoi::btoi(value).expect("WhiteElo") };
        } else if key == b"BlackElo" {
            self.black_elo = if value == b"?" { 0 } else { btoi::btoi(value).expect("BlackElo") };
        } else if key == b"TimeControl" {
            self.time_control = TimeControl::from_bytes(value).expect("TimeControl");
        } else if key == b"Variant" {
            self.standard = value == b"Standard";
            if self.standard {
                return; // we add this unconditionally later
            }
        }

        let (key, value) = if key == b"Site" {
            (&b"LichessID"[..], value.rsplitn(2, |ch| *ch == b'/').next().expect("Site"))
        } else {
            (key, value)
        };

        self.current_game.push(b'[');
        self.current_game.extend(key);
        self.current_game.extend(b" \"");
        self.current_game.extend(value);
        self.current_game.extend(b"\"]\n");
    }

    fn end_headers(&mut self) -> Skip {
        let rating = (self.white_elo + self.black_elo) / 2;

        let probability = if self.standard {
            self.current_game.extend(b"[Variant \"Standard\"]\n");

            match self.time_control {
                TimeControl::Correspondence | TimeControl::Classical => 1.0,
                TimeControl::Rapid if rating >= 2000 => 1.0,
                TimeControl::Rapid if rating >= 1800 => 2.0 / 5.0,
                TimeControl::Rapid => 1.0 / 8.0,
                TimeControl::Blitz if rating >= 2000 => 1.0,
                TimeControl::Blitz if rating >= 1800 => 1.0 / 4.0,
                TimeControl::Blitz => 1.0 / 15.0,
                TimeControl::Bullet if rating >= 2300 => 1.0,
                TimeControl::Bullet if rating >= 2200 => 4.0 / 5.0,
                TimeControl::Bullet if rating >= 2000 => 1.0 / 4.0,
                TimeControl::Bullet if rating >= 1800 => 1.0 / 7.0,
                _ => 1.0 / 20.0,
            }
        } else {
            if rating >= 1600 { 1.0 } else { 0.5 } // variant games
        };

        self.current_game.push(b'\n');

        let Closed01(rnd) = random::<Closed01<f64>>();
        let accept = min(self.white_elo, self.black_elo) >= 1500 && probability >= rnd;

        self.skip = !accept;
        Skip(self.skip)
    }

    fn san(&mut self, san: San) {
        if self.plies < MAX_PLIES {
            if self.plies > 0 {
                self.current_game.push(b' ');
            }

            self.current_game.extend(san.to_string().as_bytes());
            self.plies += 1;
        }
    }

    fn begin_variation(&mut self) -> Skip {
        Skip(true) // stay in the mainline
    }

    fn end_game(&mut self, _game: &'pgn [u8]) {
        if !self.skip && self.plies > 8 {
            if self.batch_size >= BATCH_SIZE {
                self.send();
            }

            if self.batch_size > 0 {
                self.batch.extend(b"\n\n\n");
            }

            self.batch.extend(&self.current_game);
            self.batch_size += 1;
        }
    }
}

fn main() {
    for arg in env::args().skip(1) {
        eprintln!("% indexing {} ...", arg);
        let file = File::open(&arg).expect("fopen");
        let pgn = unsafe { Mmap::map(&file).expect("mmap") };
        pgn.advise_memory_access(AccessPattern::Sequential).expect("madvise");

        let mut indexer = Indexer::new(&arg);
        Reader::new(&mut indexer, &pgn[..]).read_all();
        indexer.send(); // send last
    }
}
<|endoftext|>


<commit_before>#![no_std]
#![feature(test)]
//#[macro_use]
//extern crate crypto_tests;
extern crate threefish;

extern crate test;
extern crate block_cipher_trait;
extern crate generic_array;

use test::Bencher;
use block_cipher_trait::BlockCipher;
use generic_array::GenericArray;

#[bench]
pub fn encrypt_1_256(bh: &mut Bencher) {
    let key = Default::default();
    let tweak = Default::default();
    let state = threefish::Threefish256::new(&key, &tweak);
    let input = &[1u8; 32];
    let mut output = GenericArray::default();

    bh.iter(|| {
        state.encrypt_block(GenericArray::from_slice(input), &mut output);
    });
    bh.bytes = 32u64;
}

#[bench]
pub fn encrypt_2_512(bh: &mut Bencher) {
    let key = [0u8; 64];
    let tweak = Default::default();
    let state = threefish::Threefish512::new(&key, &tweak);
    let input = &[1u8; 64];
    let mut output = GenericArray::default();

    bh.iter(|| {
        state.encrypt_block(GenericArray::from_slice(input), &mut output);
    });
    bh.bytes = 64u64;
}

#[bench]
pub fn encrypt_3_1024(bh: &mut Bencher) {
    let key = [0u8; 128];
    let tweak = Default::default();
    let state = threefish::Threefish1024::new(&key, &tweak);
    let input = &[1u8; 128];
    let mut output = GenericArray::default();

    bh.iter(|| {
        state.encrypt_block(GenericArray::from_slice(input), &mut output);
    });
    bh.bytes = 128u64;
}
<commit_msg>threefish: fix benches for new API<commit_after>#![no_std]
#![feature(test)]
//#[macro_use]
//extern crate crypto_tests;
extern crate threefish;

extern crate test;
extern crate block_cipher_trait;
extern crate generic_array;

use test::Bencher;
use block_cipher_trait::BlockCipher;
use generic_array::GenericArray;

#[bench]
pub fn encrypt_1_256(bh: &mut Bencher) {
    let key = Default::default();
    let tweak = Default::default();
    let state = threefish::Threefish256::with_tweak(&key, &tweak);
    let input = &[1u8; 32];
    bh.iter(|| {
        state.encrypt_block(mut GenericArray::from_slice(input));
    });
    bh.bytes = 32u64;
}

#[bench]
pub fn encrypt_2_512(bh: &mut Bencher) {
    let key = Default::default();
    let tweak = Default::default();
    let state = threefish::Threefish512::with_tweak(&key, &tweak);
    let input = &[1u8; 64];
    bh.iter(|| {
        state.encrypt_block(mut GenericArray::from_slice(input));
    });
    bh.bytes = 64u64;
}

#[bench]
pub fn encrypt_3_1024(bh: &mut Bencher) {
    let key = Default::default();
    let tweak = Default::default();
    let state = threefish::Threefish1024::with_tweak(&key, &tweak);
    let input = &[1u8; 128];
    bh.iter(|| {
        state.encrypt_block(mut GenericArray::from_slice(input));
    });
    bh.bytes = 128u64;
}
<|endoftext|>


<commit_before>// TODO: Make -w flag work with decimals
// TODO: Support -f flag

// spell-checker:ignore (ToDO) istr chiter argptr ilen

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, AppSettings, Arg};
use num_bigint::BigInt;
use num_traits::One;
use num_traits::Zero;
use num_traits::{Num, ToPrimitive};
use std::cmp;
use std::io::{stdout, ErrorKind, Write};
use std::str::FromStr;

mod digits;
use crate::digits::num_fractional_digits;
use crate::digits::num_integral_digits;

use uucore::display::Quotable;

static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
static OPT_SEPARATOR: &str = "separator";
static OPT_TERMINATOR: &str = "terminator";
static OPT_WIDTHS: &str = "widths";

static ARG_NUMBERS: &str = "numbers";

fn usage() -> String {
    format!(
        "{0} [OPTION]... LAST
    {0} [OPTION]... FIRST LAST
    {0} [OPTION]... FIRST INCREMENT LAST",
        uucore::execution_phrase()
    )
}
#[derive(Clone)]
struct SeqOptions {
    separator: String,
    terminator: String,
    widths: bool,
}

enum Number {
    /// Negative zero, as if it were an integer.
    MinusZero,
    BigInt(BigInt),
    F64(f64),
}

impl Number {
    fn is_zero(&self) -> bool {
        match self {
            Number::MinusZero => true,
            Number::BigInt(n) => n.is_zero(),
            Number::F64(n) => n.is_zero(),
        }
    }

    fn into_f64(self) -> f64 {
        match self {
            Number::MinusZero => -0.,
            // BigInt::to_f64() can not return None.
            Number::BigInt(n) => n.to_f64().unwrap(),
            Number::F64(n) => n,
        }
    }

    /// Convert this number into a bigint, consuming it.
    ///
    /// For floats, this returns the [`BigInt`] corresponding to the
    /// floor of the number.
    fn into_bigint(self) -> BigInt {
        match self {
            Number::MinusZero => BigInt::zero(),
            Number::F64(x) => BigInt::from(x.floor() as i64),
            Number::BigInt(n) => n,
        }
    }
}

impl FromStr for Number {
    type Err = String;
    fn from_str(mut s: &str) -> Result<Self, Self::Err> {
        s = s.trim_start();
        if s.starts_with('+') {
            s = &s[1..];
        }

        match s.parse::<BigInt>() {
            Ok(n) => {
                // If `s` is '-0', then `parse()` returns
                // `BigInt::zero()`, but we need to return
                // `Number::MinusZero` instead.
                if n == BigInt::zero() && s.starts_with('-') {
                    Ok(Number::MinusZero)
                } else {
                    Ok(Number::BigInt(n))
                }
            }
            Err(_) => match s.parse::<f64>() {
                Ok(value) if value.is_nan() => Err(format!(
                    "invalid 'not-a-number' argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                Ok(value) => Ok(Number::F64(value)),
                Err(_) => Err(format!(
                    "invalid floating point argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
            },
        }
    }
}

/// A range of integers.
///
/// The elements are (first, increment, last).
type RangeInt = (BigInt, BigInt, BigInt);

/// A range of f64.
///
/// The elements are (first, increment, last).
type RangeF64 = (f64, f64, f64);

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = usage();
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let numbers = matches.values_of(ARG_NUMBERS).unwrap().collect::<Vec<_>>();

    let options = SeqOptions {
        separator: matches.value_of(OPT_SEPARATOR).unwrap_or("\n").to_string(),
        terminator: matches.value_of(OPT_TERMINATOR).unwrap_or("\n").to_string(),
        widths: matches.is_present(OPT_WIDTHS),
    };

    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if numbers.len() > 1 {
        let slice = numbers[0];
        largest_dec = num_fractional_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        padding = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        crash_if_err!(1, slice.parse())
    } else {
        Number::BigInt(BigInt::one())
    };
    let increment = if numbers.len() > 2 {
        let slice = numbers[1];
        let dec = num_fractional_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        let int_digits = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        largest_dec = cmp::max(largest_dec, dec);
        padding = cmp::max(padding, int_digits);
        crash_if_err!(1, slice.parse())
    } else {
        Number::BigInt(BigInt::one())
    };
    if increment.is_zero() {
        show_error!(
            "invalid Zero increment value: '{}'\nTry '{} --help' for more information.",
            numbers[1],
            uucore::execution_phrase()
        );
        return 1;
    }
    let last: Number = {
        let slice = numbers[numbers.len() - 1];
        let int_digits = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        padding = cmp::max(padding, int_digits);
        crash_if_err!(1, slice.parse())
    };

    let is_negative_zero_f64 = |x: f64| x == -0.0 && x.is_sign_negative() && largest_dec == 0;
    let result = match (first, last, increment) {
        // For example, `seq -0 1 2` or `seq -0 1 2.0`.
        (Number::MinusZero, last, Number::BigInt(increment)) => print_seq_integers(
            (BigInt::zero(), increment, last.into_bigint()),
            options.separator,
            options.terminator,
            options.widths,
            padding,
            true,
        ),
        // For example, `seq -0e0 1 2` or `seq -0e0 1 2.0`.
        (Number::F64(x), last, Number::BigInt(increment)) if is_negative_zero_f64(x) => {
            print_seq_integers(
                (BigInt::zero(), increment, last.into_bigint()),
                options.separator,
                options.terminator,
                options.widths,
                padding,
                true,
            )
        }
        // For example, `seq 0 1 2` or `seq 0 1 2.0`.
        (Number::BigInt(first), last, Number::BigInt(increment)) => print_seq_integers(
            (first, increment, last.into_bigint()),
            options.separator,
            options.terminator,
            options.widths,
            padding,
            false,
        ),
        // For example, `seq 0 0.5 1` or `seq 0.0 0.5 1` or `seq 0.0 0.5 1.0`.
        (first, last, increment) => print_seq(
            (first.into_f64(), increment.into_f64(), last.into_f64()),
            largest_dec,
            options.separator,
            options.terminator,
            options.widths,
            padding,
        ),
    };
    match result {
        Ok(_) => 0,
        Err(err) if err.kind() == ErrorKind::BrokenPipe => 0,
        Err(_) => 1,
    }
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .setting(AppSettings::AllowLeadingHyphen)
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(OPT_SEPARATOR)
                .short("s")
                .long("separator")
                .help("Separator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_TERMINATOR)
                .short("t")
                .long("terminator")
                .help("Terminator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_WIDTHS)
                .short("w")
                .long("widths")
                .help("Equalize widths of all numbers by padding with zeros"),
        )
        .arg(
            Arg::with_name(ARG_NUMBERS)
                .multiple(true)
                .takes_value(true)
                .allow_hyphen_values(true)
                .max_values(3)
                .required(true),
        )
}

fn done_printing<T: Num + PartialOrd>(next: &T, increment: &T, last: &T) -> bool {
    if increment >= &T::zero() {
        next > last
    } else {
        next < last
    }
}

/// Floating point based code path
fn print_seq(
    range: RangeF64,
    largest_dec: usize,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) -> std::io::Result<()> {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let (first, increment, last) = range;
    let mut i = 0isize;
    let is_first_minus_zero = first == -0.0 && first.is_sign_negative();
    let mut value = first + i as f64 * increment;
    let padding = if pad { padding + 1 + largest_dec } else { 0 };
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            write!(stdout, "{}", separator)?;
        }
        let mut width = padding;
        if is_first_iteration && is_first_minus_zero {
            write!(stdout, "-")?;
            width -= 1;
        }
        is_first_iteration = false;
        write!(
            stdout,
            "{value:>0width$.precision$}",
            value = value,
            width = width,
            precision = largest_dec,
        )?;
        i += 1;
        value = first + i as f64 * increment;
    }
    if !is_first_iteration {
        write!(stdout, "{}", terminator)?;
    }
    stdout.flush()?;
    Ok(())
}

/// Print an integer sequence.
///
/// This function prints a sequence of integers defined by `range`,
/// which defines the first integer, last integer, and increment of the
/// range. The `separator` is inserted between each integer and
/// `terminator` is inserted at the end.
///
/// The `pad` parameter indicates whether to pad numbers to the width
/// given in `padding`.
///
/// If `is_first_minus_zero` is `true`, then the `first` parameter is
/// printed as if it were negative zero, even though no such number
/// exists as an integer (negative zero only exists for floating point
/// numbers). Only set this to `true` if `first` is actually zero.
fn print_seq_integers(
    range: RangeInt,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
    is_first_minus_zero: bool,
) -> std::io::Result<()> {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let (first, increment, last) = range;
    let mut value = first;
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            write!(stdout, "{}", separator)?;
        }
        let mut width = padding;
        if is_first_iteration && is_first_minus_zero {
            write!(stdout, "-")?;
            width -= 1;
        }
        is_first_iteration = false;
        if pad {
            write!(stdout, "{number:>0width$}", number = value, width = width)?;
        } else {
            write!(stdout, "{}", value)?;
        }
        value += &increment;
    }

    if !is_first_iteration {
        write!(stdout, "{}", terminator)?;
    }
    Ok(())
}
<commit_msg>seq: Adds hexadecimal integer parsing<commit_after>// TODO: Make -w flag work with decimals
// TODO: Support -f flag

// spell-checker:ignore (ToDO) istr chiter argptr ilen

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, AppSettings, Arg};
use num_bigint::BigInt;
use num_traits::One;
use num_traits::Zero;
use num_traits::{Num, ToPrimitive};
use std::cmp;
use std::io::{stdout, ErrorKind, Write};
use std::str::FromStr;

mod digits;
use crate::digits::num_fractional_digits;
use crate::digits::num_integral_digits;

use uucore::display::Quotable;

static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
static OPT_SEPARATOR: &str = "separator";
static OPT_TERMINATOR: &str = "terminator";
static OPT_WIDTHS: &str = "widths";

static ARG_NUMBERS: &str = "numbers";

fn usage() -> String {
    format!(
        "{0} [OPTION]... LAST
    {0} [OPTION]... FIRST LAST
    {0} [OPTION]... FIRST INCREMENT LAST",
        uucore::execution_phrase()
    )
}
#[derive(Clone)]
struct SeqOptions {
    separator: String,
    terminator: String,
    widths: bool,
}

enum Number {
    /// Negative zero, as if it were an integer.
    MinusZero,
    BigInt(BigInt),
    F64(f64),
}

impl Number {
    fn is_zero(&self) -> bool {
        match self {
            Number::MinusZero => true,
            Number::BigInt(n) => n.is_zero(),
            Number::F64(n) => n.is_zero(),
        }
    }

    fn into_f64(self) -> f64 {
        match self {
            Number::MinusZero => -0.,
            // BigInt::to_f64() can not return None.
            Number::BigInt(n) => n.to_f64().unwrap(),
            Number::F64(n) => n,
        }
    }

    /// Convert this number into a bigint, consuming it.
    ///
    /// For floats, this returns the [`BigInt`] corresponding to the
    /// floor of the number.
    fn into_bigint(self) -> BigInt {
        match self {
            Number::MinusZero => BigInt::zero(),
            Number::F64(x) => BigInt::from(x.floor() as i64),
            Number::BigInt(n) => n,
        }
    }
}

impl FromStr for Number {
    type Err = String;
    fn from_str(mut s: &str) -> Result<Self, Self::Err> {
        s = s.trim_start();
        if s.starts_with('+') {
            s = &s[1..];
        }
        let is_neg = s.starts_with('-');
        let is_hex = {
            // GNU 20.11.2 - Parsing of Floats
            match s.find("0x") {
                Some(i) => (true, i),
                None => match s.find("0X") {
                    Some(i) => (true, i),
                    None => (false, 0),
                },
            }
        };

        match is_hex {
            (true, i) => match i <= 1 {
                false => Err(format!(
                    "invalid hexadecimal argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                true => match &s.as_bytes()[i + 2] {
                    b'-' | b'+' => Err(format!(
                    "invalid hexadecimal argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                    // TODO: hexadecimal floating point parsing (see #2660)
                    b'.' => Err(format!(
                    "NotImplemented: hexadecimal floating point numbers: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                    _ => {
                        let num = BigInt::from_str_radix(&s[i + 2..], 16)
                            .map_err(|_| format!(
                    "invalid hexadecimal argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                ))?;
                        match (is_neg, num == BigInt::zero()) {
                            (true, true) => Ok(Number::MinusZero),
                            (true, false) => Ok(Number::BigInt(-num)),
                            (false, _) => Ok(Number::BigInt(num)),
                        }
                    }
                },
            },
            (false, _) => match s.parse::<BigInt>() {
                Ok(n) => {
                    // If `s` is '-0', then `parse()` returns
                    // `BigInt::zero()`, but we need to return
                    // `Number::MinusZero` instead.
                    if n == BigInt::zero() && is_neg {
                        Ok(Number::MinusZero)
                    } else {
                        Ok(Number::BigInt(n))
                    }
                }
                Err(_) => match s.parse::<f64>() {
                    Ok(value) if value.is_nan() => Err(format!(
                    "invalid 'not-a-number' argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                    Ok(value) => Ok(Number::F64(value)),
                    Err(_) => Err(format!(
                    "invalid floating point argument: {}\nTry '{} --help' for more information.",
                    s.quote(),
                    uucore::execution_phrase(),
                )),
                },
            },
        }
    }
}

/// A range of integers.
///
/// The elements are (first, increment, last).
type RangeInt = (BigInt, BigInt, BigInt);

/// A range of f64.
///
/// The elements are (first, increment, last).
type RangeF64 = (f64, f64, f64);

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = usage();
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let numbers = matches.values_of(ARG_NUMBERS).unwrap().collect::<Vec<_>>();

    let options = SeqOptions {
        separator: matches.value_of(OPT_SEPARATOR).unwrap_or("\n").to_string(),
        terminator: matches.value_of(OPT_TERMINATOR).unwrap_or("\n").to_string(),
        widths: matches.is_present(OPT_WIDTHS),
    };

    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if numbers.len() > 1 {
        let slice = numbers[0];
        largest_dec = num_fractional_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        padding = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        crash_if_err!(1, slice.parse())
    } else {
        Number::BigInt(BigInt::one())
    };
    let increment = if numbers.len() > 2 {
        let slice = numbers[1];
        let dec = num_fractional_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        let int_digits = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        largest_dec = cmp::max(largest_dec, dec);
        padding = cmp::max(padding, int_digits);
        crash_if_err!(1, slice.parse())
    } else {
        Number::BigInt(BigInt::one())
    };
    if increment.is_zero() {
        show_error!(
            "invalid Zero increment value: '{}'\nTry '{} --help' for more information.",
            numbers[1],
            uucore::execution_phrase()
        );
        return 1;
    }
    let last: Number = {
        let slice = numbers[numbers.len() - 1];
        let int_digits = num_integral_digits(slice).unwrap_or_else(|_| {
            crash!(
                1,
                "invalid floating point argument: {}\n Try '{} --help' for more information.",
                slice.quote(),
                uucore::execution_phrase()
            )
        });
        padding = cmp::max(padding, int_digits);
        crash_if_err!(1, slice.parse())
    };

    let is_negative_zero_f64 = |x: f64| x == -0.0 && x.is_sign_negative() && largest_dec == 0;
    let result = match (first, last, increment) {
        // For example, `seq -0 1 2` or `seq -0 1 2.0`.
        (Number::MinusZero, last, Number::BigInt(increment)) => print_seq_integers(
            (BigInt::zero(), increment, last.into_bigint()),
            options.separator,
            options.terminator,
            options.widths,
            padding,
            true,
        ),
        // For example, `seq -0e0 1 2` or `seq -0e0 1 2.0`.
        (Number::F64(x), last, Number::BigInt(increment)) if is_negative_zero_f64(x) => {
            print_seq_integers(
                (BigInt::zero(), increment, last.into_bigint()),
                options.separator,
                options.terminator,
                options.widths,
                padding,
                true,
            )
        }
        // For example, `seq 0 1 2` or `seq 0 1 2.0`.
        (Number::BigInt(first), last, Number::BigInt(increment)) => print_seq_integers(
            (first, increment, last.into_bigint()),
            options.separator,
            options.terminator,
            options.widths,
            padding,
            false,
        ),
        // For example, `seq 0 0.5 1` or `seq 0.0 0.5 1` or `seq 0.0 0.5 1.0`.
        (first, last, increment) => print_seq(
            (first.into_f64(), increment.into_f64(), last.into_f64()),
            largest_dec,
            options.separator,
            options.terminator,
            options.widths,
            padding,
        ),
    };
    match result {
        Ok(_) => 0,
        Err(err) if err.kind() == ErrorKind::BrokenPipe => 0,
        Err(_) => 1,
    }
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(uucore::util_name())
        .setting(AppSettings::AllowLeadingHyphen)
        .version(crate_version!())
        .about(ABOUT)
        .arg(
            Arg::with_name(OPT_SEPARATOR)
                .short("s")
                .long("separator")
                .help("Separator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_TERMINATOR)
                .short("t")
                .long("terminator")
                .help("Terminator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_WIDTHS)
                .short("w")
                .long("widths")
                .help("Equalize widths of all numbers by padding with zeros"),
        )
        .arg(
            Arg::with_name(ARG_NUMBERS)
                .multiple(true)
                .takes_value(true)
                .allow_hyphen_values(true)
                .max_values(3)
                .required(true),
        )
}

fn done_printing<T: Num + PartialOrd>(next: &T, increment: &T, last: &T) -> bool {
    if increment >= &T::zero() {
        next > last
    } else {
        next < last
    }
}

/// Floating point based code path
fn print_seq(
    range: RangeF64,
    largest_dec: usize,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) -> std::io::Result<()> {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let (first, increment, last) = range;
    let mut i = 0isize;
    let is_first_minus_zero = first == -0.0 && first.is_sign_negative();
    let mut value = first + i as f64 * increment;
    let padding = if pad { padding + 1 + largest_dec } else { 0 };
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            write!(stdout, "{}", separator)?;
        }
        let mut width = padding;
        if is_first_iteration && is_first_minus_zero {
            write!(stdout, "-")?;
            width -= 1;
        }
        is_first_iteration = false;
        write!(
            stdout,
            "{value:>0width$.precision$}",
            value = value,
            width = width,
            precision = largest_dec,
        )?;
        i += 1;
        value = first + i as f64 * increment;
    }
    if !is_first_iteration {
        write!(stdout, "{}", terminator)?;
    }
    stdout.flush()?;
    Ok(())
}

/// Print an integer sequence.
///
/// This function prints a sequence of integers defined by `range`,
/// which defines the first integer, last integer, and increment of the
/// range. The `separator` is inserted between each integer and
/// `terminator` is inserted at the end.
///
/// The `pad` parameter indicates whether to pad numbers to the width
/// given in `padding`.
///
/// If `is_first_minus_zero` is `true`, then the `first` parameter is
/// printed as if it were negative zero, even though no such number
/// exists as an integer (negative zero only exists for floating point
/// numbers). Only set this to `true` if `first` is actually zero.
fn print_seq_integers(
    range: RangeInt,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
    is_first_minus_zero: bool,
) -> std::io::Result<()> {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let (first, increment, last) = range;
    let mut value = first;
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            write!(stdout, "{}", separator)?;
        }
        let mut width = padding;
        if is_first_iteration && is_first_minus_zero {
            write!(stdout, "-")?;
            width -= 1;
        }
        is_first_iteration = false;
        if pad {
            write!(stdout, "{number:>0width$}", number = value, width = width)?;
        } else {
            write!(stdout, "{}", value)?;
        }
        value += &increment;
    }

    if !is_first_iteration {
        write!(stdout, "{}", terminator)?;
    }
    Ok(())
}
<|endoftext|>


<commit_before>use elements::{Module, ResizableLimits, MemoryType};

pub struct Error(pub String);

pub fn validate_module(module: &Module) -> Result<(), Error> {
	if let Some(mem_section) = module.memory_section() {
		mem_section
			.entries()
			.iter()
			.map(MemoryType::validate)
			.collect::<Result<_, _>>()?
	}

	Ok(())
}

impl ResizableLimits {
	fn validate(&self) -> Result<(), Error> {
		if let Some(maximum) = self.maximum() {
			if self.initial() > maximum {
				return Err(Error(format!(
					"maximum limit {} is lesser than minimum {}",
					maximum,
					self.initial()
				)));
			}
		}
		Ok(())
	}
}

impl MemoryType {
	fn validate(&self) -> Result<(), Error> {
		self.limits().validate()
	}
}

#[cfg(test)]
mod tests {
	use super::validate_module;
	use builder::module;
	use elements::{BlockType, ExportEntry, External, FunctionType, GlobalEntry, GlobalType,
	               ImportEntry, InitExpr, Internal, MemoryType, Opcode, Opcodes, TableType,
	               ValueType};

	#[test]
	fn empty_is_valid() {
		let module = module().build();
		assert!(validate_module(&module).is_ok());
	}

	#[test]
	fn mem_limits() {
		// min > max
		let m = module()
			.memory()
				.with_min(10)
				.with_max(Some(9))
				.build()
			.build();
		assert!(validate_module(&m).is_err());

		// min = max
		let m = module()
			.memory()
				.with_min(10)
				.with_max(Some(10))
				.build()
			.build();
		assert!(validate_module(&m).is_ok());

		// mod is always valid without max.
		let m = module()
			.memory()
				.with_min(10)
				.build()
			.build();
		assert!(validate_module(&m).is_ok());
	}
}
<commit_msg>Add table validation.<commit_after>use elements::{Module, ResizableLimits, MemoryType, TableType};

pub struct Error(pub String);

pub fn validate_module(module: &Module) -> Result<(), Error> {
	if let Some(mem_section) = module.memory_section() {
		mem_section
			.entries()
			.iter()
			.map(MemoryType::validate)
			.collect::<Result<_, _>>()?
	}

	if let Some(table_section) = module.table_section() {
		table_section
			.entries()
			.iter()
			.map(TableType::validate)
			.collect::<Result<_, _>>()?
	}

	Ok(())
}

impl ResizableLimits {
	fn validate(&self) -> Result<(), Error> {
		if let Some(maximum) = self.maximum() {
			if self.initial() > maximum {
				return Err(Error(format!(
					"maximum limit {} is lesser than minimum {}",
					maximum,
					self.initial()
				)));
			}
		}
		Ok(())
	}
}

impl MemoryType {
	fn validate(&self) -> Result<(), Error> {
		self.limits().validate()
	}
}

impl TableType {
	fn validate(&self) -> Result<(), Error> {
		self.limits().validate()
	}
}

#[cfg(test)]
mod tests {
	use super::validate_module;
	use builder::module;
	use elements::{BlockType, ExportEntry, External, FunctionType, GlobalEntry, GlobalType,
	               ImportEntry, InitExpr, Internal, MemoryType, Opcode, Opcodes, TableType,
	               ValueType};

	#[test]
	fn empty_is_valid() {
		let module = module().build();
		assert!(validate_module(&module).is_ok());
	}

	#[test]
	fn mem_limits() {
		// min > max
		let m = module()
			.memory()
				.with_min(10)
				.with_max(Some(9))
				.build()
			.build();
		assert!(validate_module(&m).is_err());

		// min = max
		let m = module()
			.memory()
				.with_min(10)
				.with_max(Some(10))
				.build()
			.build();
		assert!(validate_module(&m).is_ok());

		// mem is always valid without max.
		let m = module()
			.memory()
				.with_min(10)
				.build()
			.build();
		assert!(validate_module(&m).is_ok());
	}

	#[test]
	fn table_limits() {
		// min > max
		let m = module()
			.table()
				.with_min(10)
				.with_max(Some(9))
				.build()
			.build();
		assert!(validate_module(&m).is_err());

		// min = max
		let m = module()
			.table()
				.with_min(10)
				.with_max(Some(10))
				.build()
			.build();
		assert!(validate_module(&m).is_ok());

		// table is always valid without max.
		let m = module()
			.table()
				.with_min(10)
				.build()
			.build();
		assert!(validate_module(&m).is_ok());
	}
}
<|endoftext|>