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

use cell::Cell;
use error::{Error};
use fmt;
use marker::Reflect;
use thread;

pub struct Flag { failed: Cell<bool> }

// This flag is only ever accessed with a lock previously held. Note that this
// a totally private structure.
unsafe impl Send for Flag {}
unsafe impl Sync for Flag {}

impl Flag {
    pub const fn new() -> Flag {
        Flag { failed: Cell::new(false) }
    }

    #[inline]
    pub fn borrow(&self) -> LockResult<Guard> {
        let ret = Guard { panicking: thread::panicking() };
        if self.get() {
            Err(PoisonError::new(ret))
        } else {
            Ok(ret)
        }
    }

    #[inline]
    pub fn done(&self, guard: &Guard) {
        if !guard.panicking && thread::panicking() {
            self.failed.set(true);
        }
    }

    #[inline]
    pub fn get(&self) -> bool {
        self.failed.get()
    }
}

pub struct Guard {
    panicking: bool,
}

/// A type of error which can be returned whenever a lock is acquired.
///
/// Both Mutexes and RwLocks are poisoned whenever a thread fails while the lock
/// is held. The precise semantics for when a lock is poisoned is documented on
/// each lock, but once a lock is poisoned then all future acquisitions will
/// return this error.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct PoisonError<T> {
    guard: T,
}

/// An enumeration of possible errors which can occur while calling the
/// `try_lock` method.
#[stable(feature = "rust1", since = "1.0.0")]
pub enum TryLockError<T> {
    /// The lock could not be acquired because another thread failed while holding
    /// the lock.
    #[stable(feature = "rust1", since = "1.0.0")]
    Poisoned(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PoisonError<T>),
    /// The lock could not be acquired at this time because the operation would
    /// otherwise block.
    #[stable(feature = "rust1", since = "1.0.0")]
    WouldBlock,
}

/// A type alias for the result of a lock method which can be poisoned.
///
/// The `Ok` variant of this result indicates that the primitive was not
/// poisoned, and the `Guard` is contained within. The `Err` variant indicates
/// that the primitive was poisoned. Note that the `Err` variant *also* carries
/// the associated guard, and it can be acquired through the `into_inner`
/// method.
#[stable(feature = "rust1", since = "1.0.0")]
pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;

/// A type alias for the result of a nonblocking locking method.
///
/// For more information, see `LockResult`. A `TryLockResult` doesn't
/// necessarily hold the associated guard in the `Err` type as the lock may not
/// have been acquired for other reasons.
#[stable(feature = "rust1", since = "1.0.0")]
pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Debug for PoisonError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "PoisonError { inner: .. }".fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Display for PoisonError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "poisoned lock: another task failed inside".fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + Reflect> Error for PoisonError<T> {
    fn description(&self) -> &str {
        "poisoned lock: another task failed inside"
    }
}

impl<T> PoisonError<T> {
    /// Creates a `PoisonError`.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn new(guard: T) -> PoisonError<T> {
        PoisonError { guard: guard }
    }

    /// Consumes this error indicating that a lock is poisoned, returning the
    /// underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn into_inner(self) -> T { self.guard }

    /// Reaches into this error indicating that a lock is poisoned, returning a
    /// reference to the underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn get_ref(&self) -> &T { &self.guard }

    /// Reaches into this error indicating that a lock is poisoned, returning a
    /// mutable reference to the underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<PoisonError<T>> for TryLockError<T> {
    fn from(err: PoisonError<T>) -> TryLockError<T> {
        TryLockError::Poisoned(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Debug for TryLockError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f),
            TryLockError::WouldBlock => "WouldBlock".fmt(f)
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + Reflect> fmt::Display for TryLockError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.description().fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + Reflect> Error for TryLockError<T> {
    fn description(&self) -> &str {
        match *self {
            TryLockError::Poisoned(ref p) => p.description(),
            TryLockError::WouldBlock => "try_lock failed because the operation would block"
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            TryLockError::Poisoned(ref p) => Some(p),
            _ => None
        }
    }
}

pub fn map_result<T, U, F>(result: LockResult<T>, f: F)
                           -> LockResult<U>
                           where F: FnOnce(T) -> U {
    match result {
        Ok(t) => Ok(f(t)),
        Err(PoisonError { guard }) => Err(PoisonError::new(f(guard)))
    }
}
<commit_msg>Rollup merge of #31589 - reem:remove-unnecessary-poison-bounds, r=sfackler<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cell::Cell;
use error::{Error};
use fmt;
use marker::Reflect;
use thread;

pub struct Flag { failed: Cell<bool> }

// This flag is only ever accessed with a lock previously held. Note that this
// a totally private structure.
unsafe impl Send for Flag {}
unsafe impl Sync for Flag {}

impl Flag {
    pub const fn new() -> Flag {
        Flag { failed: Cell::new(false) }
    }

    #[inline]
    pub fn borrow(&self) -> LockResult<Guard> {
        let ret = Guard { panicking: thread::panicking() };
        if self.get() {
            Err(PoisonError::new(ret))
        } else {
            Ok(ret)
        }
    }

    #[inline]
    pub fn done(&self, guard: &Guard) {
        if !guard.panicking && thread::panicking() {
            self.failed.set(true);
        }
    }

    #[inline]
    pub fn get(&self) -> bool {
        self.failed.get()
    }
}

pub struct Guard {
    panicking: bool,
}

/// A type of error which can be returned whenever a lock is acquired.
///
/// Both Mutexes and RwLocks are poisoned whenever a thread fails while the lock
/// is held. The precise semantics for when a lock is poisoned is documented on
/// each lock, but once a lock is poisoned then all future acquisitions will
/// return this error.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct PoisonError<T> {
    guard: T,
}

/// An enumeration of possible errors which can occur while calling the
/// `try_lock` method.
#[stable(feature = "rust1", since = "1.0.0")]
pub enum TryLockError<T> {
    /// The lock could not be acquired because another thread failed while holding
    /// the lock.
    #[stable(feature = "rust1", since = "1.0.0")]
    Poisoned(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PoisonError<T>),
    /// The lock could not be acquired at this time because the operation would
    /// otherwise block.
    #[stable(feature = "rust1", since = "1.0.0")]
    WouldBlock,
}

/// A type alias for the result of a lock method which can be poisoned.
///
/// The `Ok` variant of this result indicates that the primitive was not
/// poisoned, and the `Guard` is contained within. The `Err` variant indicates
/// that the primitive was poisoned. Note that the `Err` variant *also* carries
/// the associated guard, and it can be acquired through the `into_inner`
/// method.
#[stable(feature = "rust1", since = "1.0.0")]
pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;

/// A type alias for the result of a nonblocking locking method.
///
/// For more information, see `LockResult`. A `TryLockResult` doesn't
/// necessarily hold the associated guard in the `Err` type as the lock may not
/// have been acquired for other reasons.
#[stable(feature = "rust1", since = "1.0.0")]
pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Debug for PoisonError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "PoisonError { inner: .. }".fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Display for PoisonError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "poisoned lock: another task failed inside".fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect> Error for PoisonError<T> {
    fn description(&self) -> &str {
        "poisoned lock: another task failed inside"
    }
}

impl<T> PoisonError<T> {
    /// Creates a `PoisonError`.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn new(guard: T) -> PoisonError<T> {
        PoisonError { guard: guard }
    }

    /// Consumes this error indicating that a lock is poisoned, returning the
    /// underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn into_inner(self) -> T { self.guard }

    /// Reaches into this error indicating that a lock is poisoned, returning a
    /// reference to the underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn get_ref(&self) -> &T { &self.guard }

    /// Reaches into this error indicating that a lock is poisoned, returning a
    /// mutable reference to the underlying guard to allow access regardless.
    #[stable(feature = "sync_poison", since = "1.2.0")]
    pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<PoisonError<T>> for TryLockError<T> {
    fn from(err: PoisonError<T>) -> TryLockError<T> {
        TryLockError::Poisoned(err)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Debug for TryLockError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryLockError::Poisoned(..) => "Poisoned(..)".fmt(f),
            TryLockError::WouldBlock => "WouldBlock".fmt(f)
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> fmt::Display for TryLockError<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            TryLockError::Poisoned(..) => "poisoned lock: another task failed inside",
            TryLockError::WouldBlock => "try_lock failed because the operation would block"
        }.fmt(f)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect> Error for TryLockError<T> {
    fn description(&self) -> &str {
        match *self {
            TryLockError::Poisoned(ref p) => p.description(),
            TryLockError::WouldBlock => "try_lock failed because the operation would block"
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            TryLockError::Poisoned(ref p) => Some(p),
            _ => None
        }
    }
}

pub fn map_result<T, U, F>(result: LockResult<T>, f: F)
                           -> LockResult<U>
                           where F: FnOnce(T) -> U {
    match result {
        Ok(t) => Ok(f(t)),
        Err(PoisonError { guard }) => Err(PoisonError::new(f(guard)))
    }
}
<|endoftext|>


<commit_before><commit_msg>Do the fibs<commit_after><|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::process::exit;

use libimagdiary::diary::Diary;
use libimagdiary::diaryid::DiaryId;
use libimagdiary::error::DiaryErrorKind as DEK;
use libimagdiary::error::MapErrInto;
use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;
use libimagerror::trace::trace_error_exit;
use libimagutil::warn_exit::warn_exit;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;

use util::get_diary_name;

pub fn create(rt: &Runtime) {
    let diaryname = get_diary_name(rt)
        .unwrap_or_else( || warn_exit("No diary selected. Use either the configuration file or the commandline option", 1));

    let prevent_edit = rt.cli().subcommand_matches("create").unwrap().is_present("no-edit");

    fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLockEntry<'a> {
        use std::str::FromStr;

        let create = rt.cli().subcommand_matches("create").unwrap();
        let entry = if !create.is_present("timed") {
            debug!("Creating non-timed entry");
            diary.new_entry_today(diaryname)
        } else {
            let id = match create.value_of("timed") {
                Some("h") | Some("hourly") => {
                    debug!("Creating hourly-timed entry");
                    let time = DiaryId::now(String::from(diaryname));
                    let hr = create
                        .value_of("hour")
                        .map(|v| { debug!("Creating hourly entry with hour = {:?}", v); v })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    time.with_hour(hr).with_minute(0)
                },

                Some("m") | Some("minutely") => {
                    debug!("Creating minutely-timed entry");
                    let time = DiaryId::now(String::from(diaryname));
                    let hr = create
                        .value_of("hour")
                        .map(|h| { debug!("hour = {:?}", h); h })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse hour: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.hour());

                    let min = create
                        .value_of("minute")
                        .map(|m| { debug!("minute = {:?}", m); m })
                        .and_then(|s| {
                            FromStr::from_str(s)
                                .map_err(|_| warn!("Could not parse minute: '{}'", s))
                                .ok()
                        })
                        .unwrap_or(time.minute());

                    time.with_hour(hr).with_minute(min)
                },

                Some(_) => {
                    warn!("Timed creation failed: Unknown spec '{}'",
                          create.value_of("timed").unwrap());
                    exit(1);
                },

                None => warn_exit("Unexpected error, cannot continue", 1)
            };

            diary.retrieve(id).map_err_into(DEK::StoreReadError)
        };

        match entry {
            Err(e) => trace_error_exit(&e, 1),
            Ok(e) => {
                debug!("Created: {}", e.get_location());
                e
            }
        }
    }

    let mut entry = create_entry(rt.store(), &diaryname, rt);

    let res = if prevent_edit {
        debug!("Not editing new diary entry");
        Ok(())
    } else {
        debug!("Editing new diary entry");
        entry.edit_content(rt).map_err_into(DEK::DiaryEditError)
    };

    if let Err(e) = res {
        trace_error(&e);
    } else {
        info!("Ok!");
    }
}

<commit_msg>Refactor, minify create() impl<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use std::process::exit;

use clap::ArgMatches;

use libimagdiary::diary::Diary;
use libimagdiary::diaryid::DiaryId;
use libimagdiary::error::DiaryErrorKind as DEK;
use libimagdiary::error::MapErrInto;
use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error_exit;
use libimagutil::warn_exit::warn_exit;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;

use util::get_diary_name;

pub fn create(rt: &Runtime) {
    let diaryname = get_diary_name(rt)
        .unwrap_or_else( || warn_exit("No diary selected. Use either the configuration file or the commandline option", 1));

    let mut entry = create_entry(rt.store(), &diaryname, rt);

    let res = if rt.cli().subcommand_matches("create").unwrap().is_present("no-edit") {
        debug!("Not editing new diary entry");
        Ok(())
    } else {
        debug!("Editing new diary entry");
        entry.edit_content(rt)
            .map_err_into(DEK::DiaryEditError)
    };

    if let Err(e) = res {
        trace_error_exit(&e, 1);
    } else {
        info!("Ok!");
    }
}

fn create_entry<'a>(diary: &'a Store, diaryname: &str, rt: &Runtime) -> FileLockEntry<'a> {
    let create = rt.cli().subcommand_matches("create").unwrap();
    let entry  = if !create.is_present("timed") {
        debug!("Creating non-timed entry");
        diary.new_entry_today(diaryname)
    } else {
        let id = create_id_from_clispec(&create, &diaryname);
        diary.retrieve(id).map_err_into(DEK::StoreReadError)
    };

    match entry {
        Err(e) => trace_error_exit(&e, 1),
        Ok(e) => {
            debug!("Created: {}", e.get_location());
            e
        }
    }
}

fn create_id_from_clispec(create: &ArgMatches, diaryname: &str) -> DiaryId {
    use std::str::FromStr;

    let get_hourly_id = |create: &ArgMatches| -> DiaryId {
        let time = DiaryId::now(String::from(diaryname));
        let hr = create
            .value_of("hour")
            .map(|v| { debug!("Creating hourly entry with hour = {:?}", v); v })
            .and_then(|s| {
                FromStr::from_str(s)
                    .map_err(|_| warn!("Could not parse hour: '{}'", s))
                    .ok()
            })
            .unwrap_or(time.hour());

        time.with_hour(hr)
    };

    match create.value_of("timed") {
        Some("h") | Some("hourly") => {
            debug!("Creating hourly-timed entry");
            get_hourly_id(create)
        },

        Some("m") | Some("minutely") => {
            let time = get_hourly_id(create);
            let min = create
                .value_of("minute")
                .map(|m| { debug!("minute = {:?}", m); m })
                .and_then(|s| {
                    FromStr::from_str(s)
                        .map_err(|_| warn!("Could not parse minute: '{}'", s))
                        .ok()
                })
                .unwrap_or(time.minute());

            time.with_minute(min)
        },

        Some(_) => {
            warn!("Timed creation failed: Unknown spec '{}'",
                  create.value_of("timed").unwrap());
            exit(1);
        },

        None => warn_exit("Unexpected error, cannot continue", 1)
    }
}

<|endoftext|>


<commit_before><commit_msg>Working test file for comparison operations<commit_after>// Copyright 2017 Matt LaChance
//
// 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_use] extern crate hamcrest;

mod comparisons {

    use hamcrest::prelude::*;

    #[test]
    fn working_test_file() {
    }

}
<|endoftext|>


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

#![allow(dead_code)] // runtime init functions not used during testing

use os::windows::prelude::*;
use sys::windows::os::current_exe;
use sys::c;
use ffi::OsString;
use fmt;
use vec;
use core::iter;
use slice;
use path::PathBuf;

pub unsafe fn init(_argc: isize, _argv: *const *const u8) { }

pub unsafe fn cleanup() { }

pub fn args() -> Args {
    unsafe {
        let lp_cmd_line = c::GetCommandLineW();
        let parsed_args_list = parse_lp_cmd_line(
            lp_cmd_line as *const u16,
            || current_exe().map(PathBuf::into_os_string).unwrap_or_else(|_| OsString::new()));

        Args { parsed_args_list: parsed_args_list }
    }
}

/// Implements the Windows command-line argument parsing algorithm.
///
/// Microsoft's documentation for the Windows CLI argument format can be found at
/// <https://docs.microsoft.com/en-us/previous-versions//17w5ykft(v=vs.85)>.
///
/// Windows includes a function to do this in shell32.dll,
/// but linking with that DLL causes the process to be registered as a GUI application.
/// GUI applications add a bunch of overhead, even if no windows are drawn. See
/// <https://randomascii.wordpress.com/2018/12/03/a-not-called-function-can-cause-a-5x-slowdown/>.
///
/// This function was tested for equivalence to the shell32.dll implementation in
/// Windows 10 Pro v1803, using an exhaustive test suite available at
/// <https://gist.github.com/notriddle/dde431930c392e428055b2dc22e638f5> or
/// <https://paste.gg/p/anonymous/47d6ed5f5bd549168b1c69c799825223>.
unsafe fn parse_lp_cmd_line<F: Fn() -> OsString>(lp_cmd_line: *const u16, exe_name: F)
                                                 -> vec::IntoIter<OsString> {
    const BACKSLASH: u16 = '\\' as u16;
    const QUOTE: u16 = '"' as u16;
    const TAB: u16 = '\t' as u16;
    const SPACE: u16 = ' ' as u16;
    let mut in_quotes = false;
    let mut was_in_quotes = false;
    let mut backslash_count: usize = 0;
    let mut ret_val = Vec::new();
    let mut cur = Vec::new();
    if lp_cmd_line.is_null() || *lp_cmd_line == 0 {
        ret_val.push(exe_name());
        return ret_val.into_iter();
    }
    let mut i = 0;
    // The executable name at the beginning is special.
    match *lp_cmd_line {
        // The executable name ends at the next quote mark,
        // no matter what.
        QUOTE => {
            loop {
                i += 1;
                if *lp_cmd_line.offset(i) == 0 {
                    ret_val.push(OsString::from_wide(
                        slice::from_raw_parts(lp_cmd_line.offset(1), i as usize - 1)
                    ));
                    return ret_val.into_iter();
                }
                if *lp_cmd_line.offset(i) == QUOTE {
                    break;
                }
            }
            ret_val.push(OsString::from_wide(
                slice::from_raw_parts(lp_cmd_line.offset(1), i as usize - 1)
            ));
            i += 1;
        }
        // Implement quirk: when they say whitespace here,
        // they include the entire ASCII control plane:
        // "However, if lpCmdLine starts with any amount of whitespace, CommandLineToArgvW
        // will consider the first argument to be an empty string. Excess whitespace at the
        // end of lpCmdLine is ignored."
        0...SPACE => {
            ret_val.push(OsString::new());
            i += 1;
        },
        // The executable name ends at the next whitespace,
        // no matter what.
        _ => {
            loop {
                i += 1;
                if *lp_cmd_line.offset(i) == 0 {
                    ret_val.push(OsString::from_wide(
                        slice::from_raw_parts(lp_cmd_line, i as usize)
                    ));
                    return ret_val.into_iter();
                }
                if let 0...SPACE = *lp_cmd_line.offset(i) {
                    break;
                }
            }
            ret_val.push(OsString::from_wide(
                slice::from_raw_parts(lp_cmd_line, i as usize)
            ));
            i += 1;
        }
    }
    loop {
        let c = *lp_cmd_line.offset(i);
        match c {
            // backslash
            BACKSLASH => {
                backslash_count += 1;
                was_in_quotes = false;
            },
            QUOTE if backslash_count % 2 == 0 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
                backslash_count = 0;
                if was_in_quotes {
                    cur.push('"' as u16);
                    was_in_quotes = false;
                } else {
                    was_in_quotes = in_quotes;
                    in_quotes = !in_quotes;
                }
            }
            QUOTE if backslash_count % 2 != 0 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
                backslash_count = 0;
                was_in_quotes = false;
                cur.push(b'"' as u16);
            }
            SPACE | TAB if !in_quotes => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                if !cur.is_empty() || was_in_quotes {
                    ret_val.push(OsString::from_wide(&cur[..]));
                    cur.truncate(0);
                }
                backslash_count = 0;
                was_in_quotes = false;
            }
            0x00 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                // include empty quoted strings at the end of the arguments list
                if !cur.is_empty() || was_in_quotes || in_quotes {
                    ret_val.push(OsString::from_wide(&cur[..]));
                }
                break;
            }
            _ => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                backslash_count = 0;
                was_in_quotes = false;
                cur.push(c);
            }
        }
        i += 1;
    }
    ret_val.into_iter()
}

pub struct Args {
    parsed_args_list: vec::IntoIter<OsString>,
}

pub struct ArgsInnerDebug<'a> {
    args: &'a Args,
}

impl<'a> fmt::Debug for ArgsInnerDebug<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("[")?;
        let mut first = true;
        for i in self.args.parsed_args_list.as_slice() {
            if !first {
                f.write_str(", ")?;
            }
            first = false;

            fmt::Debug::fmt(i, f)?;
        }
        f.write_str("]")?;
        Ok(())
    }
}

impl Args {
    pub fn inner_debug(&self) -> ArgsInnerDebug {
        ArgsInnerDebug {
            args: self
        }
    }
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> { self.parsed_args_list.next_back() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.parsed_args_list.len() }
}

#[cfg(test)]
mod tests {
    use sys::windows::args::*;
    use ffi::OsString;

    fn chk(string: &str, parts: &[&str]) {
        let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
        wide.push(0);
        let parsed = unsafe {
            parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE"))
        };
        let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
        assert_eq!(parsed.as_slice(), expected.as_slice());
    }

    #[test]
    fn empty() {
        chk("", &["TEST.EXE"]);
        chk("\0", &["TEST.EXE"]);
    }

    #[test]
    fn single_words() {
        chk("EXE one_word", &["EXE", "one_word"]);
        chk("EXE a", &["EXE", "a"]);
        chk("EXE 😅", &["EXE", "😅"]);
        chk("EXE 😅🤦", &["EXE", "😅🤦"]);
    }

    #[test]
    fn official_examples() {
        chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
        chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
        chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
        chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
    }

    #[test]
    fn whitespace_behavior() {
        chk(r#" test"#, &["", "test"]);
        chk(r#"  test"#, &["", "test"]);
        chk(r#" test test2"#, &["", "test", "test2"]);
        chk(r#" test  test2"#, &["", "test", "test2"]);
        chk(r#"test test2 "#, &["test", "test2"]);
        chk(r#"test  test2 "#, &["test", "test2"]);
        chk(r#"test "#, &["test"]);
    }

    #[test]
    fn genius_quotes() {
        chk(r#"EXE "" """#, &["EXE", "", ""]);
        chk(r#"EXE "" """"#, &["EXE", "", "\""]);
        chk(
            r#"EXE "this is """all""" in the same argument""#,
            &["EXE", "this is \"all\" in the same argument"]
        );
        chk(r#"EXE "a"""#, &["EXE", "a\""]);
        chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
    }
}
<commit_msg>Fix nit<commit_after>// Copyright 2012-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.

#![allow(dead_code)] // runtime init functions not used during testing

use os::windows::prelude::*;
use sys::windows::os::current_exe;
use sys::c;
use ffi::OsString;
use fmt;
use vec;
use core::iter;
use slice;
use path::PathBuf;

pub unsafe fn init(_argc: isize, _argv: *const *const u8) { }

pub unsafe fn cleanup() { }

pub fn args() -> Args {
    unsafe {
        let lp_cmd_line = c::GetCommandLineW();
        let parsed_args_list = parse_lp_cmd_line(
            lp_cmd_line as *const u16,
            || current_exe().map(PathBuf::into_os_string).unwrap_or_else(|_| OsString::new()));

        Args { parsed_args_list: parsed_args_list }
    }
}

/// Implements the Windows command-line argument parsing algorithm.
///
/// Microsoft's documentation for the Windows CLI argument format can be found at
/// <https://docs.microsoft.com/en-us/previous-versions//17w5ykft(v=vs.85)>.
///
/// Windows includes a function to do this in shell32.dll,
/// but linking with that DLL causes the process to be registered as a GUI application.
/// GUI applications add a bunch of overhead, even if no windows are drawn. See
/// <https://randomascii.wordpress.com/2018/12/03/a-not-called-function-can-cause-a-5x-slowdown/>.
///
/// This function was tested for equivalence to the shell32.dll implementation in
/// Windows 10 Pro v1803, using an exhaustive test suite available at
/// <https://gist.github.com/notriddle/dde431930c392e428055b2dc22e638f5> or
/// <https://paste.gg/p/anonymous/47d6ed5f5bd549168b1c69c799825223>.
unsafe fn parse_lp_cmd_line<F: Fn() -> OsString>(lp_cmd_line: *const u16, exe_name: F)
                                                 -> vec::IntoIter<OsString> {
    const BACKSLASH: u16 = '\\' as u16;
    const QUOTE: u16 = '"' as u16;
    const TAB: u16 = '\t' as u16;
    const SPACE: u16 = ' ' as u16;
    let mut in_quotes = false;
    let mut was_in_quotes = false;
    let mut backslash_count: usize = 0;
    let mut ret_val = Vec::new();
    let mut cur = Vec::new();
    if lp_cmd_line.is_null() || *lp_cmd_line == 0 {
        ret_val.push(exe_name());
        return ret_val.into_iter();
    }
    let mut i = 0;
    // The executable name at the beginning is special.
    match *lp_cmd_line {
        // The executable name ends at the next quote mark,
        // no matter what.
        QUOTE => {
            loop {
                i += 1;
                let c = *lp_cmd_line.offset(i);
                if c == 0 {
                    ret_val.push(OsString::from_wide(
                        slice::from_raw_parts(lp_cmd_line.offset(1), i as usize - 1)
                    ));
                    return ret_val.into_iter();
                }
                if c == QUOTE {
                    break;
                }
            }
            ret_val.push(OsString::from_wide(
                slice::from_raw_parts(lp_cmd_line.offset(1), i as usize - 1)
            ));
            i += 1;
        }
        // Implement quirk: when they say whitespace here,
        // they include the entire ASCII control plane:
        // "However, if lpCmdLine starts with any amount of whitespace, CommandLineToArgvW
        // will consider the first argument to be an empty string. Excess whitespace at the
        // end of lpCmdLine is ignored."
        0...SPACE => {
            ret_val.push(OsString::new());
            i += 1;
        },
        // The executable name ends at the next whitespace,
        // no matter what.
        _ => {
            loop {
                i += 1;
                let c = *lp_cmd_line.offset(i);
                if c == 0 {
                    ret_val.push(OsString::from_wide(
                        slice::from_raw_parts(lp_cmd_line, i as usize)
                    ));
                    return ret_val.into_iter();
                }
                if c > 0 && c <= SPACE {
                    break;
                }
            }
            ret_val.push(OsString::from_wide(
                slice::from_raw_parts(lp_cmd_line, i as usize)
            ));
            i += 1;
        }
    }
    loop {
        let c = *lp_cmd_line.offset(i);
        match c {
            // backslash
            BACKSLASH => {
                backslash_count += 1;
                was_in_quotes = false;
            },
            QUOTE if backslash_count % 2 == 0 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
                backslash_count = 0;
                if was_in_quotes {
                    cur.push('"' as u16);
                    was_in_quotes = false;
                } else {
                    was_in_quotes = in_quotes;
                    in_quotes = !in_quotes;
                }
            }
            QUOTE if backslash_count % 2 != 0 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count / 2));
                backslash_count = 0;
                was_in_quotes = false;
                cur.push(b'"' as u16);
            }
            SPACE | TAB if !in_quotes => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                if !cur.is_empty() || was_in_quotes {
                    ret_val.push(OsString::from_wide(&cur[..]));
                    cur.truncate(0);
                }
                backslash_count = 0;
                was_in_quotes = false;
            }
            0x00 => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                // include empty quoted strings at the end of the arguments list
                if !cur.is_empty() || was_in_quotes || in_quotes {
                    ret_val.push(OsString::from_wide(&cur[..]));
                }
                break;
            }
            _ => {
                cur.extend(iter::repeat(b'\\' as u16).take(backslash_count));
                backslash_count = 0;
                was_in_quotes = false;
                cur.push(c);
            }
        }
        i += 1;
    }
    ret_val.into_iter()
}

pub struct Args {
    parsed_args_list: vec::IntoIter<OsString>,
}

pub struct ArgsInnerDebug<'a> {
    args: &'a Args,
}

impl<'a> fmt::Debug for ArgsInnerDebug<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("[")?;
        let mut first = true;
        for i in self.args.parsed_args_list.as_slice() {
            if !first {
                f.write_str(", ")?;
            }
            first = false;

            fmt::Debug::fmt(i, f)?;
        }
        f.write_str("]")?;
        Ok(())
    }
}

impl Args {
    pub fn inner_debug(&self) -> ArgsInnerDebug {
        ArgsInnerDebug {
            args: self
        }
    }
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> { self.parsed_args_list.next_back() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.parsed_args_list.len() }
}

#[cfg(test)]
mod tests {
    use sys::windows::args::*;
    use ffi::OsString;

    fn chk(string: &str, parts: &[&str]) {
        let mut wide: Vec<u16> = OsString::from(string).encode_wide().collect();
        wide.push(0);
        let parsed = unsafe {
            parse_lp_cmd_line(wide.as_ptr() as *const u16, || OsString::from("TEST.EXE"))
        };
        let expected: Vec<OsString> = parts.iter().map(|k| OsString::from(k)).collect();
        assert_eq!(parsed.as_slice(), expected.as_slice());
    }

    #[test]
    fn empty() {
        chk("", &["TEST.EXE"]);
        chk("\0", &["TEST.EXE"]);
    }

    #[test]
    fn single_words() {
        chk("EXE one_word", &["EXE", "one_word"]);
        chk("EXE a", &["EXE", "a"]);
        chk("EXE 😅", &["EXE", "😅"]);
        chk("EXE 😅🤦", &["EXE", "😅🤦"]);
    }

    #[test]
    fn official_examples() {
        chk(r#"EXE "abc" d e"#, &["EXE", "abc", "d", "e"]);
        chk(r#"EXE a\\\b d"e f"g h"#, &["EXE", r#"a\\\b"#, "de fg", "h"]);
        chk(r#"EXE a\\\"b c d"#, &["EXE", r#"a\"b"#, "c", "d"]);
        chk(r#"EXE a\\\\"b c" d e"#, &["EXE", r#"a\\b c"#, "d", "e"]);
    }

    #[test]
    fn whitespace_behavior() {
        chk(r#" test"#, &["", "test"]);
        chk(r#"  test"#, &["", "test"]);
        chk(r#" test test2"#, &["", "test", "test2"]);
        chk(r#" test  test2"#, &["", "test", "test2"]);
        chk(r#"test test2 "#, &["test", "test2"]);
        chk(r#"test  test2 "#, &["test", "test2"]);
        chk(r#"test "#, &["test"]);
    }

    #[test]
    fn genius_quotes() {
        chk(r#"EXE "" """#, &["EXE", "", ""]);
        chk(r#"EXE "" """"#, &["EXE", "", "\""]);
        chk(
            r#"EXE "this is """all""" in the same argument""#,
            &["EXE", "this is \"all\" in the same argument"]
        );
        chk(r#"EXE "a"""#, &["EXE", "a\""]);
        chk(r#"EXE "a"" a"#, &["EXE", "a\"", "a"]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Added a benchmark for inc_beta<commit_after>extern crate test;
extern crate specfn;

use std::rand::random;

#[bench]
fn inc_beta(b: &mut test::Bencher) {
    let (p, q) = (0.5, 1.5);
    let log_beta = specfn::log_beta(p, q);
    let x: Vec<f64> = range(0u, 1000).map(|_| random()).collect();

    b.iter(|| {
        for &x in x.iter() {
            test::black_box(specfn::inc_beta(x, p, q, log_beta))
        }
    });
}
<|endoftext|>


<commit_before><commit_msg>Add test for rustdoc ignore test<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.

/// Blah blah blah
/// ``` ignore
/// bad_assert!();
/// ```
pub fn foo() {}

<|endoftext|>


<commit_before><commit_msg>Add test of serialize_trait_object involving generics<commit_after>use erased_serde::serialize_trait_object;

pub trait MyTrait: erased_serde::Serialize {}

serialize_trait_object!(MyTrait);

pub trait MyGenericTrait<'a, T>: erased_serde::Serialize {}

serialize_trait_object!(<'a, T> MyGenericTrait<'a, T>);
<|endoftext|>


<commit_before><commit_msg>another example<commit_after>extern crate rainbowcoat;
use std::io::{self, Write};

fn run() -> io::Result<()> {
    write!(
        &mut rainbowcoat::Cat::configure(io::stdout(), 2.0, 0.4, 0.0),
        r"                  _
                 ( |
                   |
            __,--./|.--,__
          .`   \ \ / /    `.
        .`      \ | /       `.
       /   /     ^|^      \   \
      /   / |     |o     | \   \
     /===/  |     |      |  \===\
    /___/   |     |o     |   \___\
            |     |      |
            |     |o     |
            |     |      |
            |     |o     |
            |     |      |
            |     |o     |
            |_____/\_____|
"
    )?;
    Ok(())
}

fn main() {
    run().unwrap()
}
<|endoftext|>


<commit_before><commit_msg>Formatting, no Self in where.<commit_after><|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2428<commit_after>// https://leetcode.com/problems/maximum-sum-of-an-hourglass/
pub fn max_sum(grid: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        max_sum(vec![
            vec![6, 2, 1, 3],
            vec![4, 2, 1, 5],
            vec![9, 2, 8, 7],
            vec![4, 1, 2, 9]
        ])
    ); // 30
    println!(
        "{}",
        max_sum(vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]])
    ); // 35
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>Slight cleanup of manual_routes example.<commit_after><|endoftext|>


<commit_before><commit_msg>Create text.rs<commit_after>(type) (?P<Text>.*)
<|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.

trait T1 {}
trait T2 {}

trait Foo {
    type A: T1;
}

trait Bar : Foo {
    type A: T2;
    fn do_something() {
        let _: Self::A; //~ ERROR E0221
    }
}

fn main() {
}
<commit_msg>Rollup merge of #35770 - crypto-universe:E0221, r=jonathandturner<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.

trait T1 {}
trait T2 {}

trait Foo {
    type A: T1;
}

trait Bar : Foo {
    type A: T2;
    fn do_something() {
        let _: Self::A;
        //~^ ERROR E0221
        //~| NOTE ambiguous associated type `A`
        //~| NOTE associated type `Self` could derive from `Foo`
        //~| NOTE associated type `Self` could derive from `Bar`
    }
}

fn main() {
}
<|endoftext|>


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

//! Tidy check to ensure that unstable features are all in order
//!
//! This check will ensure properties like:
//!
//! * All stability attributes look reasonably well formed
//! * The set of library features is disjoint from the set of language features
//! * Library features have at most one stability level
//! * Library features have at most one `since` value

use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

#[derive(PartialEq)]
enum Status {
    Stable,
    Unstable,
}

impl fmt::Display for Status {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let as_str = match *self {
            Status::Stable => "stable",
            Status::Unstable => "unstable",
        };
        fmt::Display::fmt(as_str, f)
    }
}

struct Feature {
    level: Status,
    since: String,
}

pub fn check(path: &Path, bad: &mut bool) {
    let features = collect_lang_features(&path.join("libsyntax/feature_gate.rs"));
    assert!(!features.is_empty());
    let mut lib_features = HashMap::<String, Feature>::new();

    let mut contents = String::new();
    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        if !filename.ends_with(".rs") || filename == "features.rs" ||
           filename == "diagnostic_list.rs" {
            return;
        }

        contents.truncate(0);
        t!(t!(File::open(&file), &file).read_to_string(&mut contents));

        for (i, line) in contents.lines().enumerate() {
            let mut err = |msg: &str| {
                println!("{}:{}: {}", file.display(), i + 1, msg);
                *bad = true;
            };
            let level = if line.contains("[unstable(") {
                Status::Unstable
            } else if line.contains("[stable(") {
                Status::Stable
            } else {
                continue;
            };
            let feature_name = match find_attr_val(line, "feature") {
                Some(name) => name,
                None => {
                    err("malformed stability attribute");
                    continue;
                }
            };
            let since = match find_attr_val(line, "since") {
                Some(name) => name,
                None if level == Status::Stable => {
                    err("malformed stability attribute");
                    continue;
                }
                None => "None",
            };

            if features.contains_key(feature_name) {
                err("duplicating a lang feature");
            }
            if let Some(ref s) = lib_features.get(feature_name) {
                if s.level != level {
                    err("different stability level than before");
                }
                if s.since != since {
                    err("different `since` than before");
                }
                continue;
            }
            lib_features.insert(feature_name.to_owned(),
                                Feature {
                                    level: level,
                                    since: since.to_owned(),
                                });
        }
    });

    if *bad {
        return;
    }

    let mut lines = Vec::new();
    for (name, feature) in features {
        lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
                           name,
                           "lang",
                           feature.level,
                           feature.since));
    }
    for (name, feature) in lib_features {
        lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
                           name,
                           "lib",
                           feature.level,
                           feature.since));
    }

    lines.sort();
    for line in lines {
        println!("* {}", line);
    }
}

fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
    line.find(attr)
        .and_then(|i| line[i..].find('"').map(|j| i + j + 1))
        .and_then(|i| line[i..].find('"').map(|j| (i, i + j)))
        .map(|(i, j)| &line[i..j])
}

fn collect_lang_features(path: &Path) -> HashMap<String, Feature> {
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    contents.lines()
        .filter_map(|line| {
            let mut parts = line.trim().split(",");
            let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) {
                Some("active") => Status::Unstable,
                Some("removed") => Status::Unstable,
                Some("accepted") => Status::Stable,
                _ => return None,
            };
            let name = parts.next().unwrap().trim();
            let since = parts.next().unwrap().trim().trim_matches('"');
            Some((name.to_owned(),
                Feature {
                    level: level,
                    since: since.to_owned(),
                }))
        })
        .collect()
}
<commit_msg>Require compile-fail tests for new lang features<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.

//! Tidy check to ensure that unstable features are all in order
//!
//! This check will ensure properties like:
//!
//! * All stability attributes look reasonably well formed
//! * The set of library features is disjoint from the set of language features
//! * Library features have at most one stability level
//! * Library features have at most one `since` value
//! * All stability attributes have tests to ensure they are actually stable/unstable

use std::collections::HashMap;
use std::fmt;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

#[derive(PartialEq)]
enum Status {
    Stable,
    Unstable,
}

impl fmt::Display for Status {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let as_str = match *self {
            Status::Stable => "stable",
            Status::Unstable => "unstable",
        };
        fmt::Display::fmt(as_str, f)
    }
}

struct Feature {
    level: Status,
    since: String,
    has_gate_test: bool,
}

pub fn check(path: &Path, bad: &mut bool) {
    let mut features = collect_lang_features(&path.join("libsyntax/feature_gate.rs"));
    assert!(!features.is_empty());
    let mut lib_features = HashMap::<String, Feature>::new();

    let mut contents = String::new();
    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        if !filename.ends_with(".rs") || filename == "features.rs" ||
           filename == "diagnostic_list.rs" {
            return;
        }

        contents.truncate(0);
        t!(t!(File::open(&file), &file).read_to_string(&mut contents));

        for (i, line) in contents.lines().enumerate() {
            let mut err = |msg: &str| {
                println!("{}:{}: {}", file.display(), i + 1, msg);
                *bad = true;
            };
            let level = if line.contains("[unstable(") {
                Status::Unstable
            } else if line.contains("[stable(") {
                Status::Stable
            } else {
                continue;
            };
            let feature_name = match find_attr_val(line, "feature") {
                Some(name) => name,
                None => {
                    err("malformed stability attribute");
                    continue;
                }
            };
            let since = match find_attr_val(line, "since") {
                Some(name) => name,
                None if level == Status::Stable => {
                    err("malformed stability attribute");
                    continue;
                }
                None => "None",
            };

            if features.contains_key(feature_name) {
                err("duplicating a lang feature");
            }
            if let Some(ref s) = lib_features.get(feature_name) {
                if s.level != level {
                    err("different stability level than before");
                }
                if s.since != since {
                    err("different `since` than before");
                }
                continue;
            }
            lib_features.insert(feature_name.to_owned(),
                                Feature {
                                    level: level,
                                    since: since.to_owned(),
                                    has_gate_test: false,
                                });
        }
    });

    super::walk(&path.join("test/compile-fail"),
                &mut |path| super::filter_dirs(path),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        if !filename.ends_with(".rs") || filename == "features.rs" ||
           filename == "diagnostic_list.rs" {
            return;
        }

        contents.truncate(0);
        t!(t!(File::open(&file), &file).read_to_string(&mut contents));

        for (i, line) in contents.lines().enumerate() {
            let mut err = |msg: &str| {
                println!("{}:{}: {}", file.display(), i + 1, msg);
                *bad = true;
            };

            let gate_test_str = "gate-test-";

            if !line.contains(gate_test_str) {
                continue;
            }

            let feature_name = match line.find(gate_test_str) {
                Some(i) => {
                    &line[i+gate_test_str.len()..line[i+1..].find(' ').unwrap_or(line.len())]
                },
                None => continue,
            };
            let found_feature = features.get_mut(feature_name)
                                        .map(|v| { v.has_gate_test = true; () })
                                        .is_some();

            let found_lib_feature = features.get_mut(feature_name)
                                            .map(|v| { v.has_gate_test = true; () })
                                            .is_some();

            if !(found_feature || found_lib_feature) {
                err(&format!("gate-test test found referencing a nonexistent feature '{}'",
                             feature_name));
            }
        }
    });

    // Only check the number of lang features.
    // Obligatory testing for library features is dumb.
    let gate_untested = features.iter()
                                .filter(|&(_, f)| f.level == Status::Unstable)
                                .filter(|&(_, f)| !f.has_gate_test)
                                .count();

    // FIXME get this number down to zero.
    let gate_untested_expected = 98;

    if gate_untested != gate_untested_expected {
        print!("Expected {} gate untested features, but found {}. ",
                gate_untested_expected, gate_untested);
        if gate_untested < gate_untested_expected {
            println!("Did you forget to reduce the expected number?");
        } else {
            println!("Did you forget to add a gate test for your new feature?");
        }
        *bad = true;
    }

    if *bad {
        return;
    }

    let mut lines = Vec::new();
    for (name, feature) in features {
        lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
                           name,
                           "lang",
                           feature.level,
                           feature.since));
    }
    for (name, feature) in lib_features {
        lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
                           name,
                           "lib",
                           feature.level,
                           feature.since));
    }

    lines.sort();
    for line in lines {
        println!("* {}", line);
    }
}

fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
    line.find(attr)
        .and_then(|i| line[i..].find('"').map(|j| i + j + 1))
        .and_then(|i| line[i..].find('"').map(|j| (i, i + j)))
        .map(|(i, j)| &line[i..j])
}

fn collect_lang_features(path: &Path) -> HashMap<String, Feature> {
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    contents.lines()
        .filter_map(|line| {
            let mut parts = line.trim().split(",");
            let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) {
                Some("active") => Status::Unstable,
                Some("removed") => Status::Unstable,
                Some("accepted") => Status::Stable,
                _ => return None,
            };
            let name = parts.next().unwrap().trim();
            let since = parts.next().unwrap().trim().trim_matches('"');
            Some((name.to_owned(),
                Feature {
                    level: level,
                    since: since.to_owned(),
                    has_gate_test: false,
                }))
        })
        .collect()
}
<|endoftext|>


<commit_before><commit_msg>add levenshtein algorithm<commit_after>extern mod extra;
use extra::treemap::TreeMap;

fn main() {
  let x = levenshtein_distance("zamanfoo", "mazoo");
  println(fmt!("%u", x));
}

#[deriving(TotalOrd, TotalEq)]
struct Point(uint, uint);

fn levenshtein_distance(word1: &str, word2: &str) -> uint {
  let word1_length = word1.len() + 1;
  let word2_length = word2.len() + 1;

  let mut matrix: TreeMap<Point, uint> = TreeMap::new();
  let matrix_find = |x, y| { *matrix.find(&Point(x, y)).unwrap() };

  matrix.insert(Point(0, 0), 0);
  for i in range(1, word1_length) { matrix.insert(Point(i, 0), i); }
  for j in range(1, word2_length) { matrix.insert(Point(0, j), j); }

  for j in range(1, word2_length) {
    for i in range(1, word1_length) {
      let x: uint = if word1[i - 1] == word2[j - 1] {
        matrix_find(i - 1, j - 1)
      }
      else {
        let min_distance = do [[i - 1, j], [i, j - 1], [i - 1, j - 1]].map |vec| {
          matrix_find(vec[0], vec[1])
        };
        *min_distance.iter().min().unwrap() + 1
      };

      matrix.insert(Point(i, j), x);
    }
  }

  matrix_find(word1_length - 1, word2_length - 1)
}
<|endoftext|>


<commit_before><commit_msg>Copy bucket sizes to allow Bucket size iterator to be wrapped<commit_after><|endoftext|>


<commit_before><commit_msg>(feat) Added ContentLength header to Modifier implementation for File<commit_after><|endoftext|>


<commit_before>// 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 std::cell::RefCell;
use std::hashmap::HashSet;
use std::local_data;
use std::os;
use std::run;
use std::str;

use extra::tempfile::TempDir;
use extra::getopts;
use extra::test;
use rustc::driver::driver;
use rustc::driver::session;
use syntax::diagnostic;
use syntax::parse;

use core;
use clean;
use clean::Clean;
use fold::DocFolder;
use html::markdown;
use passes;
use visit_ast::RustdocVisitor;

pub fn run(input: &str, matches: &getopts::Matches) -> int {
    let parsesess = parse::new_parse_sess(None);
    let input = driver::file_input(Path::new(input));
    let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
    let libs = @RefCell::new(libs.move_iter().collect());

    let sessopts = @session::options {
        binary: @"rustdoc",
        maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()),
        addl_lib_search_paths: libs,
        outputs: ~[session::OutputDylib],
        .. (*session::basic_options()).clone()
    };

    let diagnostic_handler = diagnostic::mk_handler(None);
    let span_diagnostic_handler =
        diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);

    let sess = driver::build_session_(sessopts,
                                      parsesess.cm,
                                      @diagnostic::DefaultEmitter as
                                            @diagnostic::Emitter,
                                      span_diagnostic_handler);

    let cfg = driver::build_configuration(sess);
    let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
    crate = driver::phase_2_configure_and_expand(sess, cfg, crate);

    let ctx = @core::DocContext {
        crate: crate,
        tycx: None,
        sess: sess,
    };
    local_data::set(super::ctxtkey, ctx);

    let v = @mut RustdocVisitor::new();
    v.visit(&ctx.crate);
    let crate = v.clean();
    let (crate, _) = passes::unindent_comments(crate);
    let (crate, _) = passes::collapse_docs(crate);

    let mut collector = Collector {
        tests: ~[],
        names: ~[],
        cnt: 0,
        libs: libs,
        cratename: crate.name.to_owned(),
    };
    collector.fold_crate(crate);

    let args = matches.opt_strs("test-args");
    let mut args = args.iter().flat_map(|s| s.words()).map(|s| s.to_owned());
    let mut args = args.to_owned_vec();
    args.unshift(~"rustdoctest");

    test::test_main(args, collector.tests);

    0
}

fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
    let test = maketest(test, cratename);
    let parsesess = parse::new_parse_sess(None);
    let input = driver::str_input(test);

    let sessopts = @session::options {
        binary: @"rustdoctest",
        maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()),
        addl_lib_search_paths: @RefCell::new(libs),
        outputs: ~[session::OutputExecutable],
        debugging_opts: session::prefer_dynamic,
        .. (*session::basic_options()).clone()
    };

    let diagnostic_handler = diagnostic::mk_handler(None);
    let span_diagnostic_handler =
        diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);

    let sess = driver::build_session_(sessopts,
                                      parsesess.cm,
                                      @diagnostic::DefaultEmitter as
                                            @diagnostic::Emitter,
                                      span_diagnostic_handler);

    let outdir = TempDir::new("rustdoctest").expect("rustdoc needs a tempdir");
    let out = Some(outdir.path().clone());
    let cfg = driver::build_configuration(sess);
    driver::compile_input(sess, cfg, &input, &out, &None);

    let exe = outdir.path().join("rust_out");
    let out = run::process_output(exe.as_str().unwrap(), []);
    match out {
        None => fail!("couldn't run the test"),
        Some(out) => {
            if !out.status.success() {
                fail!("test executable failed:\n{}",
                      str::from_utf8(out.error));
            }
        }
    }
}

fn maketest(s: &str, cratename: &str) -> @str {
    let mut prog = ~r"
#[deny(warnings)];
#[allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)];
#[feature(macro_rules, globs, struct_variant, managed_boxes)];
";
    if s.contains("extra") {
        prog.push_str("extern mod extra;\n");
    }
    if s.contains(cratename) {
        prog.push_str(format!("extern mod {};\n", cratename));
    }
    if s.contains("fn main") {
        prog.push_str(s);
    } else {
        prog.push_str("fn main() {\n");
        prog.push_str(s);
        prog.push_str("\n}");
    }

    return prog.to_managed();
}

pub struct Collector {
    priv tests: ~[test::TestDescAndFn],
    priv names: ~[~str],
    priv libs: @RefCell<HashSet<Path>>,
    priv cnt: uint,
    priv cratename: ~str,
}

impl Collector {
    pub fn add_test(&mut self, test: &str, ignore: bool, should_fail: bool) {
        let test = test.to_owned();
        let name = format!("{}_{}", self.names.connect("::"), self.cnt);
        self.cnt += 1;
        let libs = self.libs.borrow();
        let libs = (*libs.get()).clone();
        let cratename = self.cratename.to_owned();
        debug!("Creating test {}: {}", name, test);
        self.tests.push(test::TestDescAndFn {
            desc: test::TestDesc {
                name: test::DynTestName(name),
                ignore: ignore,
                should_fail: should_fail,
            },
            testfn: test::DynTestFn(proc() {
                runtest(test, cratename, libs);
            }),
        });
    }
}

impl DocFolder for Collector {
    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
        let pushed = match item.name {
            Some(ref name) if name.len() == 0 => false,
            Some(ref name) => { self.names.push(name.to_owned()); true }
            None => false
        };
        match item.doc_value() {
            Some(doc) => {
                self.cnt = 0;
                markdown::find_testable_code(doc, self);
            }
            None => {}
        }
        let ret = self.fold_item_recur(item);
        if pushed {
            self.names.pop();
        }
        return ret;
    }
}
<commit_msg>Remove features from librustdoc<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 std::cell::RefCell;
use std::hashmap::HashSet;
use std::local_data;
use std::os;
use std::run;
use std::str;

use extra::tempfile::TempDir;
use extra::getopts;
use extra::test;
use rustc::driver::driver;
use rustc::driver::session;
use syntax::diagnostic;
use syntax::parse;

use core;
use clean;
use clean::Clean;
use fold::DocFolder;
use html::markdown;
use passes;
use visit_ast::RustdocVisitor;

pub fn run(input: &str, matches: &getopts::Matches) -> int {
    let parsesess = parse::new_parse_sess(None);
    let input = driver::file_input(Path::new(input));
    let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
    let libs = @RefCell::new(libs.move_iter().collect());

    let sessopts = @session::options {
        binary: @"rustdoc",
        maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()),
        addl_lib_search_paths: libs,
        outputs: ~[session::OutputDylib],
        .. (*session::basic_options()).clone()
    };

    let diagnostic_handler = diagnostic::mk_handler(None);
    let span_diagnostic_handler =
        diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);

    let sess = driver::build_session_(sessopts,
                                      parsesess.cm,
                                      @diagnostic::DefaultEmitter as
                                            @diagnostic::Emitter,
                                      span_diagnostic_handler);

    let cfg = driver::build_configuration(sess);
    let mut crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
    crate = driver::phase_2_configure_and_expand(sess, cfg, crate);

    let ctx = @core::DocContext {
        crate: crate,
        tycx: None,
        sess: sess,
    };
    local_data::set(super::ctxtkey, ctx);

    let v = @mut RustdocVisitor::new();
    v.visit(&ctx.crate);
    let crate = v.clean();
    let (crate, _) = passes::unindent_comments(crate);
    let (crate, _) = passes::collapse_docs(crate);

    let mut collector = Collector {
        tests: ~[],
        names: ~[],
        cnt: 0,
        libs: libs,
        cratename: crate.name.to_owned(),
    };
    collector.fold_crate(crate);

    let args = matches.opt_strs("test-args");
    let mut args = args.iter().flat_map(|s| s.words()).map(|s| s.to_owned());
    let mut args = args.to_owned_vec();
    args.unshift(~"rustdoctest");

    test::test_main(args, collector.tests);

    0
}

fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
    let test = maketest(test, cratename);
    let parsesess = parse::new_parse_sess(None);
    let input = driver::str_input(test);

    let sessopts = @session::options {
        binary: @"rustdoctest",
        maybe_sysroot: Some(@os::self_exe_path().unwrap().dir_path()),
        addl_lib_search_paths: @RefCell::new(libs),
        outputs: ~[session::OutputExecutable],
        debugging_opts: session::prefer_dynamic,
        .. (*session::basic_options()).clone()
    };

    let diagnostic_handler = diagnostic::mk_handler(None);
    let span_diagnostic_handler =
        diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);

    let sess = driver::build_session_(sessopts,
                                      parsesess.cm,
                                      @diagnostic::DefaultEmitter as
                                            @diagnostic::Emitter,
                                      span_diagnostic_handler);

    let outdir = TempDir::new("rustdoctest").expect("rustdoc needs a tempdir");
    let out = Some(outdir.path().clone());
    let cfg = driver::build_configuration(sess);
    driver::compile_input(sess, cfg, &input, &out, &None);

    let exe = outdir.path().join("rust_out");
    let out = run::process_output(exe.as_str().unwrap(), []);
    match out {
        None => fail!("couldn't run the test"),
        Some(out) => {
            if !out.status.success() {
                fail!("test executable failed:\n{}",
                      str::from_utf8(out.error));
            }
        }
    }
}

fn maketest(s: &str, cratename: &str) -> @str {
    let mut prog = ~r"
#[deny(warnings)];
#[allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)];
";
    if s.contains("extra") {
        prog.push_str("extern mod extra;\n");
    }
    if s.contains(cratename) {
        prog.push_str(format!("extern mod {};\n", cratename));
    }
    if s.contains("fn main") {
        prog.push_str(s);
    } else {
        prog.push_str("fn main() {\n");
        prog.push_str(s);
        prog.push_str("\n}");
    }

    return prog.to_managed();
}

pub struct Collector {
    priv tests: ~[test::TestDescAndFn],
    priv names: ~[~str],
    priv libs: @RefCell<HashSet<Path>>,
    priv cnt: uint,
    priv cratename: ~str,
}

impl Collector {
    pub fn add_test(&mut self, test: &str, ignore: bool, should_fail: bool) {
        let test = test.to_owned();
        let name = format!("{}_{}", self.names.connect("::"), self.cnt);
        self.cnt += 1;
        let libs = self.libs.borrow();
        let libs = (*libs.get()).clone();
        let cratename = self.cratename.to_owned();
        debug!("Creating test {}: {}", name, test);
        self.tests.push(test::TestDescAndFn {
            desc: test::TestDesc {
                name: test::DynTestName(name),
                ignore: ignore,
                should_fail: should_fail,
            },
            testfn: test::DynTestFn(proc() {
                runtest(test, cratename, libs);
            }),
        });
    }
}

impl DocFolder for Collector {
    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
        let pushed = match item.name {
            Some(ref name) if name.len() == 0 => false,
            Some(ref name) => { self.names.push(name.to_owned()); true }
            None => false
        };
        match item.doc_value() {
            Some(doc) => {
                self.cnt = 0;
                markdown::find_testable_code(doc, self);
            }
            None => {}
        }
        let ret = self.fold_item_recur(item);
        if pushed {
            self.names.pop();
        }
        return ret;
    }
}
<|endoftext|>


<commit_before><commit_msg>test: Add a test case for self regions and typeclass implementations<commit_after>type clam = { chowder: &int };

impl clam for clam {
    fn get_chowder() -> &self.int { ret self.chowder; }
}

fn main() {
    let clam = { chowder: &3 };
    log(debug, *clam.get_chowder());
}

<|endoftext|>


<commit_before><commit_msg>Add a test that unique boxes in vectors are copied when the vector is<commit_after>fn main() {
    let a = [~mutable 10];
    let b = a;

    assert *a[0] == 10;
    assert *b[0] == 10;

    // This should only modify the value in a, not b
    *a[0] = 20;

    assert *a[0] == 20;
    assert *b[0] == 10;
}<|endoftext|>


<commit_before>//! A timer wheel implementation

use std::cmp;
use std::mem;
use std::time::{Instant, Duration};

use slab::Slab;

/// An implementation of a timer wheel where data can be associated with each
/// timer firing.
///
/// This structure implements a timer wheel data structure where each timeout
/// has a piece of associated data, `T`. A timer wheel supports O(1) insertion
/// and removal of timers, as well as quickly figuring out what needs to get
/// fired.
///
/// Note, though, that the resolution of a timer wheel means that timeouts will
/// not arrive promptly when they expire, but rather in certain increments of
/// each time. The time delta between each slot of a time wheel is of a fixed
/// length, meaning that if a timeout is scheduled between two slots it'll end
/// up getting scheduled into the later slot.
pub struct TimerWheel<T> {
    // Actual timer wheel itself.
    //
    // Each slot represents a fixed duration of time, and this wheel also
    // behaves like a ring buffer. All timeouts scheduled will correspond to one
    // slot and therefore each slot has a linked list of timeouts scheduled in
    // it. Right now linked lists are done through indices into the `slab`
    // below.
    //
    // Each slot also contains the next timeout associated with it (the minimum
    // of the entire linked list).
    wheel: Vec<Slot>,

    // A slab containing all the timeout entries themselves. This is the memory
    // backing the "linked lists" in the wheel above. Each entry has a prev/next
    // pointer (indices in this array) along with the data associated with the
    // timeout and the time the timeout will fire.
    slab: Slab<Entry<T>, usize>,

    // The instant that this timer was created, through which all other timeout
    // computations are relative to.
    start: Instant,

    // State used during `poll`. The `cur_wheel_tick` field is the current tick
    // we've poll'd to. That is, all events from `cur_wheel_tick` to the
    // actual current tick in time still need to be processed.
    //
    // The `cur_slab_idx` variable is basically just an iterator over the linked
    // list associated with a wheel slot. This will get incremented as we move
    // forward in `poll`
    cur_wheel_tick: u64,
    cur_slab_idx: usize,
}

#[derive(Clone)]
struct Slot {
    head: usize,
    next_timeout: Option<Instant>,
}

struct Entry<T> {
    data: T,
    when: Instant,
    prev: usize,
    next: usize,
}

/// A timeout which has been scheduled with a timer wheel.
///
/// This can be used to later cancel a timeout, if necessary.
pub struct Timeout {
    when: Instant,
    slab_idx: usize,
}

const EMPTY: usize = 0;
const LEN: usize = 256;
const MASK: usize = LEN - 1;
const TICK_MS: u64 = 100;

impl<T> TimerWheel<T> {
    /// Creates a new timer wheel configured with no timeouts and with the
    /// default parameters.
    ///
    /// Currently this is a timer wheel of length 256 with a 100ms time
    /// resolution.
    pub fn new() -> TimerWheel<T> {
        TimerWheel {
            wheel: vec![Slot { head: EMPTY, next_timeout: None }; LEN],
            slab: Slab::new_starting_at(1, 256),
            start: Instant::now(),
            cur_wheel_tick: 0,
            cur_slab_idx: EMPTY,
        }
    }

    /// Creates a new timeout to get fired at a particular point in the future.
    ///
    /// The timeout will be associated with the specified `data`, and this data
    /// will be returned from `poll` when it's ready.
    ///
    /// The returned `Timeout` can later get passesd to `cancel` to retrieve the
    /// data and ensure the timeout doesn't fire.
    ///
    /// This method completes in O(1) time.
    ///
    /// # Panics
    ///
    /// This method will panic if `at` is before the time that this timer wheel
    /// was created.
    pub fn insert(&mut self, at: Instant, data: T) -> Timeout {
        // First up, figure out where we're gonna go in the wheel. Note that if
        // we're being scheduled on or before the current wheel tick we just
        // make sure to defer ourselves to the next tick.
        let mut tick = self.time_to_ticks(at);
        if tick <= self.cur_wheel_tick {
            debug!("moving {} to {}", tick, self.cur_wheel_tick + 1);
            tick = self.cur_wheel_tick + 1;
        }
        let wheel_idx = self.ticks_to_wheel_idx(tick);
        trace!("inserting timeout at {} for {}", wheel_idx, tick);

        // Next, make sure there's enough space in the slab for the timeout.
        if self.slab.vacant_entry().is_none() {
            let amt = self.slab.count();
            self.slab.grow(amt);
        }

        // Insert ourselves at the head of the linked list in the wheel.
        let slot = &mut self.wheel[wheel_idx];
        let prev_head;
        {
            let entry = self.slab.vacant_entry().unwrap();
            prev_head = mem::replace(&mut slot.head, entry.index());

            entry.insert(Entry {
                data: data,
                when: at,
                prev: EMPTY,
                next: prev_head,
            });
        }
        if prev_head != EMPTY {
            self.slab[prev_head].prev = slot.head;
        }

        // Update the wheel slot's next timeout field.
        if at <= slot.next_timeout.unwrap_or(at) {
            let tick = tick as u32;
            let actual_tick = self.start + Duration::from_millis(TICK_MS) * tick;
            let at = cmp::max(actual_tick, at);
            slot.next_timeout = Some(at);
        }

        Timeout {
            when: at,
            slab_idx: slot.head,
        }
    }

    /// Queries this timer to see if any timeouts are ready to fire.
    ///
    /// This function will advance the internal wheel to the time specified by
    /// `at`, returning any timeout which has happened up to that point. This
    /// method should be called in a loop until it returns `None` to ensure that
    /// all timeouts are processed.
    ///
    /// # Panics
    ///
    /// This method will panic if `at` is before the instant that this timer
    /// wheel was created.
    pub fn poll(&mut self, at: Instant) -> Option<T> {
        let wheel_tick = self.time_to_ticks(at);

        trace!("polling {} => {}", self.cur_wheel_tick, wheel_tick);

        // Advance forward in time to the `wheel_tick` specified.
        //
        // TODO: don't visit slots in the wheel more than once
        while self.cur_wheel_tick <= wheel_tick {
            let head = self.cur_slab_idx;
            trace!("next head[{} => {}]: {}",
                   self.cur_wheel_tick, wheel_tick, head);

            // If the current slot has no entries or we're done iterating go to
            // the next tick.
            if head == EMPTY {
                self.cur_wheel_tick += 1;
                let idx = self.ticks_to_wheel_idx(self.cur_wheel_tick);
                self.cur_slab_idx = self.wheel[idx].head;
                continue
            }

            // If we're starting to iterate over a slot, clear its timeout as
            // we're probably going to remove entries. As we skip over each
            // element of this slot we'll restore the `next_timeout` field if
            // necessary.
            let idx = self.ticks_to_wheel_idx(self.cur_wheel_tick);
            if head == self.wheel[idx].head {
                self.wheel[idx].next_timeout = None;
            }

            // Otherwise, continue iterating over the linked list in the wheel
            // slot we're on and remove anything which has expired.
            self.cur_slab_idx = self.slab[head].next;
            let head_timeout = self.slab[head].when;
            if self.time_to_ticks(head_timeout) <= self.time_to_ticks(at) {
                return self.remove_slab(head).map(|e| e.data)
            } else {
                let next = self.wheel[idx].next_timeout.unwrap_or(head_timeout);
                if head_timeout <= next {
                    self.wheel[idx].next_timeout = Some(head_timeout);
                }
            }
        }

        None
    }

    /// Returns the instant in time that corresponds to the next timeout
    /// scheduled in this wheel.
    pub fn next_timeout(&self) -> Option<Instant> {
        // TODO: can this be optimized to not look at the whole array?
        let timeouts = self.wheel.iter().map(|slot| slot.next_timeout);
        let min = timeouts.fold(None, |prev, cur| {
            match (prev, cur) {
                (None, cur) => cur,
                (Some(time), None) => Some(time),
                (Some(a), Some(b)) => Some(cmp::min(a, b)),
            }
        });
        let time = min.map(|min| min + Duration::from_millis(TICK_MS / 2));
        if let Some(time) = time {
            debug!("next timeout {:?}", time);
            debug!("now          {:?}", Instant::now());
        }
        return time
    }

    /// Cancels the specified timeout.
    ///
    /// For timeouts previously registered via `insert` they can be passed back
    /// to this method to cancel the associated timeout, retrieving the value
    /// inserted if the timeout has not already fired.
    ///
    /// This method completes in O(1) time.
    ///
    /// # Panics
    ///
    /// This method may panic if `timeout` wasn't created by this timer wheel.
    pub fn cancel(&mut self, timeout: &Timeout) -> Option<T> {
        match self.slab.get(timeout.slab_idx) {
            Some(e) if e.when == timeout.when => {}
            _ => return None,
        }

        self.remove_slab(timeout.slab_idx).map(|e| e.data)
    }

    fn remove_slab(&mut self, slab_idx: usize) -> Option<Entry<T>> {
        let entry = match self.slab.remove(slab_idx) {
            Some(e) => e,
            None => return None,
        };

        // Remove the node from the linked list
        if entry.prev == EMPTY {
            let idx = self.ticks_to_wheel_idx(self.time_to_ticks(entry.when));
            self.wheel[idx].head = entry.next;
        } else {
            self.slab[entry.prev].next = entry.next;
        }
        if entry.next != EMPTY {
            self.slab[entry.next].prev = entry.prev;
        }

        return Some(entry)
    }

    fn time_to_ticks(&self, time: Instant) -> u64 {
        let dur = time - self.start;
        let ms = dur.subsec_nanos() as u64 / 1_000_000;
        let ms = dur.as_secs()
                    .checked_mul(1_000)
                    .and_then(|m| m.checked_add(ms))
                    .expect("overflow scheduling timeout");
        (ms + TICK_MS / 2) / TICK_MS
    }

    fn ticks_to_wheel_idx(&self, ticks: u64) -> usize {
        (ticks as usize) & MASK
    }
}
<commit_msg>Fix timer wheel tests<commit_after>//! A timer wheel implementation

use std::cmp;
use std::mem;
use std::time::{Instant, Duration};

use slab::Slab;

/// An implementation of a timer wheel where data can be associated with each
/// timer firing.
///
/// This structure implements a timer wheel data structure where each timeout
/// has a piece of associated data, `T`. A timer wheel supports O(1) insertion
/// and removal of timers, as well as quickly figuring out what needs to get
/// fired.
///
/// Note, though, that the resolution of a timer wheel means that timeouts will
/// not arrive promptly when they expire, but rather in certain increments of
/// each time. The time delta between each slot of a time wheel is of a fixed
/// length, meaning that if a timeout is scheduled between two slots it'll end
/// up getting scheduled into the later slot.
pub struct TimerWheel<T> {
    // Actual timer wheel itself.
    //
    // Each slot represents a fixed duration of time, and this wheel also
    // behaves like a ring buffer. All timeouts scheduled will correspond to one
    // slot and therefore each slot has a linked list of timeouts scheduled in
    // it. Right now linked lists are done through indices into the `slab`
    // below.
    //
    // Each slot also contains the next timeout associated with it (the minimum
    // of the entire linked list).
    wheel: Vec<Slot>,

    // A slab containing all the timeout entries themselves. This is the memory
    // backing the "linked lists" in the wheel above. Each entry has a prev/next
    // pointer (indices in this array) along with the data associated with the
    // timeout and the time the timeout will fire.
    slab: Slab<Entry<T>, usize>,

    // The instant that this timer was created, through which all other timeout
    // computations are relative to.
    start: Instant,

    // State used during `poll`. The `cur_wheel_tick` field is the current tick
    // we've poll'd to. That is, all events from `cur_wheel_tick` to the
    // actual current tick in time still need to be processed.
    //
    // The `cur_slab_idx` variable is basically just an iterator over the linked
    // list associated with a wheel slot. This will get incremented as we move
    // forward in `poll`
    cur_wheel_tick: u64,
    cur_slab_idx: usize,
}

#[derive(Clone)]
struct Slot {
    head: usize,
    next_timeout: Option<Instant>,
}

struct Entry<T> {
    data: T,
    when: Instant,
    prev: usize,
    next: usize,
}

/// A timeout which has been scheduled with a timer wheel.
///
/// This can be used to later cancel a timeout, if necessary.
pub struct Timeout {
    when: Instant,
    slab_idx: usize,
}

const EMPTY: usize = 0;
const LEN: usize = 256;
const MASK: usize = LEN - 1;
const TICK_MS: u64 = 100;

impl<T> TimerWheel<T> {
    /// Creates a new timer wheel configured with no timeouts and with the
    /// default parameters.
    ///
    /// Currently this is a timer wheel of length 256 with a 100ms time
    /// resolution.
    pub fn new() -> TimerWheel<T> {
        TimerWheel {
            wheel: vec![Slot { head: EMPTY, next_timeout: None }; LEN],
            slab: Slab::new_starting_at(1, 256),
            start: Instant::now(),
            cur_wheel_tick: 0,
            cur_slab_idx: EMPTY,
        }
    }

    /// Creates a new timeout to get fired at a particular point in the future.
    ///
    /// The timeout will be associated with the specified `data`, and this data
    /// will be returned from `poll` when it's ready.
    ///
    /// The returned `Timeout` can later get passesd to `cancel` to retrieve the
    /// data and ensure the timeout doesn't fire.
    ///
    /// This method completes in O(1) time.
    ///
    /// # Panics
    ///
    /// This method will panic if `at` is before the time that this timer wheel
    /// was created.
    pub fn insert(&mut self, at: Instant, data: T) -> Timeout {
        // First up, figure out where we're gonna go in the wheel. Note that if
        // we're being scheduled on or before the current wheel tick we just
        // make sure to defer ourselves to the next tick.
        let mut tick = self.time_to_ticks(at);
        if tick <= self.cur_wheel_tick {
            debug!("moving {} to {}", tick, self.cur_wheel_tick + 1);
            tick = self.cur_wheel_tick + 1;
        }
        let wheel_idx = self.ticks_to_wheel_idx(tick);
        trace!("inserting timeout at {} for {}", wheel_idx, tick);

        // Next, make sure there's enough space in the slab for the timeout.
        if self.slab.vacant_entry().is_none() {
            let amt = self.slab.count();
            self.slab.grow(amt);
        }

        // Insert ourselves at the head of the linked list in the wheel.
        let slot = &mut self.wheel[wheel_idx];
        let prev_head;
        {
            let entry = self.slab.vacant_entry().unwrap();
            prev_head = mem::replace(&mut slot.head, entry.index());

            entry.insert(Entry {
                data: data,
                when: at,
                prev: EMPTY,
                next: prev_head,
            });
        }
        if prev_head != EMPTY {
            self.slab[prev_head].prev = slot.head;
        }

        // Update the wheel slot's next timeout field.
        if at <= slot.next_timeout.unwrap_or(at) {
            let tick = tick as u32;
            let actual_tick = self.start + Duration::from_millis(TICK_MS) * tick;
            let at = cmp::max(actual_tick, at);
            slot.next_timeout = Some(at);
        }

        Timeout {
            when: at,
            slab_idx: slot.head,
        }
    }

    /// Queries this timer to see if any timeouts are ready to fire.
    ///
    /// This function will advance the internal wheel to the time specified by
    /// `at`, returning any timeout which has happened up to that point. This
    /// method should be called in a loop until it returns `None` to ensure that
    /// all timeouts are processed.
    ///
    /// # Panics
    ///
    /// This method will panic if `at` is before the instant that this timer
    /// wheel was created.
    pub fn poll(&mut self, at: Instant) -> Option<T> {
        let wheel_tick = self.time_to_ticks(at);

        trace!("polling {} => {}", self.cur_wheel_tick, wheel_tick);

        // Advance forward in time to the `wheel_tick` specified.
        //
        // TODO: don't visit slots in the wheel more than once
        while self.cur_wheel_tick <= wheel_tick {
            let head = self.cur_slab_idx;
            trace!("next head[{} => {}]: {}",
                   self.cur_wheel_tick, wheel_tick, head);

            // If the current slot has no entries or we're done iterating go to
            // the next tick.
            if head == EMPTY {
                self.cur_wheel_tick += 1;
                let idx = self.ticks_to_wheel_idx(self.cur_wheel_tick);
                self.cur_slab_idx = self.wheel[idx].head;
                continue
            }

            // If we're starting to iterate over a slot, clear its timeout as
            // we're probably going to remove entries. As we skip over each
            // element of this slot we'll restore the `next_timeout` field if
            // necessary.
            let idx = self.ticks_to_wheel_idx(self.cur_wheel_tick);
            if head == self.wheel[idx].head {
                self.wheel[idx].next_timeout = None;
            }

            // Otherwise, continue iterating over the linked list in the wheel
            // slot we're on and remove anything which has expired.
            self.cur_slab_idx = self.slab[head].next;
            let head_timeout = self.slab[head].when;
            if self.time_to_ticks(head_timeout) <= self.time_to_ticks(at) {
                return self.remove_slab(head).map(|e| e.data)
            } else {
                let next = self.wheel[idx].next_timeout.unwrap_or(head_timeout);
                if head_timeout <= next {
                    self.wheel[idx].next_timeout = Some(head_timeout);
                }
            }
        }

        None
    }

    /// Returns the instant in time that corresponds to the next timeout
    /// scheduled in this wheel.
    pub fn next_timeout(&self) -> Option<Instant> {
        // TODO: can this be optimized to not look at the whole array?
        let timeouts = self.wheel.iter().map(|slot| slot.next_timeout);
        let min = timeouts.fold(None, |prev, cur| {
            match (prev, cur) {
                (None, cur) => cur,
                (Some(time), None) => Some(time),
                (Some(a), Some(b)) => Some(cmp::min(a, b)),
            }
        });
        if let Some(min) = min {
            debug!("next timeout {:?}", min);
            debug!("now          {:?}", Instant::now());
        }
        return min
    }

    /// Cancels the specified timeout.
    ///
    /// For timeouts previously registered via `insert` they can be passed back
    /// to this method to cancel the associated timeout, retrieving the value
    /// inserted if the timeout has not already fired.
    ///
    /// This method completes in O(1) time.
    ///
    /// # Panics
    ///
    /// This method may panic if `timeout` wasn't created by this timer wheel.
    pub fn cancel(&mut self, timeout: &Timeout) -> Option<T> {
        match self.slab.get(timeout.slab_idx) {
            Some(e) if e.when == timeout.when => {}
            _ => return None,
        }

        self.remove_slab(timeout.slab_idx).map(|e| e.data)
    }

    fn remove_slab(&mut self, slab_idx: usize) -> Option<Entry<T>> {
        let entry = match self.slab.remove(slab_idx) {
            Some(e) => e,
            None => return None,
        };

        // Remove the node from the linked list
        if entry.prev == EMPTY {
            let idx = self.ticks_to_wheel_idx(self.time_to_ticks(entry.when));
            self.wheel[idx].head = entry.next;
        } else {
            self.slab[entry.prev].next = entry.next;
        }
        if entry.next != EMPTY {
            self.slab[entry.next].prev = entry.prev;
        }

        return Some(entry)
    }

    fn time_to_ticks(&self, time: Instant) -> u64 {
        let dur = time - self.start;
        let ms = dur.subsec_nanos() as u64 / 1_000_000;
        let ms = dur.as_secs()
                    .checked_mul(1_000)
                    .and_then(|m| m.checked_add(ms))
                    .expect("overflow scheduling timeout");
        (ms + TICK_MS / 2) / TICK_MS
    }

    fn ticks_to_wheel_idx(&self, ticks: u64) -> usize {
        (ticks as usize) & MASK
    }
}
<|endoftext|>


<commit_before><commit_msg>Do not update the blend color if it unused<commit_after><|endoftext|>