<commit_before>use crate::rparser::*;
use crate::{gen_get_variants, Variant};
use dns_parser::Packet;

pub struct DnsUDPBuilder {}
impl RBuilder for DnsUDPBuilder {
    fn build(&self) -> Box<dyn RParser> {
        Box::new(DnsUDPParser::new(b"DNS/UDP"))
    }
    fn get_l4_probe(&self) -> Option<ProbeL4> {
        Some(dns_probe_udp)
    }
}

pub struct DnsUDPParser<'a> {
    _name: Option<&'a [u8]>,

    queries: Vec<String>,

    answers: Vec<String>,
}

impl<'a> DnsUDPParser<'a> {
    pub fn new(name: &[u8]) -> DnsUDPParser {
        DnsUDPParser {
            _name: Some(name),
            queries: Vec::new(),
            answers: Vec::new(),
        }
    }
}

impl<'a> RParser for DnsUDPParser<'a> {
    fn parse_l4(&mut self, data: &[u8], _direction: Direction) -> ParseResult {
        match Packet::parse(data) {
            Ok(pkt) => {
                if pkt.header.query {
                    debug!("DNS query");
                    for q in &pkt.questions {
                        debug!("  query: {}/{:?}", q.qname, q.qtype);
                        self.queries.push(q.qname.to_string());
                        // XXX query type is lost
                    }
                } else {
                    debug!("DNS answer");
                    for answer in &pkt.answers {
                        debug!("  answer: {}/{:?}", answer.name, answer.data);
                        self.answers.push(format!("{:?}", answer.data));
                    }
                }
                // debug!("pkt: {:?}", pkt);
                ParseResult::Ok
            }
            _ => ParseResult::Error,
        }
    }

    gen_get_variants! {DnsUDPParser, "dns.",
        queries => |s| Some(Variant::from_slice(&s.queries)),
        answers => |s| Some(Variant::from_slice(&s.answers)),
    }
}

pub fn dns_probe_udp(i: &[u8], _l4info: &L4Info) -> ProbeResult {
    Packet::parse(i).is_ok().into()
}
<commit_msg>DNS: be stricter when probing (test number of questions/answers)<commit_after>use crate::rparser::*;
use crate::{gen_get_variants, Variant};
use dns_parser::Packet;

pub struct DnsUDPBuilder {}
impl RBuilder for DnsUDPBuilder {
    fn build(&self) -> Box<dyn RParser> {
        Box::new(DnsUDPParser::new(b"DNS/UDP"))
    }
    fn get_l4_probe(&self) -> Option<ProbeL4> {
        Some(dns_probe_udp)
    }
}

pub struct DnsUDPParser<'a> {
    _name: Option<&'a [u8]>,

    queries: Vec<String>,

    answers: Vec<String>,
}

impl<'a> DnsUDPParser<'a> {
    pub fn new(name: &[u8]) -> DnsUDPParser {
        DnsUDPParser {
            _name: Some(name),
            queries: Vec::new(),
            answers: Vec::new(),
        }
    }
}

impl<'a> RParser for DnsUDPParser<'a> {
    fn parse_l4(&mut self, data: &[u8], _direction: Direction) -> ParseResult {
        match Packet::parse(data) {
            Ok(pkt) => {
                if pkt.header.query {
                    debug!("DNS query");
                    for q in &pkt.questions {
                        debug!("  query: {}/{:?}", q.qname, q.qtype);
                        self.queries.push(q.qname.to_string());
                        // XXX query type is lost
                    }
                } else {
                    debug!("DNS answer");
                    for answer in &pkt.answers {
                        debug!("  answer: {}/{:?}", answer.name, answer.data);
                        self.answers.push(format!("{:?}", answer.data));
                    }
                }
                // debug!("pkt: {:?}", pkt);
                ParseResult::Ok
            }
            _ => ParseResult::Error,
        }
    }

    gen_get_variants! {DnsUDPParser, "dns.",
        queries => |s| Some(Variant::from_slice(&s.queries)),
        answers => |s| Some(Variant::from_slice(&s.answers)),
    }
}

pub fn dns_probe_udp(i: &[u8], l4info: &L4Info) -> ProbeResult {
    match Packet::parse(i) {
        Ok(packet) => {
            if packet.header.query {
                if packet.questions.is_empty() {
                    return ProbeResult::NotForUs;
                }
            } else if packet.answers.is_empty() ||
                    // if all of the above is wrong, test port
                    ![53, 5353].contains(&l4info.dst_port)
            {
                return ProbeResult::NotForUs;
            }
            // XXX dns_parser does not return remaining bytes
            ProbeResult::Certain
        }
        _ => ProbeResult::NotForUs,
    }
}
<|endoftext|>


<commit_before>#![feature(conservative_impl_trait)]

#[macro_use]
extern crate lazy_static;

extern crate docopt;
extern crate lalrpop_intern;
extern crate graph_algorithms;
extern crate nll_repr;
extern crate rustc_serialize;

use docopt::Docopt;
use nll_repr::repr::*;
use std::env::args;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::process;

#[macro_use]
mod log;
mod borrowck;
mod env;
use self::env::Environment;
mod infer;
mod loans_in_scope;
mod liveness;
mod graph;
mod region;
mod regionck;
use self::graph::FuncGraph;

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

    for input in &args.arg_inputs {
        match process_input(&args, input) {
            Ok(()) => { }
            Err(err) => {
                println!("{}: {}", input, err);
                process::exit(1);
            }
        }
    }
}

fn process_input(args: &Args, input: &str) -> Result<(), Box<Error>> {
    let mut file_text = String::new();
    let mut file = try!(File::open(input));
    if file.read_to_string(&mut file_text).is_err() {
        return try!(Err(String::from("not UTF-8")));
    }
    let func = try!(Func::parse(&file_text));
    let graph = FuncGraph::new(func);
    graph::with_graph(&graph, || {
        let env = Environment::new(&graph);

        if args.flag_dominators {
            env.dump_dominators();
        }

        println!("Testing `{}`...", input);
        try!(regionck::region_check(&env));
        Ok(())
    })
}

const USAGE: &'static str = "
Usage: nll [options] <inputs>...

Options:
  --help
  --dominators
  --post-dominators
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_inputs: Vec<String>,
    flag_dominators: bool,
    flag_post_dominators: bool,
    flag_help: bool,
}
<commit_msg>print out more than one error<commit_after>#![feature(conservative_impl_trait)]

#[macro_use]
extern crate lazy_static;

extern crate docopt;
extern crate lalrpop_intern;
extern crate graph_algorithms;
extern crate nll_repr;
extern crate rustc_serialize;

use docopt::Docopt;
use nll_repr::repr::*;
use std::env::args;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::process;

#[macro_use]
mod log;
mod borrowck;
mod env;
use self::env::Environment;
mod infer;
mod loans_in_scope;
mod liveness;
mod graph;
mod region;
mod regionck;
use self::graph::FuncGraph;

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

    let mut errors = 0;
    for input in &args.arg_inputs {
        match process_input(&args, input) {
            Ok(()) => { }
            Err(err) => {
                println!("{}: {}", input, err);
                errors += 1;
            }
        }
    }
    if errors > 0 {
        process::exit(1);
    }
}

fn process_input(args: &Args, input: &str) -> Result<(), Box<Error>> {
    let mut file_text = String::new();
    let mut file = try!(File::open(input));
    if file.read_to_string(&mut file_text).is_err() {
        return try!(Err(String::from("not UTF-8")));
    }
    let func = try!(Func::parse(&file_text));
    let graph = FuncGraph::new(func);
    graph::with_graph(&graph, || {
        let env = Environment::new(&graph);

        if args.flag_dominators {
            env.dump_dominators();
        }

        println!("Testing `{}`...", input);
        try!(regionck::region_check(&env));
        Ok(())
    })
}

const USAGE: &'static str = "
Usage: nll [options] <inputs>...

Options:
  --help
  --dominators
  --post-dominators
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_inputs: Vec<String>,
    flag_dominators: bool,
    flag_post_dominators: bool,
    flag_help: bool,
}
<|endoftext|>


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

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

pub use self::lua::lua_Alloc;
pub use self::lua::lua_CFunction;
pub use self::lua::lua_Ctx;
pub use self::lua::lua_Debug;
pub use self::lua::lua_Hook;
pub use self::lua::lua_Integer;
pub use self::lua::lua_KFunction;
pub use self::lua::lua_Number;
pub use self::lua::lua_Reader;
pub use self::lua::lua_State;
pub use self::lua::lua_Unsigned;
pub use self::lua::lua_Writer;

pub use self::lua::lua_absindex;
pub use self::lua::lua_arith;
pub use self::lua::lua_atpanic;
pub use self::lua::lua_call;
pub use self::lua::lua_callk;
pub use self::lua::lua_checkstack;
pub use self::lua::lua_close;
pub use self::lua::lua_compare;
pub use self::lua::lua_concat;
pub use self::lua::lua_copy;
pub use self::lua::lua_createtable;
pub use self::lua::lua_dump;
pub use self::lua::lua_error;
pub use self::lua::lua_gc;
pub use self::lua::lua_getallocf;
pub use self::lua::lua_getextraspace;
pub use self::lua::lua_getfield;
pub use self::lua::lua_getglobal;
pub use self::lua::lua_gethook;
pub use self::lua::lua_gethookcount;
pub use self::lua::lua_gethookmask;
pub use self::lua::lua_getinfo;
pub use self::lua::lua_getlocal;
pub use self::lua::lua_getmetatable;
pub use self::lua::lua_getstack;
pub use self::lua::lua_gettable;
pub use self::lua::lua_gettop;
pub use self::lua::lua_getupvalue;
pub use self::lua::lua_getuservalue;
pub use self::lua::lua_insert;
pub use self::lua::lua_isboolean;
pub use self::lua::lua_iscfunction;
pub use self::lua::lua_isfunction;
pub use self::lua::lua_isinteger;
pub use self::lua::lua_islightuserdata;
pub use self::lua::lua_isnil;
pub use self::lua::lua_isnone;
pub use self::lua::lua_isnoneornil;
pub use self::lua::lua_isnumber;
pub use self::lua::lua_isstring;
pub use self::lua::lua_istable;
pub use self::lua::lua_isthread;
pub use self::lua::lua_isuserdata;
pub use self::lua::lua_isyieldable;
pub use self::lua::lua_len;
pub use self::lua::lua_load;
pub use self::lua::lua_newstate;
pub use self::lua::lua_newtable;
pub use self::lua::lua_newthread;
pub use self::lua::lua_newuserdata;
pub use self::lua::lua_next;
pub use self::luaconf::lua_numtointeger;
pub use self::lua::lua_pcall;
pub use self::lua::lua_pcallk;
pub use self::lua::lua_pop;
pub use self::lua::lua_pushboolean;
pub use self::lua::lua_pushcclosure;
pub use self::lua::lua_pushcfunction;
pub use self::lua::lua_pushfstring;
pub use self::lua::lua_pushglobaltable;
pub use self::lua::lua_pushinteger;
pub use self::lua::lua_pushlightuserdata;
pub use self::lua::lua_pushliteral;
pub use self::lua::lua_pushlstring;
pub use self::lua::lua_pushnil;
pub use self::lua::lua_pushnumber;
pub use self::lua::lua_pushstring;
pub use self::lua::lua_pushthread;
pub use self::lua::lua_pushvalue;
//pub use self::lua::lua_pushvfstring; -- not implemented
pub use self::lua::lua_rawequal;
pub use self::lua::lua_rawget;
pub use self::lua::lua_rawgeti;
pub use self::lua::lua_rawgetp;
pub use self::lua::lua_rawlen;
pub use self::lua::lua_rawset;
pub use self::lua::lua_rawseti;
pub use self::lua::lua_rawsetp;
pub use self::lua::lua_register;
pub use self::lua::lua_remove;
pub use self::lua::lua_replace;
pub use self::lua::lua_resume;
pub use self::lua::lua_rotate;
pub use self::lua::lua_setallocf;
pub use self::lua::lua_setfield;
pub use self::lua::lua_setglobal;
pub use self::lua::lua_sethook;
pub use self::lua::lua_setlocal;
pub use self::lua::lua_setmetatable;
pub use self::lua::lua_settable;
pub use self::lua::lua_settop;
pub use self::lua::lua_setupvalue;
pub use self::lua::lua_setuservalue;
pub use self::lua::lua_status;
pub use self::lua::lua_strtonum;
pub use self::lua::lua_toboolean;
pub use self::lua::lua_tocfunction;
pub use self::lua::lua_tointeger;
pub use self::lua::lua_tointegerx;
pub use self::lua::lua_tolstring;
pub use self::lua::lua_tonumber;
pub use self::lua::lua_tonumberx;
pub use self::lua::lua_topointer;
pub use self::lua::lua_tostring;
pub use self::lua::lua_tothread;
pub use self::lua::lua_touserdata;
pub use self::lua::lua_type;
pub use self::lua::lua_typename;
pub use self::lua::lua_upvalueid;
pub use self::lua::lua_upvalueindex;
pub use self::lua::lua_upvaluejoin;
pub use self::lua::lua_version;
pub use self::lua::lua_xmove;
pub use self::lua::lua_yield;
pub use self::lua::lua_yieldk;

pub use self::lauxlib::luaL_Buffer;
pub use self::lauxlib::luaL_Reg;
pub use self::lauxlib::luaL_Stream;

pub use self::lauxlib::luaL_addchar;
pub use self::lauxlib::luaL_addlstring;
pub use self::lauxlib::luaL_addsize;
pub use self::lauxlib::luaL_addstring;
pub use self::lauxlib::luaL_addvalue;
pub use self::lauxlib::luaL_argcheck;
pub use self::lauxlib::luaL_argerror;
pub use self::lauxlib::luaL_buffinit;
pub use self::lauxlib::luaL_buffinitsize;
pub use self::lauxlib::luaL_callmeta;
pub use self::lauxlib::luaL_checkany;
pub use self::lauxlib::luaL_checkint;
pub use self::lauxlib::luaL_checkinteger;
pub use self::lauxlib::luaL_checklong;
pub use self::lauxlib::luaL_checklstring;
pub use self::lauxlib::luaL_checknumber;
pub use self::lauxlib::luaL_checkoption;
pub use self::lauxlib::luaL_checkstack;
pub use self::lauxlib::luaL_checkstring;
pub use self::lauxlib::luaL_checktype;
pub use self::lauxlib::luaL_checkudata;
pub use self::lauxlib::luaL_checkversion;
pub use self::lauxlib::luaL_dofile;
pub use self::lauxlib::luaL_dostring;
pub use self::lauxlib::luaL_error;
pub use self::lauxlib::luaL_execresult;
pub use self::lauxlib::luaL_fileresult;
pub use self::lauxlib::luaL_getmetafield;
pub use self::lauxlib::luaL_getmetatable;
pub use self::lauxlib::luaL_getsubtable;
pub use self::lauxlib::luaL_gsub;
pub use self::lauxlib::luaL_len;
pub use self::lauxlib::luaL_loadbuffer;
pub use self::lauxlib::luaL_loadbufferx;
pub use self::lauxlib::luaL_loadfile;
pub use self::lauxlib::luaL_loadfilex;
pub use self::lauxlib::luaL_loadstring;
pub use self::lauxlib::luaL_newlib;
pub use self::lauxlib::luaL_newlibtable;
pub use self::lauxlib::luaL_newmetatable;
pub use self::lauxlib::luaL_newstate;
pub use self::lualib::luaL_openlibs;
pub use self::lauxlib::luaL_optint;
pub use self::lauxlib::luaL_optinteger;
pub use self::lauxlib::luaL_optlong;
pub use self::lauxlib::luaL_optlstring;
pub use self::lauxlib::luaL_optnumber;
pub use self::lauxlib::luaL_optstring;
pub use self::lauxlib::luaL_prepbuffer;
pub use self::lauxlib::luaL_prepbuffsize;
pub use self::lauxlib::luaL_pushresult;
pub use self::lauxlib::luaL_pushresultsize;
pub use self::lauxlib::luaL_ref;
pub use self::lauxlib::luaL_requiref;
pub use self::lauxlib::luaL_setfuncs;
pub use self::lauxlib::luaL_setmetatable;
pub use self::lauxlib::luaL_testudata;
pub use self::lauxlib::luaL_tolstring;
pub use self::lauxlib::luaL_traceback;
pub use self::lauxlib::luaL_typename;
pub use self::lauxlib::luaL_unref;
pub use self::lauxlib::luaL_where;

// commonly used constants from lua.h
pub use self::lua::LUA_MULTRET;
pub use self::lua::LUA_REGISTRYINDEX;

pub use self::lua::{LUA_RIDX_MAINTHREAD, LUA_RIDX_GLOBALS};

pub use self::lua::{LUA_OPADD, LUA_OPSUB, LUA_OPMUL, LUA_OPDIV, LUA_OPIDIV};
pub use self::lua::{LUA_OPMOD, LUA_OPPOW, LUA_OPUNM};
pub use self::lua::{LUA_OPBNOT, LUA_OPBAND, LUA_OPBOR, LUA_OPBXOR, LUA_OPSHL, LUA_OPSHR};
pub use self::lua::{LUA_OPEQ, LUA_OPLT, LUA_OPLE};

pub use self::lua::{LUA_OK, LUA_ERRRUN, LUA_ERRMEM, LUA_ERRERR, LUA_ERRGCMM};

pub use self::lua::{LUA_TNONE, LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING};
pub use self::lua::{LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, LUA_TLIGHTUSERDATA};

pub use self::lua::{LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_HOOKLINE, LUA_HOOKCOUNT};

pub use self::lua::{LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCCOUNTB};
pub use self::lua::{LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCISRUNNING};

// constants from lauxlib.h
pub use self::lauxlib::{LUA_REFNIL, LUA_NOREF};

mod glue;
pub mod luaconf;
pub mod lua;
pub mod lauxlib;
pub mod lualib;

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

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

pub use self::lua::lua_Alloc;
pub use self::lua::lua_CFunction;
pub use self::lua::lua_Ctx;
pub use self::lua::lua_Debug;
pub use self::lua::lua_Hook;
pub use self::lua::lua_Integer;
pub use self::lua::lua_KFunction;
pub use self::lua::lua_Number;
pub use self::lua::lua_Reader;
pub use self::lua::lua_State;
pub use self::lua::lua_Unsigned;
pub use self::lua::lua_Writer;

pub use self::lua::lua_absindex;
pub use self::lua::lua_arith;
pub use self::lua::lua_atpanic;
pub use self::lua::lua_call;
pub use self::lua::lua_callk;
pub use self::lua::lua_checkstack;
pub use self::lua::lua_close;
pub use self::lua::lua_compare;
pub use self::lua::lua_concat;
pub use self::lua::lua_copy;
pub use self::lua::lua_createtable;
pub use self::lua::lua_dump;
pub use self::lua::lua_error;
pub use self::lua::lua_gc;
pub use self::lua::lua_getallocf;
pub use self::lua::lua_getextraspace;
pub use self::lua::lua_getfield;
pub use self::lua::lua_getglobal;
pub use self::lua::lua_gethook;
pub use self::lua::lua_gethookcount;
pub use self::lua::lua_gethookmask;
pub use self::lua::lua_getinfo;
pub use self::lua::lua_getlocal;
pub use self::lua::lua_getmetatable;
pub use self::lua::lua_getstack;
pub use self::lua::lua_gettable;
pub use self::lua::lua_gettop;
pub use self::lua::lua_getupvalue;
pub use self::lua::lua_getuservalue;
pub use self::lua::lua_insert;
pub use self::lua::lua_isboolean;
pub use self::lua::lua_iscfunction;
pub use self::lua::lua_isfunction;
pub use self::lua::lua_isinteger;
pub use self::lua::lua_islightuserdata;
pub use self::lua::lua_isnil;
pub use self::lua::lua_isnone;
pub use self::lua::lua_isnoneornil;
pub use self::lua::lua_isnumber;
pub use self::lua::lua_isstring;
pub use self::lua::lua_istable;
pub use self::lua::lua_isthread;
pub use self::lua::lua_isuserdata;
pub use self::lua::lua_isyieldable;
pub use self::lua::lua_len;
pub use self::lua::lua_load;
pub use self::lua::lua_newstate;
pub use self::lua::lua_newtable;
pub use self::lua::lua_newthread;
pub use self::lua::lua_newuserdata;
pub use self::lua::lua_next;
pub use self::luaconf::lua_numtointeger;
pub use self::lua::lua_pcall;
pub use self::lua::lua_pcallk;
pub use self::lua::lua_pop;
pub use self::lua::lua_pushboolean;
pub use self::lua::lua_pushcclosure;
pub use self::lua::lua_pushcfunction;
pub use self::lua::lua_pushfstring;
pub use self::lua::lua_pushglobaltable;
pub use self::lua::lua_pushinteger;
pub use self::lua::lua_pushlightuserdata;
pub use self::lua::lua_pushliteral;
pub use self::lua::lua_pushlstring;
pub use self::lua::lua_pushnil;
pub use self::lua::lua_pushnumber;
pub use self::lua::lua_pushstring;
pub use self::lua::lua_pushthread;
pub use self::lua::lua_pushvalue;
//pub use self::lua::lua_pushvfstring; -- not implemented
pub use self::lua::lua_rawequal;
pub use self::lua::lua_rawget;
pub use self::lua::lua_rawgeti;
pub use self::lua::lua_rawgetp;
pub use self::lua::lua_rawlen;
pub use self::lua::lua_rawset;
pub use self::lua::lua_rawseti;
pub use self::lua::lua_rawsetp;
pub use self::lua::lua_register;
pub use self::lua::lua_remove;
pub use self::lua::lua_replace;
pub use self::lua::lua_resume;
pub use self::lua::lua_rotate;
pub use self::lua::lua_setallocf;
pub use self::lua::lua_setfield;
pub use self::lua::lua_setglobal;
pub use self::lua::lua_sethook;
pub use self::lua::lua_setlocal;
pub use self::lua::lua_setmetatable;
pub use self::lua::lua_settable;
pub use self::lua::lua_settop;
pub use self::lua::lua_setupvalue;
pub use self::lua::lua_setuservalue;
pub use self::lua::lua_status;
pub use self::lua::lua_strtonum;
pub use self::lua::lua_toboolean;
pub use self::lua::lua_tocfunction;
pub use self::lua::lua_tointeger;
pub use self::lua::lua_tointegerx;
pub use self::lua::lua_tolstring;
pub use self::lua::lua_tonumber;
pub use self::lua::lua_tonumberx;
pub use self::lua::lua_topointer;
pub use self::lua::lua_tostring;
pub use self::lua::lua_tothread;
pub use self::lua::lua_touserdata;
pub use self::lua::lua_type;
pub use self::lua::lua_typename;
pub use self::lua::lua_upvalueid;
pub use self::lua::lua_upvalueindex;
pub use self::lua::lua_upvaluejoin;
pub use self::lua::lua_version;
pub use self::lua::lua_xmove;
pub use self::lua::lua_yield;
pub use self::lua::lua_yieldk;

pub use self::lauxlib::luaL_Buffer;
pub use self::lauxlib::luaL_Reg;
pub use self::lauxlib::luaL_Stream;

pub use self::lauxlib::luaL_addchar;
pub use self::lauxlib::luaL_addlstring;
pub use self::lauxlib::luaL_addsize;
pub use self::lauxlib::luaL_addstring;
pub use self::lauxlib::luaL_addvalue;
pub use self::lauxlib::luaL_argcheck;
pub use self::lauxlib::luaL_argerror;
pub use self::lauxlib::luaL_buffinit;
pub use self::lauxlib::luaL_buffinitsize;
pub use self::lauxlib::luaL_callmeta;
pub use self::lauxlib::luaL_checkany;
pub use self::lauxlib::luaL_checkint;
pub use self::lauxlib::luaL_checkinteger;
pub use self::lauxlib::luaL_checklong;
pub use self::lauxlib::luaL_checklstring;
pub use self::lauxlib::luaL_checknumber;
pub use self::lauxlib::luaL_checkoption;
pub use self::lauxlib::luaL_checkstack;
pub use self::lauxlib::luaL_checkstring;
pub use self::lauxlib::luaL_checktype;
pub use self::lauxlib::luaL_checkudata;
pub use self::lauxlib::luaL_checkversion;
pub use self::lauxlib::luaL_dofile;
pub use self::lauxlib::luaL_dostring;
pub use self::lauxlib::luaL_error;
pub use self::lauxlib::luaL_execresult;
pub use self::lauxlib::luaL_fileresult;
pub use self::lauxlib::luaL_getmetafield;
pub use self::lauxlib::luaL_getmetatable;
pub use self::lauxlib::luaL_getsubtable;
pub use self::lauxlib::luaL_gsub;
pub use self::lauxlib::luaL_len;
pub use self::lauxlib::luaL_loadbuffer;
pub use self::lauxlib::luaL_loadbufferx;
pub use self::lauxlib::luaL_loadfile;
pub use self::lauxlib::luaL_loadfilex;
pub use self::lauxlib::luaL_loadstring;
pub use self::lauxlib::luaL_newlib;
pub use self::lauxlib::luaL_newlibtable;
pub use self::lauxlib::luaL_newmetatable;
pub use self::lauxlib::luaL_newstate;
pub use self::lualib::luaL_openlibs;
pub use self::lauxlib::luaL_optint;
pub use self::lauxlib::luaL_optinteger;
pub use self::lauxlib::luaL_optlong;
pub use self::lauxlib::luaL_optlstring;
pub use self::lauxlib::luaL_optnumber;
pub use self::lauxlib::luaL_optstring;
pub use self::lauxlib::luaL_prepbuffer;
pub use self::lauxlib::luaL_prepbuffsize;
pub use self::lauxlib::luaL_pushresult;
pub use self::lauxlib::luaL_pushresultsize;
pub use self::lauxlib::luaL_ref;
pub use self::lauxlib::luaL_requiref;
pub use self::lauxlib::luaL_setfuncs;
pub use self::lauxlib::luaL_setmetatable;
pub use self::lauxlib::luaL_testudata;
pub use self::lauxlib::luaL_tolstring;
pub use self::lauxlib::luaL_traceback;
pub use self::lauxlib::luaL_typename;
pub use self::lauxlib::luaL_unref;
pub use self::lauxlib::luaL_where;

// commonly used constants from lua.h
pub use self::lua::LUA_MULTRET;
pub use self::lua::LUA_REGISTRYINDEX;

pub use self::lua::{LUA_RIDX_MAINTHREAD, LUA_RIDX_GLOBALS};

pub use self::lua::{LUA_OPADD, LUA_OPSUB, LUA_OPMUL, LUA_OPDIV, LUA_OPIDIV};
pub use self::lua::{LUA_OPMOD, LUA_OPPOW, LUA_OPUNM};
pub use self::lua::{LUA_OPBNOT, LUA_OPBAND, LUA_OPBOR, LUA_OPBXOR, LUA_OPSHL, LUA_OPSHR};
pub use self::lua::{LUA_OPEQ, LUA_OPLT, LUA_OPLE};

pub use self::lua::{LUA_OK, LUA_ERRRUN, LUA_ERRMEM, LUA_ERRERR, LUA_ERRGCMM};

pub use self::lua::{LUA_TNONE, LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING};
pub use self::lua::{LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, LUA_TLIGHTUSERDATA};

pub use self::lua::{LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_HOOKLINE, LUA_HOOKCOUNT};

pub use self::lua::{LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCCOUNTB};
pub use self::lua::{LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCISRUNNING};

// constants from lauxlib.h
pub use self::lauxlib::{LUA_REFNIL, LUA_NOREF};
pub use self::lauxlib::LUA_ERRFILE;

mod glue;
pub mod luaconf;
pub mod lua;
pub mod lauxlib;
pub mod lualib;

<|endoftext|>


<commit_before>extern crate chess_move_gen;

use chess_move_gen::*;

#[test]
fn basic_functionality() {
    let mut counter = MoveCounter::new();
    let position = Position::from_fen(STARTING_POSITION_FEN).unwrap();

    let in_check = legal_moves(&position, &mut counter);
    assert!(!in_check);

    assert_eq!(counter.moves, 20);
    assert_eq!(counter.captures, 0);
    assert_eq!(counter.castles, 0);
    assert_eq!(counter.ep_captures, 0);
    assert_eq!(counter.promotions, 0);
}
<commit_msg>remove unrequired extern crate<commit_after>use chess_move_gen::*;

#[test]
fn basic_functionality() {
    let mut counter = MoveCounter::new();
    let position = Position::from_fen(STARTING_POSITION_FEN).unwrap();

    let in_check = legal_moves(&position, &mut counter);
    assert!(!in_check);

    assert_eq!(counter.moves, 20);
    assert_eq!(counter.captures, 0);
    assert_eq!(counter.castles, 0);
    assert_eq!(counter.ep_captures, 0);
    assert_eq!(counter.promotions, 0);
}
<|endoftext|>


<commit_before>use criterion::*;
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::DefaultHasher;
use ahash::{AHasher};
use fxhash::{FxHasher};
use t1ha::T1haBuildHasher;

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn aeshash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn aeshash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be enabled")
}

#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn fallbackhash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn fallbackhash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be disabled")
}

fn fnvhash<H: Hash>(b: H) -> u64 {
    let mut hasher = fnv::FnvHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn t1ha<H: Hash>(b: H) -> u64 {
    let mut hasher = builder.build_hasher();
    b.hash(&mut hasher);
    hasher.finish()
}

fn siphash<H: Hash>(b: H) -> u64 {
    let mut hasher = DefaultHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn fxhash<H: Hash>(b: H) -> u64 {
    let mut hasher = FxHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn seahash<H: Hash>(b: H) -> u64 {
    let mut hasher = seahash::SeaHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

const STRING_LENGTHS: [u32; 11] = [1, 3, 4, 7, 8, 15, 16, 24, 68, 132, 1024];

fn gen_strings() -> Vec<String> {
    STRING_LENGTHS.iter().map(|len| {
        let mut string = String::default();
        for pos in 1..=*len {
            let c = (48 + (pos % 10) as u8) as char;
            string.push(c);
        }
        string
    }).collect()

}

const U8_VALUES: [u8; 1] = [8];
const U16_VALUES: [u16; 1] = [16];
const U32_VALUES: [u32; 1] = [32];
const U64_VALUES: [u64; 1] = [64];
const U128_VALUES: [u128; 1] = [128];

fn bench_ahash(c: &mut Criterion) {
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(aeshash(&s))), &U8_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(aeshash(&s))), &U16_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(aeshash(&s))), &U32_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(aeshash(&s))), &U64_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(aeshash(&s))), &U128_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(&s))), gen_strings()),
    );
}

fn bench_fallback(c: &mut Criterion) {
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(&s))), gen_strings()),
    );
}

fn bench_fx(c: &mut Criterion) {
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fxhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fxhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fxhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fxhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fxhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(&s))), gen_strings()),
    );
}

fn bench_fnv(c: &mut Criterion) {
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fnvhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fnvhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fnvhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fnvhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fnvhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(&s))), gen_strings()),
    );
}

fn bench_sea(c: &mut Criterion) {
    c.bench(
        "sea",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(&s))), gen_strings()),
    );
}

fn bench_t1ha(c: &mut Criterion) {
    c.bench(
        "t1ha",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(t1ha(&s))), gen_strings()),
    );
}

fn bench_sip(c: &mut Criterion) {
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(siphash(&s))), &U8_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(siphash(&s))), &U16_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(siphash(&s))), &U32_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(siphash(&s))), &U64_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(siphash(&s))), &U128_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(&s))), gen_strings()),
    );
}

criterion_main!(benches);
criterion_group!(benches, bench_ahash, bench_fallback, bench_fx, bench_fnv, bench_sea, bench_t1ha, bench_sip);
<commit_msg>Fix compile error<commit_after>use criterion::*;
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::DefaultHasher;
use ahash::{AHasher};
use fxhash::{FxHasher};
use t1ha::T1haBuildHasher;

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn aeshash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn aeshash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be enabled")
}

#[cfg(not(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes")))]
fn fallbackhash<H: Hash>(b: H) -> u64 {
    let mut hasher = AHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes"))]
fn fallbackhash<H: Hash>(_b: H) -> u64 {
    panic!("aes must be disabled")
}

fn fnvhash<H: Hash>(b: H) -> u64 {
    let mut hasher = fnv::FnvHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn t1ha<H: Hash>(b: H) -> u64 {
    let mut hasher = T1haBuildHasher::default().build_hasher();
    b.hash(&mut hasher);
    hasher.finish()
}

fn siphash<H: Hash>(b: H) -> u64 {
    let mut hasher = DefaultHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn fxhash<H: Hash>(b: H) -> u64 {
    let mut hasher = FxHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

fn seahash<H: Hash>(b: H) -> u64 {
    let mut hasher = seahash::SeaHasher::default();
    b.hash(&mut hasher);
    hasher.finish()
}

const STRING_LENGTHS: [u32; 11] = [1, 3, 4, 7, 8, 15, 16, 24, 68, 132, 1024];

fn gen_strings() -> Vec<String> {
    STRING_LENGTHS.iter().map(|len| {
        let mut string = String::default();
        for pos in 1..=*len {
            let c = (48 + (pos % 10) as u8) as char;
            string.push(c);
        }
        string
    }).collect()

}

const U8_VALUES: [u8; 1] = [8];
const U16_VALUES: [u16; 1] = [16];
const U32_VALUES: [u32; 1] = [32];
const U64_VALUES: [u64; 1] = [64];
const U128_VALUES: [u128; 1] = [128];

fn bench_ahash(c: &mut Criterion) {
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(aeshash(&s))), &U8_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(aeshash(&s))), &U16_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(aeshash(&s))), &U32_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(aeshash(&s))), &U64_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(aeshash(&s))), &U128_VALUES),
    );
    c.bench(
        "aeshash",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(aeshash(&s))), gen_strings()),
    );
}

fn bench_fallback(c: &mut Criterion) {
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fallbackhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fallback",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fallbackhash(&s))), gen_strings()),
    );
}

fn bench_fx(c: &mut Criterion) {
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fxhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fxhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fxhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fxhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fxhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fx",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fxhash(&s))), gen_strings()),
    );
}

fn bench_fnv(c: &mut Criterion) {
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(fnvhash(&s))), &U8_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(fnvhash(&s))), &U16_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(fnvhash(&s))), &U32_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(fnvhash(&s))), &U64_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(fnvhash(&s))), &U128_VALUES),
    );
    c.bench(
        "fnv",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(fnvhash(&s))), gen_strings()),
    );
}

fn bench_sea(c: &mut Criterion) {
    c.bench(
        "sea",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(seahash(&s))), gen_strings()),
    );
}

fn bench_t1ha(c: &mut Criterion) {
    c.bench(
        "t1ha",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(t1ha(&s))), gen_strings()),
    );
}

fn bench_sip(c: &mut Criterion) {
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u8", |b, s| b.iter(|| black_box(siphash(&s))), &U8_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u16", |b, s| b.iter(|| black_box(siphash(&s))), &U16_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u32", |b, s| b.iter(|| black_box(siphash(&s))), &U32_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u64", |b, s| b.iter(|| black_box(siphash(&s))), &U64_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("u128", |b, s| b.iter(|| black_box(siphash(&s))), &U128_VALUES),
    );
    c.bench(
        "sip",
        ParameterizedBenchmark::new("string", |b, s| b.iter(|| black_box(siphash(&s))), gen_strings()),
    );
}

criterion_main!(benches);
criterion_group!(benches, bench_ahash, bench_fallback, bench_fx, bench_fnv, bench_sea, bench_t1ha, bench_sip);
<|endoftext|>


<commit_before>extern crate bytecount;
#[macro_use]
extern crate quickcheck;
extern crate rand;

use std::iter;
use bytecount::{
    count, naive_count,
    num_chars, naive_num_chars,
};
use rand::RngCore;

fn random_bytes(len: usize) -> Vec<u8> {
    let mut result = vec![0; len];
    rand::thread_rng().fill_bytes(&mut result);
    result
}

quickcheck! {
    fn check_count_correct(x: (Vec<u8>, u8)) -> bool {
        let (haystack, needle) = x;
        count(&haystack, needle) == naive_count(&haystack, needle)
    }
}

#[test]
fn check_count_large() {
    let haystack = vec![0u8; 10_000_000];
    assert_eq!(naive_count(&haystack, 0), count(&haystack, 0));
    assert_eq!(naive_count(&haystack, 1), count(&haystack, 1));
}

#[test]
fn check_count_large_rand() {
    let haystack = random_bytes(100_000);
    for i in (0..255).chain(iter::once(255)) {
        assert_eq!(naive_count(&haystack, i), count(&haystack, i));
    }
}

#[test]
fn check_count_some() {
    let haystack = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68];
    let needle = 68;
    assert_eq!(count(&haystack, needle), naive_count(&haystack, needle));
}

#[test]
fn check_count_overflow() {
    let haystack = vec![0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    let needle = 2;
    assert_eq!(count(&haystack, needle), naive_count(&haystack, needle));
}

quickcheck! {
    fn check_num_chars_correct(haystack: Vec<u8>) -> bool {
        num_chars(&haystack) == naive_num_chars(&haystack)
    }
}

#[test]
fn check_num_chars_large() {
    let haystack = vec![0u8; 10_000_000];
    assert_eq!(naive_num_chars(&haystack), num_chars(&haystack));
    assert_eq!(naive_num_chars(&haystack), num_chars(&haystack));
}

#[test]
fn check_num_chars_some() {
    let haystack = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68];
    assert_eq!(num_chars(&haystack), naive_num_chars(&haystack));
}

#[test]
fn check_num_chars_overflow() {
    let haystack = vec![0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    assert_eq!(num_chars(&haystack), naive_num_chars(&haystack));
}
<commit_msg>tweak test sizes in Miri<commit_after>extern crate bytecount;
#[macro_use]
extern crate quickcheck;
extern crate rand;

use std::iter;
use bytecount::{
    count, naive_count,
    num_chars, naive_num_chars,
};
use rand::RngCore;

fn random_bytes(len: usize) -> Vec<u8> {
    let mut result = vec![0; len];
    rand::thread_rng().fill_bytes(&mut result);
    result
}

quickcheck! {
    fn check_count_correct(x: (Vec<u8>, u8)) -> bool {
        let (haystack, needle) = x;
        count(&haystack, needle) == naive_count(&haystack, needle)
    }
}

#[test]
fn check_count_large() {
    let haystack = vec![0u8; if cfg!(miri) { 2_000 } else { 10_000_000 }];
    assert_eq!(naive_count(&haystack, 0), count(&haystack, 0));
    assert_eq!(naive_count(&haystack, 1), count(&haystack, 1));
}

#[test]
fn check_count_large_rand() {
    let haystack = random_bytes(if cfg!(miri) { 200 } else { 100_000 });
    for i in (0..255).chain(iter::once(255)) {
        assert_eq!(naive_count(&haystack, i), count(&haystack, i));
    }
}

#[test]
fn check_count_some() {
    let haystack = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68];
    let needle = 68;
    assert_eq!(count(&haystack, needle), naive_count(&haystack, needle));
}

#[test]
fn check_count_overflow() {
    let haystack = vec![0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    let needle = 2;
    assert_eq!(count(&haystack, needle), naive_count(&haystack, needle));
}

quickcheck! {
    fn check_num_chars_correct(haystack: Vec<u8>) -> bool {
        num_chars(&haystack) == naive_num_chars(&haystack)
    }
}

#[test]
fn check_num_chars_large() {
    let haystack = vec![0u8; if cfg!(miri) { 2_000 } else { 10_000_000 }];
    assert_eq!(naive_num_chars(&haystack), num_chars(&haystack));
    assert_eq!(naive_num_chars(&haystack), num_chars(&haystack));
}

#[test]
fn check_num_chars_some() {
    let haystack = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68];
    assert_eq!(num_chars(&haystack), naive_num_chars(&haystack));
}

#[test]
fn check_num_chars_overflow() {
    let haystack = vec![0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    assert_eq!(num_chars(&haystack), naive_num_chars(&haystack));
}
<|endoftext|>


<commit_before>//! A double-ended iterator over entity references.

use EntityRef;
use std::marker::PhantomData;

/// Iterate over all keys in order.
pub struct Keys<K: EntityRef> {
    pos: usize,
    rev_pos: usize,
    unused: PhantomData<K>,
}

impl<K: EntityRef> Keys<K> {
    /// Create a `Keys` iterator that visits `len` entities starting from 0.
    pub fn with_len(len: usize) -> Self {
        Self {
            pos: 0,
            rev_pos: len,
            unused: PhantomData,
        }
    }
}

impl<K: EntityRef> Iterator for Keys<K> {
    type Item = K;

    fn next(&mut self) -> Option<Self::Item> {
        if self.pos < self.rev_pos {
            let k = K::new(self.pos);
            self.pos += 1;
            Some(k)
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let size = self.rev_pos - self.pos;
        (size, Some(size))
    }
}

impl<K: EntityRef> DoubleEndedIterator for Keys<K> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.rev_pos > self.pos {
            let k = K::new(self.rev_pos - 1);
            self.rev_pos -= 1;
            Some(k)
        } else {
            None
        }
    }
}

impl<K: EntityRef> ExactSizeIterator for Keys<K> {}
<commit_msg>Add a comment about implementing `Keys` in terms of `Range` in the future.<commit_after>//! A double-ended iterator over entity references.
//!
//! When `std::iter::Step` is stablized, `Keys` could be implemented as a wrapper around
//! `std::ops::Range`, but for now, we implment it manually.

use EntityRef;
use std::marker::PhantomData;

/// Iterate over all keys in order.
pub struct Keys<K: EntityRef> {
    pos: usize,
    rev_pos: usize,
    unused: PhantomData<K>,
}

impl<K: EntityRef> Keys<K> {
    /// Create a `Keys` iterator that visits `len` entities starting from 0.
    pub fn with_len(len: usize) -> Self {
        Self {
            pos: 0,
            rev_pos: len,
            unused: PhantomData,
        }
    }
}

impl<K: EntityRef> Iterator for Keys<K> {
    type Item = K;

    fn next(&mut self) -> Option<Self::Item> {
        if self.pos < self.rev_pos {
            let k = K::new(self.pos);
            self.pos += 1;
            Some(k)
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let size = self.rev_pos - self.pos;
        (size, Some(size))
    }
}

impl<K: EntityRef> DoubleEndedIterator for Keys<K> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.rev_pos > self.pos {
            let k = K::new(self.rev_pos - 1);
            self.rev_pos -= 1;
            Some(k)
        } else {
            None
        }
    }
}

impl<K: EntityRef> ExactSizeIterator for Keys<K> {}
<|endoftext|>


<commit_before>use std::error::Error;

use mio::{self, EventLoop, Token, EventSet, Sender};
use mio::util::Slab;

use scope::scope;
use {SpawnError, Scope, Response, Machine};
use SpawnError::{NoSlabSpace, UserError};

pub enum Timeo {
    Fsm(Token),
}

pub enum Notify {
    Fsm(Token),
}

/// Standard mio loop handler
///
///
/// # Examples
///
/// ```ignore
/// extern crate mio;
/// extern crate rotor;
///
/// let mut event_loop = mio::EventLoop::new().unwrap();
/// let mut handler = rotor::Handler::new(Context, &mut event_loop);
/// let conn = handler.add_machine_with(&mut event_loop, |scope| {
///     Ok(StateMachineConstuctor(..))
/// });
/// assert!(conn.is_ok());
/// event_loop.run(&mut handler).unwrap();
/// ```
pub struct Handler<Ctx, M>
    where M: Machine<Context=Ctx>
{
    slab: Slab<M>,
    context: Ctx,
    channel: Sender<Notify>,
}

impl<C, M> Handler<C, M>
    where M: Machine<Context=C>,
{
    pub fn new_with_capacity(context: C, eloop: &mut EventLoop<Handler<C, M>>,
        capacity: usize)
        -> Handler<C, M>
    {
        Handler {
            slab: Slab::new(capacity),
            context: context,
            channel: eloop.channel(),
        }
    }
    pub fn new(context: C, eloop: &mut EventLoop<Handler<C, M>>)
        -> Handler<C, M>
    {
        // TODO(tailhook) create default config from the ulimit data instead
        // of using real defaults
        Handler {
            slab: Slab::new(4096),
            context: context,
            channel: eloop.channel(),
        }
    }
}

pub fn create_handler<C, M>(slab: Slab<M>, context: C, channel: Sender<Notify>)
    -> Handler<C, M>
    where M: Machine<Context=C>
{
    Handler {
        slab: slab,
        context: context,
        channel: channel,
    }
}

impl<C, M> Handler<C, M>
    where M: Machine<Context=C>
{
    pub fn add_machine_with<F>(&mut self,
        eloop: &mut EventLoop<Self>, fun: F) -> Result<(), SpawnError<()>>
        where F: FnOnce(&mut Scope<C>) -> Result<M, Box<Error>>
    {
        let ref mut ctx = self.context;
        let ref mut chan = self.channel;
        let res = self.slab.insert_with(|token| {
            let ref mut scope = scope(token, ctx, chan, eloop);
            match fun(scope) {
                Ok(x) => x,
                Err(_) => {
                // TODO(tailhook) when Slab::insert_with_opt() lands, fix it
                    panic!("Unimplemented: Slab::insert_with_opt");
                }
            }
        });
        if res.is_some() {
            Ok(())
        } else {
            Err(NoSlabSpace(()))
        }
    }

}

fn machine_loop<C, M, F>(handler: &mut Handler<C, M>,
    eloop: &mut EventLoop<Handler<C, M>>, token: Token, fun: F)
    where M: Machine<Context=C>,
          F: FnOnce(M, &mut Scope<C>) -> Response<M, M::Seed>
{
    let mut creator = None;
    {
        let ref mut scope = scope(token, &mut handler.context,
            &mut handler.channel, eloop);
        handler.slab.replace_with(token, |m| {
            let res = fun(m, scope);
            creator = res.1;
            res.0
        }).ok();  // Spurious events are ok in mio
    }
    while let Some(new) = creator.take() {
        let mut new = Some(new);
        let res = handler.add_machine_with(eloop, |scope| {
            M::create(new.take().unwrap(), scope)
        });
        if let Err(err) = res {
            let err = if let Some(new) = new.take() {
                NoSlabSpace(new)
            } else if let UserError(e) = err {
                UserError(e)
            } else {
                unreachable!();
            };
            let ref mut scope = scope(token, &mut handler.context,
                &mut handler.channel, eloop);
            handler.slab.replace_with(token, |m| {
                m.spawn_error(scope, err)
            }).ok();
            break;
        } else {
            let ref mut scope = scope(token, &mut handler.context,
                &mut handler.channel, eloop);
            handler.slab.replace_with(token, |m| {
                let res = m.spawned(scope);
                creator = res.1;
                res.0
            }).ok();
        }
    }
}

impl<Ctx, M> mio::Handler for Handler<Ctx, M>
    where M: Machine<Context=Ctx>
{
    type Message = Notify;
    type Timeout = Timeo;
    fn ready<'x>(&mut self, eloop: &'x mut EventLoop<Self>,
        token: Token, events: EventSet)
    {
        machine_loop(self, eloop, token, |m, scope| { m.ready(events, scope) })
    }

    fn notify(&mut self, eloop: &mut EventLoop<Self>, msg: Notify) {
        match msg {
            Notify::Fsm(token) => {
                machine_loop(self, eloop, token,
                    |m, scope| { m.wakeup(scope) })
            }
        }
    }

    fn timeout(&mut self, eloop: &mut EventLoop<Self>, timeo: Timeo) {
        match timeo {
            Timeo::Fsm(token) => {
                machine_loop(self, eloop, token,
                    |m, scope| { m.timeout(scope) })
            }
        }
    }
}
<commit_msg>Remove old-style loop constructors<commit_after>use std::error::Error;

use mio::{self, EventLoop, Token, EventSet, Sender};
use mio::util::Slab;

use scope::scope;
use {SpawnError, Scope, Response, Machine};
use SpawnError::{NoSlabSpace, UserError};

pub enum Timeo {
    Fsm(Token),
}

pub enum Notify {
    Fsm(Token),
}

/// Standard mio loop handler
///
///
/// # Examples
///
/// ```ignore
/// extern crate mio;
/// extern crate rotor;
///
/// let mut event_loop = mio::EventLoop::new().unwrap();
/// let mut handler = rotor::Handler::new(Context, &mut event_loop);
/// let conn = handler.add_machine_with(&mut event_loop, |scope| {
///     Ok(StateMachineConstuctor(..))
/// });
/// assert!(conn.is_ok());
/// event_loop.run(&mut handler).unwrap();
/// ```
pub struct Handler<Ctx, M>
    where M: Machine<Context=Ctx>
{
    slab: Slab<M>,
    context: Ctx,
    channel: Sender<Notify>,
}

pub fn create_handler<C, M>(slab: Slab<M>, context: C, channel: Sender<Notify>)
    -> Handler<C, M>
    where M: Machine<Context=C>
{
    Handler {
        slab: slab,
        context: context,
        channel: channel,
    }
}

impl<C, M> Handler<C, M>
    where M: Machine<Context=C>
{
    pub fn add_machine_with<F>(&mut self,
        eloop: &mut EventLoop<Self>, fun: F) -> Result<(), SpawnError<()>>
        where F: FnOnce(&mut Scope<C>) -> Result<M, Box<Error>>
    {
        let ref mut ctx = self.context;
        let ref mut chan = self.channel;
        let res = self.slab.insert_with(|token| {
            let ref mut scope = scope(token, ctx, chan, eloop);
            match fun(scope) {
                Ok(x) => x,
                Err(_) => {
                // TODO(tailhook) when Slab::insert_with_opt() lands, fix it
                    panic!("Unimplemented: Slab::insert_with_opt");
                }
            }
        });
        if res.is_some() {
            Ok(())
        } else {
            Err(NoSlabSpace(()))
        }
    }

}

fn machine_loop<C, M, F>(handler: &mut Handler<C, M>,
    eloop: &mut EventLoop<Handler<C, M>>, token: Token, fun: F)
    where M: Machine<Context=C>,
          F: FnOnce(M, &mut Scope<C>) -> Response<M, M::Seed>
{
    let mut creator = None;
    {
        let ref mut scope = scope(token, &mut handler.context,
            &mut handler.channel, eloop);
        handler.slab.replace_with(token, |m| {
            let res = fun(m, scope);
            creator = res.1;
            res.0
        }).ok();  // Spurious events are ok in mio
    }
    while let Some(new) = creator.take() {
        let mut new = Some(new);
        let res = handler.add_machine_with(eloop, |scope| {
            M::create(new.take().unwrap(), scope)
        });
        if let Err(err) = res {
            let err = if let Some(new) = new.take() {
                NoSlabSpace(new)
            } else if let UserError(e) = err {
                UserError(e)
            } else {
                unreachable!();
            };
            let ref mut scope = scope(token, &mut handler.context,
                &mut handler.channel, eloop);
            handler.slab.replace_with(token, |m| {
                m.spawn_error(scope, err)
            }).ok();
            break;
        } else {
            let ref mut scope = scope(token, &mut handler.context,
                &mut handler.channel, eloop);
            handler.slab.replace_with(token, |m| {
                let res = m.spawned(scope);
                creator = res.1;
                res.0
            }).ok();
        }
    }
}

impl<Ctx, M> mio::Handler for Handler<Ctx, M>
    where M: Machine<Context=Ctx>
{
    type Message = Notify;
    type Timeout = Timeo;
    fn ready<'x>(&mut self, eloop: &'x mut EventLoop<Self>,
        token: Token, events: EventSet)
    {
        machine_loop(self, eloop, token, |m, scope| { m.ready(events, scope) })
    }

    fn notify(&mut self, eloop: &mut EventLoop<Self>, msg: Notify) {
        match msg {
            Notify::Fsm(token) => {
                machine_loop(self, eloop, token,
                    |m, scope| { m.wakeup(scope) })
            }
        }
    }

    fn timeout(&mut self, eloop: &mut EventLoop<Self>, timeo: Timeo) {
        match timeo {
            Timeo::Fsm(token) => {
                machine_loop(self, eloop, token,
                    |m, scope| { m.timeout(scope) })
            }
        }
    }
}
<|endoftext|>


<commit_before>use regex::RegexSet;
use slog::Logger;
use std::{thread, time};
use std::fs::canonicalize;
use std::path::Path;
use std::process::exit;

pub fn resolve_path(dir: &str) -> Option<String> {
    match canonicalize(Path::new(dir)) {
        Ok(p) => Some(p.to_string_lossy().into_owned()),
        Err(_) => None,
    }
}

#[cfg_attr(feature="clippy", allow(print_stdout))]
pub fn print_error_and_exit(msg: &str) {
    println!("{}", msg);
    exit(1);
}

pub fn log_error_and_exit(log: &Logger, msg: &str) {
    error!(log, msg);
    thread::sleep(time::Duration::from_millis(500));
    exit(1);
}

pub fn process_ignores(log: &Logger, vec: &mut Vec<String>) -> RegexSet {
    if vec.is_empty() {
        vec.push("^\\.git(?:/[^/]+)*$".to_owned());
    }
    vec.push("^\\.bindrs.*$".to_owned());

    vec_to_regex_set(log, vec)
}

fn vec_to_regex_set(log: &Logger, ignores: &[String]) -> RegexSet {
    let mut regexes: Vec<String> = vec![];

    for i in ignores.iter() {
        let mut ignore = i.clone();
        if !(ignore.starts_with('^') && ignore.ends_with('$')) {
            ignore = format!("^{}(?:/[^/]+)*$", ignore);
        }
        regexes.push(ignore)
    }

    match RegexSet::new(&regexes[..]) {
        Ok(rs) => rs,
        Err(e) => {
            log_error_and_exit(log, &format!("Provided regex failed to parse: {}", e));
            panic!() // For compilation
        }
    }
}
<commit_msg>Add tests to helpers module<commit_after>use regex::RegexSet;
#[cfg(test)]
use slog::Discard;
use slog::Logger;
use std::{thread, time};
#[cfg(test)]
use std::env::current_dir;
use std::fs::canonicalize;
use std::path::Path;
use std::process::exit;

pub fn resolve_path(dir: &str) -> Option<String> {
    match canonicalize(Path::new(dir)) {
        Ok(p) => Some(p.to_string_lossy().into_owned()),
        Err(_) => None,
    }
}

#[cfg_attr(feature="clippy", allow(print_stdout))]
pub fn print_error_and_exit(msg: &str) {
    println!("{}", msg);
    exit(1);
}

pub fn log_error_and_exit(log: &Logger, msg: &str) {
    error!(log, msg);
    thread::sleep(time::Duration::from_millis(500));
    exit(1);
}

pub fn process_ignores(log: &Logger, vec: &mut Vec<String>) -> RegexSet {
    if vec.is_empty() {
        vec.push("^\\.git(?:/[^/]+)*$".to_owned());
    }
    vec.push("^\\.bindrs.*$".to_owned());

    vec_to_regex_set(log, vec)
}

fn vec_to_regex_set(log: &Logger, ignores: &[String]) -> RegexSet {
    match RegexSet::new(&convert_to_project_regex_strings(ignores)[..]) {
        Ok(rs) => rs,
        Err(e) => {
            log_error_and_exit(log, &format!("Provided regex failed to parse: {}", e));
            panic!() // For compilation
        }
    }
}

fn convert_to_project_regex_strings<'a>(ignores: &'a [String]) -> Vec<String> {
    let mut regexes: Vec<String> = vec![];

    for i in ignores.iter() {
        let mut ignore = i.clone();
        if !(ignore.starts_with('^') && ignore.ends_with('$')) {
            ignore = format!("^{}(?:/[^/]+)*$", ignore);
        }
        regexes.push(ignore)
    }

    regexes
}

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

    fn test_logger() -> Logger {
        Logger::root(Discard, o!())
    }

    #[test]
    fn including_custom_ignore_skips_git() {
        let mut strings: Vec<String> = vec![];
        strings.push("^something$".to_owned());
        let regex_set = process_ignores(&test_logger(), &mut strings);
        assert!(regex_set.is_match("something"));
        assert!(regex_set.is_match(".bindrsasdf"));
        assert!(!regex_set.is_match(".git/something"));
    }

    #[test]
    fn excluding_custom_ignore_includes_git() {
        let mut strings: Vec<String> = vec![];
        let regex_set = process_ignores(&test_logger(), &mut strings);
        assert!(!regex_set.is_match("something"));
        assert!(regex_set.is_match(".bindrsasdf"));
        assert!(regex_set.is_match(".git/something"));
    }

    #[test]
    fn regex_strings_are_not_modified() {
        let mut strings: Vec<String> = vec![];
        strings.push("^something$".to_owned());
        let regex_set = process_ignores(&test_logger(), &mut strings);
        assert!(regex_set.is_match("something"));
        assert!(!regex_set.is_match("somethin"));
        assert!(!regex_set.is_match("somethingg"));
        assert!(!regex_set.is_match("something/somethingelse"));
    }

    #[test]
    fn non_regex_strings_are_modified() {
        let mut strings: Vec<String> = vec![];
        strings.push("something".to_owned());
        let regex_set = process_ignores(&test_logger(), &mut strings);
        assert!(regex_set.is_match("something"));
        assert!(!regex_set.is_match("somethin"));
        assert!(!regex_set.is_match("somethingg"));
        assert!(regex_set.is_match("something/somethingelse"));
    }

    #[test]
    fn resolve_path_canonicalize_correctly() {
        let mut path = current_dir().unwrap();
        path.push("src");
        assert_eq!(canonicalize(path.as_path()).unwrap().to_str().unwrap(),
                   resolve_path("./src/processors/../../src").unwrap());
    }
}
<|endoftext|>


<commit_before>//! Reimplements core logic and types from `std::io` in an `alloc`-friendly
//! fashion.

use lib::*;

pub enum ErrorKind {
    InvalidData,
    WriteZero,
    Other,
    UnexpectedEof,
}

pub struct Error {
    repr: Box<dyn Display + Send + Sync>,
}

impl Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(self.repr.as_ref(), fmt)
    }
}

impl Debug for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(self, fmt)
    }
}

impl serde::de::StdError for Error {}

impl Error {
    pub(crate) fn new<E>(kind: ErrorKind, error: E) -> Error
    where
        E: Display + Send + Sync + 'static,
    {
        let _ = kind;
        Error {
            repr: Box::new(error),
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

pub trait Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize>;

    fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
        while !buf.is_empty() {
            match self.write(buf) {
                Ok(0) => {
                    return Err(Error::new(
                        ErrorKind::WriteZero,
                        "failed to write whole buffer",
                    ))
                }
                Ok(n) => buf = &buf[n..],
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    fn flush(&mut self) -> Result<()>;
}

impl<W: Write> Write for &mut W {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        (*self).write(buf)
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        (*self).write_all(buf)
    }

    #[inline]
    fn flush(&mut self) -> Result<()> {
        (*self).flush()
    }
}

impl Write for Vec<u8> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.extend_from_slice(buf);
        Ok(buf.len())
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        self.extend_from_slice(buf);
        Ok(())
    }

    #[inline]
    fn flush(&mut self) -> Result<()> {
        Ok(())
    }
}

pub trait Read {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
    fn bytes(self) -> Bytes<Self>
    where
        Self: Sized,
    {
        Bytes { inner: self }
    }
}

pub struct Bytes<R> {
    inner: R,
}

impl<R: Read> Iterator for Bytes<R> {
    type Item = Result<u8>;

    fn next(&mut self) -> Option<Result<u8>> {
        let mut byte = 0;
        match self.inner.read(slice::from_mut(&mut byte)) {
            Ok(0) => None,
            Ok(..) => Some(Ok(byte)),
            Err(e) => Some(Err(e)),
        }
    }
}
<commit_msg>Preserve underlying Debug representation for io error<commit_after>//! Reimplements core logic and types from `std::io` in an `alloc`-friendly
//! fashion.

use lib::*;

pub enum ErrorKind {
    InvalidData,
    WriteZero,
    Other,
    UnexpectedEof,
}

pub struct Error {
    repr: Box<dyn ErrorRepr + Send + Sync>,
}

trait ErrorRepr: Display + Debug {}
impl<T: Display + Debug> ErrorRepr for T {}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(self.repr.as_ref(), formatter)
    }
}

impl Debug for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        Debug::fmt(self.repr.as_ref(), formatter)
    }
}

impl serde::de::StdError for Error {}

impl Error {
    pub(crate) fn new<E>(kind: ErrorKind, error: E) -> Error
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        let _ = kind;
        Error {
            repr: Box::new(error),
        }
    }
}

pub type Result<T> = result::Result<T, Error>;

pub trait Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize>;

    fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
        while !buf.is_empty() {
            match self.write(buf) {
                Ok(0) => {
                    return Err(Error::new(
                        ErrorKind::WriteZero,
                        "failed to write whole buffer",
                    ))
                }
                Ok(n) => buf = &buf[n..],
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    fn flush(&mut self) -> Result<()>;
}

impl<W: Write> Write for &mut W {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        (*self).write(buf)
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        (*self).write_all(buf)
    }

    #[inline]
    fn flush(&mut self) -> Result<()> {
        (*self).flush()
    }
}

impl Write for Vec<u8> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        self.extend_from_slice(buf);
        Ok(buf.len())
    }

    #[inline]
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
        self.extend_from_slice(buf);
        Ok(())
    }

    #[inline]
    fn flush(&mut self) -> Result<()> {
        Ok(())
    }
}

pub trait Read {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
    fn bytes(self) -> Bytes<Self>
    where
        Self: Sized,
    {
        Bytes { inner: self }
    }
}

pub struct Bytes<R> {
    inner: R,
}

impl<R: Read> Iterator for Bytes<R> {
    type Item = Result<u8>;

    fn next(&mut self) -> Option<Result<u8>> {
        let mut byte = 0;
        match self.inner.read(slice::from_mut(&mut byte)) {
            Ok(0) => None,
            Ok(..) => Some(Ok(byte)),
            Err(e) => Some(Err(e)),
        }
    }
}
<|endoftext|>


<commit_before>//! Provides MIDI input from OS MIDI devices.

#![unstable]

extern crate portmidi;

use std::vec::Vec;

use types::{Device, MidiEvent, MidiMessage, Time};
use components::OutputElement;
use init;

/// Defines the maximum event buffer size for portmidi
static BUFFER_SIZE: i32 = 256;

/// Converts a raw portmidi message to an oxcable MIDI event
fn midievent_from_portmidi(event: portmidi::MidiEvent) -> MidiEvent {
    let msg = event.message;
    let channel = (msg.status & 0x0F) as u8;
    let payload = match (msg.status as u8) >> 4 {
        0b1000 => {
            let note = msg.data1 as u8;
            let velocity = (msg.data2 as f32) / 127.0;
            MidiMessage::NoteOff(note, velocity)
        },
        0b1001 => {
            let note = msg.data1 as u8;
            let velocity = (msg.data2 as f32) / 127.0;
            MidiMessage::NoteOn(note, velocity)
        }
        0b1110 => {
            let int_value = ((msg.data2 as i16) << 7) | (msg.data1 as i16);
            let bend = (int_value - 0x2000) as f32 /
                (0x2000i16) as f32;
            MidiMessage::PitchBend(bend)
        }
        0b1010 => {
            let note = msg.data1 as u8;
            let pressure = (msg.data2 as f32) / 127.0;
            MidiMessage::KeyPressure(note, pressure)
        }
        0b1011 => MidiMessage::ControlChange(msg.data1 as u8, msg.data2 as u8),
        0b1100 => MidiMessage::ProgramChange(msg.data1 as u8),
        0b1101 => MidiMessage::ChannelPressure(msg.data1 as f32 / 127.0),
        _ => MidiMessage::Other(msg.status as u8, msg.data1 as u8,
                                msg.data2 as u8)
    };

    MidiEvent { channel: channel, payload: payload }
}

/// Reads audio from the OS's default midi device.
#[stable]
pub struct MidiIn {
    /// Output midi channel
    #[stable]
    pub output: OutputElement<Vec<MidiEvent>>,

    pm_stream: portmidi::InputPort,
}

#[stable]
impl MidiIn {
    /// Opens a midi input stream.
    #[stable]
    pub fn new() -> MidiIn {
        // Check for initialization
        if !init::is_initialized() {
            panic!("Must initialize oxcable first");
        }

        // Open a stream. For now, use firs device
        let mut pm_stream = portmidi::InputPort::new(1, BUFFER_SIZE);
        assert!(pm_stream.open().is_ok());

        MidiIn {
            output: OutputElement::new(),
            pm_stream: pm_stream,
        }
    }

    /// Closes the portmidi stream
    #[stable]
    pub fn stop(&mut self) {
        assert!(self.pm_stream.close().is_ok());
    }
}

impl Device for MidiIn {
    fn tick(&mut self, _t: Time) {
        let mut events = Vec::new();
        loop {
            match self.pm_stream.read().unwrap() {
                Some(pm_event) =>
                    events.push(midievent_from_portmidi(pm_event)),
                None => break
            }
        }
        self.output.push(events);
    }
}
<commit_msg>Fix midi channel<commit_after>//! Provides MIDI input from OS MIDI devices.

#![unstable]

extern crate portmidi;

use std::vec::Vec;

use types::{Device, MidiEvent, MidiMessage, Time};
use components::OutputElement;
use init;

/// Defines the maximum event buffer size for portmidi
static BUFFER_SIZE: i32 = 256;

/// Converts a raw portmidi message to an oxcable MIDI event
fn midievent_from_portmidi(event: portmidi::MidiEvent) -> MidiEvent {
    let msg = event.message;
    let channel = (msg.status & 0x0F) as u8;
    let payload = match (msg.status as u8) >> 4 {
        0b1000 => {
            let note = msg.data1 as u8;
            let velocity = (msg.data2 as f32) / 127.0;
            MidiMessage::NoteOff(note, velocity)
        },
        0b1001 => {
            let note = msg.data1 as u8;
            let velocity = (msg.data2 as f32) / 127.0;
            MidiMessage::NoteOn(note, velocity)
        }
        0b1110 => {
            let int_value = ((msg.data2 as i16) << 7) | (msg.data1 as i16);
            let bend = (int_value - 0x2000) as f32 /
                (0x2000i16) as f32;
            MidiMessage::PitchBend(bend)
        }
        0b1010 => {
            let note = msg.data1 as u8;
            let pressure = (msg.data2 as f32) / 127.0;
            MidiMessage::KeyPressure(note, pressure)
        }
        0b1011 => MidiMessage::ControlChange(msg.data1 as u8, msg.data2 as u8),
        0b1100 => MidiMessage::ProgramChange(msg.data1 as u8),
        0b1101 => MidiMessage::ChannelPressure(msg.data1 as f32 / 127.0),
        _ => MidiMessage::Other(msg.status as u8, msg.data1 as u8,
                                msg.data2 as u8)
    };

    MidiEvent { channel: channel, payload: payload }
}

/// Reads audio from the OS's default midi device.
#[stable]
pub struct MidiIn {
    /// Output midi channel
    #[stable]
    pub output: OutputElement<Vec<MidiEvent>>,

    pm_stream: portmidi::InputPort,
}

#[stable]
impl MidiIn {
    /// Opens a midi input stream.
    #[stable]
    pub fn new() -> MidiIn {
        // Check for initialization
        if !init::is_initialized() {
            panic!("Must initialize oxcable first");
        }

        // Open a stream. For now, use firs device
        let mut pm_stream = portmidi::InputPort::new(0, BUFFER_SIZE);
        assert!(pm_stream.open().is_ok());

        MidiIn {
            output: OutputElement::new(),
            pm_stream: pm_stream,
        }
    }

    /// Closes the portmidi stream
    #[stable]
    pub fn stop(&mut self) {
        assert!(self.pm_stream.close().is_ok());
    }
}

impl Device for MidiIn {
    fn tick(&mut self, _t: Time) {
        let mut events = Vec::new();
        loop {
            match self.pm_stream.read().unwrap() {
                Some(pm_event) =>
                    events.push(midievent_from_portmidi(pm_event)),
                None => break
            }
        }
        self.output.push(events);
    }
}
<|endoftext|>