<commit_before>// Copyright 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.

use std::os;

fn max(a: i32, b: i32) -> i32 {
    if a > b {
        a
    } else {
        b
    }
}

fn fannkuch_redux(n: i32) -> i32 {
    let mut perm = Vec::from_elem(n as uint, 0i32);
    let mut perm1 = Vec::from_fn(n as uint, |i| i as i32);
    let mut count = Vec::from_elem(n as uint, 0i32);
    let mut max_flips_count = 0i32;
    let mut perm_count = 0i32;
    let mut checksum = 0i32;

    let perm = perm.as_mut_slice();
    let perm1 = perm1.as_mut_slice();
    let count = count.as_mut_slice();

    let mut r = n;
    loop {
        while r != 1 {
            count[r as uint - 1] = r;
            r -= 1;
        }

        for (perm_i, perm1_i) in perm.mut_iter().zip(perm1.iter()) {
            *perm_i = *perm1_i;
        }

        let mut flips_count: i32 = 0;
        let mut k: i32;
        loop {
            k = perm[0];
            if k == 0 {
                break;
            }

            let k2 = (k+1) >> 1;
            for i in range(0i32, k2) {
                perm.swap(i as uint, (k - i) as uint);
            }
            flips_count += 1;
        }

        max_flips_count = max(max_flips_count, flips_count);
        checksum += if perm_count % 2 == 0 {
            flips_count
        } else {
            -flips_count
        };

        // Use incremental change to generate another permutation.
        loop {
            if r == n {
                println!("{}", checksum);
                return max_flips_count;
            }

            let perm0 = perm1[0];
            let mut i: i32 = 0;
            while i < r {
                let j = i + 1;
                perm1[i as uint] = perm1[j as uint];
                i = j;
            }
            perm1[r as uint] = perm0;

            count[r as uint] -= 1;
            if count[r as uint] > 0 {
                break;
            }
            r += 1;
        }

        perm_count += 1;
    }
}

fn main() {
    let args = os::args();
    let n = if args.len() > 1 {
        from_str::<i32>(args[1]).unwrap()
    } else {
        2
    };
    println!("Pfannkuchen({}) = {}", n as int, fannkuch_redux(n) as int);
}
<commit_msg>auto merge of #13633 : TeXitoi/rust/shootout-fannkuch-redux-rewrite, r=alexcrichton<commit_after>// Copyright 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.

use std::cmp::max;

fn fact(n: uint) -> uint {
    range(1, n + 1).fold(1, |accu, i| accu * i)
}

fn fannkuch(n: uint, i: uint) -> (int, int) {
    let mut perm = Vec::from_fn(n, |e| ((n + e - i) % n + 1) as i32);
    let mut tperm = perm.clone();
    let mut count = Vec::from_elem(n, 0u);
    let mut perm_count = 0;
    let mut checksum = 0;

    for countdown in range(1, fact(n - 1) + 1).rev() {
        for i in range(1, n) {
            let perm0 = *perm.get(0);
            for j in range(0, i) {
                *perm.get_mut(j) = *perm.get(j + 1);
            }
            *perm.get_mut(i) = perm0;

            let count_i = count.get_mut(i);
            if *count_i >= i {
                *count_i = 0;
            } else {
                *count_i += 1;
                break;
            }
        }

        tperm.clone_from(&perm);
        let mut flips_count = 0;
        loop {
            let k = *tperm.get(0);
            if k == 1 { break; }
            tperm.mut_slice_to(k as uint).reverse();
            flips_count += 1;
        }
        perm_count = max(perm_count, flips_count);
        checksum += if countdown & 1 == 1 {flips_count} else {-flips_count}
    }
    (checksum, perm_count)
}

fn main() {
    let n = std::os::args().get(1).and_then(|arg| from_str(*arg)).unwrap_or(2u);

    let (tx, rx) = channel();
    for i in range(0, n) {
        let tx = tx.clone();
        spawn(proc() tx.send(fannkuch(n, i)));
    }
    drop(tx);

    let mut checksum = 0;
    let mut perm = 0;
    for (cur_cks, cur_perm) in rx.iter() {
        checksum += cur_cks;
        perm = max(perm, cur_perm);
    }
    println!("{}\nPfannkuchen({}) = {}", checksum, n, perm);
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use regex::Regex;

#[repr(u32)]
#[derive(Debug, Clone)]
pub enum SubToken {
    Plus,
    Minus,
    Multiply,
    Divide,
    Power,
    Modulo,

    Number,

    LParen,
    RParen,

    End
}

#[derive(Debug, Clone)]
pub struct Token {
    kind: SubToken,
    value: Option<f64>
}

impl Token {
    pub fn new(kind: SubToken, value: Option<f64>) -> Self {
        Token{kind: kind, value: value}
    }
    pub fn set_kind(&mut self, kind: SubToken) {
        self.kind = kind;
    }
    pub fn set_value(&mut self, value: Option<f64>) {
        self.value = value;
    }
    pub fn get_kind(&self) -> SubToken {
        self.kind.clone()
    }
    pub fn get_value(&self) -> Option<f64> {
        self.value.clone()
    }
}

#[derive(Debug)]
pub struct Lexer {
    input: String,
    return_previous_token: bool,
    previous_token: Option<Token>
}

impl Lexer {
    pub fn new(input: String) -> Self {
        Lexer{input: input, return_previous_token: false, previous_token: None}
    }
    pub fn get_next_token(&mut self) -> Result<Token, String> {
        if self.return_previous_token {
            self.return_previous_token = false;
            return match self.previous_token.clone() {
                Some(t) => Ok(t),
                None => Err(String::from("No previous token"))
            }
        }
        let mut strip_input = strip_white_space(self.input.clone());
        lazy_static! {
            static ref PLUS_RE: Regex = Regex::new(r"\A\+").unwrap();
            static ref MINUS_RE: Regex = Regex::new(r"\A-").unwrap();
            static ref MULT_RE: Regex = Regex::new(r"\A\*").unwrap();
            static ref DIV_RE: Regex = Regex::new(r"\A/").unwrap();
            static ref POW_RE: Regex = Regex::new(r"\A\^").unwrap();
            static ref MOD_RE: Regex = Regex::new(r"\A%").unwrap();
            static ref NUM_RE: Regex = Regex::new(r"\A\d+(\.\d+)?").unwrap();
            static ref LPAREN_RE: Regex = Regex::new(r"\A\(").unwrap();
            static ref RPAREN_RE: Regex = Regex::new(r"\A\)").unwrap();
        }
        let token: Token;
        let temp = &(strip_input.clone())[..];
        if PLUS_RE.is_match(temp) {
            strip_input = PLUS_RE.replace(temp, "");
            token = Token::new(SubToken::Plus, None);
        } else if MINUS_RE.is_match(temp) {
            strip_input = MINUS_RE.replace(temp, "");
            token = Token::new(SubToken::Minus, None);
        } else if MULT_RE.is_match(temp) {
            strip_input = MULT_RE.replace(temp, "");
            token = Token::new(SubToken::Multiply, None);
        } else if DIV_RE.is_match(temp) {
            strip_input = DIV_RE.replace(temp, "");
            token = Token::new(SubToken::Divide, None);
        } else if POW_RE.is_match(temp) {
            strip_input = POW_RE.replace(temp, "");
            token = Token::new(SubToken::Power, None);
        } else if MOD_RE.is_match(temp) {
            strip_input = MOD_RE.replace(temp, "");
            token = Token::new(SubToken::Modulo, None);
        } else if NUM_RE.is_match(temp) {
            use std::str::FromStr;
            let value: Option<f64> = f64::from_str(NUM_RE.captures(temp).unwrap().at(0).unwrap()).ok();
            strip_input = NUM_RE.replace(temp, "");
            token = Token::new(SubToken::Number, value);
        } else if LPAREN_RE.is_match(temp) {
            strip_input = LPAREN_RE.replace(temp, "");
            token = Token::new(SubToken::LParen, None);
        } else if RPAREN_RE.is_match(temp) {
            strip_input = RPAREN_RE.replace(temp, "");
            token = Token::new(SubToken::RParen, None);
        } else if strip_input.is_empty() {
            token = Token::new(SubToken::End, None);
        } else {
            let mut error: String = String::from("Unknown token: ");
            error.push_str(temp);
            return Err(error);
        }
        self.input = strip_input;
        self.previous_token = Some(token.clone());
        println!("{:?}", token);
        Ok(token)
    }
    pub fn revert(&mut self) {
        self.return_previous_token = true;
    }
}

fn strip_white_space(input: String) -> String {
    input.split_whitespace().collect::<Vec<&str>>().join("")
}
<commit_msg>Removed ugly printing code<commit_after>#![allow(dead_code)]

use regex::Regex;

#[repr(u32)]
#[derive(Debug, Clone)]
pub enum SubToken {
    Plus,
    Minus,
    Multiply,
    Divide,
    Power,
    Modulo,

    Number,

    LParen,
    RParen,

    End
}

#[derive(Debug, Clone)]
pub struct Token {
    kind: SubToken,
    value: Option<f64>
}

impl Token {
    pub fn new(kind: SubToken, value: Option<f64>) -> Self {
        Token{kind: kind, value: value}
    }
    pub fn set_kind(&mut self, kind: SubToken) {
        self.kind = kind;
    }
    pub fn set_value(&mut self, value: Option<f64>) {
        self.value = value;
    }
    pub fn get_kind(&self) -> SubToken {
        self.kind.clone()
    }
    pub fn get_value(&self) -> Option<f64> {
        self.value.clone()
    }
}

#[derive(Debug)]
pub struct Lexer {
    input: String,
    return_previous_token: bool,
    previous_token: Option<Token>
}

impl Lexer {
    pub fn new(input: String) -> Self {
        Lexer{input: input, return_previous_token: false, previous_token: None}
    }
    pub fn get_next_token(&mut self) -> Result<Token, String> {
        if self.return_previous_token {
            self.return_previous_token = false;
            return match self.previous_token.clone() {
                Some(t) => Ok(t),
                None => Err(String::from("No previous token"))
            }
        }
        let mut strip_input = strip_white_space(self.input.clone());
        lazy_static! {
            static ref PLUS_RE: Regex = Regex::new(r"\A\+").unwrap();
            static ref MINUS_RE: Regex = Regex::new(r"\A-").unwrap();
            static ref MULT_RE: Regex = Regex::new(r"\A\*").unwrap();
            static ref DIV_RE: Regex = Regex::new(r"\A/").unwrap();
            static ref POW_RE: Regex = Regex::new(r"\A\^").unwrap();
            static ref MOD_RE: Regex = Regex::new(r"\A%").unwrap();
            static ref NUM_RE: Regex = Regex::new(r"\A\d+(\.\d+)?").unwrap();
            static ref LPAREN_RE: Regex = Regex::new(r"\A\(").unwrap();
            static ref RPAREN_RE: Regex = Regex::new(r"\A\)").unwrap();
        }
        let token: Token;
        let temp = &(strip_input.clone())[..];
        if PLUS_RE.is_match(temp) {
            strip_input = PLUS_RE.replace(temp, "");
            token = Token::new(SubToken::Plus, None);
        } else if MINUS_RE.is_match(temp) {
            strip_input = MINUS_RE.replace(temp, "");
            token = Token::new(SubToken::Minus, None);
        } else if MULT_RE.is_match(temp) {
            strip_input = MULT_RE.replace(temp, "");
            token = Token::new(SubToken::Multiply, None);
        } else if DIV_RE.is_match(temp) {
            strip_input = DIV_RE.replace(temp, "");
            token = Token::new(SubToken::Divide, None);
        } else if POW_RE.is_match(temp) {
            strip_input = POW_RE.replace(temp, "");
            token = Token::new(SubToken::Power, None);
        } else if MOD_RE.is_match(temp) {
            strip_input = MOD_RE.replace(temp, "");
            token = Token::new(SubToken::Modulo, None);
        } else if NUM_RE.is_match(temp) {
            use std::str::FromStr;
            let value: Option<f64> = f64::from_str(NUM_RE.captures(temp).unwrap().at(0).unwrap()).ok();
            strip_input = NUM_RE.replace(temp, "");
            token = Token::new(SubToken::Number, value);
        } else if LPAREN_RE.is_match(temp) {
            strip_input = LPAREN_RE.replace(temp, "");
            token = Token::new(SubToken::LParen, None);
        } else if RPAREN_RE.is_match(temp) {
            strip_input = RPAREN_RE.replace(temp, "");
            token = Token::new(SubToken::RParen, None);
        } else if strip_input.is_empty() {
            token = Token::new(SubToken::End, None);
        } else {
            let mut error: String = String::from("Unknown token: ");
            error.push_str(temp);
            return Err(error);
        }
        self.input = strip_input;
        self.previous_token = Some(token.clone());
        Ok(token)
    }
    pub fn revert(&mut self) {
        self.return_previous_token = true;
    }
}

fn strip_white_space(input: String) -> String {
    input.split_whitespace().collect::<Vec<&str>>().join("")
}
<|endoftext|>


<commit_before>extern crate libc;

use super::daemon::*;
use std::io::{Error, ErrorKind};
use std::sync::mpsc::channel;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;
use std::sync::StaticMutex;
use std::sync::MUTEX_INIT;

static LOCK: StaticMutex = MUTEX_INIT;

static mut daemon_static:*mut DaemonStatic = 0 as *mut DaemonStatic;

struct DaemonStatic
{
	holder: Box<DaemonFunc>,
}

trait DaemonFunc
{
	fn exec(&mut self) -> Result<(), Error>;
	fn send(&mut self, state: State) -> Result<(), Error>;
	fn take_tx(&mut self) -> Option<Sender<State>>;
}

struct DaemonFuncHolder <F: FnOnce(Receiver<State>)>
{
	tx: Option<Sender<State>>,
	func: Option<(F, Receiver<State>)>,
}

impl <F: FnOnce(Receiver<State>)> DaemonFunc for DaemonFuncHolder<F>
{
	fn exec(&mut self) -> Result<(), Error>
	{
		match self.func.take()
		{
			Some((func, rx)) => {
				func(rx);
				Ok(())
			}
			None => Err(Error::new(ErrorKind::Other, "INTERNAL ERROR: Can't unwrap daemon function"))
		}
	}

	fn send(&mut self, state: State) -> Result<(), Error>
	{
		match self.tx
		{
			Some(ref tx) => match tx.send(state)
			{
				Ok(_) => Ok(()),
				Err(e) => Err(Error::new(ErrorKind::Other, e)),
			},
			None => Err(Error::new(ErrorKind::Other, "Service is already exited")),
		}
	}

	fn take_tx(&mut self) -> Option<Sender<State>>
	{
		self.tx.take()
	}
}

impl DaemonRunner for Daemon
{
	fn run<F: 'static + FnOnce(Receiver<State>)>(&self, func: F) -> Result<(), Error> {
		let (tx, rx) = channel();
		tx.send(State::Start).unwrap();
		let mut daemon = DaemonStatic
		{
			holder: Box::new(DaemonFuncHolder
			{
				tx: Some(tx),
				func: Some((func, rx)),
			}),
		};
		try! (guard_compare_and_swap(daemon_null(), &mut daemon));
		let result = daemon_console(&mut daemon);
		try! (guard_compare_and_swap(&mut daemon, daemon_null()));
		result
	}
}

fn guard_compare_and_swap(old_value: *mut DaemonStatic, new_value: *mut DaemonStatic) -> Result<(), Error>
{
	unsafe
	{
		let guard = LOCK.lock().unwrap();
		if daemon_static != old_value
		{
			return Err(Error::new(ErrorKind::Other, "This function is not reentrant."));
		}
		daemon_static = new_value;
		let _ = guard;
	}
	Ok(())
}

fn daemon_console(daemon: &mut DaemonStatic) -> Result<(), Error>
{
	let result;
	unsafe
	{
		//if SetConsoleCtrlHandler(Some(console_handler), TRUE) == FALSE
		//{
		//	return Err(format! ("Failed SetConsoleCtrlHandler: {}", error_string(GetLastError() as i32)));
		//}
		result = daemon.holder.exec();
		//if SetConsoleCtrlHandler(Some(console_handler), FALSE) == FALSE
		//{
		//	return Err(format! ("Failed SetConsoleCtrlHandler: {}", error_string(GetLastError() as i32)));
		//}
	}
	result
}

unsafe extern "system" fn signal_handler(sig: libc::c_int)
{
	let guard = LOCK.lock().unwrap();
	if daemon_static != daemon_null()
	{
		let daemon = &mut *daemon_static;
		return match daemon.holder.take_tx()
		{
			Some(ref tx) => {
				let _ = tx.send(State::Stop);
			}
			None => ()
		}
	}
	let _ = guard;
}

fn daemon_null() -> *mut DaemonStatic {
	0 as *mut DaemonStatic
}

extern "C" {
	fn raise(sig: libc::c_int) -> libc::c_int;
	fn signal(sig: libc::c_int, handler: *const libc::c_void) -> libc::c_int;
	fn kill(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int;
}
<commit_msg>rust-1.0.0: linux<commit_after>extern crate libc;

use super::daemon::*;
use std::io::{Error, ErrorKind};
use std::sync::mpsc::channel;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::Sender;

declare_singleton! (singleton, DaemonHolder, DaemonHolder {holder: 0 as *mut DaemonStatic});

struct DaemonHolder {
	holder: *mut DaemonStatic,
}

struct DaemonStatic
{
	holder: Box<DaemonFunc>,
}

trait DaemonFunc
{
	fn exec(&mut self) -> Result<(), Error>;
	fn send(&mut self, state: State) -> Result<(), Error>;
	fn take_tx(&mut self) -> Option<Sender<State>>;
}

struct DaemonFuncHolder <F: FnOnce(Receiver<State>)>
{
	tx: Option<Sender<State>>,
	func: Option<(F, Receiver<State>)>,
}

impl <F: FnOnce(Receiver<State>)> DaemonFunc for DaemonFuncHolder<F>
{
	fn exec(&mut self) -> Result<(), Error>
	{
		match self.func.take()
		{
			Some((func, rx)) => {
				func(rx);
				Ok(())
			}
			None => Err(Error::new(ErrorKind::Other, "INTERNAL ERROR: Can't unwrap daemon function"))
		}
	}

	fn send(&mut self, state: State) -> Result<(), Error>
	{
		match self.tx
		{
			Some(ref tx) => match tx.send(state)
			{
				Ok(_) => Ok(()),
				Err(e) => Err(Error::new(ErrorKind::Other, e)),
			},
			None => Err(Error::new(ErrorKind::Other, "Service is already exited")),
		}
	}

	fn take_tx(&mut self) -> Option<Sender<State>>
	{
		self.tx.take()
	}
}

fn daemon_wrapper<R, F: FnOnce(&mut DaemonHolder) -> R>(func: F) -> R {
	let singleton = singleton();
	let result = match singleton.lock() {
		Ok(ref mut daemon) => {
			func(daemon)
		}
		Err(e) => {
			panic!("Mutex error: {:?}", e);
		}
	};
	result
}

impl DaemonRunner for Daemon
{
	fn run<F: 'static + FnOnce(Receiver<State>)>(&self, func: F) -> Result<(), Error> {
		let (tx, rx) = channel();
		tx.send(State::Start).unwrap();
		let mut daemon = DaemonStatic
		{
			holder: Box::new(DaemonFuncHolder
			{
				tx: Some(tx),
				func: Some((func, rx)),
			}),
		};
		try! (guard_compare_and_swap(daemon_null(), &mut daemon));
		let result = daemon_console(&mut daemon);
		try! (guard_compare_and_swap(&mut daemon, daemon_null()));
		result
	}
}

fn guard_compare_and_swap(old_value: *mut DaemonStatic, new_value: *mut DaemonStatic) -> Result<(), Error>
{
	daemon_wrapper(|daemon_static: &mut DaemonHolder| -> Result<(), Error> {
		if daemon_static.holder != old_value
		{
			return Err(Error::new(ErrorKind::Other, "This function is not reentrant."));
		}
		daemon_static.holder = new_value;
		Ok(())
	})
}

fn daemon_console(daemon: &mut DaemonStatic) -> Result<(), Error>
{
	let result;
	unsafe
	{
		//if SetConsoleCtrlHandler(Some(console_handler), TRUE) == FALSE
		//{
		//	return Err(format! ("Failed SetConsoleCtrlHandler: {}", error_string(GetLastError() as i32)));
		//}
		result = daemon.holder.exec();
		//if SetConsoleCtrlHandler(Some(console_handler), FALSE) == FALSE
		//{
		//	return Err(format! ("Failed SetConsoleCtrlHandler: {}", error_string(GetLastError() as i32)));
		//}
	}
	result
}

unsafe extern "system" fn signal_handler(sig: libc::c_int)
{
	daemon_wrapper(|daemon_static: &mut DaemonHolder| {
		let daemon = &mut *daemon_static.holder;
		return match daemon.holder.take_tx()
		{
			Some(ref tx) => {
				let _ = tx.send(State::Stop);
			}
			None => ()
		}
	});
}

fn daemon_null() -> *mut DaemonStatic {
	0 as *mut DaemonStatic
}

extern "C" {
	fn raise(sig: libc::c_int) -> libc::c_int;
	fn signal(sig: libc::c_int, handler: *const libc::c_void) -> libc::c_int;
	fn kill(pid: libc::pid_t, sig: libc::c_int) -> libc::c_int;
}
<|endoftext|>


<commit_before>//! Instruction Set Architectures.
//!
//! The `isa` module provides a `TargetIsa` trait which provides the behavior specialization needed
//! by the ISA-independent code generator. The sub-modules of this module provide definitions for
//! the instruction sets that Cretonne can target. Each sub-module has it's own implementation of
//! `TargetIsa`.
//!
//! # Constructing a `TargetIsa` instance
//!
//! The target ISA is built from the following information:
//!
//! - The name of the target ISA as a string. Cretonne is a cross-compiler, so the ISA to target
//!   can be selected dynamically. Individual ISAs can be left out when Cretonne is compiled, so a
//!   string is used to identify the proper sub-module.
//! - Values for settings that apply to all ISAs. This is represented by a `settings::Flags`
//!   instance.
//! - Values for ISA-specific settings.
//!
//! The `isa::lookup()` function is the main entry point which returns an `isa::Builder`
//! appropriate for the requested ISA:
//!
//! ```
//! use cretonne::settings::{self, Configurable};
//! use cretonne::isa;
//!
//! let shared_builder = settings::builder();
//! let shared_flags = settings::Flags::new(&shared_builder);
//!
//! match isa::lookup("riscv") {
//!     None => {
//!         // The RISC-V target ISA is not available.
//!     }
//!     Some(mut isa_builder) => {
//!         isa_builder.set("supports_m", "on");
//!         let isa = isa_builder.finish(shared_flags);
//!     }
//! }
//! ```
//!
//! The configured target ISA trait object is a `Box<TargetIsa>` which can be used for multiple
//! concurrent function compilations.

pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind, BranchRange};
pub use isa::encoding::{Encoding, EncInfo};
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex, regs_overlap};

use binemit;
use settings;
use ir;
use regalloc;
use isa::enc_tables::Encodings;

pub mod riscv;
pub mod intel;
pub mod arm32;
pub mod arm64;
pub mod registers;
mod encoding;
mod enc_tables;
mod constraints;

/// Look for a supported ISA with the given `name`.
/// Return a builder that can create a corresponding `TargetIsa`.
pub fn lookup(name: &str) -> Option<Builder> {
    match name {
        "riscv" => riscv_builder(),
        "intel" => intel_builder(),
        "arm32" => arm32_builder(),
        "arm64" => arm64_builder(),
        _ => None,
    }
}

// Make a builder for RISC-V.
fn riscv_builder() -> Option<Builder> {
    Some(riscv::isa_builder())
}

fn intel_builder() -> Option<Builder> {
    Some(intel::isa_builder())
}

fn arm32_builder() -> Option<Builder> {
    Some(arm32::isa_builder())
}

fn arm64_builder() -> Option<Builder> {
    Some(arm64::isa_builder())
}

/// Builder for a `TargetIsa`.
/// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`.
pub struct Builder {
    setup: settings::Builder,
    constructor: fn(settings::Flags, &settings::Builder) -> Box<TargetIsa>,
}

impl Builder {
    /// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
    /// fully configured `TargetIsa` trait object.
    pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> {
        (self.constructor)(shared_flags, &self.setup)
    }
}

impl settings::Configurable for Builder {
    fn set(&mut self, name: &str, value: &str) -> settings::Result<()> {
        self.setup.set(name, value)
    }

    fn enable(&mut self, name: &str) -> settings::Result<()> {
        self.setup.enable(name)
    }
}

/// After determining that an instruction doesn't have an encoding, how should we proceed to
/// legalize it?
///
/// These actions correspond to the transformation groups defined in `meta/cretonne/legalize.py`.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Legalize {
    /// Legalize in terms of narrower types.
    Narrow,

    /// Expanding in terms of other instructions using the same types.
    Expand,
}

/// Translate a legalization code into a `Legalize` enum.
///
/// This mapping is going away soon. It depends on matching the `TargetISA.legalize_code()`
/// mapping.
impl From<u8> for Legalize {
    fn from(x: u8) -> Legalize {
        match x {
            0 => Legalize::Narrow,
            1 => Legalize::Expand,
            _ => panic!("Unknown legalization code {}"),
        }
    }
}

/// Methods that are specialized to a target ISA.
pub trait TargetIsa {
    /// Get the name of this ISA.
    fn name(&self) -> &'static str;

    /// Get the ISA-independent flags that were used to make this trait object.
    fn flags(&self) -> &settings::Flags;

    /// Get a data structure describing the registers in this ISA.
    fn register_info(&self) -> RegInfo;

    /// Returns an iterartor over legal encodings for the instruction.
    fn legal_encodings<'a>(&'a self,
                           dfg: &'a ir::DataFlowGraph,
                           inst: &'a ir::InstructionData,
                           ctrl_typevar: ir::Type)
                           -> Encodings<'a>;

    /// Encode an instruction after determining it is legal.
    ///
    /// If `inst` can legally be encoded in this ISA, produce the corresponding `Encoding` object.
    /// Otherwise, return `Legalize` action.
    ///
    /// This is also the main entry point for determining if an instruction is legal.
    fn encode(&self,
              dfg: &ir::DataFlowGraph,
              inst: &ir::InstructionData,
              ctrl_typevar: ir::Type)
              -> Result<Encoding, Legalize> {
        let mut iter = self.legal_encodings(dfg, inst, ctrl_typevar);
        iter.next().ok_or(iter.legalize().into())
    }

    /// Get a data structure describing the instruction encodings in this ISA.
    fn encoding_info(&self) -> EncInfo;

    /// Legalize a function signature.
    ///
    /// This is used to legalize both the signature of the function being compiled and any called
    /// functions. The signature should be modified by adding `ArgumentLoc` annotations to all
    /// arguments and return values.
    ///
    /// Arguments with types that are not supported by the ABI can be expanded into multiple
    /// arguments:
    ///
    /// - Integer types that are too large to fit in a register can be broken into multiple
    ///   arguments of a smaller integer type.
    /// - Floating point types can be bit-cast to an integer type of the same size, and possible
    ///   broken into smaller integer types.
    /// - Vector types can be bit-cast and broken down into smaller vectors or scalars.
    ///
    /// The legalizer will adapt argument and return values as necessary at all ABI boundaries.
    ///
    /// When this function is called to legalize the signature of the function currently begin
    /// compiler, `current` is true. The legalized signature can then also contain special purpose
    /// arguments and return values such as:
    ///
    /// - A `link` argument representing the link registers on RISC architectures that don't push
    ///   the return address on the stack.
    /// - A `link` return value which will receive the value that was passed to the `link`
    ///   argument.
    /// - An `sret` argument can be added if one wasn't present already. This is necessary if the
    ///   signature returns more values than registers are available for returning values.
    /// - An `sret` return value can be added if the ABI requires a function to return its `sret`
    ///   argument in a register.
    ///
    /// Arguments and return values for the caller's frame pointer and other callee-saved registers
    /// should not be added by this function. These arguments are not added until after register
    /// allocation.
    fn legalize_signature(&self, sig: &mut ir::Signature, current: bool);

    /// Get the register class that should be used to represent an ABI argument or return value of
    /// type `ty`. This should be the top-level register class that contains the argument
    /// registers.
    ///
    /// This function can assume that it will only be asked to provide register classes for types
    /// that `legalize_signature()` produces in `ArgumentLoc::Reg` entries.
    fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass;

    /// Get the set of allocatable registers that can be used when compiling `func`.
    ///
    /// This set excludes reserved registers like the stack pointer and other special-purpose
    /// registers.
    fn allocatable_registers(&self, func: &ir::Function) -> regalloc::AllocatableSet;

    /// Emit binary machine code for a single instruction into the `sink` trait object.
    ///
    /// Note that this will call `put*` methods on the trait object via its vtable which is not the
    /// fastest way of emitting code.
    fn emit_inst(&self,
                 func: &ir::Function,
                 inst: ir::Inst,
                 divert: &mut regalloc::RegDiversions,
                 sink: &mut binemit::CodeSink);

    /// Emit a whole function into memory.
    ///
    /// This is more performant than calling `emit_inst` for each instruction.
    fn emit_function(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);

    /// Get a static array of names associated with relocations in this ISA.
    ///
    /// This array can be indexed by the contents of `binemit::Reloc` objects passed to a
    /// `CodeSink`.
    fn reloc_names(&self) -> &'static [&'static str];
}
<commit_msg>Bugfix: encode function wasn't calling legalize function properly<commit_after>//! Instruction Set Architectures.
//!
//! The `isa` module provides a `TargetIsa` trait which provides the behavior specialization needed
//! by the ISA-independent code generator. The sub-modules of this module provide definitions for
//! the instruction sets that Cretonne can target. Each sub-module has it's own implementation of
//! `TargetIsa`.
//!
//! # Constructing a `TargetIsa` instance
//!
//! The target ISA is built from the following information:
//!
//! - The name of the target ISA as a string. Cretonne is a cross-compiler, so the ISA to target
//!   can be selected dynamically. Individual ISAs can be left out when Cretonne is compiled, so a
//!   string is used to identify the proper sub-module.
//! - Values for settings that apply to all ISAs. This is represented by a `settings::Flags`
//!   instance.
//! - Values for ISA-specific settings.
//!
//! The `isa::lookup()` function is the main entry point which returns an `isa::Builder`
//! appropriate for the requested ISA:
//!
//! ```
//! use cretonne::settings::{self, Configurable};
//! use cretonne::isa;
//!
//! let shared_builder = settings::builder();
//! let shared_flags = settings::Flags::new(&shared_builder);
//!
//! match isa::lookup("riscv") {
//!     None => {
//!         // The RISC-V target ISA is not available.
//!     }
//!     Some(mut isa_builder) => {
//!         isa_builder.set("supports_m", "on");
//!         let isa = isa_builder.finish(shared_flags);
//!     }
//! }
//! ```
//!
//! The configured target ISA trait object is a `Box<TargetIsa>` which can be used for multiple
//! concurrent function compilations.

pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind, BranchRange};
pub use isa::encoding::{Encoding, EncInfo};
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex, regs_overlap};

use binemit;
use settings;
use ir;
use regalloc;
use isa::enc_tables::Encodings;

pub mod riscv;
pub mod intel;
pub mod arm32;
pub mod arm64;
pub mod registers;
mod encoding;
mod enc_tables;
mod constraints;

/// Look for a supported ISA with the given `name`.
/// Return a builder that can create a corresponding `TargetIsa`.
pub fn lookup(name: &str) -> Option<Builder> {
    match name {
        "riscv" => riscv_builder(),
        "intel" => intel_builder(),
        "arm32" => arm32_builder(),
        "arm64" => arm64_builder(),
        _ => None,
    }
}

// Make a builder for RISC-V.
fn riscv_builder() -> Option<Builder> {
    Some(riscv::isa_builder())
}

fn intel_builder() -> Option<Builder> {
    Some(intel::isa_builder())
}

fn arm32_builder() -> Option<Builder> {
    Some(arm32::isa_builder())
}

fn arm64_builder() -> Option<Builder> {
    Some(arm64::isa_builder())
}

/// Builder for a `TargetIsa`.
/// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`.
pub struct Builder {
    setup: settings::Builder,
    constructor: fn(settings::Flags, &settings::Builder) -> Box<TargetIsa>,
}

impl Builder {
    /// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
    /// fully configured `TargetIsa` trait object.
    pub fn finish(self, shared_flags: settings::Flags) -> Box<TargetIsa> {
        (self.constructor)(shared_flags, &self.setup)
    }
}

impl settings::Configurable for Builder {
    fn set(&mut self, name: &str, value: &str) -> settings::Result<()> {
        self.setup.set(name, value)
    }

    fn enable(&mut self, name: &str) -> settings::Result<()> {
        self.setup.enable(name)
    }
}

/// After determining that an instruction doesn't have an encoding, how should we proceed to
/// legalize it?
///
/// These actions correspond to the transformation groups defined in `meta/cretonne/legalize.py`.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Legalize {
    /// Legalize in terms of narrower types.
    Narrow,

    /// Expanding in terms of other instructions using the same types.
    Expand,
}

/// Translate a legalization code into a `Legalize` enum.
///
/// This mapping is going away soon. It depends on matching the `TargetISA.legalize_code()`
/// mapping.
impl From<u8> for Legalize {
    fn from(x: u8) -> Legalize {
        match x {
            0 => Legalize::Narrow,
            1 => Legalize::Expand,
            _ => panic!("Unknown legalization code {}"),
        }
    }
}

/// Methods that are specialized to a target ISA.
pub trait TargetIsa {
    /// Get the name of this ISA.
    fn name(&self) -> &'static str;

    /// Get the ISA-independent flags that were used to make this trait object.
    fn flags(&self) -> &settings::Flags;

    /// Get a data structure describing the registers in this ISA.
    fn register_info(&self) -> RegInfo;

    /// Returns an iterartor over legal encodings for the instruction.
    fn legal_encodings<'a>(&'a self,
                           dfg: &'a ir::DataFlowGraph,
                           inst: &'a ir::InstructionData,
                           ctrl_typevar: ir::Type)
                           -> Encodings<'a>;

    /// Encode an instruction after determining it is legal.
    ///
    /// If `inst` can legally be encoded in this ISA, produce the corresponding `Encoding` object.
    /// Otherwise, return `Legalize` action.
    ///
    /// This is also the main entry point for determining if an instruction is legal.
    fn encode(&self,
              dfg: &ir::DataFlowGraph,
              inst: &ir::InstructionData,
              ctrl_typevar: ir::Type)
              -> Result<Encoding, Legalize> {
        let mut iter = self.legal_encodings(dfg, inst, ctrl_typevar);
        iter.next().ok_or_else(|| iter.legalize().into())
    }

    /// Get a data structure describing the instruction encodings in this ISA.
    fn encoding_info(&self) -> EncInfo;

    /// Legalize a function signature.
    ///
    /// This is used to legalize both the signature of the function being compiled and any called
    /// functions. The signature should be modified by adding `ArgumentLoc` annotations to all
    /// arguments and return values.
    ///
    /// Arguments with types that are not supported by the ABI can be expanded into multiple
    /// arguments:
    ///
    /// - Integer types that are too large to fit in a register can be broken into multiple
    ///   arguments of a smaller integer type.
    /// - Floating point types can be bit-cast to an integer type of the same size, and possible
    ///   broken into smaller integer types.
    /// - Vector types can be bit-cast and broken down into smaller vectors or scalars.
    ///
    /// The legalizer will adapt argument and return values as necessary at all ABI boundaries.
    ///
    /// When this function is called to legalize the signature of the function currently begin
    /// compiler, `current` is true. The legalized signature can then also contain special purpose
    /// arguments and return values such as:
    ///
    /// - A `link` argument representing the link registers on RISC architectures that don't push
    ///   the return address on the stack.
    /// - A `link` return value which will receive the value that was passed to the `link`
    ///   argument.
    /// - An `sret` argument can be added if one wasn't present already. This is necessary if the
    ///   signature returns more values than registers are available for returning values.
    /// - An `sret` return value can be added if the ABI requires a function to return its `sret`
    ///   argument in a register.
    ///
    /// Arguments and return values for the caller's frame pointer and other callee-saved registers
    /// should not be added by this function. These arguments are not added until after register
    /// allocation.
    fn legalize_signature(&self, sig: &mut ir::Signature, current: bool);

    /// Get the register class that should be used to represent an ABI argument or return value of
    /// type `ty`. This should be the top-level register class that contains the argument
    /// registers.
    ///
    /// This function can assume that it will only be asked to provide register classes for types
    /// that `legalize_signature()` produces in `ArgumentLoc::Reg` entries.
    fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass;

    /// Get the set of allocatable registers that can be used when compiling `func`.
    ///
    /// This set excludes reserved registers like the stack pointer and other special-purpose
    /// registers.
    fn allocatable_registers(&self, func: &ir::Function) -> regalloc::AllocatableSet;

    /// Emit binary machine code for a single instruction into the `sink` trait object.
    ///
    /// Note that this will call `put*` methods on the trait object via its vtable which is not the
    /// fastest way of emitting code.
    fn emit_inst(&self,
                 func: &ir::Function,
                 inst: ir::Inst,
                 divert: &mut regalloc::RegDiversions,
                 sink: &mut binemit::CodeSink);

    /// Emit a whole function into memory.
    ///
    /// This is more performant than calling `emit_inst` for each instruction.
    fn emit_function(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);

    /// Get a static array of names associated with relocations in this ISA.
    ///
    /// This array can be indexed by the contents of `binemit::Reloc` objects passed to a
    /// `CodeSink`.
    fn reloc_names(&self) -> &'static [&'static str];
}
<|endoftext|>


<commit_before>extern crate gst;

use std::env;
use std::os::raw::c_void;
use std::mem;

extern "C" fn signal_callback(_src: *mut gst::GstElement, pad: *mut gst::GstPad, sinkpad: &mut gst::Pad){
    unsafe{
        if !sinkpad.is_linked(){
            let mut decodebin_pad = gst::Pad::new(pad).unwrap();
            let caps = decodebin_pad.query_caps(None).unwrap();
            let structure = caps.structure(0).unwrap();
            if structure.name().starts_with("video") {
                decodebin_pad.link(sinkpad).unwrap();
            }
        }
    }
}

fn main(){
    gst::init();
    let args: Vec<_> = env::args().collect();
    let uri: &str = if args.len() == 2 {
        args[1].as_ref()
    }else{
        panic!("Usage: pipeline file_path");
    };

    let mut pipeline = gst::Pipeline::new("video_player").expect("Couldn't create playbin");
    let mut filesrc = gst::Element::new("filesrc", "").unwrap();
    filesrc.set("location", uri);
    let decodebin = gst::Element::new("decodebin", "").unwrap();
    let mut sink = gst::Element::new("glimagesink", "").unwrap();
    let mut sink_pad = sink.static_pad("sink").unwrap();
    let mut decodebin_ref = gst::Ref::new(&decodebin);
    if !pipeline.add_and_link(filesrc, decodebin){
        panic!("couldn't link filesrc and decodebin");
    }
    unsafe{
        decodebin_ref.signal_connect("pad-added", mem::transmute(signal_callback as *mut c_void), &mut sink_pad);
    }
    pipeline.add(sink);
    let mut mainloop = gst::MainLoop::new();
    let mut bus = pipeline.bus().expect("Couldn't get pipeline bus");
    let bus_receiver = bus.receiver();
    mainloop.spawn();
    pipeline.play();
    for message in bus_receiver.iter(){
        match message.parse(){
            gst::Message::StateChangedParsed{ref old, ref new, ..} => {
                println!("element `{}` changed from {:?} to {:?}", message.src_name(), old, new);
            }
            gst::Message::ErrorParsed{ref error, ref debug, ..} => {
				println!("error msg from element `{}`: {}, {}. Quitting", message.src_name(), error.message(), debug);
                break;
            }
            gst::Message::Eos(_) => {
                println!("eos received quiting");
                break;
            }
            _ => {
                println!("msg of type `{}` from element `{}`", message.type_name(), message.src_name());
            }
        }
    }
    mainloop.quit();
}
<commit_msg>decodebin example: don't use unneded reference<commit_after>extern crate gst;

use std::env;
use std::os::raw::c_void;
use std::mem;

extern "C" fn signal_callback(_src: *mut gst::GstElement, pad: *mut gst::GstPad, sinkpad: &mut gst::Pad){
    unsafe{
        if !sinkpad.is_linked(){
            let mut decodebin_pad = gst::Pad::new(pad).unwrap();
            let caps = decodebin_pad.query_caps(None).unwrap();
            let structure = caps.structure(0).unwrap();
            if structure.name().starts_with("video") {
                decodebin_pad.link(sinkpad).unwrap();
            }
        }
    }
}

fn main(){
    gst::init();
    let args: Vec<_> = env::args().collect();
    let uri: &str = if args.len() == 2 {
        args[1].as_ref()
    }else{
        panic!("Usage: pipeline file_path");
    };

    let mut pipeline = gst::Pipeline::new("video_player").expect("Couldn't create playbin");
    let mut filesrc = gst::Element::new("filesrc", "").unwrap();
    filesrc.set("location", uri);
    let mut decodebin = gst::Element::new("decodebin", "").unwrap();
    let mut sink = gst::Element::new("glimagesink", "").unwrap();
    let mut sink_pad = sink.static_pad("sink").unwrap();
    unsafe{
        decodebin.signal_connect("pad-added", mem::transmute(signal_callback as *mut c_void), &mut sink_pad);
    }
    if !pipeline.add_and_link(filesrc, decodebin){
        panic!("couldn't link filesrc and decodebin");
    }
    pipeline.add(sink);
    let mut mainloop = gst::MainLoop::new();
    let mut bus = pipeline.bus().expect("Couldn't get pipeline bus");
    let bus_receiver = bus.receiver();
    mainloop.spawn();
    pipeline.play();
    for message in bus_receiver.iter(){
        match message.parse(){
            gst::Message::StateChangedParsed{ref old, ref new, ..} => {
                println!("element `{}` changed from {:?} to {:?}", message.src_name(), old, new);
            }
            gst::Message::ErrorParsed{ref error, ref debug, ..} => {
				println!("error msg from element `{}`: {}, {}. Quitting", message.src_name(), error.message(), debug);
                break;
            }
            gst::Message::Eos(_) => {
                println!("eos received quiting");
                break;
            }
            _ => {
                println!("msg of type `{}` from element `{}`", message.type_name(), message.src_name());
            }
        }
    }
    mainloop.quit();
}
<|endoftext|>


<commit_before>extern crate zip;

use std::fs;

fn main() {
    std::process::exit(real_main());
}

fn real_main() -> i32 {
    let args: Vec<_> = std::env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <filename>", args[0]);
        return 1;
    }
    let fname = std::path::Path::new(&*args[1]);
    let file = fs::File::open(&fname).unwrap();

    let mut archive = zip::ZipArchive::new(file).unwrap();

    for i in 0..archive.len() {
        let file = archive.by_index(i).unwrap();
        let outpath = file.sanitized_name();

        {
            let comment = file.comment();
            if !comment.is_empty() {
                println!("Entry {} comment: {}", i, comment);
            }
        }

        if (&*file.name()).ends_with('/') {
            println!("Entry {} is a directory with name \"{}\"", i, outpath.as_path().display());
        } else {
            println!("Entry {} is a file with name \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size());
        }
    }
    return 0;
}
<commit_msg>Use BufReader in file_info example<commit_after>extern crate zip;

use std::fs;
use std::io::BufReader;

fn main() {
    std::process::exit(real_main());
}

fn real_main() -> i32 {
    let args: Vec<_> = std::env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <filename>", args[0]);
        return 1;
    }
    let fname = std::path::Path::new(&*args[1]);
    let file = fs::File::open(&fname).unwrap();
    let reader = BufReader::new(file);

    let mut archive = zip::ZipArchive::new(reader).unwrap();

    for i in 0..archive.len() {
        let file = archive.by_index(i).unwrap();
        let outpath = file.sanitized_name();

        {
            let comment = file.comment();
            if !comment.is_empty() {
                println!("Entry {} comment: {}", i, comment);
            }
        }

        if (&*file.name()).ends_with('/') {
            println!("Entry {} is a directory with name \"{}\"", i, outpath.as_path().display());
        } else {
            println!("Entry {} is a file with name \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size());
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>#![deny(warnings)]
extern crate futures;
extern crate hyper;
extern crate pretty_env_logger;

use futures::{Future, Sink};
use futures::sync::{mpsc, oneshot};

use hyper::{Chunk, Get, StatusCode};
use hyper::error::Error;
use hyper::header::ContentLength;
use hyper::server::{Http, Service, Request, Response};

use std::fs::File;
use std::io::{self, copy, Read};
use std::thread;

static NOTFOUND: &[u8] = b"Not Found";
static INDEX: &str = "examples/send_file_index.html";

fn simple_file_send(f: &str) -> Box<Future<Item = Response, Error = hyper::Error>> {
    // Serve a file by reading it entirely into memory. As a result
    // this is limited to serving small files, but it is somewhat
    // simpler with a little less overhead.
    //
    // On channel errors, we panic with the expect method. The thread
    // ends at that point in any case.
    let filename = f.to_string(); // we need to copy for lifetime issues
    let (tx, rx) = oneshot::channel();
    thread::spawn(move || {
        let mut file = match File::open(filename) {
            Ok(f) => f,
            Err(_) => {
                tx.send(Response::new()
                        .with_status(StatusCode::NotFound)
                        .with_header(ContentLength(NOTFOUND.len() as u64))
                        .with_body(NOTFOUND))
                    .expect("Send error on open");
                return;
            },
        };
        let mut buf: Vec<u8> = Vec::new();
        match copy(&mut file, &mut buf) {
            Ok(_) => {
                let res = Response::new()
                    .with_header(ContentLength(buf.len() as u64))
                    .with_body(buf);
                tx.send(res).expect("Send error on successful file read");
            },
            Err(_) => {
                tx.send(Response::new().with_status(StatusCode::InternalServerError)).
                    expect("Send error on error reading file");
            },
        };
    });

    Box::new(rx.map_err(|e| Error::from(io::Error::new(io::ErrorKind::Other, e))))
}

struct ResponseExamples;

impl Service for ResponseExamples {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;

    fn call(&self, req: Request) -> Self::Future {
        match (req.method(), req.path()) {
            (&Get, "/") | (&Get, "/index.html") => {
                simple_file_send(INDEX)
            },
            (&Get, "/big_file.html") => {
                // Stream a large file in chunks. This requires a
                // little more overhead with two channels, (one for
                // the response future, and a second for the response
                // body), but can handle arbitrarily large files.
                //
                // We use an artificially small buffer, since we have
                // a small test file.
                let (tx, rx) = oneshot::channel();
                thread::spawn(move || {
                    let mut file = match File::open(INDEX) {
                        Ok(f) => f,
                        Err(_) => {
                            tx.send(Response::new()
                                    .with_status(StatusCode::NotFound)
                                    .with_header(ContentLength(NOTFOUND.len() as u64))
                                    .with_body(NOTFOUND))
                                .expect("Send error on open");
                            return;
                        },
                    };
                    let (mut tx_body, rx_body) = mpsc::channel(1);
                    let res = Response::new().with_body(rx_body);
                    tx.send(res).expect("Send error on successful file read");
                    let mut buf = [0u8; 16];
                    loop {
                        match file.read(&mut buf) {
                            Ok(n) => {
                                if n == 0 {
                                    // eof
                                    tx_body.close().expect("panic closing");
                                    break;
                                } else {
                                    let chunk: Chunk = buf.to_vec().into();
                                    match tx_body.send(Ok(chunk)).wait() {
                                        Ok(t) => { tx_body = t; },
                                        Err(_) => { break; }
                                    };
                                }
                            },
                            Err(_) => { break; }
                        }
                    }
                });

                Box::new(rx.map_err(|e| Error::from(io::Error::new(io::ErrorKind::Other, e))))
            },
            (&Get, "/no_file.html") => {
                // Test what happens when file cannot be be found
                simple_file_send("this_file_should_not_exist.html")
            },
            _ => {
                Box::new(futures::future::ok(Response::new()
                                    .with_status(StatusCode::NotFound)))
            }
        }
    }

}

fn main() {
    pretty_env_logger::init();
    let addr = "127.0.0.1:1337".parse().unwrap();

    let server = Http::new().bind(&addr, || Ok(ResponseExamples)).unwrap();
    println!("Listening on http://{} with 1 thread.", server.local_addr().unwrap());
    server.run().unwrap();
}
<commit_msg>docs(example): fix send file to only send range of buffer read into<commit_after>#![deny(warnings)]
extern crate futures;
extern crate hyper;
extern crate pretty_env_logger;

use futures::{Future, Sink};
use futures::sync::{mpsc, oneshot};

use hyper::{Chunk, Get, StatusCode};
use hyper::error::Error;
use hyper::header::ContentLength;
use hyper::server::{Http, Service, Request, Response};

use std::fs::File;
use std::io::{self, copy, Read};
use std::thread;

static NOTFOUND: &[u8] = b"Not Found";
static INDEX: &str = "examples/send_file_index.html";

fn simple_file_send(f: &str) -> Box<Future<Item = Response, Error = hyper::Error>> {
    // Serve a file by reading it entirely into memory. As a result
    // this is limited to serving small files, but it is somewhat
    // simpler with a little less overhead.
    //
    // On channel errors, we panic with the expect method. The thread
    // ends at that point in any case.
    let filename = f.to_string(); // we need to copy for lifetime issues
    let (tx, rx) = oneshot::channel();
    thread::spawn(move || {
        let mut file = match File::open(filename) {
            Ok(f) => f,
            Err(_) => {
                tx.send(Response::new()
                        .with_status(StatusCode::NotFound)
                        .with_header(ContentLength(NOTFOUND.len() as u64))
                        .with_body(NOTFOUND))
                    .expect("Send error on open");
                return;
            },
        };
        let mut buf: Vec<u8> = Vec::new();
        match copy(&mut file, &mut buf) {
            Ok(_) => {
                let res = Response::new()
                    .with_header(ContentLength(buf.len() as u64))
                    .with_body(buf);
                tx.send(res).expect("Send error on successful file read");
            },
            Err(_) => {
                tx.send(Response::new().with_status(StatusCode::InternalServerError)).
                    expect("Send error on error reading file");
            },
        };
    });

    Box::new(rx.map_err(|e| Error::from(io::Error::new(io::ErrorKind::Other, e))))
}

struct ResponseExamples;

impl Service for ResponseExamples {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;

    fn call(&self, req: Request) -> Self::Future {
        match (req.method(), req.path()) {
            (&Get, "/") | (&Get, "/index.html") => {
                simple_file_send(INDEX)
            },
            (&Get, "/big_file.html") => {
                // Stream a large file in chunks. This requires a
                // little more overhead with two channels, (one for
                // the response future, and a second for the response
                // body), but can handle arbitrarily large files.
                //
                // We use an artificially small buffer, since we have
                // a small test file.
                let (tx, rx) = oneshot::channel();
                thread::spawn(move || {
                    let mut file = match File::open(INDEX) {
                        Ok(f) => f,
                        Err(_) => {
                            tx.send(Response::new()
                                    .with_status(StatusCode::NotFound)
                                    .with_header(ContentLength(NOTFOUND.len() as u64))
                                    .with_body(NOTFOUND))
                                .expect("Send error on open");
                            return;
                        },
                    };
                    let (mut tx_body, rx_body) = mpsc::channel(1);
                    let res = Response::new().with_body(rx_body);
                    tx.send(res).expect("Send error on successful file read");
                    let mut buf = [0u8; 16];
                    loop {
                        match file.read(&mut buf) {
                            Ok(n) => {
                                if n == 0 {
                                    // eof
                                    tx_body.close().expect("panic closing");
                                    break;
                                } else {
                                    let chunk: Chunk = buf[0..n].to_vec().into();
                                    match tx_body.send(Ok(chunk)).wait() {
                                        Ok(t) => { tx_body = t; },
                                        Err(_) => { break; }
                                    };
                                }
                            },
                            Err(_) => { break; }
                        }
                    }
                });

                Box::new(rx.map_err(|e| Error::from(io::Error::new(io::ErrorKind::Other, e))))
            },
            (&Get, "/no_file.html") => {
                // Test what happens when file cannot be be found
                simple_file_send("this_file_should_not_exist.html")
            },
            _ => {
                Box::new(futures::future::ok(Response::new()
                                    .with_status(StatusCode::NotFound)))
            }
        }
    }

}

fn main() {
    pretty_env_logger::init();
    let addr = "127.0.0.1:1337".parse().unwrap();

    let server = Http::new().bind(&addr, || Ok(ResponseExamples)).unwrap();
    println!("Listening on http://{} with 1 thread.", server.local_addr().unwrap());
    server.run().unwrap();
}
<|endoftext|>


<commit_before>/// Model represents the global states needed in FZF.
/// It will also define how the states will be shown on the terminal

use std::sync::{Arc, RwLock};
use item::{Item, MatchedItem, MatchedRange};
use ncurses::*;
use std::cmp;
use std::cell::RefCell;
use std::collections::HashSet;
use orderedvec::OrderedVec;
use curses::*;

pub struct Model {
    pub query: String,
    query_cursor: i32,  // > qu<query_cursor>ery
    num_matched: u64,
    num_total: u64,
    pub items: Arc<RwLock<Vec<Item>>>, // all items
    selected_indics: HashSet<usize>,
    pub matched_items: RefCell<OrderedVec<MatchedItem>>,
    item_cursor: usize, // the index of matched item currently highlighted.
    line_cursor: usize, // line No.
    item_start_pos: usize, // for screen scroll.
    max_y: i32,
    max_x: i32,
    curses: Curses,
}

impl Model {
    pub fn new(curses: Curses) -> Self {
        let (max_y, max_x) = curses.get_maxyx();

        Model {
            query: String::new(),
            query_cursor: 0,
            num_matched: 0,
            num_total: 0,
            items: Arc::new(RwLock::new(Vec::new())),
            selected_indics: HashSet::new(),
            matched_items: RefCell::new(OrderedVec::new()),
            item_cursor: 0,
            line_cursor: (max_y - 3) as usize,
            item_start_pos: 0,
            max_y: max_y,
            max_x: max_x,
            curses: curses,
        }
    }

    pub fn output(&self) {
        let mut selected = self.selected_indics.iter().collect::<Vec<&usize>>();
        selected.sort();
        let items = self.items.read().unwrap();
        for index in selected {
            println!("{}", items[*index].text);
        }
    }

    pub fn toggle_select(&mut self, selected: Option<bool>) {
        let mut matched_items = self.matched_items.borrow_mut();
        let index = matched_items.get(self.item_cursor).unwrap().index;
        match selected {
            Some(true) => {
                let _ = self.selected_indics.insert(index);
            }
            Some(false) => {
                let _ = self.selected_indics.remove(&index);
            }
            None => {
                if self.selected_indics.contains(&index) {
                    let _ = self.selected_indics.remove(&index);
                } else {
                    let _ = self.selected_indics.insert(index);
                }
            }
        }
    }

    pub fn update_query(&mut self, query: String, cursor: i32) {
        self.query = query;
        self.query_cursor = cursor;
    }

    pub fn update_process_info(&mut self, matched: u64, total: u64) {
        self.num_matched = matched;
        self.num_total = total;
    }

    pub fn push_item(&mut self, item: MatchedItem) {
        self.matched_items.borrow_mut().push(item);
    }

    pub fn clear_items(&mut self) {
        self.matched_items.borrow_mut().clear();
    }

    pub fn move_line_cursor(&mut self, diff: i32) {

        let y = self.line_cursor as i32 + diff;
        let item_y = cmp::max(0, self.item_cursor as i32 - diff);
        let screen_height = (self.max_y - 3) as usize;

        match y {
            y if y < 0 => {
                self.line_cursor = 0;
                self.item_cursor = cmp::min(item_y as usize, self.matched_items.borrow().len()-1);
                self.item_start_pos = self.item_cursor - screen_height;
            }

            y if y > screen_height as i32 => {
                self.line_cursor = screen_height;
                self.item_cursor = cmp::max(0, item_y as usize);
                self.item_start_pos = self.item_cursor;
            }

            y => {
                self.line_cursor = y as usize;
                self.item_cursor = item_y as usize;
            }
        }
    }

    pub fn print_query(&self) {
        // > query
        mv(self.max_y-1, 0);
        addstr("> ");
        addstr(&self.query);
        mv(self.max_y-1, self.query_cursor+2);
    }

    pub fn print_info(&self) {
        mv(self.max_y-2, 0);
        addstr(format!("  {}/{}", self.num_matched, self.num_total).as_str());
    }

    fn print_item(&self, item: &Item, matched: &MatchedItem) {
        if self.selected_indics.contains(&matched.index) {
            printw(">");
        } else {
            printw(" ");
        }

        match matched.matched_range {
            Some(MatchedRange::Chars(ref matched_indics)) => {
                let mut matched_indics_iter = matched_indics.iter().peekable();
                for (idx, ch) in item.text.chars().enumerate() {
                    if let Some(&&index) = matched_indics_iter.peek() {
                        if idx == index {
                            let attr = self.curses.get_color(COLOR_MATCHED, false);
                            attron(attr);
                            addch(ch as u64);
                            attroff(attr);
                            let _ = matched_indics_iter.next();
                        } else {
                            addch(ch as u64);
                        }
                    } else {
                        addch(ch as u64);
                    }
                    if idx >= (self.max_x - 3) as usize {
                        break;
                    }
                }
            }
            Some(MatchedRange::Range(_, _)) => {
                // pass
            }
            None => {
                // pass
            }
        }

    }

    pub fn print_items(&self) {
        let items = self.items.read().unwrap();
        let mut matched_items = self.matched_items.borrow_mut();

        let mut y = self.max_y - 3;
        let mut i = self.item_start_pos;
        while let Some(matched) = matched_items.get(i) {
            i+=1;

            mv(y, 0);
            let is_current_line = y == self.line_cursor as i32;

            let mut label = if is_current_line {">"} else {" "};

            self.curses.cprint(COLOR_CURSOR, true, label);

            self.print_item(&items[matched.index], matched);

            y -= 1;
            if y < 0 {
                break;
            }
        }
    }

    pub fn refresh(&self) {
        refresh();
    }

    pub fn display(&self) {
        erase();
        self.print_items();
        self.print_info();
        self.print_query();
        self.refresh();
    }

    // the terminal resizes, so we need to recalculate the margins.
    pub fn resize(&mut self) {
        clear();
        endwin();
        refresh();
        let mut max_y = 0;
        let mut max_x = 0;
        getmaxyx(stdscr, &mut max_y, &mut max_x);
        self.max_y = max_y;
        self.max_x = max_x;
    }
}
<commit_msg>[model] set color for selected mark<commit_after>/// Model represents the global states needed in FZF.
/// It will also define how the states will be shown on the terminal

use std::sync::{Arc, RwLock};
use item::{Item, MatchedItem, MatchedRange};
use ncurses::*;
use std::cmp;
use std::cell::RefCell;
use std::collections::HashSet;
use orderedvec::OrderedVec;
use curses::*;

pub struct Model {
    pub query: String,
    query_cursor: i32,  // > qu<query_cursor>ery
    num_matched: u64,
    num_total: u64,
    pub items: Arc<RwLock<Vec<Item>>>, // all items
    selected_indics: HashSet<usize>,
    pub matched_items: RefCell<OrderedVec<MatchedItem>>,
    item_cursor: usize, // the index of matched item currently highlighted.
    line_cursor: usize, // line No.
    item_start_pos: usize, // for screen scroll.
    max_y: i32,
    max_x: i32,
    curses: Curses,
}

impl Model {
    pub fn new(curses: Curses) -> Self {
        let (max_y, max_x) = curses.get_maxyx();

        Model {
            query: String::new(),
            query_cursor: 0,
            num_matched: 0,
            num_total: 0,
            items: Arc::new(RwLock::new(Vec::new())),
            selected_indics: HashSet::new(),
            matched_items: RefCell::new(OrderedVec::new()),
            item_cursor: 0,
            line_cursor: (max_y - 3) as usize,
            item_start_pos: 0,
            max_y: max_y,
            max_x: max_x,
            curses: curses,
        }
    }

    pub fn output(&self) {
        let mut selected = self.selected_indics.iter().collect::<Vec<&usize>>();
        selected.sort();
        let items = self.items.read().unwrap();
        for index in selected {
            println!("{}", items[*index].text);
        }
    }

    pub fn toggle_select(&mut self, selected: Option<bool>) {
        let mut matched_items = self.matched_items.borrow_mut();
        let index = matched_items.get(self.item_cursor).unwrap().index;
        match selected {
            Some(true) => {
                let _ = self.selected_indics.insert(index);
            }
            Some(false) => {
                let _ = self.selected_indics.remove(&index);
            }
            None => {
                if self.selected_indics.contains(&index) {
                    let _ = self.selected_indics.remove(&index);
                } else {
                    let _ = self.selected_indics.insert(index);
                }
            }
        }
    }

    pub fn update_query(&mut self, query: String, cursor: i32) {
        self.query = query;
        self.query_cursor = cursor;
    }

    pub fn update_process_info(&mut self, matched: u64, total: u64) {
        self.num_matched = matched;
        self.num_total = total;
    }

    pub fn push_item(&mut self, item: MatchedItem) {
        self.matched_items.borrow_mut().push(item);
    }

    pub fn clear_items(&mut self) {
        self.matched_items.borrow_mut().clear();
    }

    pub fn move_line_cursor(&mut self, diff: i32) {

        let y = self.line_cursor as i32 + diff;
        let item_y = cmp::max(0, self.item_cursor as i32 - diff);
        let screen_height = (self.max_y - 3) as usize;

        match y {
            y if y < 0 => {
                self.line_cursor = 0;
                self.item_cursor = cmp::min(item_y as usize, self.matched_items.borrow().len()-1);
                self.item_start_pos = self.item_cursor - screen_height;
            }

            y if y > screen_height as i32 => {
                self.line_cursor = screen_height;
                self.item_cursor = cmp::max(0, item_y as usize);
                self.item_start_pos = self.item_cursor;
            }

            y => {
                self.line_cursor = y as usize;
                self.item_cursor = item_y as usize;
            }
        }
    }

    pub fn print_query(&self) {
        // > query
        mv(self.max_y-1, 0);
        addstr("> ");
        addstr(&self.query);
        mv(self.max_y-1, self.query_cursor+2);
    }

    pub fn print_info(&self) {
        mv(self.max_y-2, 0);
        addstr(format!("  {}/{}", self.num_matched, self.num_total).as_str());
    }

    fn print_item(&self, matched: &MatchedItem, is_current: bool) {
        let items = self.items.read().unwrap();
        let ref item = items[matched.index];

        let is_selected = self.selected_indics.contains(&matched.index);

        if is_selected {
            self.curses.cprint(COLOR_SELECTED, true, ">");
        } else {
            self.curses.cprint(if is_current {COLOR_CURRENT} else {COLOR_NORMAL}, false, " ");
        }

        match matched.matched_range {
            Some(MatchedRange::Chars(ref matched_indics)) => {
                let mut matched_indics_iter = matched_indics.iter().peekable();
                for (idx, ch) in item.text.chars().enumerate() {
                    if let Some(&&index) = matched_indics_iter.peek() {
                        if idx == index {
                            let attr = self.curses.get_color(COLOR_MATCHED, false);
                            attron(attr);
                            addch(ch as u64);
                            attroff(attr);
                            let _ = matched_indics_iter.next();
                        } else {
                            addch(ch as u64);
                        }
                    } else {
                        addch(ch as u64);
                    }
                    if idx >= (self.max_x - 3) as usize {
                        break;
                    }
                }
            }
            Some(MatchedRange::Range(_, _)) => {
                // pass
            }
            None => {
                // pass
            }
        }

    }

    pub fn print_items(&self) {
        let mut matched_items = self.matched_items.borrow_mut();

        let mut y = self.max_y - 3;
        let mut i = self.item_start_pos;
        while let Some(matched) = matched_items.get(i) {
            i+=1;

            mv(y, 0);
            let is_current_line = y == self.line_cursor as i32;

            let mut label = if is_current_line {">"} else {" "};

            self.curses.cprint(COLOR_CURSOR, true, label);

            self.print_item(matched, is_current_line);

            y -= 1;
            if y < 0 {
                break;
            }
        }
    }

    pub fn refresh(&self) {
        refresh();
    }

    pub fn display(&self) {
        erase();
        self.print_items();
        self.print_info();
        self.print_query();
        self.refresh();
    }

    // the terminal resizes, so we need to recalculate the margins.
    pub fn resize(&mut self) {
        clear();
        endwin();
        refresh();
        let mut max_y = 0;
        let mut max_x = 0;
        getmaxyx(stdscr, &mut max_y, &mut max_x);
        self.max_y = max_y;
        self.max_x = max_x;
    }
}
<|endoftext|>


<commit_before>#![allow(unused_variables)]

use std::error::Error;
use wavefront_obj::obj::{self, Object, Shape};

use glium::index::{PrimitiveType, IndexBuffer};
use glium::{Surface, DrawError, VertexBuffer, Program};
use glium::uniforms::Uniforms;
use glium::backend::glutin_backend::GlutinFacade;
use {assets, Api};

#[derive(Debug)]
pub struct Model {
    meshes: Vec<Mesh>,
}

impl Model {
    pub fn load(facade: &GlutinFacade, path: &str) -> Result<Model, Box<Error>> {
        use wavefront_obj::obj;

        let objset = obj::parse(try!(assets::slurp(&format!("./assets/models/{}", path))))
                         .expect("Failed to parse an obj model");

        let meshes = try!(objset.objects
                                .into_iter()
                                .map(|o| Mesh::from_obj(facade, o))
                                .collect::<Result<Vec<_>, Box<Error>>>());

        Ok(Model { meshes: meshes })
    }

    pub fn draw<S: Surface, U: Uniforms>(&self,
                            api: &mut Api<S>,
                            program: &Program,
                            uniforms: &U)
                            -> Result<(), DrawError> {
        for m in &self.meshes {
            try!(m.draw(api, program, uniforms))
        }
        Ok(())
    }
}

#[derive(Debug)]
struct Mesh {
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u16>,
}

impl Mesh {
    fn from_obj(facade: &GlutinFacade, obj: Object) -> Result<Mesh, Box<Error>> {
        let vertices = obj.vertices
                          .into_iter()
                          .map(Vertex::from)
                          .collect::<Vec<_>>();
        let indices = obj.geometry
                         .into_iter()
                         .flat_map(|g| {
                             g.shapes.into_iter().flat_map(|s| {
                                 match s {
                                     Shape::Triangle(a, b, c) => vec![a, b, c].into_iter(),
                                     _ => panic!("unsupported shape"),
                                 }
                             })
                         })
                         .map(|(v, _, _)| v as u16)
                         .collect::<Vec<_>>();

        Ok(Mesh {
            vertex_buffer: try!(VertexBuffer::new(facade, &vertices)),
            index_buffer: IndexBuffer::new(facade, PrimitiveType::TrianglesList, &indices)
                              .expect("Failed to create an index buffer"),
        })
    }
}

impl Mesh {
    pub fn draw<S: Surface, U: Uniforms>(&self,
                                         api: &mut Api<S>,
                                         program: &Program,
                                         uniforms: &U)
                                         -> Result<(), DrawError> {

        api.surface.draw(&self.vertex_buffer,
                         &self.index_buffer,
                         program,
                         uniforms,
                         &api.default_params)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Vertex {
    position: [f32; 3],
}

impl From<obj::Vertex> for Vertex {
    fn from(v: obj::Vertex) -> Vertex {
        Vertex { position: [v.x as f32, v.y as f32, v.z as f32] }
    }
}

implement_vertex!(Vertex, position);
<commit_msg>don't unwrap errors<commit_after>#![allow(unused_variables)]

use glium::backend::glutin_backend::GlutinFacade;
use glium::index::{PrimitiveType, IndexBuffer};
use glium::uniforms::Uniforms;
use glium::vertex::BufferCreationError as VertexBufferCreationError;
use glium::index::BufferCreationError as IndexBufferCreationError;
use glium::{Surface, DrawError, VertexBuffer, Program};

use wavefront_obj::obj::{self, Object, Shape};
use wavefront_obj::ParseError;

use {assets, Api};

quick_error! {
    #[derive(Debug)]
    pub enum ModelLoadingError {
        AssetError(err: assets::AssetLoadingError) {
            from()
            cause(err)
        }
        VertexBufferCreationError(err: VertexBufferCreationError) {
            from()
            cause(err)
        }
        IndexBufferCreationError(err: IndexBufferCreationError) {
            from()
        }
        ParseError(err: ParseError) {
            from()
        }
    }
}

#[derive(Debug)]
pub struct Model {
    meshes: Vec<Mesh>,
}

impl Model {
    pub fn load(facade: &GlutinFacade, path: &str) -> Result<Model, ModelLoadingError> {
        let bytes = try!(assets::slurp(&format!("./assets/models/{}", path)));
        let objset = try!(obj::parse(bytes));

        let meshes = try!(objset.objects
                                .into_iter()
                                .map(|o| Mesh::from_obj(facade, o))
                                .collect::<Result<Vec<_>, _>>());

        Ok(Model { meshes: meshes })
    }

    pub fn draw<S: Surface, U: Uniforms>(&self,
                                         api: &mut Api<S>,
                                         program: &Program,
                                         uniforms: &U)
                                         -> Result<(), DrawError> {
        for m in &self.meshes {
            try!(m.draw(api, program, uniforms))
        }
        Ok(())
    }
}

#[derive(Debug)]
struct Mesh {
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u16>,
}

impl Mesh {
    fn from_obj(facade: &GlutinFacade, obj: Object) -> Result<Mesh, ModelLoadingError> {
        let vertices = obj.vertices
                          .into_iter()
                          .map(Vertex::from)
                          .collect::<Vec<_>>();
        let indices = obj.geometry
                         .into_iter()
                         .flat_map(|g| {
                             g.shapes.into_iter().flat_map(|s| {
                                 match s {
                                     Shape::Triangle(a, b, c) => vec![a, b, c].into_iter(),
                                     _ => panic!("unsupported shape"),
                                 }
                             })
                         })
                         .map(|(v, _, _)| v as u16)
                         .collect::<Vec<_>>();

        Ok(Mesh {
            vertex_buffer: try!(VertexBuffer::new(facade, &vertices)),
            index_buffer: try!(IndexBuffer::new(facade, PrimitiveType::TrianglesList, &indices)),
        })
    }
}

impl Mesh {
    pub fn draw<S: Surface, U: Uniforms>(&self,
                                         api: &mut Api<S>,
                                         program: &Program,
                                         uniforms: &U)
                                         -> Result<(), DrawError> {

        api.surface.draw(&self.vertex_buffer,
                         &self.index_buffer,
                         program,
                         uniforms,
                         &api.default_params)
    }
}

#[derive(Copy, Clone, Debug)]
pub struct Vertex {
    position: [f32; 3],
}

impl From<obj::Vertex> for Vertex {
    fn from(v: obj::Vertex) -> Vertex {
        Vertex { position: [v.x as f32, v.y as f32, v.z as f32] }
    }
}

implement_vertex!(Vertex, position);
<|endoftext|>


<commit_before>#![crate_name = "uu_od"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Ben Hirsch <benhirsch24@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::fs::File;
use std::io::Read;
use std::mem;
use std::path::Path;

#[derive(Debug)]
enum Radix { Decimal, Hexadecimal, Octal, Binary }

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = getopts::Options::new();

    opts.optopt("A", "address-radix",
                "Select the base in which file offsets are printed.", "RADIX");
    opts.optopt("j", "skip-bytes",
                "Skip bytes input bytes before formatting and writing.", "BYTES");
    opts.optopt("N", "read-bytes",
                "limit dump to BYTES input bytes", "BYTES");
    opts.optopt("S", "strings",
                ("output strings of at least BYTES graphic chars. 3 is assumed when \
                 BYTES is not specified."),
                "BYTES");
    opts.optopt("t", "format", "select output format or formats", "TYPE");
    opts.optflag("v", "output-duplicates", "do not use * to mark line suppression");
    opts.optopt("w", "width",
                ("output BYTES bytes per output line. 32 is implied when BYTES is not \
                 specified."),
                "BYTES");
    opts.optflag("h", "help", "display this help and exit.");
    opts.optflag("", "version", "output version information and exit.");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let input_offset_base = match parse_radix(matches.opt_str("A")) {
        Ok(r) => r,
        Err(f) => { panic!("Invalid -A/--address-radix\n{}", f) }
    };

    let fname = match args.last() {
        Some(n) => n,
        None => { panic!("Need fname for now") ; }
    };

    odfunc(&input_offset_base, &fname);

    0
}

const LINEBYTES:usize = 16;
const WORDBYTES:usize = 2;

fn odfunc(input_offset_base: &Radix, fname: &str) {
    let mut f = match File::open(Path::new(fname)) {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e)
    };

    let mut addr = 0;
    let bytes = &mut [b'\x00'; LINEBYTES];
    loop { // print each line
        print_with_radix(input_offset_base, addr); // print offset
        match f.read(bytes) {
            Ok(0) => {
                print!("\n");
                break;
            }
            Ok(n) => {
                print!("  "); // 4 spaces after offset - we print 2 more before each word

                for b in 0 .. n / mem::size_of::<u16>() {
                    let bs = &bytes[(2 * b) .. (2 * b + 2)];
                    let p: u16 = (bs[1] as u16) << 8 | bs[0] as u16;
                    print!("  {:06o}", p);
                }
                if n % mem::size_of::<u16>() == 1 {
                    print!("  {:06o}", bytes[n - 1]);
                }

                // Add extra spaces to pad out the short, presumably last, line.
                if n<LINEBYTES {
                    // calc # of items we did not print, must be short at least WORDBYTES to be missing any.
                    let words_short = (LINEBYTES-n)/WORDBYTES;
                    print!("{:>width$}", "", width=(words_short)*(6+2));
                }

                print!("\n");
                addr += n;
            },
            Err(_) => {
                break;
            }
        };
    };
}

fn parse_radix(radix_str: Option<String>) -> Result<Radix, &'static str> {
    match radix_str {
        None => Ok(Radix::Octal),
        Some(s) => {
            let st = s.into_bytes();
            if st.len() != 1 {
                Err("Radix must be one of [d, o, b, x]\n")
            } else {
                let radix: char = *(st.get(0)
                                      .expect("byte string of length 1 lacks a 0th elem")) as char;
                match radix {
                    'd' => Ok(Radix::Decimal),
                    'x' => Ok(Radix::Hexadecimal),
                    'o' => Ok(Radix::Octal),
                    'b' => Ok(Radix::Binary),
                    _ => Err("Radix must be one of [d, o, b, x]\n")
                }
            }
        }
    }
}

fn print_with_radix(r: &Radix, x: usize) {
    // TODO(keunwoo): field widths should be based on sizeof(x), or chosen dynamically based on the
    // expected range of address values.  Binary in particular is not great here.
    match *r {
        Radix::Decimal => print!("{:07}", x),
        Radix::Hexadecimal => print!("{:07X}", x),
        Radix::Octal => print!("{:07o}", x),
        Radix::Binary => print!("{:07b}", x)
    }
}<commit_msg>od: Accept multiple files names as input<commit_after>#![crate_name = "uu_od"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Ben Hirsch <benhirsch24@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::fs::File;
use std::io::Read;
use std::mem;
use std::io::BufReader;
use std::io::Write;
use std::io;

#[derive(Debug)]
enum Radix { Decimal, Hexadecimal, Octal, Binary }

pub fn uumain(args: Vec<String>) -> i32 {
    let mut opts = getopts::Options::new();

    opts.optopt("A", "address-radix",
                "Select the base in which file offsets are printed.", "RADIX");
    opts.optopt("j", "skip-bytes",
                "Skip bytes input bytes before formatting and writing.", "BYTES");
    opts.optopt("N", "read-bytes",
                "limit dump to BYTES input bytes", "BYTES");
    opts.optopt("S", "strings",
                ("output strings of at least BYTES graphic chars. 3 is assumed when \
                 BYTES is not specified."),
                "BYTES");
    opts.optopt("t", "format", "select output format or formats", "TYPE");
    opts.optflag("v", "output-duplicates", "do not use * to mark line suppression");
    opts.optopt("w", "width",
                ("output BYTES bytes per output line. 32 is implied when BYTES is not \
                 specified."),
                "BYTES");
    opts.optflag("h", "help", "display this help and exit.");
    opts.optflag("", "version", "output version information and exit.");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!("Invalid options\n{}", f)
    };

    let input_offset_base = match parse_radix(matches.opt_str("A")) {
        Ok(r) => r,
        Err(f) => { panic!("Invalid -A/--address-radix\n{}", f) }
    };

    // Gather up file names - args wich don't start with '-'
    let fnames = args[1..]
                     .iter()
                     .filter(|w| !w.starts_with('-'))
                     .map(|x| x.clone())
                     .collect::<Vec<_>>();

    // With no filenames, od would use stdin as input, which is currently not supported.
    if fnames.len() == 0 {
        panic!("Need fname for now") ;
    };
    odfunc(&input_offset_base, fnames)
}

const LINEBYTES:usize = 16;
const WORDBYTES:usize = 2;

fn odfunc(input_offset_base: &Radix, fnames: Vec<String>) -> i32 {

    let mut status = 0;
    let mut ni = fnames.iter();
    {
        // Open and return the next file to process as a BufReader
        // Returns None when no more files.
        let mut next_file = || -> Option<BufReader<File>> {
            // loop retries with subsequent files if err - normally 'loops' once
            loop {
                let fname = match ni.next() {
                    None => return None,
                    Some(s) => s,
                };
                match File::open(fname) {
                    Ok(f) => return Some(BufReader::new(f)),
                    Err(e) => {
                        // If any file can't be opened,
                        // print an error at the time that the file is needed,
                        // then move on the the next file.
                        // This matches the behavior of the original `od`
                        let _ = writeln!(&mut std::io::stderr(), "od: '{}': {}", fname, e);
                        if status == 0 {status = 1}
                    }
                }
            }
        };

        let mut curr_file: BufReader<File> = match next_file() {
            Some(f) => f,
            None => {
                return 1;
            }
        };

        let mut exhausted = false; // There is no more input, gone to the end of the last file.

        // Fill buf with bytes read from the list of files
        // Returns Ok(<number of bytes read>)
        // Handles io errors itself, thus always returns OK
        // Fills the provided buffer completely, unless it has run out of input.
        // If any call returns short (< buf.len()), all subsequent calls will return Ok<0>
        let mut f_read = |buf: &mut [u8]| -> io::Result<usize> {
            if exhausted {
                Ok(0)
            } else {
                let mut xfrd = 0;
                while xfrd < buf.len() {
                    xfrd += match curr_file.read(&mut buf[xfrd..]) {
                        Ok(n) => n,
                        Err(e) => panic!("file error: {}", e),
                    };
                    if xfrd == buf.len() {
                        // transferred all that was asked for.
                        break;
                    }
                    curr_file = match next_file() {
                        Some(f) => f,
                        None => {
                            exhausted = true;
                            break;
                        }
                    };
                }
                Ok(xfrd)
            }
        };

        let mut addr = 0;
        let bytes = &mut [b'\x00'; LINEBYTES];
        loop { // print each line
            print_with_radix(input_offset_base, addr); // print offset
            match f_read(bytes) {
                Ok(0) => {
                    print!("\n");
                    break;
                }
                Ok(n) => {
                    print!("  "); // 4 spaces after offset - we print 2 more before each word

                    for b in 0 .. n / mem::size_of::<u16>() {
                        let bs = &bytes[(2 * b) .. (2 * b + 2)];
                        let p: u16 = (bs[1] as u16) << 8 | bs[0] as u16;
                        print!("  {:06o}", p);
                    }
                    if n % mem::size_of::<u16>() == 1 {
                        print!("  {:06o}", bytes[n - 1]);
                    }

                    // Add extra spaces to pad out the short, presumably last, line.
                    if n<LINEBYTES {
                        // calc # of items we did not print, must be short at least WORDBYTES to be missing any.
                        let words_short = (LINEBYTES-n)/WORDBYTES;
                        print!("{:>width$}", "", width=(words_short)*(6+2));
                    }

                    print!("\n");
                    addr += n;
                },
                Err(_) => {
                    break;
                }
            };
        };
    };
    status
}

fn parse_radix(radix_str: Option<String>) -> Result<Radix, &'static str> {
    match radix_str {
        None => Ok(Radix::Octal),
        Some(s) => {
            let st = s.into_bytes();
            if st.len() != 1 {
                Err("Radix must be one of [d, o, b, x]\n")
            } else {
                let radix: char = *(st.get(0)
                                      .expect("byte string of length 1 lacks a 0th elem")) as char;
                match radix {
                    'd' => Ok(Radix::Decimal),
                    'x' => Ok(Radix::Hexadecimal),
                    'o' => Ok(Radix::Octal),
                    'b' => Ok(Radix::Binary),
                    _ => Err("Radix must be one of [d, o, b, x]\n")
                }
            }
        }
    }
}

fn print_with_radix(r: &Radix, x: usize) {
    // TODO(keunwoo): field widths should be based on sizeof(x), or chosen dynamically based on the
    // expected range of address values.  Binary in particular is not great here.
    match *r {
        Radix::Decimal => print!("{:07}", x),
        Radix::Hexadecimal => print!("{:07X}", x),
        Radix::Octal => print!("{:07o}", x),
        Radix::Binary => print!("{:07b}", x)
    }
}<|endoftext|>


<commit_before>use std::any::Any;
use std::cell::RefCell;
use std::panic::{self, AssertUnwindSafe};

thread_local! {
    static LAST_ERROR: RefCell<Option<Box<Any + Send>>> = RefCell::new(None);
    static UNWINDING: RefCell<bool> = RefCell::new(false);
}

pub fn catch<T, F: FnOnce() -> T>(f: F) -> Option<T> {
    if LAST_ERROR.with(|slot| slot.borrow().is_some()) {
        return None
    }

    if UNWINDING.with(|slot| *slot.borrow()) {
        return None
    }

    match panic::catch_unwind(AssertUnwindSafe(f)) {
        Ok(ret) => Some(ret),
        Err(e) => {
            LAST_ERROR.with(|slot| *slot.borrow_mut() = Some(e));
            None
        }
    }
}

pub fn propagate() {
    if let Some(t) = LAST_ERROR.with(|slot| slot.borrow_mut().take()) {
        UNWINDING.with(|slot| *slot.borrow_mut() = true);
        panic::resume_unwind(t);
        UNWINDING.with(|slot| *slot.borrow_mut() = false);
    }
}
<commit_msg>unreachable code<commit_after>use std::any::Any;
use std::cell::RefCell;
use std::panic::{self, AssertUnwindSafe};

thread_local! {
    static LAST_ERROR: RefCell<Option<Box<Any + Send>>> = RefCell::new(None);
    static UNWINDING: RefCell<bool> = RefCell::new(false);
}

pub fn catch<T, F: FnOnce() -> T>(f: F) -> Option<T> {
    if LAST_ERROR.with(|slot| slot.borrow().is_some()) {
        return None
    }

    if UNWINDING.with(|slot| *slot.borrow()) {
        return None
    }

    match panic::catch_unwind(AssertUnwindSafe(f)) {
        Ok(ret) => Some(ret),
        Err(e) => {
            LAST_ERROR.with(|slot| *slot.borrow_mut() = Some(e));
            None
        }
    }
}

pub fn propagate() {
    if let Some(t) = LAST_ERROR.with(|slot| slot.borrow_mut().take()) {
        UNWINDING.with(|slot| *slot.borrow_mut() = true);
        panic::resume_unwind(t);
    }
}
<|endoftext|>