<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.

//! Implementation of various bits and pieces of the `panic!` macro and
//! associated runtime pieces.
//!
//! Specifically, this module contains the implementation of:
//!
//! * Panic hooks
//! * Executing a panic up to doing the actual implementation
//! * Shims around "try"

use prelude::v1::*;
use io::prelude::*;

use any::Any;
use cell::Cell;
use cell::RefCell;
use fmt;
use intrinsics;
use mem;
use raw;
use sys_common::rwlock::RWLock;
use sync::atomic::{AtomicBool, Ordering};
use sys::stdio::Stderr;
use sys_common::backtrace;
use sys_common::thread_info;
use sys_common::util;
use thread;

thread_local! {
    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
        RefCell::new(None)
    }
}

thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }

// Binary interface to the panic runtime that the standard library depends on.
//
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
// RFC 1513) to indicate that it requires some other crate tagged with
// `#![panic_runtime]` to exist somewhere. Each panic runtime is intended to
// implement these symbols (with the same signatures) so we can get matched up
// to them.
//
// One day this may look a little less ad-hoc with the compiler helping out to
// hook up these functions, but it is not this day!
#[allow(improper_ctypes)]
extern {
    fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                data: *mut u8,
                                data_ptr: *mut usize,
                                vtable_ptr: *mut usize) -> u32;
    #[unwind]
    fn __rust_start_panic(data: usize, vtable: usize) -> u32;
}

#[derive(Copy, Clone)]
enum Hook {
    Default,
    Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
}

static HOOK_LOCK: RWLock = RWLock::new();
static mut HOOK: Hook = Hook::Default;
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);

/// Registers a custom panic hook, replacing any that was previously registered.
///
/// The panic hook is invoked when a thread panics, but before the panic runtime
/// is invoked. As such, the hook will run with both the aborting and unwinding
/// runtimes. The default hook prints a message to standard error and generates
/// a backtrace if requested, but this behavior can be customized with the
/// `set_hook` and `take_hook` functions.
///
/// The hook is provided with a `PanicInfo` struct which contains information
/// about the origin of the panic, including the payload passed to `panic!` and
/// the source code location from which the panic originated.
///
/// The panic hook is a global resource.
///
/// # Panics
///
/// Panics if called from a panicking thread.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
    if thread::panicking() {
        panic!("cannot modify the panic hook from a panicking thread");
    }

    unsafe {
        HOOK_LOCK.write();
        let old_hook = HOOK;
        HOOK = Hook::Custom(Box::into_raw(hook));
        HOOK_LOCK.write_unlock();

        if let Hook::Custom(ptr) = old_hook {
            Box::from_raw(ptr);
        }
    }
}

/// Unregisters the current panic hook, returning it.
///
/// If no custom hook is registered, the default hook will be returned.
///
/// # Panics
///
/// Panics if called from a panicking thread.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
    if thread::panicking() {
        panic!("cannot modify the panic hook from a panicking thread");
    }

    unsafe {
        HOOK_LOCK.write();
        let hook = HOOK;
        HOOK = Hook::Default;
        HOOK_LOCK.write_unlock();

        match hook {
            Hook::Default => Box::new(default_hook),
            Hook::Custom(ptr) => {Box::from_raw(ptr)} // FIXME #30530
        }
    }
}

/// A struct providing information about a panic.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct PanicInfo<'a> {
    payload: &'a (Any + Send),
    location: Location<'a>,
}

impl<'a> PanicInfo<'a> {
    /// Returns the payload associated with the panic.
    ///
    /// This will commonly, but not always, be a `&'static str` or `String`.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn payload(&self) -> &(Any + Send) {
        self.payload
    }

    /// Returns information about the location from which the panic originated,
    /// if available.
    ///
    /// This method will currently always return `Some`, but this may change
    /// in future versions.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn location(&self) -> Option<&Location> {
        Some(&self.location)
    }
}

/// A struct containing information about the location of a panic.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct Location<'a> {
    file: &'a str,
    line: u32,
}

impl<'a> Location<'a> {
    /// Returns the name of the source file from which the panic originated.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn file(&self) -> &str {
        self.file
    }

    /// Returns the line number from which the panic originated.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn line(&self) -> u32 {
        self.line
    }
}

fn default_hook(info: &PanicInfo) {
    let panics = PANIC_COUNT.with(|c| c.get());

    // If this is a double panic, make sure that we print a backtrace
    // for this panic. Otherwise only print it if logging is enabled.
    let log_backtrace = panics >= 2 || backtrace::log_enabled();

    let file = info.location.file;
    let line = info.location.line;

    let msg = match info.payload.downcast_ref::<&'static str>() {
        Some(s) => *s,
        None => match info.payload.downcast_ref::<String>() {
            Some(s) => &s[..],
            None => "Box<Any>",
        }
    };
    let mut err = Stderr::new().ok();
    let thread = thread_info::current_thread();
    let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");

    let write = |err: &mut ::io::Write| {
        let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
                         name, msg, file, line);

        if log_backtrace {
            let _ = backtrace::write(err);
        } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
            let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace.");
        }
    };

    let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
    match (prev, err.as_mut()) {
        (Some(mut stderr), _) => {
            write(&mut *stderr);
            let mut s = Some(stderr);
            LOCAL_STDERR.with(|slot| {
                *slot.borrow_mut() = s.take();
            });
        }
        (None, Some(ref mut err)) => { write(err) }
        _ => {}
    }
}

/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
    let mut slot = None;
    let mut f = Some(f);
    let ret;

    {
        let mut to_run = || {
            slot = Some(f.take().unwrap()());
        };
        let fnptr = get_call(&mut to_run);
        let dataptr = &mut to_run as *mut _ as *mut u8;
        let mut any_data = 0;
        let mut any_vtable = 0;
        let fnptr = mem::transmute::<fn(&mut _), fn(*mut u8)>(fnptr);
        let r = __rust_maybe_catch_panic(fnptr,
                                         dataptr,
                                         &mut any_data,
                                         &mut any_vtable);
        if r == 0 {
            ret = Ok(());
        } else {
            PANIC_COUNT.with(|s| {
                let prev = s.get();
                s.set(prev - 1);
            });
            ret = Err(mem::transmute(raw::TraitObject {
                data: any_data as *mut _,
                vtable: any_vtable as *mut _,
            }));
        }
    }

    debug_assert!(PANIC_COUNT.with(|c| c.get() == 0));
    return ret.map(|()| {
        slot.take().unwrap()
    });

    fn get_call<F: FnMut()>(_: &mut F) -> fn(&mut F) {
        call
    }

    fn call<F: FnMut()>(f: &mut F) {
        f()
    }
}

/// Determines whether the current thread is unwinding because of panic.
pub fn panicking() -> bool {
    PANIC_COUNT.with(|c| c.get() != 0)
}

/// Entry point of panic from the libcore crate.
#[cfg(not(test))]
#[lang = "panic_fmt"]
#[unwind]
pub extern fn rust_begin_panic(msg: fmt::Arguments,
                               file: &'static str,
                               line: u32) -> ! {
    begin_panic_fmt(&msg, &(file, line))
}

/// The entry point for panicking with a formatted message.
///
/// This is designed to reduce the amount of code required at the call
/// site as much as possible (so that `panic!()` has as low an impact
/// on (e.g.) the inlining of other functions as possible), by moving
/// the actual formatting into this shared place.
#[unstable(feature = "libstd_sys_internals",
           reason = "used by the panic! macro",
           issue = "0")]
#[inline(never)] #[cold]
pub fn begin_panic_fmt(msg: &fmt::Arguments,
                       file_line: &(&'static str, u32)) -> ! {
    use fmt::Write;

    // We do two allocations here, unfortunately. But (a) they're
    // required with the current scheme, and (b) we don't handle
    // panic + OOM properly anyway (see comment in begin_panic
    // below).

    let mut s = String::new();
    let _ = s.write_fmt(*msg);
    begin_panic(s, file_line)
}

/// This is the entry point of panicking for panic!() and assert!().
#[unstable(feature = "libstd_sys_internals",
           reason = "used by the panic! macro",
           issue = "0")]
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
pub fn begin_panic<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
    // Note that this should be the only allocation performed in this code path.
    // Currently this means that panic!() on OOM will invoke this code path,
    // but then again we're not really ready for panic on OOM anyway. If
    // we do start doing this, then we should propagate this allocation to
    // be performed in the parent of this thread instead of the thread that's
    // panicking.

    rust_panic_with_hook(Box::new(msg), file_line)
}

/// Executes the primary logic for a panic, including checking for recursive
/// panics and panic hooks.
///
/// This is the entry point or panics from libcore, formatted panics, and
/// `Box<Any>` panics. Here we'll verify that we're not panicking recursively,
/// run panic hooks, and then delegate to the actual implementation of panics.
#[inline(never)]
#[cold]
fn rust_panic_with_hook(msg: Box<Any + Send>,
                        file_line: &(&'static str, u32)) -> ! {
    let (file, line) = *file_line;

    let panics = PANIC_COUNT.with(|c| {
        let prev = c.get();
        c.set(prev + 1);
        prev
    });

    // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
    // the panic hook probably triggered the last panic, otherwise the
    // double-panic check would have aborted the process. In this case abort the
    // process real quickly as we don't want to try calling it again as it'll
    // probably just panic again.
    if panics > 1 {
        util::dumb_print(format_args!("thread panicked while processing \
                                       panic. aborting.\n"));
        unsafe { intrinsics::abort() }
    }

    unsafe {
        let info = PanicInfo {
            payload: &*msg,
            location: Location {
                file: file,
                line: line,
            },
        };
        HOOK_LOCK.read();
        match HOOK {
            Hook::Default => default_hook(&info),
            Hook::Custom(ptr) => (*ptr)(&info),
        }
        HOOK_LOCK.read_unlock();
    }

    if panics > 0 {
        // If a thread panics while it's already unwinding then we
        // have limited options. Currently our preference is to
        // just abort. In the future we may consider resuming
        // unwinding or otherwise exiting the thread cleanly.
        util::dumb_print(format_args!("thread panicked while panicking. \
                                       aborting.\n"));
        unsafe { intrinsics::abort() }
    }

    rust_panic(msg)
}

/// A private no-mangle function on which to slap yer breakpoints.
#[no_mangle]
#[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints
pub fn rust_panic(msg: Box<Any + Send>) -> ! {
    let code = unsafe {
        let obj = mem::transmute::<_, raw::TraitObject>(msg);
        __rust_start_panic(obj.data as usize, obj.vtable as usize)
    };
    rtabort!("failed to initiate panic, error {}", code)
}
<commit_msg>Revert "Refactored code to access TLS only in case of panic"<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.

//! Implementation of various bits and pieces of the `panic!` macro and
//! associated runtime pieces.
//!
//! Specifically, this module contains the implementation of:
//!
//! * Panic hooks
//! * Executing a panic up to doing the actual implementation
//! * Shims around "try"

use prelude::v1::*;
use io::prelude::*;

use any::Any;
use cell::Cell;
use cell::RefCell;
use fmt;
use intrinsics;
use mem;
use raw;
use sys_common::rwlock::RWLock;
use sync::atomic::{AtomicBool, Ordering};
use sys::stdio::Stderr;
use sys_common::backtrace;
use sys_common::thread_info;
use sys_common::util;
use thread;

thread_local! {
    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
        RefCell::new(None)
    }
}

thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }

// Binary interface to the panic runtime that the standard library depends on.
//
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
// RFC 1513) to indicate that it requires some other crate tagged with
// `#![panic_runtime]` to exist somewhere. Each panic runtime is intended to
// implement these symbols (with the same signatures) so we can get matched up
// to them.
//
// One day this may look a little less ad-hoc with the compiler helping out to
// hook up these functions, but it is not this day!
#[allow(improper_ctypes)]
extern {
    fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                data: *mut u8,
                                data_ptr: *mut usize,
                                vtable_ptr: *mut usize) -> u32;
    #[unwind]
    fn __rust_start_panic(data: usize, vtable: usize) -> u32;
}

#[derive(Copy, Clone)]
enum Hook {
    Default,
    Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
}

static HOOK_LOCK: RWLock = RWLock::new();
static mut HOOK: Hook = Hook::Default;
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);

/// Registers a custom panic hook, replacing any that was previously registered.
///
/// The panic hook is invoked when a thread panics, but before the panic runtime
/// is invoked. As such, the hook will run with both the aborting and unwinding
/// runtimes. The default hook prints a message to standard error and generates
/// a backtrace if requested, but this behavior can be customized with the
/// `set_hook` and `take_hook` functions.
///
/// The hook is provided with a `PanicInfo` struct which contains information
/// about the origin of the panic, including the payload passed to `panic!` and
/// the source code location from which the panic originated.
///
/// The panic hook is a global resource.
///
/// # Panics
///
/// Panics if called from a panicking thread.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
    if thread::panicking() {
        panic!("cannot modify the panic hook from a panicking thread");
    }

    unsafe {
        HOOK_LOCK.write();
        let old_hook = HOOK;
        HOOK = Hook::Custom(Box::into_raw(hook));
        HOOK_LOCK.write_unlock();

        if let Hook::Custom(ptr) = old_hook {
            Box::from_raw(ptr);
        }
    }
}

/// Unregisters the current panic hook, returning it.
///
/// If no custom hook is registered, the default hook will be returned.
///
/// # Panics
///
/// Panics if called from a panicking thread.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
    if thread::panicking() {
        panic!("cannot modify the panic hook from a panicking thread");
    }

    unsafe {
        HOOK_LOCK.write();
        let hook = HOOK;
        HOOK = Hook::Default;
        HOOK_LOCK.write_unlock();

        match hook {
            Hook::Default => Box::new(default_hook),
            Hook::Custom(ptr) => {Box::from_raw(ptr)} // FIXME #30530
        }
    }
}

/// A struct providing information about a panic.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct PanicInfo<'a> {
    payload: &'a (Any + Send),
    location: Location<'a>,
}

impl<'a> PanicInfo<'a> {
    /// Returns the payload associated with the panic.
    ///
    /// This will commonly, but not always, be a `&'static str` or `String`.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn payload(&self) -> &(Any + Send) {
        self.payload
    }

    /// Returns information about the location from which the panic originated,
    /// if available.
    ///
    /// This method will currently always return `Some`, but this may change
    /// in future versions.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn location(&self) -> Option<&Location> {
        Some(&self.location)
    }
}

/// A struct containing information about the location of a panic.
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub struct Location<'a> {
    file: &'a str,
    line: u32,
}

impl<'a> Location<'a> {
    /// Returns the name of the source file from which the panic originated.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn file(&self) -> &str {
        self.file
    }

    /// Returns the line number from which the panic originated.
    #[stable(feature = "panic_hooks", since = "1.10.0")]
    pub fn line(&self) -> u32 {
        self.line
    }
}

fn default_hook(info: &PanicInfo) {
    let panics = PANIC_COUNT.with(|c| c.get());

    // If this is a double panic, make sure that we print a backtrace
    // for this panic. Otherwise only print it if logging is enabled.
    let log_backtrace = panics >= 2 || backtrace::log_enabled();

    let file = info.location.file;
    let line = info.location.line;

    let msg = match info.payload.downcast_ref::<&'static str>() {
        Some(s) => *s,
        None => match info.payload.downcast_ref::<String>() {
            Some(s) => &s[..],
            None => "Box<Any>",
        }
    };
    let mut err = Stderr::new().ok();
    let thread = thread_info::current_thread();
    let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");

    let write = |err: &mut ::io::Write| {
        let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
                         name, msg, file, line);

        if log_backtrace {
            let _ = backtrace::write(err);
        } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
            let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace.");
        }
    };

    let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
    match (prev, err.as_mut()) {
        (Some(mut stderr), _) => {
            write(&mut *stderr);
            let mut s = Some(stderr);
            LOCAL_STDERR.with(|slot| {
                *slot.borrow_mut() = s.take();
            });
        }
        (None, Some(ref mut err)) => { write(err) }
        _ => {}
    }
}

/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
    let mut slot = None;
    let mut f = Some(f);
    let ret = PANIC_COUNT.with(|s| {
        let prev = s.get();
        s.set(0);

        let mut to_run = || {
            slot = Some(f.take().unwrap()());
        };
        let fnptr = get_call(&mut to_run);
        let dataptr = &mut to_run as *mut _ as *mut u8;
        let mut any_data = 0;
        let mut any_vtable = 0;
        let fnptr = mem::transmute::<fn(&mut _), fn(*mut u8)>(fnptr);
        let r = __rust_maybe_catch_panic(fnptr,
                                         dataptr,
                                         &mut any_data,
                                         &mut any_vtable);
        s.set(prev);

        if r == 0 {
            Ok(())
        } else {
            Err(mem::transmute(raw::TraitObject {
                data: any_data as *mut _,
                vtable: any_vtable as *mut _,
            }))
        }
    });

    return ret.map(|()| {
        slot.take().unwrap()
    });

    fn get_call<F: FnMut()>(_: &mut F) -> fn(&mut F) {
        call
    }

    fn call<F: FnMut()>(f: &mut F) {
        f()
    }
}

/// Determines whether the current thread is unwinding because of panic.
pub fn panicking() -> bool {
    PANIC_COUNT.with(|c| c.get() != 0)
}

/// Entry point of panic from the libcore crate.
#[cfg(not(test))]
#[lang = "panic_fmt"]
#[unwind]
pub extern fn rust_begin_panic(msg: fmt::Arguments,
                               file: &'static str,
                               line: u32) -> ! {
    begin_panic_fmt(&msg, &(file, line))
}

/// The entry point for panicking with a formatted message.
///
/// This is designed to reduce the amount of code required at the call
/// site as much as possible (so that `panic!()` has as low an impact
/// on (e.g.) the inlining of other functions as possible), by moving
/// the actual formatting into this shared place.
#[unstable(feature = "libstd_sys_internals",
           reason = "used by the panic! macro",
           issue = "0")]
#[inline(never)] #[cold]
pub fn begin_panic_fmt(msg: &fmt::Arguments,
                       file_line: &(&'static str, u32)) -> ! {
    use fmt::Write;

    // We do two allocations here, unfortunately. But (a) they're
    // required with the current scheme, and (b) we don't handle
    // panic + OOM properly anyway (see comment in begin_panic
    // below).

    let mut s = String::new();
    let _ = s.write_fmt(*msg);
    begin_panic(s, file_line)
}

/// This is the entry point of panicking for panic!() and assert!().
#[unstable(feature = "libstd_sys_internals",
           reason = "used by the panic! macro",
           issue = "0")]
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
pub fn begin_panic<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
    // Note that this should be the only allocation performed in this code path.
    // Currently this means that panic!() on OOM will invoke this code path,
    // but then again we're not really ready for panic on OOM anyway. If
    // we do start doing this, then we should propagate this allocation to
    // be performed in the parent of this thread instead of the thread that's
    // panicking.

    rust_panic_with_hook(Box::new(msg), file_line)
}

/// Executes the primary logic for a panic, including checking for recursive
/// panics and panic hooks.
///
/// This is the entry point or panics from libcore, formatted panics, and
/// `Box<Any>` panics. Here we'll verify that we're not panicking recursively,
/// run panic hooks, and then delegate to the actual implementation of panics.
#[inline(never)]
#[cold]
fn rust_panic_with_hook(msg: Box<Any + Send>,
                        file_line: &(&'static str, u32)) -> ! {
    let (file, line) = *file_line;

    let panics = PANIC_COUNT.with(|c| {
        let prev = c.get();
        c.set(prev + 1);
        prev
    });

    // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
    // the panic hook probably triggered the last panic, otherwise the
    // double-panic check would have aborted the process. In this case abort the
    // process real quickly as we don't want to try calling it again as it'll
    // probably just panic again.
    if panics > 1 {
        util::dumb_print(format_args!("thread panicked while processing \
                                       panic. aborting.\n"));
        unsafe { intrinsics::abort() }
    }

    unsafe {
        let info = PanicInfo {
            payload: &*msg,
            location: Location {
                file: file,
                line: line,
            },
        };
        HOOK_LOCK.read();
        match HOOK {
            Hook::Default => default_hook(&info),
            Hook::Custom(ptr) => (*ptr)(&info),
        }
        HOOK_LOCK.read_unlock();
    }

    if panics > 0 {
        // If a thread panics while it's already unwinding then we
        // have limited options. Currently our preference is to
        // just abort. In the future we may consider resuming
        // unwinding or otherwise exiting the thread cleanly.
        util::dumb_print(format_args!("thread panicked while panicking. \
                                       aborting.\n"));
        unsafe { intrinsics::abort() }
    }

    rust_panic(msg)
}

/// A private no-mangle function on which to slap yer breakpoints.
#[no_mangle]
#[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints
pub fn rust_panic(msg: Box<Any + Send>) -> ! {
    let code = unsafe {
        let obj = mem::transmute::<_, raw::TraitObject>(msg);
        __rust_start_panic(obj.data as usize, obj.vtable as usize)
    };
    rtabort!("failed to initiate panic, error {}", code)
}
<|endoftext|>


<commit_before><commit_msg>Add component-wise map, map2 and fold performance tests<commit_after>/**
 * Component-wise map and fold function speed tests. For best results, compile
 * with the optimise flag (-O). These functions would allow for even more generic
 * operations on dimensional data structures. Map seems to be faster than hand
 * unrolling for add_t, but map2 for add_v is slower. A combination of map2 and
 * foldl is faster for dot product.
 */

extern mod std;
use std::time::precise_time_ns;
use cast::transmute;
use vec::raw::buf_as_slice;
use ptr::to_unsafe_ptr;
use cmp::Eq;
use num::from_int;

pub struct Vec4<T> { x: T, y: T, z: T, w: T }

pub mod Vec4 {
    #[inline(always)]
    pub pure fn new<T>(x: T, y: T, z: T, w: T) -> Vec4<T> {
        Vec4 { x: move x, y: move y, z: move z, w: move w }
    }
}

pub impl<T:Copy Num> Vec4<T> {
    #[inline(always)]
    pure fn index(i: uint) -> T {
        unsafe { do buf_as_slice(
            transmute::<*Vec4<T>, *T>(
                to_unsafe_ptr(&self)), 4) |slice| { slice[i] }
        }
    }

    ////////////////////////////////////////////////////////////////////////////

    #[inline(always)]
    pure fn map(f: fn&(a: &T) -> T) -> Vec4<T> {
        Vec4::new(f(&self[0]),
                  f(&self[1]),
                  f(&self[2]),
                  f(&self[3]))
    }

    #[inline(always)]
    pure fn map2(other: &Vec4<T>, f: fn&(a: &T, b: &T) -> T) -> Vec4<T> {
        Vec4::new(f(&self[0], &other[0]),
                  f(&self[1], &other[1]),
                  f(&self[2], &other[2]),
                  f(&self[3], &other[3]))
    }

    pure fn foldl<U: Copy>(z: U, p: &fn(t: T, u: &U) -> U) -> U {
        p(self[3], &p(self[2], &p(self[1], &p(self[0], &z))))
    }
    pure fn foldr<U: Copy>(z: U, p: &fn(t: &T, u: U) -> U) -> U {
        p(&self[0], p(&self[1], p(&self[2], p(&self[3], z))))
    }

    ////////////////////////////////////////////////////////////////////////////

    #[inline(always)]
    pure fn mul_t(value: T) -> Vec4<T> {
        Vec4::new(self[0] * value,
                  self[1] * value,
                  self[2] * value,
                  self[3] * value)
    }

    #[inline(always)]
    pure fn mul_t_map(value: T) -> Vec4<T> {
        do self.map |a| { a * value }
    }

    #[inline(always)]
    pure fn add_v(other: &Vec4<T>) -> Vec4<T> {
        Vec4::new(self[0] + other[0],
                  self[1] + other[1],
                  self[2] + other[2],
                  self[3] + other[3])
    }

    #[inline(always)]
    pure fn add_v_map2(other: &Vec4<T>) -> Vec4<T> {
        do self.map2(other) |a, b| { a + *b }
    }

    #[inline(always)]
    pure fn dot(other: &Vec4<T>) -> T {
        self[0] * other[0] +
        self[1] * other[1] +
        self[2] * other[2] +
        self[3] * other[3]
    }

    #[inline(always)]
    pure fn dot_foldl(other: &Vec4<T>) -> T {
        self.map2(other, |a, b| { a * *b })
            .foldl(from_int(0), |t, u| { t + *u })
    }
}

pub impl<T:Copy Num Eq> Vec4<T>: Eq {
    #[inline(always)]
    pure fn eq(other: &Vec4<T>) -> bool {
        self[0] == other[0] &&
        self[1] == other[1] &&
        self[2] == other[2] &&
        self[3] == other[3]
    }

    #[inline(always)]
    pure fn ne(other: &Vec4<T>) -> bool {
        !(self == *other)
    }
}

fn main() {
    let n_tests = 10000;

    // Map

    let a = Vec4::new(1f, 2f, 3f, 4f);
    let b = Vec4::new(5f, 6f, 7f, 8f);

    let mul_t_avg = do test_avg_time_ns(n_tests) {
        assert a.mul_t(8f) == Vec4::new(8f, 16f, 24f, 32f);
    };

    let mul_t_map_avg = do test_avg_time_ns(n_tests) {
        assert a.mul_t_map(8f) == Vec4::new(8f, 16f, 24f, 32f);
    };

    let min = [mul_t_avg, mul_t_map_avg].min();

    io::println(fmt!("mul_t:        %d = %d", mul_t_avg as int, (mul_t_avg - min) as int));
    io::println(fmt!("mul_t_map:    %d = %d", mul_t_map_avg as int, (mul_t_map_avg - min) as int));

    // Zip

    let add_v_avg = do test_avg_time_ns(n_tests) {
        assert a.add_v(&b) == Vec4::new( 6f,  8f, 10f, 12f);
    };

    let add_v_map2_avg = do test_avg_time_ns(n_tests) {
        assert a.add_v_map2(&b) == Vec4::new( 6f,  8f, 10f, 12f);
    };

    let min = [add_v_avg, add_v_map2_avg].min();

    io::println(fmt!("add_v:        %d = %d", add_v_avg as int, (add_v_avg - min) as int));
    io::println(fmt!("add_v_map2:    %d = %d", add_v_map2_avg as int, (add_v_map2_avg - min) as int));

    // Dot

    let dot_avg = do test_avg_time_ns(n_tests) {
        assert a.dot(&b) == 70f;
    };

    let dot_foldl_avg = do test_avg_time_ns(n_tests) {
        assert a.dot_foldl(&b) == 70f;
    };

    let min = [dot_avg, dot_foldl_avg].min();

    io::println(fmt!("dot:        %d = %d", dot_avg as int, (dot_avg - min) as int));
    io::println(fmt!("dot_foldl:  %d = %d", dot_foldl_avg as int, (dot_foldl_avg - min) as int));

}

fn test_avg_time_ns(n: uint, f: fn&()) -> u64 {

    let mut total = 0;
    for n.times {
        let start_time = precise_time_ns();

        f();

        total += precise_time_ns() - start_time;
    }

    return total / (n as u64);
}<|endoftext|>


<commit_before>#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#![feature(const_fn, asm, repr_transparent)]
#![no_std]
#![cfg_attr(test, allow(unused_features))]

#[macro_use]
extern crate bitflags;
extern crate raw_cpuid;
#[cfg(feature = "performance-counter")]
#[macro_use]
extern crate phf;

#[cfg(test)]
#[macro_use]
extern crate std;

#[cfg(target_arch = "x86")]
use core::arch::x86 as arch;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64 as arch;

macro_rules! bit {
    ($x:expr) => {
        1 << $x
    };
}

pub mod bits16;
pub mod bits32;
pub mod bits64;

pub mod controlregs;
pub mod dtables;
pub mod io;
pub mod irq;
pub mod msr;
pub mod segmentation;
pub mod task;
pub mod time;
pub mod tlb;

#[cfg(feature = "performance-counter")]
pub mod perfcnt;

pub mod current {
    #[cfg(target_arch = "x86")]
    pub use bits32::*;
    #[cfg(target_arch = "x86_64")]
    pub use bits64::*;
}

pub mod cpuid {
    pub use raw_cpuid::*;
}

#[cfg(not(test))]
mod std {
    pub use core::fmt;
    pub use core::ops;
    pub use core::option;
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
/// x86 Protection levels
/// Note: This should not contain values larger than 2 bits, otherwise
/// segment descriptor code needs to be adjusted accordingly.
pub enum Ring {
    Ring0 = 0b00,
    Ring1 = 0b01,
    Ring2 = 0b10,
    Ring3 = 0b11,
}

#[inline(always)]
pub unsafe fn halt() {
    asm!("hlt" :::: "volatile");
}
<commit_msg>Allow stable features so docs.rs compiles with version 1.28.<commit_after>#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#![allow(stable_features)]
#![feature(const_fn, asm, repr_transparent)]
#![no_std]
#![cfg_attr(test, allow(unused_features))]

#[macro_use]
extern crate bitflags;
extern crate raw_cpuid;
#[cfg(feature = "performance-counter")]
#[macro_use]
extern crate phf;

#[cfg(test)]
#[macro_use]
extern crate std;

#[cfg(target_arch = "x86")]
use core::arch::x86 as arch;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64 as arch;

macro_rules! bit {
    ($x:expr) => {
        1 << $x
    };
}

pub mod bits16;
pub mod bits32;
pub mod bits64;

pub mod controlregs;
pub mod dtables;
pub mod io;
pub mod irq;
pub mod msr;
pub mod segmentation;
pub mod task;
pub mod time;
pub mod tlb;

#[cfg(feature = "performance-counter")]
pub mod perfcnt;

pub mod current {
    #[cfg(target_arch = "x86")]
    pub use bits32::*;
    #[cfg(target_arch = "x86_64")]
    pub use bits64::*;
}

pub mod cpuid {
    pub use raw_cpuid::*;
}

#[cfg(not(test))]
mod std {
    pub use core::fmt;
    pub use core::ops;
    pub use core::option;
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
/// x86 Protection levels
/// Note: This should not contain values larger than 2 bits, otherwise
/// segment descriptor code needs to be adjusted accordingly.
pub enum Ring {
    Ring0 = 0b00,
    Ring1 = 0b01,
    Ring2 = 0b10,
    Ring3 = 0b11,
}

#[inline(always)]
pub unsafe fn halt() {
    asm!("hlt" :::: "volatile");
}
<|endoftext|>


<commit_before>//!Log tools.

use std::old_io::{self, Writer};
use std::sync::Mutex;

///Common trait for log tools.
pub trait Log {
	///Print a note to the log.
	fn note(&self, message: &str);
	///Print a warning to the log.
	fn warning(&self, message: &str);
	///Print an error to the log.
	fn error(&self, message: &str);
}

///Log tool for printing to standard output.
pub struct StdOut;

impl Log for StdOut {
	fn note(&self, message: &str) {
		println!("note: {}", message);
	}

	fn warning(&self, message: &str) {
		println!("warning: {}", message);
	}

	fn error(&self, message: &str) {
		println!("error: {}", message);
	}
}

///Log tool for printing to a file.
pub struct File {
	file: Mutex<old_io::File>
}

impl File {
	pub fn new(file: old_io::File) -> File {
		File {
			file: Mutex::new(file)
		}
	}
}

impl Log for File {
	fn note(&self, message: &str) {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "note: {}", message);
	}

	fn warning(&self, message: &str) {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "warning: {}", message);
	}

	fn error(&self, message: &str) {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "error: {}", message);
	}
}

#[cfg(test)]
mod test {
	use std::old_io::{self, TempDir};
	use log;
	use Server;
	use Context;
	use Response;

	fn handler(_c: Context, _w: Response) {}

	#[test]
	fn log_to_file() {
		let dir = TempDir::new("log_to_file").unwrap();
		let file = old_io::File::create(&dir.path().join("test.log")).unwrap();
		Server::new().handlers(handler).log(log::File::new(file)).build();
	}
}<commit_msg>Return IoResult from log methods<commit_after>//!Log tools.

use std::old_io::{self, Writer, IoResult};
use std::sync::Mutex;

///Common trait for log tools.
pub trait Log {
	///Print a note to the log.
	fn note(&self, message: &str) -> IoResult<()>;
	///Print a warning to the log.
	fn warning(&self, message: &str) -> IoResult<()>;
	///Print an error to the log.
	fn error(&self, message: &str) -> IoResult<()>;
}

///Log tool for printing to standard output.
pub struct StdOut;

impl Log for StdOut {
	fn note(&self, message: &str) -> IoResult<()> {
		println!("note: {}", message);
		Ok(())
	}

	fn warning(&self, message: &str) -> IoResult<()> {
		println!("warning: {}", message);
		Ok(())
	}

	fn error(&self, message: &str) -> IoResult<()> {
		println!("error: {}", message);
		Ok(())
	}
}

///Log tool for printing to a file.
pub struct File {
	file: Mutex<old_io::File>
}

impl File {
	pub fn new(file: old_io::File) -> File {
		File {
			file: Mutex::new(file)
		}
	}
}

impl Log for File {
	fn note(&self, message: &str) -> IoResult<()> {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "note: {}", message)
	}

	fn warning(&self, message: &str) -> IoResult<()> {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "warning: {}", message)
	}

	fn error(&self, message: &str) -> IoResult<()> {
		let mut f = match self.file.lock() {
			Ok(f) => f,
			Err(e) => e.into_inner()
		};
		write!(f, "error: {}", message)
	}
}

#[cfg(test)]
mod test {
	use std::old_io::{self, TempDir};
	use log;
	use Server;
	use Context;
	use Response;

	fn handler(_c: Context, _w: Response) {}

	#[test]
	fn log_to_file() {
		let dir = TempDir::new("log_to_file").unwrap();
		let file = old_io::File::create(&dir.path().join("test.log")).unwrap();
		Server::new().handlers(handler).log(log::File::new(file)).build();
	}
}<|endoftext|>


<commit_before><commit_msg>Make the namespace structure safe.<commit_after><|endoftext|>


<commit_before><commit_msg>Added type example<commit_after>fn main() {
    // Type annotated variable
    let _a_float: f64 = 1.0;

    // This variable is an `i32`
    let mut _an_integer = 5i32;

    // Error! The type of a variable can't be changed
    // an_integer = true;
}
<|endoftext|>


<commit_before><commit_msg>fix macos<commit_after><|endoftext|>


<commit_before><commit_msg>Upgraded to latest Gfx<commit_after><|endoftext|>


<commit_before><commit_msg>(feat) Add a prelude module that is meant to be glob imported.<commit_after><|endoftext|>


<commit_before>extern crate crypto;
extern crate rustc_serialize;

use crypto::digest::Digest;
use crypto::hmac::Hmac;
use crypto::mac::Mac;
use rustc_serialize::base64::{
    self,
    CharacterSet,
    Newline,
    ToBase64,
};

pub mod error;
pub mod header;
pub mod claims;

const BASE_CONFIG: base64::Config = base64::Config {
    char_set: CharacterSet::Standard,
    newline: Newline::LF,
    pad: false,
    line_length: None,
};

fn sign<D: Digest>(data: &str, key: &str, digest: D) -> String {
    let mut hmac = Hmac::new(digest, key.as_bytes());
    hmac.input(data.as_bytes());

    let mac = hmac.result();
    let code = mac.code();
    (*code).to_base64(BASE_CONFIG)
}

#[cfg(test)]
mod tests {
    use sign;
    use crypto::sha2::Sha256;

    #[test]
    pub fn sign_data() {
        let header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
        let claims = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9";
        let real_sig = "TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
        let data = format!("{}.{}", header, claims);

        let sig = sign(&*data, "secret", Sha256::new());

        assert_eq!(sig, real_sig);
    }
}
<commit_msg>Add token type<commit_after>extern crate crypto;
extern crate rustc_serialize;

use crypto::digest::Digest;
use crypto::hmac::Hmac;
use crypto::mac::Mac;
use rustc_serialize::base64::{
    self,
    CharacterSet,
    Newline,
    ToBase64,
};
use header::Header;
use claims::Claims;

pub mod error;
pub mod header;
pub mod claims;

pub struct Token {
    header: Header,
    claims: Claims,
}

const BASE_CONFIG: base64::Config = base64::Config {
    char_set: CharacterSet::Standard,
    newline: Newline::LF,
    pad: false,
    line_length: None,
};

fn sign<D: Digest>(data: &str, key: &str, digest: D) -> String {
    let mut hmac = Hmac::new(digest, key.as_bytes());
    hmac.input(data.as_bytes());

    let mac = hmac.result();
    let code = mac.code();
    (*code).to_base64(BASE_CONFIG)
}

#[cfg(test)]
mod tests {
    use sign;
    use crypto::sha2::Sha256;

    #[test]
    pub fn sign_data() {
        let header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
        let claims = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9";
        let real_sig = "TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
        let data = format!("{}.{}", header, claims);

        let sig = sign(&*data, "secret", Sha256::new());

        assert_eq!(sig, real_sig);
    }
}
<|endoftext|>


<commit_before><commit_msg>(fix) Document type aliases.<commit_after><|endoftext|>


<commit_before><commit_msg>Not actually sure if this will work but we might be able to re-export the various libraries we build so gossyp can be a library too<commit_after>extern crate serde_json;
extern crate gossyp_base;
extern crate gossyp_toolkit;
extern crate gossyp_lang;

pub use gossyp_base::*;
pub use gossyp_toolkit::*;
pub use gossyp_lang::*;
<|endoftext|>


<commit_before><commit_msg>Add some prototypical objet relational mapping<commit_after>macro_rules! rdf{
    (
        $(
            class $name:ident = $id:expr {
                $(
                    $prop_name:ident : $prop_type:ty = $prop_id:expr
                ),*
            }
        )*
    ) => (
        $(
            pub struct $name{
                pub id: String
            }
            impl $name{
                pub fn id() -> &'static str{ $id }
                $(
                    pub fn $prop_name () -> Option<$prop_type>{
                        None
                    }
                )*
            }
        )*
    )
}

macro_rules! rules{
    (
        {
            $($rule:tt)*
        }=>{
            $($implies:tt)*
        }
    ) => (

    )
}

rdf!{
    class Term = "http://www.w3.org/1999/02/22-rdf-syntax-ns#Term" {
        name: BNode = "..."
    }
    class BNode = "..."{

    }
    class RdfTerm = "..."{

    }
    class Literal = "..."{

    }
    class RdfGraph = "..."{

    }
    class Symbol = "..."{

    }
    class Formula = "..."{
        statements: Symbol = "..."
    }
}

rules!{
    {
        Simon Wohnort Laufach .
    } => {
        |s, p, o| name
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove prepresent_command_buffers, and use command_buffers instead<commit_after><|endoftext|>


<commit_before><commit_msg>Add comment processing in tokenizer and fix mistakes.<commit_after><|endoftext|>


<commit_before><commit_msg>fixed parenthesis level in argparser<commit_after><|endoftext|>


<commit_before><commit_msg>Document Database::new<commit_after><|endoftext|>


<commit_before>use std::sync::Arc;

use {Wake, Tokens};
use stream::{Stream, StreamResult};

/// A stream which "fuse"s a stream once it's terminated.
///
/// Normally streams can behave unpredictably after they've terminated or
/// returned an error, but `Fuse` is always defined to return `None` from `poll`
/// after terination/errors, and afterwards all calls to `schedule` will be
/// ignored.
pub struct Fuse<S> {
    stream: Option<S>,
}

pub fn new<S: Stream>(s: S) -> Fuse<S> {
    Fuse { stream: Some(s) }
}

impl<S: Stream> Stream for Fuse<S> {
    type Item = S::Item;
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<StreamResult<S::Item, S::Error>> {
        if let Some(mut s) = self.stream.take() {
            let res = s.poll(tokens);
            match res {
                None => self.stream = Some(s),
                Some(Ok(Some(_))) => self.stream = Some(s),
                _ => {},
            }
            res
        } else {
            Some(Ok(None))
        }
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        if let Some(ref mut stream) = self.stream {
            stream.schedule(wake)
        }
    }
}

impl<S> Fuse<S> {
    pub fn is_done(&self) -> bool {
        self.stream.is_none()
    }
}
<commit_msg>Don't end Stream::fuse on an error, only on Ok(None)<commit_after>use std::sync::Arc;

use {Wake, Tokens};
use stream::{Stream, StreamResult};

/// A stream which "fuse"s a stream once it's terminated.
///
/// Normally streams can behave unpredictably after they've terminated or
/// returned an error, but `Fuse` is always defined to return `None` from `poll`
/// after terination/errors, and afterwards all calls to `schedule` will be
/// ignored.
pub struct Fuse<S> {
    stream: Option<S>,
}

pub fn new<S: Stream>(s: S) -> Fuse<S> {
    Fuse { stream: Some(s) }
}

impl<S: Stream> Stream for Fuse<S> {
    type Item = S::Item;
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Option<StreamResult<S::Item, S::Error>> {
        let ret = self.stream.as_mut().and_then(|s| s.poll(tokens));
        if let Some(Ok(None)) = ret {
            self.stream = None;
        }
        return ret
    }

    fn schedule(&mut self, wake: Arc<Wake>) {
        if let Some(ref mut stream) = self.stream {
            stream.schedule(wake)
        }
    }
}

impl<S> Fuse<S> {
    pub fn is_done(&self) -> bool {
        self.stream.is_none()
    }
}
<|endoftext|>


<commit_before><commit_msg>Resouce loader (empty) module<commit_after><|endoftext|>


<commit_before><commit_msg>add test data for u8<commit_after><|endoftext|>


<commit_before><commit_msg>getting travis to work<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test<commit_after>// Copyright 2015 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.

macro_rules! m {
    ( $( any_token $field_rust_type )* ) => {}; //~ ERROR missing fragment
}

fn main() {
    m!();
}
<|endoftext|>


<commit_before><commit_msg>Explain the purpose of src/buffered.rs.<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for assert!() hygiene in edition 2021.<commit_after>// check-pass
// edition:2021

#![no_implicit_prelude]

fn main() {
    assert!(true, "hoi");
    assert!(false, "hoi {}", 123);
}
<|endoftext|>


<commit_before><commit_msg>examples/8puzzle: Programming Assignment: 8 Puzzle TODO: fails at test case 28<commit_after>// http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html
extern crate algs4;

use std::io::prelude::*;
use std::io;
use std::fmt;
use std::cmp::Ordering;

use algs4::priority_queues::MinPQ;
use algs4::priority_queues::binary_heaps::BinaryHeapMinPQ;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Board {
    blocks: Vec<Vec<usize>>,
    n: usize
}

impl Board {
    pub fn new(blocks: Vec<Vec<usize>>) -> Board {
        assert!(blocks.len() == blocks[0].len());
        let len = blocks.len();
        Board { blocks: blocks, n: len }
    }

    pub fn dimension(&self) -> usize {
        return self.n
    }
    pub fn hamming(&self) -> usize {
        let mut num = 0;
        for i in 0 .. self.n {
            for j in 0 .. self.n {
                if self.blocks[i][j] != i * self.n + j + 1 && self.blocks[i][j] != 0 {
                    num += 1;
                }
            }
        }
        num
    }

    pub fn manhattan(&self) -> usize {
        let mut distance = 0;
        for i in 0 .. self.n {
            for j in 0 .. self.n {
                //let val = i * self.n + j + 1;
                // if val == 0 {
                //     continue;
                // }
                let val = self.blocks[i][j];
                if val != i * self.n + j + 1 && val != 0 {
                    // current block's val is not in position
                    let actual_row = (val - 1) / self.n;
                    let actual_col = (val - 1) % self.n;

                    let dist = (actual_row as isize - i as isize).abs() + (actual_col as isize - j as isize).abs();
                    distance += dist as usize;
                }
            }
        }
        distance
    }

    pub fn is_goal(&self) -> bool {
        self.hamming() == 0
    }

    fn position_of(&self, val: usize) -> (usize, usize) {
        for i in 0 .. self.n {
            for j in 0 .. self.n {
                if self.blocks[i][j] == val {
                    return (i, j)
                }
            }
        }
        (9999, 9999)
    }

    pub fn neighbors(&self) -> Vec<Board> {
        let (row, col) = self.position_of(0);
        let mut positions = Vec::new();
        if row >= 1 {
            positions.push((row-1, col));
        }
        if row < self.n - 1{
            positions.push((row+1, col));
        }
        if col >= 1 {
            positions.push((row, col-1));
        }
        if col < self.n - 1{
            positions.push((row, col+1));
        }

        let mut ret = Vec::new();
        for (r, c) in positions {
            let mut b = self.clone();
            b.blocks[row][col] = b.blocks[r][c];
            b.blocks[r][c] = 0;
            ret.push(b);
        }
        ret
    }
}

impl fmt::Display for Board {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in self.blocks.iter() {
            try!(write!(f, "|"));
            for val in row.iter() {
                try!(write!(f, "{:-3}", val));
            }
            try!(write!(f, " |\n"));
        }
        Ok(())
    }
}

// impl PartialOrd for Board {
//     fn partial_cmp(&self, other: &Board) -> Option<Ordering> {
//         self.manhattan().partial_cmp(&other.manhattan())
//     }
// }

// a search Node
#[derive(PartialEq)]
pub struct Node {
    board: Board,
    moves: usize,
    operations: Vec<Board>
}

impl Node {
    pub fn new(board: Board, moves: usize, operations: Vec<Board>) -> Node {
        Node {
            board: board,
            moves: moves,
            operations: operations
        }
    }

    #[inline]
    fn priority(&self) -> usize {
        self.board.manhattan() + self.moves
    }

    fn take(self) -> (Board, usize, Vec<Board>) {
        (self.board, self.moves, self.operations)
    }
}

impl PartialOrd for Node {
    fn partial_cmp(&self, other: &Node) -> Option<Ordering> {
        self.priority().partial_cmp(&other.priority())
    }
}

pub struct Solver {
    solvable: bool,
    solution: Vec<Board>,
    moves: usize,
}

impl Solver {
    pub fn new(initial: Board) -> Solver {
        let mut pq: BinaryHeapMinPQ<Node> = BinaryHeapMinPQ::with_capacity(10240);

        pq.insert(Node::new(initial.clone(), 0, Vec::new()));

        let max_iteration = initial.dimension().pow(3);
        let mut visited = Vec::new();

        visited.push(initial.clone());
        while !pq.is_empty() {
            let (b, mut moves, mut operations) = pq.del_min().unwrap().take();
            if operations.contains(&b) {
                continue;
            }

            operations.push(b.clone());

            if b.is_goal() {
                return Solver {
                    solvable: true,
                    solution: operations,
                    moves: moves
                }
            }

            moves += 1;
            //println!("moves => {:2} size={}", moves, visited.len());
            for neighbor in b.neighbors() {
                if !visited.contains(&neighbor) {
                    visited.push(neighbor.clone());
                    pq.insert(Node::new(neighbor, moves, operations.clone()));
                }
            }

            if moves > max_iteration {
                break;
            }

        }

        Solver {
            solvable: false,
            solution: Vec::new(),
            moves: 0
        }
    }
}

impl fmt::Display for Solver {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.solvable {
            try!(writeln!(f, "Minimum number of moves = {}", self.moves));
            for m in self.solution.iter() {
                try!(writeln!(f, "{}", m));
            }
        } else {
            try!(writeln!(f, "No solution possible"));
        }
        Ok(())
    }
}

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();
    let n = lines.next().unwrap().unwrap().parse().unwrap();

    let mut blks: Vec<Vec<usize>> = Vec::new();
    for _ in 0 .. n {
        let segs: Vec<usize> = lines.next().unwrap().unwrap().split(' ').
            filter(|s| !s.is_empty()).map(|n| n.parse().unwrap()).collect();
        blks.push(segs);
    }

    let b = Board::new(blks);
    let solver = Solver::new(b);
    println!("{}", solver);

}

#[test]
fn test_solver() {
    // let blks = vec![
    //     vec![8, 1, 3],
    //     vec![4, 0, 2],
    //     vec![7, 6, 5],
    //     ];
    let blks = vec![
        vec![0, 1, 3],
        vec![4, 2, 5],
        vec![7, 8, 6],
        ];
    // unsolveable
    // let blks = vec![
    //     vec![1, 2, 3],
    //     vec![4, 5, 6],
    //     vec![8, 7, 0],
    //     ];

    let b = Board::new(blks);
    println!("block:\n{}", b);
    println!("hamming => {}", b.hamming());
    println!("manhattan => {}", b.manhattan());
    println!("is goal => {}", b.is_goal());

    for i in b.neighbors() {
        println!("neighbor:\n{}", i);
    }

    let solver = Solver::new(b);
    println!("{}", solver);
}
<|endoftext|>


<commit_before><commit_msg>Disable H2 ALPN.<commit_after><|endoftext|>


<commit_before><commit_msg>Version using chennels. Needs cleanup.<commit_after><|endoftext|>


<commit_before><commit_msg>Create a fibonacci code sample<commit_after>fn fib(n: i64) -> i64 {
    if n == 0 {
        0
    } else if n == 1 {
        1
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

fn main() {
    let argument = 10;

    println!("fib({}) = {}", argument, fib(argument));
}
<|endoftext|>


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

//! Memory profiling functions.

use libc::{c_char,c_int,c_void,size_t};
use std::borrow::ToOwned;
use std::ffi::CString;
use std::old_io::timer::sleep;
#[cfg(target_os="linux")]
use std::old_io::File;
use std::mem;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::env::page_size;
use std::ptr::null_mut;
use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
use task_info::task_basic_info::{virtual_size,resident_size};

pub struct MemoryProfilerChan(pub Sender<MemoryProfilerMsg>);

impl MemoryProfilerChan {
    pub fn send(&self, msg: MemoryProfilerMsg) {
        let MemoryProfilerChan(ref c) = *self;
        c.send(msg).unwrap();
    }
}

pub enum MemoryProfilerMsg {
    /// Message used to force print the memory profiling metrics.
    Print,
    /// Tells the memory profiler to shut down.
    Exit,
}

pub struct MemoryProfiler {
    pub port: Receiver<MemoryProfilerMsg>,
}

impl MemoryProfiler {
    pub fn create(period: Option<f64>) -> MemoryProfilerChan {
        let (chan, port) = channel();
        match period {
            Some(period) => {
                let period = Duration::milliseconds((period * 1000f64) as i64);
                let chan = chan.clone();
                spawn_named("Memory profiler timer".to_owned(), move || {
                    loop {
                        sleep(period);
                        if chan.send(MemoryProfilerMsg::Print).is_err() {
                            break;
                        }
                    }
                });
                // Spawn the memory profiler.
                spawn_named("Memory profiler".to_owned(), move || {
                    let memory_profiler = MemoryProfiler::new(port);
                    memory_profiler.start();
                });
            }
            None => {
                // No-op to handle messages when the memory profiler is
                // inactive.
                spawn_named("Memory profiler".to_owned(), move || {
                    loop {
                        match port.recv() {
                            Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
                            _ => {}
                        }
                    }
                });
            }
        }

        MemoryProfilerChan(chan)
    }

    pub fn new(port: Receiver<MemoryProfilerMsg>) -> MemoryProfiler {
        MemoryProfiler {
            port: port
        }
    }

    pub fn start(&self) {
        loop {
            match self.port.recv() {
               Ok(msg) => {
                   if !self.handle_msg(msg) {
                       break
                   }
               }
               _ => break
            }
        }
    }

    fn handle_msg(&self, msg: MemoryProfilerMsg) -> bool {
        match msg {
            MemoryProfilerMsg::Print => {
                self.handle_print_msg();
                true
            },
            MemoryProfilerMsg::Exit => false
        }
    }

    fn print_measurement(path: &str, nbytes: Option<u64>) {
        match nbytes {
            Some(nbytes) => {
                let mebi = 1024f64 * 1024f64;
                println!("{:24}: {:12.2}", path, (nbytes as f64) / mebi);
            }
            None => {
                println!("{:24}: {:>12}", path, "???");
            }
        }
    }

    fn handle_print_msg(&self) {
        println!("{:24}: {:12}", "_category_", "_size (MiB)_");

        // Virtual and physical memory usage, as reported by the OS.
        MemoryProfiler::print_measurement("vsize", get_vsize());
        MemoryProfiler::print_measurement("resident", get_resident());

        // Total number of bytes allocated by the application on the system
        // heap.
        MemoryProfiler::print_measurement("system-heap-allocated",
                                          get_system_heap_allocated());

        // The descriptions of the following jemalloc measurements are taken
        // directly from the jemalloc documentation.

        // "Total number of bytes allocated by the application."
        MemoryProfiler::print_measurement("jemalloc-heap-allocated",
                                          get_jemalloc_stat("stats.allocated"));

        // "Total number of bytes in active pages allocated by the application.
        // This is a multiple of the page size, and greater than or equal to
        // |stats.allocated|."
        MemoryProfiler::print_measurement("jemalloc-heap-active",
                                          get_jemalloc_stat("stats.active"));

        // "Total number of bytes in chunks mapped on behalf of the application.
        // This is a multiple of the chunk size, and is at least as large as
        // |stats.active|. This does not include inactive chunks."
        MemoryProfiler::print_measurement("jemalloc-heap-mapped",
                                          get_jemalloc_stat("stats.mapped"));

        println!("");
    }
}

#[cfg(target_os="linux")]
extern {
    fn mallinfo() -> struct_mallinfo;
}

#[cfg(target_os="linux")]
#[repr(C)]
pub struct struct_mallinfo {
    arena:    c_int,
    ordblks:  c_int,
    smblks:   c_int,
    hblks:    c_int,
    hblkhd:   c_int,
    usmblks:  c_int,
    fsmblks:  c_int,
    uordblks: c_int,
    fordblks: c_int,
    keepcost: c_int,
}

#[cfg(target_os="linux")]
fn get_system_heap_allocated() -> Option<u64> {
    let mut info: struct_mallinfo;
    unsafe {
        info = mallinfo();
    }
    // The documentation in the glibc man page makes it sound like |uordblks|
    // would suffice, but that only gets the small allocations that are put in
    // the brk heap. We need |hblkhd| as well to get the larger allocations
    // that are mmapped.
    Some((info.hblkhd + info.uordblks) as u64)
}

#[cfg(not(target_os="linux"))]
fn get_system_heap_allocated() -> Option<u64> {
    None
}

extern {
    fn je_mallctl(name: *const c_char, oldp: *mut c_void, oldlenp: *mut size_t,
                  newp: *mut c_void, newlen: size_t) -> c_int;
}

fn get_jemalloc_stat(value_name: &str) -> Option<u64> {
    // Before we request the measurement of interest, we first send an "epoch"
    // request. Without that jemalloc gives cached statistics(!) which can be
    // highly inaccurate.
    let epoch_name = "epoch";
    let epoch_c_name = CString::from_slice(epoch_name.as_bytes());
    let mut epoch: u64 = 0;
    let epoch_ptr = &mut epoch as *mut _ as *mut c_void;
    let mut epoch_len = size_of::<u64>() as size_t;

    let value_c_name = CString::from_slice(value_name.as_bytes());
    let mut value: size_t = 0;
    let value_ptr = &mut value as *mut _ as *mut c_void;
    let mut value_len = size_of::<size_t>() as size_t;

    let mut rv: c_int;
    unsafe {
        // Using the same values for the `old` and `new` parameters is enough
        // to get the statistics updated.
        rv = je_mallctl(epoch_c_name.as_ptr(), epoch_ptr, &mut epoch_len, epoch_ptr, epoch_len);
        if rv == 0 {
            rv = je_mallctl(value_c_name.as_ptr(), value_ptr, &mut value_len, null_mut(), 0);
        }
    }
    if rv == 0 { Some(value as u64) } else { None }
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
    let mut f = File::open(&Path::new("/proc/self/statm"));
    match f.read_to_string() {
        Ok(contents) => {
            let s = option_try!(contents.as_slice().words().nth(field));
            let npages: u64 = option_try!(s.parse().ok());
            Some(npages * (page_size() as u64))
        }
        Err(_) => None
    }
}

#[cfg(target_os="linux")]
fn get_vsize() -> Option<u64> {
    get_proc_self_statm_field(0)
}

#[cfg(target_os="linux")]
fn get_resident() -> Option<u64> {
    get_proc_self_statm_field(1)
}

#[cfg(target_os="macos")]
fn get_vsize() -> Option<u64> {
    virtual_size()
}

#[cfg(target_os="macos")]
fn get_resident() -> Option<u64> {
    resident_size()
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_vsize() -> Option<u64> {
    None
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_resident() -> Option<u64> {
    None
}
<commit_msg>auto merge of #4927 : Ms2ger/servo/mem, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Memory profiling functions.

use libc::{c_char,c_int,c_void,size_t};
use std::borrow::ToOwned;
use std::ffi::CString;
use std::old_io::timer::sleep;
#[cfg(target_os="linux")]
use std::old_io::File;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::env::page_size;
use std::ptr::null_mut;
use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
use task_info::task_basic_info::{virtual_size,resident_size};

pub struct MemoryProfilerChan(pub Sender<MemoryProfilerMsg>);

impl MemoryProfilerChan {
    pub fn send(&self, msg: MemoryProfilerMsg) {
        let MemoryProfilerChan(ref c) = *self;
        c.send(msg).unwrap();
    }
}

pub enum MemoryProfilerMsg {
    /// Message used to force print the memory profiling metrics.
    Print,
    /// Tells the memory profiler to shut down.
    Exit,
}

pub struct MemoryProfiler {
    pub port: Receiver<MemoryProfilerMsg>,
}

impl MemoryProfiler {
    pub fn create(period: Option<f64>) -> MemoryProfilerChan {
        let (chan, port) = channel();
        match period {
            Some(period) => {
                let period = Duration::milliseconds((period * 1000f64) as i64);
                let chan = chan.clone();
                spawn_named("Memory profiler timer".to_owned(), move || {
                    loop {
                        sleep(period);
                        if chan.send(MemoryProfilerMsg::Print).is_err() {
                            break;
                        }
                    }
                });
                // Spawn the memory profiler.
                spawn_named("Memory profiler".to_owned(), move || {
                    let memory_profiler = MemoryProfiler::new(port);
                    memory_profiler.start();
                });
            }
            None => {
                // No-op to handle messages when the memory profiler is
                // inactive.
                spawn_named("Memory profiler".to_owned(), move || {
                    loop {
                        match port.recv() {
                            Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
                            _ => {}
                        }
                    }
                });
            }
        }

        MemoryProfilerChan(chan)
    }

    pub fn new(port: Receiver<MemoryProfilerMsg>) -> MemoryProfiler {
        MemoryProfiler {
            port: port
        }
    }

    pub fn start(&self) {
        loop {
            match self.port.recv() {
               Ok(msg) => {
                   if !self.handle_msg(msg) {
                       break
                   }
               }
               _ => break
            }
        }
    }

    fn handle_msg(&self, msg: MemoryProfilerMsg) -> bool {
        match msg {
            MemoryProfilerMsg::Print => {
                self.handle_print_msg();
                true
            },
            MemoryProfilerMsg::Exit => false
        }
    }

    fn print_measurement(path: &str, nbytes: Option<u64>) {
        match nbytes {
            Some(nbytes) => {
                let mebi = 1024f64 * 1024f64;
                println!("{:24}: {:12.2}", path, (nbytes as f64) / mebi);
            }
            None => {
                println!("{:24}: {:>12}", path, "???");
            }
        }
    }

    fn handle_print_msg(&self) {
        println!("{:24}: {:12}", "_category_", "_size (MiB)_");

        // Virtual and physical memory usage, as reported by the OS.
        MemoryProfiler::print_measurement("vsize", get_vsize());
        MemoryProfiler::print_measurement("resident", get_resident());

        // Total number of bytes allocated by the application on the system
        // heap.
        MemoryProfiler::print_measurement("system-heap-allocated",
                                          get_system_heap_allocated());

        // The descriptions of the following jemalloc measurements are taken
        // directly from the jemalloc documentation.

        // "Total number of bytes allocated by the application."
        MemoryProfiler::print_measurement("jemalloc-heap-allocated",
                                          get_jemalloc_stat("stats.allocated"));

        // "Total number of bytes in active pages allocated by the application.
        // This is a multiple of the page size, and greater than or equal to
        // |stats.allocated|."
        MemoryProfiler::print_measurement("jemalloc-heap-active",
                                          get_jemalloc_stat("stats.active"));

        // "Total number of bytes in chunks mapped on behalf of the application.
        // This is a multiple of the chunk size, and is at least as large as
        // |stats.active|. This does not include inactive chunks."
        MemoryProfiler::print_measurement("jemalloc-heap-mapped",
                                          get_jemalloc_stat("stats.mapped"));

        println!("");
    }
}

#[cfg(target_os="linux")]
extern {
    fn mallinfo() -> struct_mallinfo;
}

#[cfg(target_os="linux")]
#[repr(C)]
pub struct struct_mallinfo {
    arena:    c_int,
    ordblks:  c_int,
    smblks:   c_int,
    hblks:    c_int,
    hblkhd:   c_int,
    usmblks:  c_int,
    fsmblks:  c_int,
    uordblks: c_int,
    fordblks: c_int,
    keepcost: c_int,
}

#[cfg(target_os="linux")]
fn get_system_heap_allocated() -> Option<u64> {
    let mut info: struct_mallinfo;
    unsafe {
        info = mallinfo();
    }
    // The documentation in the glibc man page makes it sound like |uordblks|
    // would suffice, but that only gets the small allocations that are put in
    // the brk heap. We need |hblkhd| as well to get the larger allocations
    // that are mmapped.
    Some((info.hblkhd + info.uordblks) as u64)
}

#[cfg(not(target_os="linux"))]
fn get_system_heap_allocated() -> Option<u64> {
    None
}

extern {
    fn je_mallctl(name: *const c_char, oldp: *mut c_void, oldlenp: *mut size_t,
                  newp: *mut c_void, newlen: size_t) -> c_int;
}

fn get_jemalloc_stat(value_name: &str) -> Option<u64> {
    // Before we request the measurement of interest, we first send an "epoch"
    // request. Without that jemalloc gives cached statistics(!) which can be
    // highly inaccurate.
    let epoch_name = "epoch";
    let epoch_c_name = CString::from_slice(epoch_name.as_bytes());
    let mut epoch: u64 = 0;
    let epoch_ptr = &mut epoch as *mut _ as *mut c_void;
    let mut epoch_len = size_of::<u64>() as size_t;

    let value_c_name = CString::from_slice(value_name.as_bytes());
    let mut value: size_t = 0;
    let value_ptr = &mut value as *mut _ as *mut c_void;
    let mut value_len = size_of::<size_t>() as size_t;

    // Using the same values for the `old` and `new` parameters is enough
    // to get the statistics updated.
    let rv = unsafe {
        je_mallctl(epoch_c_name.as_ptr(), epoch_ptr, &mut epoch_len, epoch_ptr,
                   epoch_len)
    };
    if rv != 0 {
        return None;
    }

    let rv = unsafe {
        je_mallctl(value_c_name.as_ptr(), value_ptr, &mut value_len,
                   null_mut(), 0)
    };
    if rv != 0 {
        return None;
    }

    Some(value as u64)
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
    let mut f = File::open(&Path::new("/proc/self/statm"));
    match f.read_to_string() {
        Ok(contents) => {
            let s = option_try!(contents.as_slice().words().nth(field));
            let npages: u64 = option_try!(s.parse().ok());
            Some(npages * (page_size() as u64))
        }
        Err(_) => None
    }
}

#[cfg(target_os="linux")]
fn get_vsize() -> Option<u64> {
    get_proc_self_statm_field(0)
}

#[cfg(target_os="linux")]
fn get_resident() -> Option<u64> {
    get_proc_self_statm_field(1)
}

#[cfg(target_os="macos")]
fn get_vsize() -> Option<u64> {
    virtual_size()
}

#[cfg(target_os="macos")]
fn get_resident() -> Option<u64> {
    resident_size()
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_vsize() -> Option<u64> {
    None
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_resident() -> Option<u64> {
    None
}
<|endoftext|>


<commit_before><commit_msg>cmd: Include exit code/reason on failure<commit_after><|endoftext|>


<commit_before><commit_msg>Only create directory if it does not exist<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: PathIterBuilder should not yield directories<commit_after><|endoftext|>


<commit_before><commit_msg>Fix types<commit_after><|endoftext|>


<commit_before><commit_msg>Implement io::native::stdio<commit_after>// Copyright 2013 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 libc;
use option::Option;
use rt::io::{Reader, Writer};
use super::file;

/// Creates a new handle to the stdin of this process
pub fn stdin() -> StdIn { StdIn::new() }
/// Creates a new handle to the stdout of this process
pub fn stdout() -> StdOut { StdOut::new(libc::STDOUT_FILENO) }
/// Creates a new handle to the stderr of this process
pub fn stderr() -> StdOut { StdOut::new(libc::STDERR_FILENO) }

pub fn print(s: &str) {
    stdout().write(s.as_bytes())
}

pub fn println(s: &str) {
    let mut out = stdout();
    out.write(s.as_bytes());
    out.write(['\n' as u8]);
}

pub struct StdIn {
    priv fd: file::FileDesc
}

impl StdIn {
    /// Duplicates the stdin file descriptor, returning an io::Reader
    #[fixed_stack_segment] #[inline(never)]
    pub fn new() -> StdIn {
        let fd = unsafe { libc::dup(libc::STDIN_FILENO) };
        StdIn { fd: file::FileDesc::new(fd) }
    }
}

impl Reader for StdIn {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.fd.read(buf) }
    fn eof(&mut self) -> bool { self.fd.eof() }
}

pub struct StdOut {
    priv fd: file::FileDesc
}

impl StdOut {
    /// Duplicates the specified file descriptor, returning an io::Writer
    #[fixed_stack_segment] #[inline(never)]
    pub fn new(fd: file::fd_t) -> StdOut {
        let fd = unsafe { libc::dup(fd) };
        StdOut { fd: file::FileDesc::new(fd) }
    }
}

impl Writer for StdOut {
    fn write(&mut self, buf: &[u8]) { self.fd.write(buf) }
    fn flush(&mut self) { self.fd.flush() }
}
<|endoftext|>


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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0178: r##"
In types, the `+` type operator has low precedence, so it is often necessary
to use parentheses.

For example:

```compile_fail,E0178
trait Foo {}

struct Bar<'a> {
    w: &'a Foo + Copy,   // error, use &'a (Foo + Copy)
    x: &'a Foo + 'a,     // error, use &'a (Foo + 'a)
    y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
    z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
}
```

More details can be found in [RFC 438].

[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
"##,

E0536: r##"
The `not` cfg-predicate was malformed.

Erroneous code example:

```compile_fail,E0536
#[cfg(not())] // error: expected 1 cfg-pattern
pub fn something() {}

pub fn main() {}
```

The `not` predicate expects one cfg-pattern. Example:

```
#[cfg(not(target_os = "linux"))] // ok!
pub fn something() {}

pub fn main() {}
```

For more information about the cfg attribute, read:
https://doc.rust-lang.org/reference.html#conditional-compilation
"##,

E0537: r##"
An unknown predicate was used inside the `cfg` attribute.

Erroneous code example:

```compile_fail,E0537
#[cfg(unknown())] // error: invalid predicate `unknown`
pub fn something() {}

pub fn main() {}
```

The `cfg` attribute supports only three kinds of predicates:

 * any
 * all
 * not

Example:

```
#[cfg(not(target_os = "linux"))] // ok!
pub fn something() {}

pub fn main() {}
```

For more information about the cfg attribute, read:
https://doc.rust-lang.org/reference.html#conditional-compilation
"##,

E0541: r##"
An unknown meta item was used.

Erroneous code example:

```compile_fail,E0541
#[deprecated(
    since="1.0.0",
    // error: unknown meta item
    reason="Example invalid meta item. Should be 'note'")
]
fn deprecated_function() {}
```

Meta items are the key-value pairs inside of an attribute. The keys provided
must be one of the valid keys for the specified attribute.

To fix the problem, either remove the unknown meta item, or rename it if you
provided the wrong name.

In the erroneous code example above, the wrong name was provided, so changing
to a correct one it will fix the error. Example:

```
#[deprecated(
    since="1.0.0",
    note="This is a valid meta item for the deprecated attribute."
)]
fn deprecated_function() {}
```
"##,

E0552: r##"
A unrecognized representation attribute was used.

Erroneous code example:

```compile_fail,E0552
#[repr(D)] // error: unrecognized representation hint
struct MyStruct {
    my_field: usize
}
```

You can use a `repr` attribute to tell the compiler how you want a struct or
enum to be laid out in memory.

Make sure you're using one of the supported options:

```
#[repr(C)] // ok!
struct MyStruct {
    my_field: usize
}
```

For more information about specifying representations, see the ["Alternative
Representations" section] of the Rustonomicon.

["Alternative Representations" section]: https://doc.rust-lang.org/nomicon/other-reprs.html
"##,

E0554: r##"
Feature attributes are only allowed on the nightly release channel. Stable or
beta compilers will not comply.

Example of erroneous code (on a stable compiler):

```ignore (depends on release channel)
#![feature(non_ascii_idents)] // error: #![feature] may not be used on the
                              //        stable release channel
```

If you need the feature, make sure to use a nightly release of the compiler
(but be warned that the feature may be removed or altered in the future).
"##,

E0557: r##"
A feature attribute named a feature that has been removed.

Erroneous code example:

```compile_fail,E0557
#![feature(managed_boxes)] // error: feature has been removed
```

Delete the offending feature attribute.
"##,

E0565: r##"
A literal was used in an attribute that doesn't support literals.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
#![feature(attr_literals)]

#[inline("always")] // error: unsupported literal
pub fn something() {}
```

Literals in attributes are new and largely unsupported. Work to support literals
where appropriate is ongoing. Try using an unquoted name instead:

```
#[inline(always)]
pub fn something() {}
```
"##,

E0583: r##"
A file wasn't found for an out-of-line module.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
mod file_that_doesnt_exist; // error: file not found for module

fn main() {}
```

Please be sure that a file corresponding to the module exists. If you
want to use a module named `file_that_doesnt_exist`, you need to have a file
named `file_that_doesnt_exist.rs` or `file_that_doesnt_exist/mod.rs` in the
same directory.
"##,

E0585: r##"
A documentation comment that doesn't document anything was found.

Erroneous code example:

```compile_fail,E0585
fn main() {
    // The following doc comment will fail:
    /// This is a useless doc comment!
}
```

Documentation comments need to be followed by items, including functions,
types, modules, etc. Examples:

```
/// I'm documenting the following struct:
struct Foo;

/// I'm documenting the following function:
fn foo() {}
```
"##,

E0586: r##"
An inclusive range was used with no end.

Erroneous code example:

```compile_fail,E0586
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..=]; // error: inclusive range was used with no end
}
```

An inclusive range needs an end in order to *include* it. If you just need a
start and no end, use a non-inclusive range (with `..`):

```
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..]; // ok!
}
```

Or put an end to your inclusive range:

```
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..=3]; // ok!
}
```
"##,

E0589: r##"
The value of `N` that was specified for `repr(align(N))` was not a power
of two, or was greater than 2^29.

```compile_fail,E0589
#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
enum Foo {
    Bar(u64),
}
```
"##,

E0658: r##"
An unstable feature was used.

Erroneous code example:

```compile_fail,E658
#[repr(u128)] // error: use of unstable library feature 'repr128'
enum Foo {
    Bar(u64),
}
```

If you're using a stable or a beta version of rustc, you won't be able to use
any unstable features. In order to do so, please switch to a nightly version of
rustc (by using rustup).

If you're using a nightly version of rustc, just add the corresponding feature
to be able to use it:

```
#![feature(repr128)]

#[repr(u128)] // ok!
enum Foo {
    Bar(u64),
}
```
"##,

E0633: r##"
The `unwind` attribute was malformed.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
#[unwind()] // error: expected one argument
pub extern fn something() {}

fn main() {}
```

The `#[unwind]` attribute should be used as follows:

- `#[unwind(aborts)]` -- specifies that if a non-Rust ABI function
  should abort the process if it attempts to unwind. This is the safer
  and preferred option.

- `#[unwind(allowed)]` -- specifies that a non-Rust ABI function
  should be allowed to unwind. This can easily result in Undefined
  Behavior (UB), so be careful.

NB. The default behavior here is "allowed", but this is unspecified
and likely to change in the future.

"##,

}

register_diagnostics! {
    E0538, // multiple [same] items
    E0539, // incorrect meta item
    E0540, // multiple rustc_deprecated attributes
    E0542, // missing 'since'
    E0543, // missing 'reason'
    E0544, // multiple stability levels
    E0545, // incorrect 'issue'
    E0546, // missing 'feature'
    E0547, // missing 'issue'
    E0548, // incorrect stability attribute type
    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
    E0550, // multiple deprecated attributes
    E0551, // incorrect meta item
    E0553, // multiple rustc_const_unstable attributes
    E0555, // malformed feature attribute, expected #![feature(...)]
    E0556, // malformed feature, expected just one word
    E0584, // file for module `..` found at both .. and ..
    E0629, // missing 'feature' (rustc_const_unstable)
    E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
    E0693, // incorrect `repr(align)` attribute format
    E0694, // an unknown tool name found in scoped attributes
}
<commit_msg>Long diagnostic for E0538<commit_after>// Copyright 2016 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0178: r##"
In types, the `+` type operator has low precedence, so it is often necessary
to use parentheses.

For example:

```compile_fail,E0178
trait Foo {}

struct Bar<'a> {
    w: &'a Foo + Copy,   // error, use &'a (Foo + Copy)
    x: &'a Foo + 'a,     // error, use &'a (Foo + 'a)
    y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
    z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
}
```

More details can be found in [RFC 438].

[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
"##,

E0536: r##"
The `not` cfg-predicate was malformed.

Erroneous code example:

```compile_fail,E0536
#[cfg(not())] // error: expected 1 cfg-pattern
pub fn something() {}

pub fn main() {}
```

The `not` predicate expects one cfg-pattern. Example:

```
#[cfg(not(target_os = "linux"))] // ok!
pub fn something() {}

pub fn main() {}
```

For more information about the cfg attribute, read:
https://doc.rust-lang.org/reference.html#conditional-compilation
"##,

E0537: r##"
An unknown predicate was used inside the `cfg` attribute.

Erroneous code example:

```compile_fail,E0537
#[cfg(unknown())] // error: invalid predicate `unknown`
pub fn something() {}

pub fn main() {}
```

The `cfg` attribute supports only three kinds of predicates:

 * any
 * all
 * not

Example:

```
#[cfg(not(target_os = "linux"))] // ok!
pub fn something() {}

pub fn main() {}
```

For more information about the cfg attribute, read:
https://doc.rust-lang.org/reference.html#conditional-compilation
"##,

E0538: r##"
Attribute contains multiple of the same meta item.

Erroneous code example:

```compile_fail,E0538
#[deprecated(
    since="1.0.0",
    note="First deprecation note.",
    note="Second deprecation note." // error: multiple same meta item
)]
fn deprecated_function() {}
```

Meta items are the key-value pairs inside of an attribute. Each key may only be
used once in each attribute.

To fix the problem, remove all but one of the meta items with the same key.

Example:

```
#[deprecated(
    since="1.0.0",
    note="First deprecation note."
)]
fn deprecated_function() {}
```
"##,

E0541: r##"
An unknown meta item was used.

Erroneous code example:

```compile_fail,E0541
#[deprecated(
    since="1.0.0",
    // error: unknown meta item
    reason="Example invalid meta item. Should be 'note'")
]
fn deprecated_function() {}
```

Meta items are the key-value pairs inside of an attribute. The keys provided
must be one of the valid keys for the specified attribute.

To fix the problem, either remove the unknown meta item, or rename it if you
provided the wrong name.

In the erroneous code example above, the wrong name was provided, so changing
to a correct one it will fix the error. Example:

```
#[deprecated(
    since="1.0.0",
    note="This is a valid meta item for the deprecated attribute."
)]
fn deprecated_function() {}
```
"##,

E0552: r##"
A unrecognized representation attribute was used.

Erroneous code example:

```compile_fail,E0552
#[repr(D)] // error: unrecognized representation hint
struct MyStruct {
    my_field: usize
}
```

You can use a `repr` attribute to tell the compiler how you want a struct or
enum to be laid out in memory.

Make sure you're using one of the supported options:

```
#[repr(C)] // ok!
struct MyStruct {
    my_field: usize
}
```

For more information about specifying representations, see the ["Alternative
Representations" section] of the Rustonomicon.

["Alternative Representations" section]: https://doc.rust-lang.org/nomicon/other-reprs.html
"##,

E0554: r##"
Feature attributes are only allowed on the nightly release channel. Stable or
beta compilers will not comply.

Example of erroneous code (on a stable compiler):

```ignore (depends on release channel)
#![feature(non_ascii_idents)] // error: #![feature] may not be used on the
                              //        stable release channel
```

If you need the feature, make sure to use a nightly release of the compiler
(but be warned that the feature may be removed or altered in the future).
"##,

E0557: r##"
A feature attribute named a feature that has been removed.

Erroneous code example:

```compile_fail,E0557
#![feature(managed_boxes)] // error: feature has been removed
```

Delete the offending feature attribute.
"##,

E0565: r##"
A literal was used in an attribute that doesn't support literals.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
#![feature(attr_literals)]

#[inline("always")] // error: unsupported literal
pub fn something() {}
```

Literals in attributes are new and largely unsupported. Work to support literals
where appropriate is ongoing. Try using an unquoted name instead:

```
#[inline(always)]
pub fn something() {}
```
"##,

E0583: r##"
A file wasn't found for an out-of-line module.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
mod file_that_doesnt_exist; // error: file not found for module

fn main() {}
```

Please be sure that a file corresponding to the module exists. If you
want to use a module named `file_that_doesnt_exist`, you need to have a file
named `file_that_doesnt_exist.rs` or `file_that_doesnt_exist/mod.rs` in the
same directory.
"##,

E0585: r##"
A documentation comment that doesn't document anything was found.

Erroneous code example:

```compile_fail,E0585
fn main() {
    // The following doc comment will fail:
    /// This is a useless doc comment!
}
```

Documentation comments need to be followed by items, including functions,
types, modules, etc. Examples:

```
/// I'm documenting the following struct:
struct Foo;

/// I'm documenting the following function:
fn foo() {}
```
"##,

E0586: r##"
An inclusive range was used with no end.

Erroneous code example:

```compile_fail,E0586
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..=]; // error: inclusive range was used with no end
}
```

An inclusive range needs an end in order to *include* it. If you just need a
start and no end, use a non-inclusive range (with `..`):

```
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..]; // ok!
}
```

Or put an end to your inclusive range:

```
fn main() {
    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
    let x = &tmp[1..=3]; // ok!
}
```
"##,

E0589: r##"
The value of `N` that was specified for `repr(align(N))` was not a power
of two, or was greater than 2^29.

```compile_fail,E0589
#[repr(align(15))] // error: invalid `repr(align)` attribute: not a power of two
enum Foo {
    Bar(u64),
}
```
"##,

E0658: r##"
An unstable feature was used.

Erroneous code example:

```compile_fail,E658
#[repr(u128)] // error: use of unstable library feature 'repr128'
enum Foo {
    Bar(u64),
}
```

If you're using a stable or a beta version of rustc, you won't be able to use
any unstable features. In order to do so, please switch to a nightly version of
rustc (by using rustup).

If you're using a nightly version of rustc, just add the corresponding feature
to be able to use it:

```
#![feature(repr128)]

#[repr(u128)] // ok!
enum Foo {
    Bar(u64),
}
```
"##,

E0633: r##"
The `unwind` attribute was malformed.

Erroneous code example:

```ignore (compile_fail not working here; see Issue #43707)
#[unwind()] // error: expected one argument
pub extern fn something() {}

fn main() {}
```

The `#[unwind]` attribute should be used as follows:

- `#[unwind(aborts)]` -- specifies that if a non-Rust ABI function
  should abort the process if it attempts to unwind. This is the safer
  and preferred option.

- `#[unwind(allowed)]` -- specifies that a non-Rust ABI function
  should be allowed to unwind. This can easily result in Undefined
  Behavior (UB), so be careful.

NB. The default behavior here is "allowed", but this is unspecified
and likely to change in the future.

"##,

}

register_diagnostics! {
    E0539, // incorrect meta item
    E0540, // multiple rustc_deprecated attributes
    E0542, // missing 'since'
    E0543, // missing 'reason'
    E0544, // multiple stability levels
    E0545, // incorrect 'issue'
    E0546, // missing 'feature'
    E0547, // missing 'issue'
    E0548, // incorrect stability attribute type
    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
    E0550, // multiple deprecated attributes
    E0551, // incorrect meta item
    E0553, // multiple rustc_const_unstable attributes
    E0555, // malformed feature attribute, expected #![feature(...)]
    E0556, // malformed feature, expected just one word
    E0584, // file for module `..` found at both .. and ..
    E0629, // missing 'feature' (rustc_const_unstable)
    E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
    E0693, // incorrect `repr(align)` attribute format
    E0694, // an unknown tool name found in scoped attributes
}
<|endoftext|>


<commit_before><commit_msg>Add a regression test for ICE #33287<commit_after>// Copyright 2017 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.

const A: [u32; 1] = [0];

fn test() {
    let range = A[1]..;
}

fn main() { }

<|endoftext|>


<commit_before><commit_msg>add regression test<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.

// Regression test for #49685: drop elaboration was not revealing the
// value of `impl Trait` returns, leading to an ICE.

fn main() {
    let _ = Some(())
        .into_iter()
        .flat_map(|_| Some(()).into_iter().flat_map(func));
}

fn func(_: ()) -> impl Iterator<Item = ()> {
    Some(()).into_iter().flat_map(|_| vec![])
}
<|endoftext|>


<commit_before><commit_msg>Document -Z extra-link-arg.<commit_after><|endoftext|>


<commit_before><commit_msg>Rename `error_type` to `kind` in `protocol::QueryError`<commit_after><|endoftext|>


<commit_before>//! An implementation of Google Protobuf's Variable-Length Integers

#![cfg_attr(feature = "nightly", feature(test))]

extern crate bit_utils;

mod zigzag;

pub use zigzag::ZigZag;

#[cfg(feature = "io-operations")]
extern crate io_operations;

#[cfg(feature = "io-operations")]
mod iooperations;

//#[cfg(feature = "io-operations")]
//pub use io-operations;

/// The maximum number of bytes used by a 32-bit Varint
pub const VARINT_32_MAX_BYTES: usize = 5;

/// The maximum number of bytes used by a 32-bit Varint
pub const VARINT_64_MAX_BYTES: usize = 10;
<commit_msg>Publically export VarintReader and VarintWriter<commit_after>//! An implementation of Google Protobuf's Variable-Length Integers

#![cfg_attr(feature = "nightly", feature(test))]

extern crate bit_utils;

mod zigzag;

pub use zigzag::ZigZag;

#[cfg(feature = "io-operations")]
extern crate io_operations;

#[cfg(feature = "io-operations")]
mod iooperations;

#[cfg(feature = "io-operations")]
pub use iooperations::VarintReader as VarintReader;
#[cfg(feature = "io-operations")]
pub use iooperations::VarintWriter as VarintWriter;

/// The maximum number of bytes used by a 32-bit Varint
pub const VARINT_32_MAX_BYTES: usize = 5;

/// The maximum number of bytes used by a 32-bit Varint
pub const VARINT_64_MAX_BYTES: usize = 10;
<|endoftext|>