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

use std::borrow::Cow;
use std::fmt::Display;
use std::path::Path;
use std::vec::Vec;
use std::rc::Rc;
use std::cell::RefCell;

use dbus;
use dbus::Connection;
use dbus::BusType;
use dbus::Message;
use dbus::MessageItem;
use dbus::NameFlag;
use dbus::arg::Array;
use dbus::arg::IterAppend;
use dbus::tree::Access;
use dbus::tree::EmitsChangedSignal;
use dbus::tree::Factory;
use dbus::tree::MethodErr;
use dbus::tree::MTFn;
use dbus::tree::MethodResult;
use dbus::tree::MethodInfo;
use dbus::tree::PropInfo;
use dbus::tree::Tree;
use dbus::ConnectionItem;

use engine::{Engine, Redundancy};
use stratis::VERSION;

use super::filesystem::create_dbus_filesystem;
use super::blockdev::create_dbus_blockdev;
use super::pool::create_dbus_pool;
use super::types::{ActionQueue, DeferredAction, DbusContext, DbusErrorEnum, TData};
use super::util::STRATIS_BASE_PATH;
use super::util::STRATIS_BASE_SERVICE;
use super::util::code_to_message_items;
use super::util::default_object_path;
use super::util::engine_to_dbus_err;
use super::util::get_next_arg;
use super::util::ok_message_items;
use super::util::tuple_to_option;

fn create_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let name: &str = get_next_arg(&mut iter, 0)?;
    let redundancy: (bool, u16) = get_next_arg(&mut iter, 1)?;
    let force: bool = get_next_arg(&mut iter, 2)?;
    let devs: Array<&str, _> = get_next_arg(&mut iter, 3)?;

    let blockdevs = devs.map(|x| Path::new(x)).collect::<Vec<&Path>>();

    let object_path = m.path.get_name();
    let dbus_context = m.tree.get_data();
    let mut engine = dbus_context.engine.borrow_mut();
    let result = engine.create_pool(name, &blockdevs, tuple_to_option(redundancy), force);

    let return_message = message.method_return();

    let msg = match result {
        Ok(pool_uuid) => {
            let pool_object_path: dbus::Path =
                create_dbus_pool(dbus_context, object_path.clone(), pool_uuid);
            let default_return =
                MessageItem::Struct(vec![MessageItem::ObjectPath(default_object_path()),
                                         MessageItem::Array(vec![], "o".into())]);
            let pool = get_mut_pool!(engine; pool_uuid; default_return; return_message);

            let bd_object_paths = pool.blockdevs()
                .iter()
                .map(|bd| {
                         MessageItem::ObjectPath(create_dbus_blockdev(dbus_context,
                                                                      pool_object_path.clone(),
                                                                      bd.uuid()))
                     })
                .collect::<Vec<_>>();

            let return_path = MessageItem::ObjectPath(pool_object_path);
            let return_list = MessageItem::Array(bd_object_paths, "o".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = ok_message_items();
            return_message.append3(return_value, rc, rs)
        }
        Err(x) => {
            let return_path = MessageItem::ObjectPath(default_object_path());
            let return_list = MessageItem::Array(vec![], "s".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = engine_to_dbus_err(&x);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(return_value, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn destroy_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {

    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let object_path: dbus::Path<'static> = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();

    let default_return = MessageItem::Bool(false);
    let return_message = message.method_return();

    let pool_uuid = match m.tree.get(&object_path) {
        Some(pool_path) => get_data!(pool_path; default_return; return_message).uuid,
        None => {
            let (rc, rs) = ok_message_items();
            return Ok(vec![return_message.append3(default_return, rc, rs)]);
        }
    };

    let msg = match dbus_context.engine.borrow_mut().destroy_pool(pool_uuid) {
        Ok(action) => {
            dbus_context
                .actions
                .borrow_mut()
                .push_remove(object_path);
            let (rc, rs) = ok_message_items();
            return_message.append3(MessageItem::Bool(action), rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(default_return, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_list_items<T, I>(i: &mut IterAppend, iter: I) -> Result<(), MethodErr>
    where T: Display + Into<u16>,
          I: Iterator<Item = T>
{
    let msg_vec = iter.map(|item| {
                               MessageItem::Struct(vec![MessageItem::Str(format!("{}", item)),
                                                        MessageItem::UInt16(item.into())])
                           })
        .collect::<Vec<MessageItem>>();
    i.append(MessageItem::Array(msg_vec, Cow::Borrowed("(sq)")));
    Ok(())
}

fn get_error_values(i: &mut IterAppend,
                    _p: &PropInfo<MTFn<TData>, TData>)
                    -> Result<(), MethodErr> {
    get_list_items(i, DbusErrorEnum::iter_variants())
}

fn get_redundancy_values(i: &mut IterAppend,
                         _p: &PropInfo<MTFn<TData>, TData>)
                         -> Result<(), MethodErr> {
    get_list_items(i, Redundancy::iter_variants())
}

fn get_version(i: &mut IterAppend, _p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    i.append(VERSION);
    Ok(())
}

fn configure_simulator(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message = m.msg;
    let mut iter = message.iter_init();

    let denominator: u32 = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();
    let result = dbus_context
        .engine
        .borrow_mut()
        .configure_simulator(denominator);

    let return_message = message.method_return();

    let msg = match result {
        Ok(_) => {
            let (rc, rs) = ok_message_items();
            return_message.append2(rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append2(rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_base_tree<'a>(dbus_context: DbusContext) -> (Tree<MTFn<TData>, TData>, dbus::Path<'a>) {

    let f = Factory::new_fn();

    let base_tree = f.tree(dbus_context);

    let create_pool_method = f.method("CreatePool", (), create_pool)
        .in_arg(("name", "s"))
        .in_arg(("redundancy", "(bq)"))
        .in_arg(("force", "b"))
        .in_arg(("devices", "as"))
        .out_arg(("result", "(oao)"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroy_pool_method = f.method("DestroyPool", (), destroy_pool)
        .in_arg(("pool", "o"))
        .out_arg(("action", "b"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let configure_simulator_method = f.method("ConfigureSimulator", (), configure_simulator)
        .in_arg(("denominator", "u"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let redundancy_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("RedundancyValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_redundancy_values);

    let error_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("ErrorValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_error_values);

    let version_property = f.property::<&str, _>("Version", ())
        .access(Access::Read)
        .emits_changed(EmitsChangedSignal::Const)
        .on_get(get_version);

    let interface_name = format!("{}.{}", STRATIS_BASE_SERVICE, "Manager");

    let obj_path = f.object_path(STRATIS_BASE_PATH, None)
        .introspectable()
        .object_manager()
        .add(f.interface(interface_name, ())
                 .add_m(create_pool_method)
                 .add_m(destroy_pool_method)
                 .add_m(configure_simulator_method)
                 .add_p(error_values_property)
                 .add_p(redundancy_values_property)
                 .add_p(version_property));

    let path = obj_path.get_name().to_owned();
    (base_tree.add(obj_path), path)
}

#[allow(type_complexity)]
pub fn connect(engine: Rc<RefCell<Engine>>)
               -> Result<(Connection, Tree<MTFn<TData>, TData>, DbusContext), dbus::Error> {
    let c = Connection::get_private(BusType::System)?;

    let local_engine = Rc::clone(&engine);

    let (mut tree, object_path) = get_base_tree(DbusContext::new(engine));
    let dbus_context = tree.get_data().clone();

    // This should never panic as create_dbus_pool(),
    // create_dbus_filesystem(), and create_dbus_blockdev() do not borrow the
    // engine.
    for pool in local_engine.borrow().pools() {
        let pool_path = create_dbus_pool(&dbus_context, object_path.clone(), pool.uuid());
        for fs_uuid in pool.filesystems().iter().map(|f| f.uuid()) {
            create_dbus_filesystem(&dbus_context, pool_path.clone(), fs_uuid);
        }
        for dev_uuid in pool.blockdevs().iter().map(|bd| bd.uuid()) {
            create_dbus_blockdev(&dbus_context, pool_path.clone(), dev_uuid);
        }
    }

    tree.set_registered(&c, true)?;

    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32)?;

    process_deferred_actions(&c, &mut tree, &dbus_context.actions)?;

    Ok((c, tree, dbus_context))
}

/// Update the dbus tree with deferred adds and removes.
fn process_deferred_actions(c: &Connection,
                            tree: &mut Tree<MTFn<TData>, TData>,
                            actions: &Rc<RefCell<ActionQueue>>)
                            -> Result<(), dbus::Error> {
    let mut b_actions = actions.borrow_mut();
    for action in b_actions.drain() {
        match action {
            DeferredAction::Add(path) => {
                c.register_object_path(path.get_name())?;
                tree.insert(path);
            }
            DeferredAction::Remove(path) => {
                c.unregister_object_path(&path);
                tree.remove(&path);
            }
        }
    }
    Ok(())
}

pub fn handle(c: &Connection,
              item: &ConnectionItem,
              tree: &mut Tree<MTFn<TData>, TData>,
              dbus_context: &DbusContext)
              -> Result<(), dbus::Error> {
    if let ConnectionItem::MethodCall(ref msg) = *item {
        if let Some(v) = tree.handle(msg) {
            // Probably the wisest is to ignore any send errors here -
            // maybe the remote has disconnected during our processing.
            for m in v {
                let _ = c.send(m);
            }
        }

        process_deferred_actions(c, tree, &dbus_context.actions)?;
    }

    Ok(())
}
<commit_msg>Make process_deferred_actions take a simple ActionQueue argument<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::borrow::Cow;
use std::fmt::Display;
use std::path::Path;
use std::vec::Vec;
use std::rc::Rc;
use std::cell::RefCell;

use dbus;
use dbus::Connection;
use dbus::BusType;
use dbus::Message;
use dbus::MessageItem;
use dbus::NameFlag;
use dbus::arg::Array;
use dbus::arg::IterAppend;
use dbus::tree::Access;
use dbus::tree::EmitsChangedSignal;
use dbus::tree::Factory;
use dbus::tree::MethodErr;
use dbus::tree::MTFn;
use dbus::tree::MethodResult;
use dbus::tree::MethodInfo;
use dbus::tree::PropInfo;
use dbus::tree::Tree;
use dbus::ConnectionItem;

use engine::{Engine, Redundancy};
use stratis::VERSION;

use super::filesystem::create_dbus_filesystem;
use super::blockdev::create_dbus_blockdev;
use super::pool::create_dbus_pool;
use super::types::{ActionQueue, DeferredAction, DbusContext, DbusErrorEnum, TData};
use super::util::STRATIS_BASE_PATH;
use super::util::STRATIS_BASE_SERVICE;
use super::util::code_to_message_items;
use super::util::default_object_path;
use super::util::engine_to_dbus_err;
use super::util::get_next_arg;
use super::util::ok_message_items;
use super::util::tuple_to_option;

fn create_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let name: &str = get_next_arg(&mut iter, 0)?;
    let redundancy: (bool, u16) = get_next_arg(&mut iter, 1)?;
    let force: bool = get_next_arg(&mut iter, 2)?;
    let devs: Array<&str, _> = get_next_arg(&mut iter, 3)?;

    let blockdevs = devs.map(|x| Path::new(x)).collect::<Vec<&Path>>();

    let object_path = m.path.get_name();
    let dbus_context = m.tree.get_data();
    let mut engine = dbus_context.engine.borrow_mut();
    let result = engine.create_pool(name, &blockdevs, tuple_to_option(redundancy), force);

    let return_message = message.method_return();

    let msg = match result {
        Ok(pool_uuid) => {
            let pool_object_path: dbus::Path =
                create_dbus_pool(dbus_context, object_path.clone(), pool_uuid);
            let default_return =
                MessageItem::Struct(vec![MessageItem::ObjectPath(default_object_path()),
                                         MessageItem::Array(vec![], "o".into())]);
            let pool = get_mut_pool!(engine; pool_uuid; default_return; return_message);

            let bd_object_paths = pool.blockdevs()
                .iter()
                .map(|bd| {
                         MessageItem::ObjectPath(create_dbus_blockdev(dbus_context,
                                                                      pool_object_path.clone(),
                                                                      bd.uuid()))
                     })
                .collect::<Vec<_>>();

            let return_path = MessageItem::ObjectPath(pool_object_path);
            let return_list = MessageItem::Array(bd_object_paths, "o".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = ok_message_items();
            return_message.append3(return_value, rc, rs)
        }
        Err(x) => {
            let return_path = MessageItem::ObjectPath(default_object_path());
            let return_list = MessageItem::Array(vec![], "s".into());
            let return_value = MessageItem::Struct(vec![return_path, return_list]);
            let (rc, rs) = engine_to_dbus_err(&x);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(return_value, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn destroy_pool(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {

    let message: &Message = m.msg;
    let mut iter = message.iter_init();

    let object_path: dbus::Path<'static> = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();

    let default_return = MessageItem::Bool(false);
    let return_message = message.method_return();

    let pool_uuid = match m.tree.get(&object_path) {
        Some(pool_path) => get_data!(pool_path; default_return; return_message).uuid,
        None => {
            let (rc, rs) = ok_message_items();
            return Ok(vec![return_message.append3(default_return, rc, rs)]);
        }
    };

    let msg = match dbus_context.engine.borrow_mut().destroy_pool(pool_uuid) {
        Ok(action) => {
            dbus_context
                .actions
                .borrow_mut()
                .push_remove(object_path);
            let (rc, rs) = ok_message_items();
            return_message.append3(MessageItem::Bool(action), rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append3(default_return, rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_list_items<T, I>(i: &mut IterAppend, iter: I) -> Result<(), MethodErr>
    where T: Display + Into<u16>,
          I: Iterator<Item = T>
{
    let msg_vec = iter.map(|item| {
                               MessageItem::Struct(vec![MessageItem::Str(format!("{}", item)),
                                                        MessageItem::UInt16(item.into())])
                           })
        .collect::<Vec<MessageItem>>();
    i.append(MessageItem::Array(msg_vec, Cow::Borrowed("(sq)")));
    Ok(())
}

fn get_error_values(i: &mut IterAppend,
                    _p: &PropInfo<MTFn<TData>, TData>)
                    -> Result<(), MethodErr> {
    get_list_items(i, DbusErrorEnum::iter_variants())
}

fn get_redundancy_values(i: &mut IterAppend,
                         _p: &PropInfo<MTFn<TData>, TData>)
                         -> Result<(), MethodErr> {
    get_list_items(i, Redundancy::iter_variants())
}

fn get_version(i: &mut IterAppend, _p: &PropInfo<MTFn<TData>, TData>) -> Result<(), MethodErr> {
    i.append(VERSION);
    Ok(())
}

fn configure_simulator(m: &MethodInfo<MTFn<TData>, TData>) -> MethodResult {
    let message = m.msg;
    let mut iter = message.iter_init();

    let denominator: u32 = get_next_arg(&mut iter, 0)?;

    let dbus_context = m.tree.get_data();
    let result = dbus_context
        .engine
        .borrow_mut()
        .configure_simulator(denominator);

    let return_message = message.method_return();

    let msg = match result {
        Ok(_) => {
            let (rc, rs) = ok_message_items();
            return_message.append2(rc, rs)
        }
        Err(err) => {
            let (rc, rs) = engine_to_dbus_err(&err);
            let (rc, rs) = code_to_message_items(rc, rs);
            return_message.append2(rc, rs)
        }
    };
    Ok(vec![msg])
}

fn get_base_tree<'a>(dbus_context: DbusContext) -> (Tree<MTFn<TData>, TData>, dbus::Path<'a>) {

    let f = Factory::new_fn();

    let base_tree = f.tree(dbus_context);

    let create_pool_method = f.method("CreatePool", (), create_pool)
        .in_arg(("name", "s"))
        .in_arg(("redundancy", "(bq)"))
        .in_arg(("force", "b"))
        .in_arg(("devices", "as"))
        .out_arg(("result", "(oao)"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let destroy_pool_method = f.method("DestroyPool", (), destroy_pool)
        .in_arg(("pool", "o"))
        .out_arg(("action", "b"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let configure_simulator_method = f.method("ConfigureSimulator", (), configure_simulator)
        .in_arg(("denominator", "u"))
        .out_arg(("return_code", "q"))
        .out_arg(("return_string", "s"));

    let redundancy_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("RedundancyValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_redundancy_values);

    let error_values_property =
        f.property::<Array<(&str, u16), &Iterator<Item = (&str, u16)>>, _>("ErrorValues", ())
            .access(Access::Read)
            .emits_changed(EmitsChangedSignal::Const)
            .on_get(get_error_values);

    let version_property = f.property::<&str, _>("Version", ())
        .access(Access::Read)
        .emits_changed(EmitsChangedSignal::Const)
        .on_get(get_version);

    let interface_name = format!("{}.{}", STRATIS_BASE_SERVICE, "Manager");

    let obj_path = f.object_path(STRATIS_BASE_PATH, None)
        .introspectable()
        .object_manager()
        .add(f.interface(interface_name, ())
                 .add_m(create_pool_method)
                 .add_m(destroy_pool_method)
                 .add_m(configure_simulator_method)
                 .add_p(error_values_property)
                 .add_p(redundancy_values_property)
                 .add_p(version_property));

    let path = obj_path.get_name().to_owned();
    (base_tree.add(obj_path), path)
}

#[allow(type_complexity)]
pub fn connect(engine: Rc<RefCell<Engine>>)
               -> Result<(Connection, Tree<MTFn<TData>, TData>, DbusContext), dbus::Error> {
    let c = Connection::get_private(BusType::System)?;

    let local_engine = Rc::clone(&engine);

    let (mut tree, object_path) = get_base_tree(DbusContext::new(engine));
    let dbus_context = tree.get_data().clone();

    // This should never panic as create_dbus_pool(),
    // create_dbus_filesystem(), and create_dbus_blockdev() do not borrow the
    // engine.
    for pool in local_engine.borrow().pools() {
        let pool_path = create_dbus_pool(&dbus_context, object_path.clone(), pool.uuid());
        for fs_uuid in pool.filesystems().iter().map(|f| f.uuid()) {
            create_dbus_filesystem(&dbus_context, pool_path.clone(), fs_uuid);
        }
        for dev_uuid in pool.blockdevs().iter().map(|bd| bd.uuid()) {
            create_dbus_blockdev(&dbus_context, pool_path.clone(), dev_uuid);
        }
    }

    tree.set_registered(&c, true)?;

    c.register_name(STRATIS_BASE_SERVICE, NameFlag::ReplaceExisting as u32)?;

    process_deferred_actions(&c, &mut tree, &mut dbus_context.actions.borrow_mut())?;

    Ok((c, tree, dbus_context))
}

/// Update the dbus tree with deferred adds and removes.
fn process_deferred_actions(c: &Connection,
                            tree: &mut Tree<MTFn<TData>, TData>,
                            actions: &mut ActionQueue)
                            -> Result<(), dbus::Error> {
    for action in actions.drain() {
        match action {
            DeferredAction::Add(path) => {
                c.register_object_path(path.get_name())?;
                tree.insert(path);
            }
            DeferredAction::Remove(path) => {
                c.unregister_object_path(&path);
                tree.remove(&path);
            }
        }
    }
    Ok(())
}

pub fn handle(c: &Connection,
              item: &ConnectionItem,
              tree: &mut Tree<MTFn<TData>, TData>,
              dbus_context: &DbusContext)
              -> Result<(), dbus::Error> {
    if let ConnectionItem::MethodCall(ref msg) = *item {
        if let Some(v) = tree.handle(msg) {
            // Probably the wisest is to ignore any send errors here -
            // maybe the remote has disconnected during our processing.
            for m in v {
                let _ = c.send(m);
            }
        }

        process_deferred_actions(c, tree, &mut dbus_context.actions.borrow_mut())?;
    }

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>add CPU monitor example<commit_after>//! CPU usage monitor

#![feature(const_fn)]
#![feature(used)]
#![no_std]

// version = "0.2.9"
#[macro_use]
extern crate cortex_m;

// version = "0.2.4"
extern crate cortex_m_rt;

// version = "0.1.0"
#[macro_use]
extern crate cortex_m_rtfm as rtfm;

extern crate blue_pill;

use core::cell::Cell;

use blue_pill::stm32f103xx;
use blue_pill::timer::Timer;
use rtfm::{C1, P0, P1, Resource, T0, T1, TMax};
use stm32f103xx::interrupt::Tim1UpTim10;

// CONFIGURATION
const FREQUENCY: u32 = 1; // Hz

// RESOURCES
peripherals!(stm32f103xx, {
    DWT: Peripheral {
        register_block: Dwt,
        ceiling: C0,
    },
    ITM: Peripheral {
        register_block: Itm,
        ceiling: C1,
    },
    RCC: Peripheral {
        register_block: Rcc,
        ceiling: C0,
    },
    TIM1: Peripheral {
        register_block: Tim1,
        ceiling: C1,
    },
});

static SLEEP_CYCLES: Resource<Cell<u32>, C1> = Resource::new(Cell::new(0));

// INITIALIZATION PHASE
fn init(ref prio: P0, thr: &TMax) {
    let dwt = &DWT.access(prio, thr);
    let rcc = &RCC.access(prio, thr);
    let tim1 = &TIM1.access(prio, thr);

    let timer = Timer(tim1);

    dwt.enable_cycle_counter();

    timer.init(FREQUENCY, rcc);
    timer.resume();
}

// IDLE LOOP
fn idle(ref prio: P0, _thr: T0) -> ! {
    // Sleep
    loop {
        rtfm::atomic(|thr| {
            let dwt = DWT.access(prio, thr);
            let sleep_cycles = SLEEP_CYCLES.access(prio, thr);

            let before = dwt.cyccnt.read();
            rtfm::wfi();
            let after = dwt.cyccnt.read();

            let elapsed = after.wrapping_sub(before);

            sleep_cycles.set(sleep_cycles.get() + elapsed);
        });

        // Tasks are serviced here
    }
}

// TASKS
tasks!(stm32f103xx, {
    periodic: Task {
        interrupt: Tim1UpTim10,
        priority: P1,
        enabled: true,
    },
});

fn periodic(_task: Tim1UpTim10, ref prio: P1, ref thr: T1) {
    let tim1 = &TIM1.access(prio, thr);
    let itm = ITM.access(prio, thr);
    let sleep_cycles = SLEEP_CYCLES.access(prio, thr);

    let timer = Timer(tim1);

    if timer.clear_update_flag().is_ok() {
        // Report clock cycles spent sleeping
        iprintln!(&itm.stim[0], "{}", sleep_cycles.get());

        // Reset sleep cycle counter to zero
        sleep_cycles.set(0);
    } else {
        // Only reachable via `rtfm::request(periodic)`
        unreachable!()
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use std::env;
use std::time::{Duration, Instant};

use core::shell::Verbosity;
use util::{CargoResult, Config};

use unicode_width::UnicodeWidthChar;

pub struct Progress<'cfg> {
    state: Option<State<'cfg>>,
}

pub enum ProgressStyle {
    Percentage,
    Ratio,
}

struct State<'cfg> {
    config: &'cfg Config,
    format: Format,
    first: bool,
    last_update: Instant,
    name: String,
    done: bool,
}

struct Format {
    style: ProgressStyle,
    max_width: usize,
    width: usize,
}

impl<'cfg> Progress<'cfg> {
    pub fn with_style(name: &str, style: ProgressStyle, cfg: &'cfg Config) -> Progress<'cfg> {
        // report no progress when -q (for quiet) or TERM=dumb are set
        let dumb = match env::var("TERM") {
            Ok(term) => term == "dumb",
            Err(_) => false,
        };
        if cfg.shell().verbosity() == Verbosity::Quiet || dumb {
            return Progress { state: None };
        }

        Progress {
            state: cfg.shell().err_width().map(|n| State {
                config: cfg,
                format: Format {
                    style,
                    max_width: n,
                    width: cmp::min(n, 80),
                },
                first: true,
                last_update: Instant::now(),
                name: name.to_string(),
                done: false,
            }),
        }
    }

    pub fn disable(&mut self) {
        self.state = None;
    }

    pub fn new(name: &str, cfg: &'cfg Config) -> Progress<'cfg> {
        Self::with_style(name, ProgressStyle::Percentage, cfg)
    }

    pub fn tick(&mut self, cur: usize, max: usize) -> CargoResult<()> {
        match self.state {
            Some(ref mut s) => s.tick(cur, max, "", true),
            None => Ok(()),
        }
    }

    pub fn clear(&mut self) {
        if let Some(ref mut s) = self.state {
            clear(s.format.max_width, s.config);
        }
    }

    pub fn tick_now(&mut self, cur: usize, max: usize, msg: &str) -> CargoResult<()> {
        match self.state {
            Some(ref mut s) => s.tick(cur, max, msg, false),
            None => Ok(()),
        }
    }
}

impl<'cfg> State<'cfg> {
    fn tick(&mut self, cur: usize, max: usize, msg: &str, throttle: bool) -> CargoResult<()> {
        if self.done {
            return Ok(());
        }

        // Don't update too often as it can cause excessive performance loss
        // just putting stuff onto the terminal. We also want to avoid
        // flickering by not drawing anything that goes away too quickly. As a
        // result we've got two branches here:
        //
        // 1. If we haven't drawn anything, we wait for a period of time to
        //    actually start drawing to the console. This ensures that
        //    short-lived operations don't flicker on the console. Currently
        //    there's a 500ms delay to when we first draw something.
        // 2. If we've drawn something, then we rate limit ourselves to only
        //    draw to the console every so often. Currently there's a 100ms
        //    delay between updates.
        if throttle {
            if self.first {
                let delay = Duration::from_millis(500);
                if self.last_update.elapsed() < delay {
                    return Ok(());
                }
                self.first = false;
            } else {
                let interval = Duration::from_millis(100);
                if self.last_update.elapsed() < interval {
                    return Ok(());
                }
            }
            self.last_update = Instant::now();
        }

        if cur == max {
            self.done = true;
        }

        // Write out a pretty header, then the progress bar itself, and then
        // return back to the beginning of the line for the next print.
        if let Some(string) = self.format.progress_status(cur, max, msg) {
            self.config.shell().status_header(&self.name)?;
            write!(self.config.shell().err(), "{}\r", string)?;
        }
        Ok(())
    }
}

impl Format {
    fn progress_status(&self, cur: usize, max: usize, msg: &str) -> Option<String> {
        // Render the percentage at the far right and then figure how long the
        // progress bar is
        let pct = (cur as f64) / (max as f64);
        let pct = if !pct.is_finite() { 0.0 } else { pct };
        let stats = match self.style {
            ProgressStyle::Percentage => format!(" {:6.02}%", pct * 100.0),
            ProgressStyle::Ratio => format!(" {}/{}", cur, max),
        };
        let extra_len = stats.len() + 2 /* [ and ] */ + 15 /* status header */;
        let display_width = match self.width.checked_sub(extra_len) {
            Some(n) => n,
            None => return None,
        };

        let mut string = String::with_capacity(self.max_width);
        string.push('[');
        let hashes = display_width as f64 * pct;
        let hashes = hashes as usize;

        // Draw the `===>`
        if hashes > 0 {
            for _ in 0..hashes - 1 {
                string.push_str("=");
            }
            if cur == max {
                string.push_str("=");
            } else {
                string.push_str(">");
            }
        }

        // Draw the empty space we have left to do
        for _ in 0..(display_width - hashes) {
            string.push_str(" ");
        }
        string.push_str("]");
        string.push_str(&stats);

        let mut avail_msg_len = self.max_width - self.width;
        let mut ellipsis_pos = 0;
        if avail_msg_len > 3 {
            for c in msg.chars() {
                let display_width = c.width().unwrap_or(0);
                if avail_msg_len >= display_width {
                    avail_msg_len -= display_width;
                    string.push(c);
                    if avail_msg_len >= 3 {
                        ellipsis_pos = string.len();
                    }
                } else {
                    string.truncate(ellipsis_pos);
                    string.push_str("...");
                    break;
                }
            }
        }

        Some(string)
    }
}

fn clear(width: usize, config: &Config) {
    let blank = " ".repeat(width);
    drop(write!(config.shell().err(), "{}\r", blank));
}

impl<'cfg> Drop for State<'cfg> {
    fn drop(&mut self) {
        clear(self.format.max_width, self.config);
    }
}

#[test]
fn test_progress_status() {
    let format = Format {
        style: ProgressStyle::Ratio,
        width: 40,
        max_width: 60,
    };
    assert_eq!(
        format.progress_status(0, 4, ""),
        Some("[                   ] 0/4".to_string())
    );
    assert_eq!(
        format.progress_status(1, 4, ""),
        Some("[===>               ] 1/4".to_string())
    );
    assert_eq!(
        format.progress_status(2, 4, ""),
        Some("[========>          ] 2/4".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ""),
        Some("[=============>     ] 3/4".to_string())
    );
    assert_eq!(
        format.progress_status(4, 4, ""),
        Some("[===================] 4/4".to_string())
    );

    assert_eq!(
        format.progress_status(3999, 4000, ""),
        Some("[===========> ] 3999/4000".to_string())
    );
    assert_eq!(
        format.progress_status(4000, 4000, ""),
        Some("[=============] 4000/4000".to_string())
    );

    assert_eq!(
        format.progress_status(3, 4, ": short message"),
        Some("[=============>     ] 3/4: short message".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ": msg thats just fit"),
        Some("[=============>     ] 3/4: msg thats just fit".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ": msg that's just fit"),
        Some("[=============>     ] 3/4: msg that's just...".to_string())
    );

    // combining diacritics have width zero and thus can fit max_width.
    let zalgo_msg = "z̸̧̢̗͉̝̦͍̱ͧͦͨ̑̅̌ͥ́͢a̢̫̝̪̤͎̱̣͍̭̞̙̱͙͍̘̭͚ͬͨ̽ͯ̅̑ͥ͋̏̑ͫ̄͢l̶̡̛̥̝̰̭̹̯̯̞̪͇̱̦͙͔̘̼͇͓̈ͨ͗ͧ̓͒ͦ̀̇ͣ̈ͭ͊͛̃̑͒̿̕͜g̸̷̢̩̻̻͚̠͓̞̥͐ͩ͌̑ͥ̊̽͋͐̐͌͛̐̇̑ͨ́ͅo͙̳̣͔̰̠̜͕͕̞̦̙̭̜̯̹̬̻̓͑ͦ͋̈̉͌̃ͯ̀̂͠ͅ ̸̡͎̦̲̖̤̺̜̮̱̰̥͔̯̅̏ͬ̂ͨ̋̃̽̈́̾̔̇ͣ̚͜͜h̡ͫ̐̅̿̍̀͜҉̛͇̭̹̰̠͙̞ẽ̶̙̹̳̖͉͎̦͂̋̓ͮ̔ͬ̐̀͂̌͑̒͆̚͜͠ ͓͓̟͍̮̬̝̝̰͓͎̼̻ͦ͐̾̔͒̃̓͟͟c̮̦͍̺͈͚̯͕̄̒͐̂͊̊͗͊ͤͣ̀͘̕͝͞o̶͍͚͍̣̮͌ͦ̽̑ͩ̅ͮ̐̽̏͗́͂̅ͪ͠m̷̧͖̻͔̥̪̭͉͉̤̻͖̩̤͖̘ͦ̂͌̆̂ͦ̒͊ͯͬ͊̉̌ͬ͝͡e̵̹̣͍̜̺̤̤̯̫̹̠̮͎͙̯͚̰̼͗͐̀̒͂̉̀̚͝͞s̵̲͍͙͖̪͓͓̺̱̭̩̣͖̣ͤͤ͂̎̈͗͆ͨͪ̆̈͗͝͠";
    assert_eq!(
        format.progress_status(3, 4, zalgo_msg),
        Some("[=============>     ] 3/4".to_string() + zalgo_msg)
    );

    // some non-ASCII ellipsize test
    assert_eq!(
        format.progress_status(3, 4, "_123456789123456e\u{301}\u{301}8\u{301}90a"),
        Some("[=============>     ] 3/4_123456789123456e\u{301}\u{301}...".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, "：每個漢字佔據了兩個字元"),
        Some("[=============>     ] 3/4：每個漢字佔據了...".to_string())
    );
}

#[test]
fn test_progress_status_percentage() {
    let format = Format {
        style: ProgressStyle::Percentage,
        width: 40,
        max_width: 60,
    };
    assert_eq!(
        format.progress_status(0, 77, ""),
        Some("[               ]   0.00%".to_string())
    );
    assert_eq!(
        format.progress_status(1, 77, ""),
        Some("[               ]   1.30%".to_string())
    );
    assert_eq!(
        format.progress_status(76, 77, ""),
        Some("[=============> ]  98.70%".to_string())
    );
    assert_eq!(
        format.progress_status(77, 77, ""),
        Some("[===============] 100.00%".to_string())
    );
}

#[test]
fn test_progress_status_too_short() {
    let format = Format {
        style: ProgressStyle::Percentage,
        width: 25,
        max_width: 25,
    };
    assert_eq!(
        format.progress_status(1, 1, ""),
        Some("[] 100.00%".to_string())
    );

    let format = Format {
        style: ProgressStyle::Percentage,
        width: 24,
        max_width: 24,
    };
    assert_eq!(
        format.progress_status(1, 1, ""),
        None
    );
}
<commit_msg>Auto merge of #5700 - alexcrichton:update-width, r=matklad<commit_after>use std::cmp;
use std::env;
use std::time::{Duration, Instant};

use core::shell::Verbosity;
use util::{CargoResult, Config};

use unicode_width::UnicodeWidthChar;

pub struct Progress<'cfg> {
    state: Option<State<'cfg>>,
}

pub enum ProgressStyle {
    Percentage,
    Ratio,
}

struct State<'cfg> {
    config: &'cfg Config,
    format: Format,
    first: bool,
    last_update: Instant,
    name: String,
    done: bool,
}

struct Format {
    style: ProgressStyle,
    max_width: usize,
    max_print: usize,
}

impl<'cfg> Progress<'cfg> {
    pub fn with_style(name: &str, style: ProgressStyle, cfg: &'cfg Config) -> Progress<'cfg> {
        // report no progress when -q (for quiet) or TERM=dumb are set
        let dumb = match env::var("TERM") {
            Ok(term) => term == "dumb",
            Err(_) => false,
        };
        if cfg.shell().verbosity() == Verbosity::Quiet || dumb {
            return Progress { state: None };
        }

        Progress {
            state: cfg.shell().err_width().map(|n| State {
                config: cfg,
                format: Format {
                    style,
                    max_width: n,
                    max_print: 80,
                },
                first: true,
                last_update: Instant::now(),
                name: name.to_string(),
                done: false,
            }),
        }
    }

    pub fn disable(&mut self) {
        self.state = None;
    }

    pub fn new(name: &str, cfg: &'cfg Config) -> Progress<'cfg> {
        Self::with_style(name, ProgressStyle::Percentage, cfg)
    }

    pub fn tick(&mut self, cur: usize, max: usize) -> CargoResult<()> {
        match self.state {
            Some(ref mut s) => s.tick(cur, max, "", true),
            None => Ok(()),
        }
    }

    pub fn clear(&mut self) {
        if let Some(ref mut s) = self.state {
            s.clear();
        }
    }

    pub fn tick_now(&mut self, cur: usize, max: usize, msg: &str) -> CargoResult<()> {
        match self.state {
            Some(ref mut s) => s.tick(cur, max, msg, false),
            None => Ok(()),
        }
    }
}

impl<'cfg> State<'cfg> {
    fn tick(&mut self, cur: usize, max: usize, msg: &str, throttle: bool) -> CargoResult<()> {
        if self.done {
            return Ok(());
        }

        // Don't update too often as it can cause excessive performance loss
        // just putting stuff onto the terminal. We also want to avoid
        // flickering by not drawing anything that goes away too quickly. As a
        // result we've got two branches here:
        //
        // 1. If we haven't drawn anything, we wait for a period of time to
        //    actually start drawing to the console. This ensures that
        //    short-lived operations don't flicker on the console. Currently
        //    there's a 500ms delay to when we first draw something.
        // 2. If we've drawn something, then we rate limit ourselves to only
        //    draw to the console every so often. Currently there's a 100ms
        //    delay between updates.
        if throttle {
            if self.first {
                let delay = Duration::from_millis(500);
                if self.last_update.elapsed() < delay {
                    return Ok(());
                }
                self.first = false;
            } else {
                let interval = Duration::from_millis(100);
                if self.last_update.elapsed() < interval {
                    return Ok(());
                }
            }
            self.last_update = Instant::now();
        }

        if cur == max {
            self.done = true;
        }

        // Write out a pretty header, then the progress bar itself, and then
        // return back to the beginning of the line for the next print.
        self.try_update_max_width();
        if let Some(string) = self.format.progress_status(cur, max, msg) {
            self.config.shell().status_header(&self.name)?;
            write!(self.config.shell().err(), "{}\r", string)?;
        }
        Ok(())
    }

    fn clear(&mut self) {
        self.try_update_max_width();
        let blank = " ".repeat(self.format.max_width);
        drop(write!(self.config.shell().err(), "{}\r", blank));
    }

    fn try_update_max_width(&mut self) {
        if let Some(n) = self.config.shell().err_width() {
            self.format.max_width = n;
        }
    }
}

impl Format {
    fn progress_status(&self, cur: usize, max: usize, msg: &str) -> Option<String> {
        // Render the percentage at the far right and then figure how long the
        // progress bar is
        let pct = (cur as f64) / (max as f64);
        let pct = if !pct.is_finite() { 0.0 } else { pct };
        let stats = match self.style {
            ProgressStyle::Percentage => format!(" {:6.02}%", pct * 100.0),
            ProgressStyle::Ratio => format!(" {}/{}", cur, max),
        };
        let extra_len = stats.len() + 2 /* [ and ] */ + 15 /* status header */;
        let display_width = match self.width().checked_sub(extra_len) {
            Some(n) => n,
            None => return None,
        };

        let mut string = String::with_capacity(self.max_width);
        string.push('[');
        let hashes = display_width as f64 * pct;
        let hashes = hashes as usize;

        // Draw the `===>`
        if hashes > 0 {
            for _ in 0..hashes - 1 {
                string.push_str("=");
            }
            if cur == max {
                string.push_str("=");
            } else {
                string.push_str(">");
            }
        }

        // Draw the empty space we have left to do
        for _ in 0..(display_width - hashes) {
            string.push_str(" ");
        }
        string.push_str("]");
        string.push_str(&stats);

        let mut avail_msg_len = self.max_width - self.width();
        let mut ellipsis_pos = 0;
        if avail_msg_len > 3 {
            for c in msg.chars() {
                let display_width = c.width().unwrap_or(0);
                if avail_msg_len >= display_width {
                    avail_msg_len -= display_width;
                    string.push(c);
                    if avail_msg_len >= 3 {
                        ellipsis_pos = string.len();
                    }
                } else {
                    string.truncate(ellipsis_pos);
                    string.push_str("...");
                    break;
                }
            }
        }

        Some(string)
    }

    fn width(&self) -> usize {
        cmp::min(self.max_width, self.max_print)
    }
}

impl<'cfg> Drop for State<'cfg> {
    fn drop(&mut self) {
        self.clear();
    }
}

#[test]
fn test_progress_status() {
    let format = Format {
        style: ProgressStyle::Ratio,
        max_print: 40,
        max_width: 60,
    };
    assert_eq!(
        format.progress_status(0, 4, ""),
        Some("[                   ] 0/4".to_string())
    );
    assert_eq!(
        format.progress_status(1, 4, ""),
        Some("[===>               ] 1/4".to_string())
    );
    assert_eq!(
        format.progress_status(2, 4, ""),
        Some("[========>          ] 2/4".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ""),
        Some("[=============>     ] 3/4".to_string())
    );
    assert_eq!(
        format.progress_status(4, 4, ""),
        Some("[===================] 4/4".to_string())
    );

    assert_eq!(
        format.progress_status(3999, 4000, ""),
        Some("[===========> ] 3999/4000".to_string())
    );
    assert_eq!(
        format.progress_status(4000, 4000, ""),
        Some("[=============] 4000/4000".to_string())
    );

    assert_eq!(
        format.progress_status(3, 4, ": short message"),
        Some("[=============>     ] 3/4: short message".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ": msg thats just fit"),
        Some("[=============>     ] 3/4: msg thats just fit".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, ": msg that's just fit"),
        Some("[=============>     ] 3/4: msg that's just...".to_string())
    );

    // combining diacritics have width zero and thus can fit max_width.
    let zalgo_msg = "z̸̧̢̗͉̝̦͍̱ͧͦͨ̑̅̌ͥ́͢a̢̫̝̪̤͎̱̣͍̭̞̙̱͙͍̘̭͚ͬͨ̽ͯ̅̑ͥ͋̏̑ͫ̄͢l̶̡̛̥̝̰̭̹̯̯̞̪͇̱̦͙͔̘̼͇͓̈ͨ͗ͧ̓͒ͦ̀̇ͣ̈ͭ͊͛̃̑͒̿̕͜g̸̷̢̩̻̻͚̠͓̞̥͐ͩ͌̑ͥ̊̽͋͐̐͌͛̐̇̑ͨ́ͅo͙̳̣͔̰̠̜͕͕̞̦̙̭̜̯̹̬̻̓͑ͦ͋̈̉͌̃ͯ̀̂͠ͅ ̸̡͎̦̲̖̤̺̜̮̱̰̥͔̯̅̏ͬ̂ͨ̋̃̽̈́̾̔̇ͣ̚͜͜h̡ͫ̐̅̿̍̀͜҉̛͇̭̹̰̠͙̞ẽ̶̙̹̳̖͉͎̦͂̋̓ͮ̔ͬ̐̀͂̌͑̒͆̚͜͠ ͓͓̟͍̮̬̝̝̰͓͎̼̻ͦ͐̾̔͒̃̓͟͟c̮̦͍̺͈͚̯͕̄̒͐̂͊̊͗͊ͤͣ̀͘̕͝͞o̶͍͚͍̣̮͌ͦ̽̑ͩ̅ͮ̐̽̏͗́͂̅ͪ͠m̷̧͖̻͔̥̪̭͉͉̤̻͖̩̤͖̘ͦ̂͌̆̂ͦ̒͊ͯͬ͊̉̌ͬ͝͡e̵̹̣͍̜̺̤̤̯̫̹̠̮͎͙̯͚̰̼͗͐̀̒͂̉̀̚͝͞s̵̲͍͙͖̪͓͓̺̱̭̩̣͖̣ͤͤ͂̎̈͗͆ͨͪ̆̈͗͝͠";
    assert_eq!(
        format.progress_status(3, 4, zalgo_msg),
        Some("[=============>     ] 3/4".to_string() + zalgo_msg)
    );

    // some non-ASCII ellipsize test
    assert_eq!(
        format.progress_status(3, 4, "_123456789123456e\u{301}\u{301}8\u{301}90a"),
        Some("[=============>     ] 3/4_123456789123456e\u{301}\u{301}...".to_string())
    );
    assert_eq!(
        format.progress_status(3, 4, "：每個漢字佔據了兩個字元"),
        Some("[=============>     ] 3/4：每個漢字佔據了...".to_string())
    );
}

#[test]
fn test_progress_status_percentage() {
    let format = Format {
        style: ProgressStyle::Percentage,
        max_print: 40,
        max_width: 60,
    };
    assert_eq!(
        format.progress_status(0, 77, ""),
        Some("[               ]   0.00%".to_string())
    );
    assert_eq!(
        format.progress_status(1, 77, ""),
        Some("[               ]   1.30%".to_string())
    );
    assert_eq!(
        format.progress_status(76, 77, ""),
        Some("[=============> ]  98.70%".to_string())
    );
    assert_eq!(
        format.progress_status(77, 77, ""),
        Some("[===============] 100.00%".to_string())
    );
}

#[test]
fn test_progress_status_too_short() {
    let format = Format {
        style: ProgressStyle::Percentage,
        max_print: 25,
        max_width: 25,
    };
    assert_eq!(
        format.progress_status(1, 1, ""),
        Some("[] 100.00%".to_string())
    );

    let format = Format {
        style: ProgressStyle::Percentage,
        max_print: 24,
        max_width: 24,
    };
    assert_eq!(
        format.progress_status(1, 1, ""),
        None
    );
}
<|endoftext|>


<commit_before><commit_msg>Fixing bugs with index out of bounds exceptions.<commit_after><|endoftext|>


<commit_before>//! Tasks used to drive a future computation
//!
//! It's intended over time a particular operation (such as servicing an HTTP
//! request) will involve many futures. This entire operation, however, can be
//! thought of as one unit, as the entire result is essentially just moving
//! through one large state machine.
//!
//! A "task" is the unit of abstraction for what is driving this state machine
//! and tree of futures forward. A task is used to poll futures and schedule
//! futures with, and has utilities for sharing data between tasks and handles
//! for notifying when a future is ready. Each task also has its own set of
//! task-local data generated by `task_local!`.
//!
//! Note that libraries typically should not manage tasks themselves, but rather
//! leave that to event loops and other "executors" (see the `executor` module),
//! or by using the `wait` method to create and execute a task directly on the
//! current thread.
//!
//! ## Functions
//!
//! There is an important bare function in this module: `park`. The `park`
//! function is similar to the standard library's `thread::park` method where it
//! returns a handle to wake up a task at a later date (via an `unpark` method).

#[doc(hidden)]
#[deprecated(since = "0.1.4", note = "import through the executor module instead")]
pub use task_impl::{Spawn, spawn, Executor, Run};

pub use task_impl::{Task, TaskRc, LocalKey, park}
pub use task_impl::{with_unpark_event, UnparkEvent, EventSet, Unpark};
<commit_msg>Syntax<commit_after>//! Tasks used to drive a future computation
//!
//! It's intended over time a particular operation (such as servicing an HTTP
//! request) will involve many futures. This entire operation, however, can be
//! thought of as one unit, as the entire result is essentially just moving
//! through one large state machine.
//!
//! A "task" is the unit of abstraction for what is driving this state machine
//! and tree of futures forward. A task is used to poll futures and schedule
//! futures with, and has utilities for sharing data between tasks and handles
//! for notifying when a future is ready. Each task also has its own set of
//! task-local data generated by `task_local!`.
//!
//! Note that libraries typically should not manage tasks themselves, but rather
//! leave that to event loops and other "executors" (see the `executor` module),
//! or by using the `wait` method to create and execute a task directly on the
//! current thread.
//!
//! ## Functions
//!
//! There is an important bare function in this module: `park`. The `park`
//! function is similar to the standard library's `thread::park` method where it
//! returns a handle to wake up a task at a later date (via an `unpark` method).

#[doc(hidden)]
#[deprecated(since = "0.1.4", note = "import through the executor module instead")]
pub use task_impl::{Spawn, spawn, Executor, Run};

pub use task_impl::{Task, TaskRc, LocalKey, park};
pub use task_impl::{with_unpark_event, UnparkEvent, EventSet, Unpark};
<|endoftext|>


<commit_before><commit_msg>show avatars on right when engaged<commit_after><|endoftext|>


<commit_before><commit_msg>test: Add test for #1821<commit_after>// Issue #1821 - Don't recurse trying to typecheck this
enum t {
    foo([t])
}
fn main() {}<|endoftext|>


<commit_before><commit_msg>Adding xfailed test for #3874<commit_after>// xfail-test
enum PureCounter { PureCounter(uint) }

pure fn each(self: PureCounter, blk: fn(v: &uint)) {
    let PureCounter(ref x) = self;
    blk(x);
}

fn main() {}
<|endoftext|>


<commit_before>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent {
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct NodeData {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

pub struct Node {
    pub address: u64,
    pub name: String,
    pub extents: [Extent; 16]
}

impl Node {
    pub fn new(address: u64, data: NodeData) -> Node {
        let mut utf8: Vec<u8> = Vec::new();
        for i in 0..data.name.len() {
            let c = data.name[i];
            if c == 0 {
                break;
            }else{
                utf8.push(c);
            }
        }

        Node {
            address: address,
            name: String::from_utf8(&utf8),
            extents: data.extents
        }
    }
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            address: self.address,
            name: self.name.clone(),
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem {
        unsafe {
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_data: *const NodeData = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_data as usize);

                        nodes.push(Node::new(node_address, ptr::read(node_data)));
                    }
                }
            }
            unalloc(node_data as usize);

            return FileSystem {
                disk: disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node> {
        for node in self.nodes.iter() {
            if node.name == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            if node.name.starts_with(directory.clone()) {
                ret.push(node.name.substr(directory.len(), node.name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub disk: Disk,
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize,
    pub dirty: bool
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&("file:///".to_string() + &self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        if i > 0 {
            self.dirty = true;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    // TODO: Rename to sync
    // TODO: Check to make sure proper amount of bytes written. See Disk::write
    // TODO: Allow reallocation
    fn flush(&mut self) -> bool {
        let block_size = 512;

        let mut pos: usize = 0;
        for extent in &self.node.extents {
            //Make sure it is a valid extent
            if extent.block > 0 && extent.length > 0 {
                let remaining = self.vec.len() - pos;

                let current_sectors = (extent.length as usize + block_size - 1)/block_size;
                let max_size = current_sectors * 512;

                let size = min(remaining, max_size);
                let sectors = (size + block_size - 1)/block_size;

                unsafe {
                    let mem_to_write = self.vec.as_ptr().offset(pos as isize) as usize;
                    //TODO: Make sure mem_to_write is copied safely into an zeroed area of the right size!
                    let bytes_written = self.disk.write(extent.block,
                                ((size + 511)/512) as u16,
                                mem_to_write as usize);
                }

                pos += size;
            }
        }
        if pos + 1 < self.vec.len() {
            d("Need to reallocate file\n");
        }
        return true;
    }
}

impl Drop for FileResource {
    fn drop(&mut self) {
        self.flush();
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        } else {
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    } else {
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        } else {
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    //TODO: Handle more extents
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        disk: self.fs.disk,
                        node: node,
                        vec: vec,
                        seek: 0,
                        dirty: false
                    };
                },
                Option::None => {
                    /*
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                    */
                    return box NoneResource;
                }
            }
        }
    }
}
<commit_msg>Add reallocation warning<commit_after>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent {
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct NodeData {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

pub struct Node {
    pub address: u64,
    pub name: String,
    pub extents: [Extent; 16]
}

impl Node {
    pub fn new(address: u64, data: NodeData) -> Node {
        let mut utf8: Vec<u8> = Vec::new();
        for i in 0..data.name.len() {
            let c = data.name[i];
            if c == 0 {
                break;
            }else{
                utf8.push(c);
            }
        }

        Node {
            address: address,
            name: String::from_utf8(&utf8),
            extents: data.extents
        }
    }
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            address: self.address,
            name: self.name.clone(),
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem {
        unsafe {
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_data: *const NodeData = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_data as usize);

                        nodes.push(Node::new(node_address, ptr::read(node_data)));
                    }
                }
            }
            unalloc(node_data as usize);

            return FileSystem {
                disk: disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node> {
        for node in self.nodes.iter() {
            if node.name == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            if node.name.starts_with(directory.clone()) {
                ret.push(node.name.substr(directory.len(), node.name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub disk: Disk,
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize,
    pub dirty: bool
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&("file:///".to_string() + &self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        if i > 0 {
            self.dirty = true;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    // TODO: Rename to sync
    // TODO: Check to make sure proper amount of bytes written. See Disk::write
    // TODO: Allow reallocation
    fn flush(&mut self) -> bool {
        if self.dirty {
            let block_size: usize = 512;

            let mut pos: isize = 0;
            let mut remaining = self.vec.len() as isize;
            for extent in &self.node.extents {
                //Make sure it is a valid extent
                if extent.block > 0 && extent.length > 0 {
                    let current_sectors = (extent.length as usize + block_size - 1)/block_size;
                    let max_size = current_sectors * 512;

                    let size = min(remaining as usize, max_size);
                    let sectors = (size + block_size - 1)/block_size;

                    unsafe {
                        let mem_to_write = self.vec.as_ptr().offset(pos) as usize;
                        //TODO: Make sure mem_to_write is copied safely into an zeroed area of the right size!
                        let bytes_written = self.disk.write(extent.block,
                                    sectors as u16,
                                    mem_to_write as usize);
                    }

                    pos += size as isize;
                    remaining -= size as isize;
                }
            }

            self.dirty = false;

            if remaining > 0 {
                d("Need to reallocate file, extra: ");
                ds(remaining);
                dl();
                return false;
            }
        }
        return true;
    }
}

impl Drop for FileResource {
    fn drop(&mut self) {
        self.flush();
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        } else {
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    } else {
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        } else {
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    //TODO: Handle more extents
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        disk: self.fs.disk,
                        node: node,
                        vec: vec,
                        seek: 0,
                        dirty: false
                    };
                },
                Option::None => {
                    /*
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                    */
                    return box NoneResource;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add PageAllocator.<commit_after><|endoftext|>


<commit_before><commit_msg>Do Not Excude Units in /etc<commit_after><|endoftext|>


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

use std::fmt::Debug;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DepNode<D: Clone + Debug> {
    // The `D` type is "how definitions are identified".
    // During compilation, it is always `DefId`, but when serializing
    // it is mapped to `DefPath`.

    // Represents the `Krate` as a whole (the `hir::Krate` value) (as
    // distinct from the krate module). This is basically a hash of
    // the entire krate, so if you read from `Krate` (e.g., by calling
    // `tcx.map.krate()`), we will have to assume that any change
    // means that you need to be recompiled. This is because the
    // `Krate` value gives you access to all other items. To avoid
    // this fate, do not call `tcx.map.krate()`; instead, prefer
    // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
    // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
    // access to the krate, but you must remember to add suitable
    // edges yourself for the individual items that you read.
    Krate,

    // Represents the HIR node with the given node-id
    Hir(D),

    // Represents different phases in the compiler.
    CrateReader,
    CollectLanguageItems,
    CheckStaticRecursion,
    ResolveLifetimes,
    RegionResolveCrate,
    CheckLoops,
    PluginRegistrar,
    StabilityIndex,
    CollectItem(D),
    Coherence,
    EffectCheck,
    Liveness,
    Resolve,
    EntryPoint,
    CheckEntryFn,
    CoherenceCheckImpl(D),
    CoherenceOverlapCheck(D),
    CoherenceOverlapCheckSpecial(D),
    CoherenceOverlapInherentCheck(D),
    CoherenceOrphanCheck(D),
    Variance,
    WfCheck(D),
    TypeckItemType(D),
    TypeckItemBody(D),
    Dropck,
    DropckImpl(D),
    UnusedTraitCheck,
    CheckConst(D),
    Privacy,
    IntrinsicCheck(D),
    MatchCheck(D),
    MirMapConstruction(D),
    MirPass(D),
    MirTypeck(D),
    BorrowCheck(D),
    RvalueCheck(D),
    Reachability,
    DeadCheck,
    StabilityCheck,
    LateLintCheck,
    TransCrate,
    TransCrateItem(D),
    TransInlinedItem(D),
    TransWriteMetadata,

    // Nodes representing bits of computed IR in the tcx. Each shared
    // table in the tcx (or elsewhere) maps to one of these
    // nodes. Often we map multiple tables to the same node if there
    // is no point in distinguishing them (e.g., both the type and
    // predicates for an item wind up in `ItemSignature`). Other
    // times, such as `ImplItems` vs `TraitItemDefIds`, tables which
    // might be mergable are kept distinct because the sets of def-ids
    // to which they apply are disjoint, and hence we might as well
    // have distinct labels for easier debugging.
    ImplOrTraitItems(D),
    ItemSignature(D),
    FieldTy(D),
    SizedConstraint(D),
    TraitItemDefIds(D),
    InherentImpls(D),
    ImplItems(D),

    // The set of impls for a given trait. Ultimately, it would be
    // nice to get more fine-grained here (e.g., to include a
    // simplified type), but we can't do that until we restructure the
    // HIR to distinguish the *header* of an impl from its body.  This
    // is because changes to the header may change the self-type of
    // the impl and hence would require us to be more conservative
    // than changes in the impl body.
    TraitImpls(D),

    // Nodes representing caches. To properly handle a true cache, we
    // don't use a DepTrackingMap, but rather we push a task node.
    // Otherwise the write into the map would be incorrectly
    // attributed to the first task that happened to fill the cache,
    // which would yield an overly conservative dep-graph.
    TraitItems(D),
    ReprHints(D),
    TraitSelect(D),
}

impl<D: Clone + Debug> DepNode<D> {
    /// Used in testing
    pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
        macro_rules! check {
            ($($name:ident,)*) => {
                match label {
                    $(stringify!($name) => Ok(DepNode::$name(data)),)*
                    _ => Err(())
                }
            }
        }

        check! {
            CollectItem,
            BorrowCheck,
            TransCrateItem,
            TypeckItemType,
            TypeckItemBody,
            ImplOrTraitItems,
            ItemSignature,
            FieldTy,
            TraitItemDefIds,
            InherentImpls,
            ImplItems,
            TraitImpls,
            ReprHints,
        }
    }

    pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
        where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
    {
        use self::DepNode::*;

        match *self {
            Krate => Some(Krate),
            CrateReader => Some(CrateReader),
            CollectLanguageItems => Some(CollectLanguageItems),
            CheckStaticRecursion => Some(CheckStaticRecursion),
            ResolveLifetimes => Some(ResolveLifetimes),
            RegionResolveCrate => Some(RegionResolveCrate),
            CheckLoops => Some(CheckLoops),
            PluginRegistrar => Some(PluginRegistrar),
            StabilityIndex => Some(StabilityIndex),
            Coherence => Some(Coherence),
            EffectCheck => Some(EffectCheck),
            Liveness => Some(Liveness),
            Resolve => Some(Resolve),
            EntryPoint => Some(EntryPoint),
            CheckEntryFn => Some(CheckEntryFn),
            Variance => Some(Variance),
            Dropck => Some(Dropck),
            UnusedTraitCheck => Some(UnusedTraitCheck),
            Privacy => Some(Privacy),
            Reachability => Some(Reachability),
            DeadCheck => Some(DeadCheck),
            StabilityCheck => Some(StabilityCheck),
            LateLintCheck => Some(LateLintCheck),
            TransCrate => Some(TransCrate),
            TransWriteMetadata => Some(TransWriteMetadata),
            Hir(ref d) => op(d).map(Hir),
            CollectItem(ref d) => op(d).map(CollectItem),
            CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
            CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
            CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
            CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
            CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
            WfCheck(ref d) => op(d).map(WfCheck),
            TypeckItemType(ref d) => op(d).map(TypeckItemType),
            TypeckItemBody(ref d) => op(d).map(TypeckItemBody),
            DropckImpl(ref d) => op(d).map(DropckImpl),
            CheckConst(ref d) => op(d).map(CheckConst),
            IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
            MatchCheck(ref d) => op(d).map(MatchCheck),
            MirMapConstruction(ref d) => op(d).map(MirMapConstruction),
            MirPass(ref d) => op(d).map(MirPass),
            MirTypeck(ref d) => op(d).map(MirTypeck),
            BorrowCheck(ref d) => op(d).map(BorrowCheck),
            RvalueCheck(ref d) => op(d).map(RvalueCheck),
            TransCrateItem(ref d) => op(d).map(TransCrateItem),
            TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
            ImplOrTraitItems(ref d) => op(d).map(ImplOrTraitItems),
            ItemSignature(ref d) => op(d).map(ItemSignature),
            FieldTy(ref d) => op(d).map(FieldTy),
            SizedConstraint(ref d) => op(d).map(SizedConstraint),
            TraitItemDefIds(ref d) => op(d).map(TraitItemDefIds),
            InherentImpls(ref d) => op(d).map(InherentImpls),
            ImplItems(ref d) => op(d).map(ImplItems),
            TraitImpls(ref d) => op(d).map(TraitImpls),
            TraitItems(ref d) => op(d).map(TraitItems),
            ReprHints(ref d) => op(d).map(ReprHints),
            TraitSelect(ref d) => op(d).map(TraitSelect),
        }
    }
}
<commit_msg>add MetaData DepNode variant<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt::Debug;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DepNode<D: Clone + Debug> {
    // The `D` type is "how definitions are identified".
    // During compilation, it is always `DefId`, but when serializing
    // it is mapped to `DefPath`.

    // Represents the `Krate` as a whole (the `hir::Krate` value) (as
    // distinct from the krate module). This is basically a hash of
    // the entire krate, so if you read from `Krate` (e.g., by calling
    // `tcx.map.krate()`), we will have to assume that any change
    // means that you need to be recompiled. This is because the
    // `Krate` value gives you access to all other items. To avoid
    // this fate, do not call `tcx.map.krate()`; instead, prefer
    // wrappers like `tcx.visit_all_items_in_krate()`.  If there is no
    // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
    // access to the krate, but you must remember to add suitable
    // edges yourself for the individual items that you read.
    Krate,

    // Represents the HIR node with the given node-id
    Hir(D),

    // Represents the meta-data for a node. For local def-ids, this is
    // created by trans. For remote def-ids, we add a read of this
    // node each time we pull the information for an item out of the
    // crate store.
    MetaData(D),

    // Represents different phases in the compiler.
    CrateReader,
    CollectLanguageItems,
    CheckStaticRecursion,
    ResolveLifetimes,
    RegionResolveCrate,
    CheckLoops,
    PluginRegistrar,
    StabilityIndex,
    CollectItem(D),
    Coherence,
    EffectCheck,
    Liveness,
    Resolve,
    EntryPoint,
    CheckEntryFn,
    CoherenceCheckImpl(D),
    CoherenceOverlapCheck(D),
    CoherenceOverlapCheckSpecial(D),
    CoherenceOverlapInherentCheck(D),
    CoherenceOrphanCheck(D),
    Variance,
    WfCheck(D),
    TypeckItemType(D),
    TypeckItemBody(D),
    Dropck,
    DropckImpl(D),
    UnusedTraitCheck,
    CheckConst(D),
    Privacy,
    IntrinsicCheck(D),
    MatchCheck(D),
    MirMapConstruction(D),
    MirPass(D),
    MirTypeck(D),
    BorrowCheck(D),
    RvalueCheck(D),
    Reachability,
    DeadCheck,
    StabilityCheck,
    LateLintCheck,
    TransCrate,
    TransCrateItem(D),
    TransInlinedItem(D),
    TransWriteMetadata,

    // Nodes representing bits of computed IR in the tcx. Each shared
    // table in the tcx (or elsewhere) maps to one of these
    // nodes. Often we map multiple tables to the same node if there
    // is no point in distinguishing them (e.g., both the type and
    // predicates for an item wind up in `ItemSignature`). Other
    // times, such as `ImplItems` vs `TraitItemDefIds`, tables which
    // might be mergable are kept distinct because the sets of def-ids
    // to which they apply are disjoint, and hence we might as well
    // have distinct labels for easier debugging.
    ImplOrTraitItems(D),
    ItemSignature(D),
    FieldTy(D),
    SizedConstraint(D),
    TraitItemDefIds(D),
    InherentImpls(D),
    ImplItems(D),

    // The set of impls for a given trait. Ultimately, it would be
    // nice to get more fine-grained here (e.g., to include a
    // simplified type), but we can't do that until we restructure the
    // HIR to distinguish the *header* of an impl from its body.  This
    // is because changes to the header may change the self-type of
    // the impl and hence would require us to be more conservative
    // than changes in the impl body.
    TraitImpls(D),

    // Nodes representing caches. To properly handle a true cache, we
    // don't use a DepTrackingMap, but rather we push a task node.
    // Otherwise the write into the map would be incorrectly
    // attributed to the first task that happened to fill the cache,
    // which would yield an overly conservative dep-graph.
    TraitItems(D),
    ReprHints(D),
    TraitSelect(D),
}

impl<D: Clone + Debug> DepNode<D> {
    /// Used in testing
    pub fn from_label_string(label: &str, data: D) -> Result<DepNode<D>, ()> {
        macro_rules! check {
            ($($name:ident,)*) => {
                match label {
                    $(stringify!($name) => Ok(DepNode::$name(data)),)*
                    _ => Err(())
                }
            }
        }

        check! {
            CollectItem,
            BorrowCheck,
            TransCrateItem,
            TypeckItemType,
            TypeckItemBody,
            ImplOrTraitItems,
            ItemSignature,
            FieldTy,
            TraitItemDefIds,
            InherentImpls,
            ImplItems,
            TraitImpls,
            ReprHints,
        }
    }

    pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
        where OP: FnMut(&D) -> Option<E>, E: Clone + Debug
    {
        use self::DepNode::*;

        match *self {
            Krate => Some(Krate),
            CrateReader => Some(CrateReader),
            CollectLanguageItems => Some(CollectLanguageItems),
            CheckStaticRecursion => Some(CheckStaticRecursion),
            ResolveLifetimes => Some(ResolveLifetimes),
            RegionResolveCrate => Some(RegionResolveCrate),
            CheckLoops => Some(CheckLoops),
            PluginRegistrar => Some(PluginRegistrar),
            StabilityIndex => Some(StabilityIndex),
            Coherence => Some(Coherence),
            EffectCheck => Some(EffectCheck),
            Liveness => Some(Liveness),
            Resolve => Some(Resolve),
            EntryPoint => Some(EntryPoint),
            CheckEntryFn => Some(CheckEntryFn),
            Variance => Some(Variance),
            Dropck => Some(Dropck),
            UnusedTraitCheck => Some(UnusedTraitCheck),
            Privacy => Some(Privacy),
            Reachability => Some(Reachability),
            DeadCheck => Some(DeadCheck),
            StabilityCheck => Some(StabilityCheck),
            LateLintCheck => Some(LateLintCheck),
            TransCrate => Some(TransCrate),
            TransWriteMetadata => Some(TransWriteMetadata),
            Hir(ref d) => op(d).map(Hir),
            CollectItem(ref d) => op(d).map(CollectItem),
            CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
            CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
            CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
            CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
            CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
            WfCheck(ref d) => op(d).map(WfCheck),
            TypeckItemType(ref d) => op(d).map(TypeckItemType),
            TypeckItemBody(ref d) => op(d).map(TypeckItemBody),
            DropckImpl(ref d) => op(d).map(DropckImpl),
            CheckConst(ref d) => op(d).map(CheckConst),
            IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
            MatchCheck(ref d) => op(d).map(MatchCheck),
            MirMapConstruction(ref d) => op(d).map(MirMapConstruction),
            MirPass(ref d) => op(d).map(MirPass),
            MirTypeck(ref d) => op(d).map(MirTypeck),
            BorrowCheck(ref d) => op(d).map(BorrowCheck),
            RvalueCheck(ref d) => op(d).map(RvalueCheck),
            TransCrateItem(ref d) => op(d).map(TransCrateItem),
            TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
            ImplOrTraitItems(ref d) => op(d).map(ImplOrTraitItems),
            ItemSignature(ref d) => op(d).map(ItemSignature),
            FieldTy(ref d) => op(d).map(FieldTy),
            SizedConstraint(ref d) => op(d).map(SizedConstraint),
            TraitItemDefIds(ref d) => op(d).map(TraitItemDefIds),
            InherentImpls(ref d) => op(d).map(InherentImpls),
            ImplItems(ref d) => op(d).map(ImplItems),
            TraitImpls(ref d) => op(d).map(TraitImpls),
            TraitItems(ref d) => op(d).map(TraitItems),
            ReprHints(ref d) => op(d).map(ReprHints),
            TraitSelect(ref d) => op(d).map(TraitSelect),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added Default implementation for PropertyDescriptor<commit_after>use jsapi::PropertyDescriptor
use jsapi::UndefinedValue
use std::ptr::null

impl Default for PropertyDescriptor {
    fn defuault() -> PropertyDescriptor {
        PropertyDescriptor {null, 0, None, None, UndefinedValue()}
    }
}<|endoftext|>


<commit_before><commit_msg>Add test<commit_after><|endoftext|>


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

#[cfg_attr(all(), path = "nonexistent_file.rs")] mod foo;
//~^ ERROR nonexistent_file.rs
<|endoftext|>


<commit_before><commit_msg>Add test for issue 3033<commit_after>use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerBinding::
    BluetoothRemoteGATTServerMethods;
<|endoftext|>


<commit_before><commit_msg>Quick first pass on parser testing<commit_after>use super::parse_module;

use core::semantic::ASTNode;

#[test]
fn test_basic_parse() {
    assert_eq!( parse_module("(+ 1 2)")
                    .unwrap()[0]
                    .to_sexpr(0)
              , "(+ 1 2)" )
}
<|endoftext|>


<commit_before>//!Router asigns handlers to paths and resolves them per request
pub use self::http_router::HttpRouter;
pub use self::request_handler::{RequestHandler, ResponseFinalizer};
pub use self::router::{Router, Route, RouteResult};
mod http_router;
mod request_handler;

mod router;

/// The path_utils collects some small helper methods that operate on the path
mod path_utils {
    use regex::Regex;
    use std::collections::hashmap::HashMap;

    // matches named variables (e.g. :userid)
    static REGEX_VAR_SEQ: Regex                 = regex!(r":([,a-zA-Z0-9_-]*)");
    static VAR_SEQ:&'static str                 = "[,a-zA-Z0-9_-]*";
    static VAR_SEQ_WITH_SLASH:&'static str      = "[,/a-zA-Z0-9_-]*";
    static VAR_SEQ_WITH_CAPTURE:&'static str    = "([,a-zA-Z0-9%_-]*)";
    // matches request params (e.g. ?foo=true&bar=false)
    static REGEX_PARAM_SEQ:&'static str         = "(\\?[a-zA-Z0-9%_=&-]*)?";
    static REGEX_START:&'static str             = "^";
    static REGEX_END:&'static str               = "$";
    pub fn create_regex (route_path: &str) -> Regex {
        let updated_path =
            route_path.to_string()
                      // first mark all double wildcards for replacement.
                      // We can't directly replace them since the replacement
                      // does contain the * symbol as well, which would get
                      // overwritten with the next replace call
                      .replace("**", "___DOUBLE_WILDCARD___")
                      // then replace the regular wildcard symbols (*) with the
                      // appropriate regex
                      .replace("*", VAR_SEQ)
                      // now replace the previously marked double wild cards (**)
                      .replace("___DOUBLE_WILDCARD___", VAR_SEQ_WITH_SLASH);

        // then replace the variable symbols (:variable) with the appropriate regex
        let result = [REGEX_START,
                      REGEX_VAR_SEQ.replace_all(updated_path.as_slice(),
                                                VAR_SEQ_WITH_CAPTURE)
                                   .as_slice(),
                      REGEX_PARAM_SEQ,
                      REGEX_END].concat();

        Regex::new(result.as_slice()).ok().unwrap()
    }

    pub fn get_variable_info (route_path: &str) -> HashMap<String, uint> {
        REGEX_VAR_SEQ.captures_iter(route_path)
             .enumerate()
             .map(|(i, matched)| (matched.at(1).to_string(), i))
             .collect()
    }
}
<commit_msg>fix(router): handle changes to trait resolution<commit_after>//!Router asigns handlers to paths and resolves them per request
pub use self::http_router::HttpRouter;
pub use self::request_handler::{RequestHandler, ResponseFinalizer};
pub use self::router::{Router, Route, RouteResult};
pub mod http_router;
pub mod request_handler;

pub mod router;

/// The path_utils collects some small helper methods that operate on the path
mod path_utils {
    use regex::Regex;
    use std::collections::hashmap::HashMap;

    // matches named variables (e.g. :userid)
    static REGEX_VAR_SEQ: Regex                 = regex!(r":([,a-zA-Z0-9_-]*)");
    static VAR_SEQ:&'static str                 = "[,a-zA-Z0-9_-]*";
    static VAR_SEQ_WITH_SLASH:&'static str      = "[,/a-zA-Z0-9_-]*";
    static VAR_SEQ_WITH_CAPTURE:&'static str    = "([,a-zA-Z0-9%_-]*)";
    // matches request params (e.g. ?foo=true&bar=false)
    static REGEX_PARAM_SEQ:&'static str         = "(\\?[a-zA-Z0-9%_=&-]*)?";
    static REGEX_START:&'static str             = "^";
    static REGEX_END:&'static str               = "$";
    pub fn create_regex (route_path: &str) -> Regex {
        let updated_path =
            route_path.to_string()
                      // first mark all double wildcards for replacement.
                      // We can't directly replace them since the replacement
                      // does contain the * symbol as well, which would get
                      // overwritten with the next replace call
                      .replace("**", "___DOUBLE_WILDCARD___")
                      // then replace the regular wildcard symbols (*) with the
                      // appropriate regex
                      .replace("*", VAR_SEQ)
                      // now replace the previously marked double wild cards (**)
                      .replace("___DOUBLE_WILDCARD___", VAR_SEQ_WITH_SLASH);

        // then replace the variable symbols (:variable) with the appropriate regex
        let result = [REGEX_START,
                      REGEX_VAR_SEQ.replace_all(updated_path.as_slice(),
                                                VAR_SEQ_WITH_CAPTURE)
                                   .as_slice(),
                      REGEX_PARAM_SEQ,
                      REGEX_END].concat();

        Regex::new(result.as_slice()).ok().unwrap()
    }

    pub fn get_variable_info (route_path: &str) -> HashMap<String, uint> {
        REGEX_VAR_SEQ.captures_iter(route_path)
             .enumerate()
             .map(|(i, matched)| (matched.at(1).to_string(), i))
             .collect()
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a 'dump' example program.<commit_after>extern crate mp4parse;

use std::fs::File;

fn main() {
    let mut f = File::open("test.mp4").unwrap();
    let h = mp4parse::read_box(&mut f).unwrap();
    println!("{}", h);
}
<|endoftext|>