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

//! The compiler code necessary to implement the `#[derive]` extensions.

use syntax::ast::{self, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate;
use syntax::codemap;
use syntax::parse::token::{intern, intern_and_get_ident};
use syntax::ptr::P;
use syntax_pos::Span;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

macro_rules! path_std {
    ($($x:tt)*) => (
        ::deriving::generic::ty::Path::new( pathvec_std!( $($x)* ) )
    )
}

pub mod bounds;
pub mod clone;
pub mod encodable;
pub mod decodable;
pub mod hash;
pub mod debug;
pub mod default;
pub mod custom;

#[path="cmp/partial_eq.rs"]
pub mod partial_eq;
#[path="cmp/eq.rs"]
pub mod eq;
#[path="cmp/partial_ord.rs"]
pub mod partial_ord;
#[path="cmp/ord.rs"]
pub mod ord;

pub mod generic;

fn allow_unstable(cx: &mut ExtCtxt, span: Span, attr_name: &str) -> Span {
    Span {
        expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
            call_site: span,
            callee: codemap::NameAndSpan {
                format: codemap::MacroAttribute(intern(attr_name)),
                span: Some(span),
                allow_internal_unstable: true,
            },
        }),
        ..span
    }
}

pub fn expand_derive(cx: &mut ExtCtxt,
                 span: Span,
                 mitem: &MetaItem,
                 annotatable: Annotatable)
                 -> Vec<Annotatable> {
    debug!("expand_derive: span = {:?}", span);
    debug!("expand_derive: mitem = {:?}", mitem);
    debug!("expand_derive: annotatable input  = {:?}", annotatable);
    let mut item = match annotatable {
        Annotatable::Item(item) => item,
        other => {
            cx.span_err(span, "`derive` can only be applied to items");
            return vec![other]
        }
    };

    if mitem.value_str().is_some() {
        cx.span_err(mitem.span, "unexpected value in `derive`");
    }

    let mut traits = mitem.meta_item_list().unwrap_or(&[]).to_owned();
    if traits.is_empty() {
        cx.span_warn(mitem.span, "empty trait list in `derive`");
    }

    // First, weed out malformed #[derive]
    traits.retain(|titem| {
        if titem.word().is_none() {
            cx.span_err(titem.span, "malformed `derive` entry");
            false
        } else {
            true
        }
    });

    // Next, check for old-style #[derive(Foo)]
    //
    // These all get expanded to `#[derive_Foo]` and will get expanded first. If
    // we actually add any attributes here then we return to get those expanded
    // and then eventually we'll come back to finish off the other derive modes.
    let mut new_attributes = Vec::new();
    traits.retain(|titem| {
        let tword = titem.word().unwrap();
        let tname = tword.name();

        let derive_mode = ast::Ident::with_empty_ctxt(intern(&tname));
        let derive_mode = cx.resolver.resolve_derive_mode(derive_mode);
        if is_builtin_trait(&tname) || derive_mode.is_some() {
            return true
        }

        if !cx.ecfg.enable_custom_derive() {
            feature_gate::emit_feature_err(&cx.parse_sess,
                                           "custom_derive",
                                           titem.span,
                                           feature_gate::GateIssue::Language,
                                           feature_gate::EXPLAIN_CUSTOM_DERIVE);
        } else {
            let name = intern_and_get_ident(&format!("derive_{}", tname));
            let mitem = cx.meta_word(titem.span, name);
            new_attributes.push(cx.attribute(mitem.span, mitem));
        }
        false
    });
    if new_attributes.len() > 0 {
        item = item.map(|mut i| {
            let list = cx.meta_list(mitem.span,
                                    intern_and_get_ident("derive"),
                                    traits);
            i.attrs.extend(new_attributes);
            i.attrs.push(cx.attribute(mitem.span, list));
            i
        });
        return vec![Annotatable::Item(item)]
    }

    // Now check for macros-1.1 style custom #[derive].
    //
    // Expand each of them in order given, but *before* we expand any built-in
    // derive modes. The logic here is to:
    //
    // 1. Collect the remaining `#[derive]` annotations into a list. If
    //    there are any left, attach a `#[derive]` attribute to the item
    //    that we're currently expanding with the remaining derive modes.
    // 2. Manufacture a `#[derive(Foo)]` attribute to pass to the expander.
    // 3. Expand the current item we're expanding, getting back a list of
    //    items that replace it.
    // 4. Extend the returned list with the current list of items we've
    //    collected so far.
    // 5. Return everything!
    //
    // If custom derive extensions end up threading through the `#[derive]`
    // attribute, we'll get called again later on to continue expanding
    // those modes.
    let macros_11_derive = traits.iter()
                                 .cloned()
                                 .enumerate()
                                 .filter(|&(_, ref name)| !is_builtin_trait(&name.name().unwrap()))
                                 .next();
    if let Some((i, titem)) = macros_11_derive {
        let tname = ast::Ident::with_empty_ctxt(intern(&titem.name().unwrap()));
        let ext = cx.resolver.resolve_derive_mode(tname).unwrap();
        traits.remove(i);
        if traits.len() > 0 {
            item = item.map(|mut i| {
                let list = cx.meta_list(mitem.span,
                                        intern_and_get_ident("derive"),
                                        traits);
                i.attrs.push(cx.attribute(mitem.span, list));
                i
            });
        }
        let titem = cx.meta_list_item_word(titem.span, titem.name().unwrap());
        let mitem = cx.meta_list(titem.span,
                                 intern_and_get_ident("derive"),
                                 vec![titem]);
        let item = Annotatable::Item(item);
        return ext.expand(cx, mitem.span, &mitem, item)
    }

    // Ok, at this point we know that there are no old-style `#[derive_Foo]` nor
    // any macros-1.1 style `#[derive(Foo)]`. Expand all built-in traits here.

    // RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
    // `#[structural_match]` attribute.
    if traits.iter().filter_map(|t| t.name()).any(|t| t == "PartialEq") &&
       traits.iter().filter_map(|t| t.name()).any(|t| t == "Eq") {
        let structural_match = intern_and_get_ident("structural_match");
        let span = allow_unstable(cx, span, "derive(PartialEq, Eq)");
        let meta = cx.meta_word(span, structural_match);
        item = item.map(|mut i| {
            i.attrs.push(cx.attribute(span, meta));
            i
        });
    }

    // RFC #1521. `Clone` can assume that `Copy` types' clone implementation is
    // the same as the copy implementation.
    //
    // Add a marker attribute here picked up during #[derive(Clone)]
    if traits.iter().filter_map(|t| t.name()).any(|t| t == "Clone") &&
       traits.iter().filter_map(|t| t.name()).any(|t| t == "Copy") {
        let marker = intern_and_get_ident("rustc_copy_clone_marker");
        let span = allow_unstable(cx, span, "derive(Copy, Clone)");
        let meta = cx.meta_word(span, marker);
        item = item.map(|mut i| {
            i.attrs.push(cx.attribute(span, meta));
            i
        });
    }

    let mut items = Vec::new();
    for titem in traits.iter() {
        let tname = titem.word().unwrap().name();
        let name = intern_and_get_ident(&format!("derive({})", tname));
        let mitem = cx.meta_word(titem.span, name);

        let span = Span {
            expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
                call_site: titem.span,
                callee: codemap::NameAndSpan {
                    format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
                    span: Some(titem.span),
                    allow_internal_unstable: true,
                },
            }),
            ..titem.span
        };

        let my_item = Annotatable::Item(item);
        expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| {
            items.push(a);
        });
        item = my_item.expect_item();
    }

    items.insert(0, Annotatable::Item(item));
    return items
}

macro_rules! derive_traits {
    ($( $name:expr => $func:path, )+) => {
        pub fn is_builtin_trait(name: &str) -> bool {
            match name {
                $( $name )|+ => true,
                _ => false,
            }
        }

        fn expand_builtin(name: &str,
                          ecx: &mut ExtCtxt,
                          span: Span,
                          mitem: &MetaItem,
                          item: &Annotatable,
                          push: &mut FnMut(Annotatable)) {
            match name {
                $(
                    $name => {
                        warn_if_deprecated(ecx, span, $name);
                        $func(ecx, span, mitem, item, push);
                    }
                )*
                _ => panic!("not a builtin derive mode: {}", name),
            }
        }
    }
}

derive_traits! {
    "Clone" => clone::expand_deriving_clone,

    "Hash" => hash::expand_deriving_hash,

    "RustcEncodable" => encodable::expand_deriving_rustc_encodable,

    "RustcDecodable" => decodable::expand_deriving_rustc_decodable,

    "PartialEq" => partial_eq::expand_deriving_partial_eq,
    "Eq" => eq::expand_deriving_eq,
    "PartialOrd" => partial_ord::expand_deriving_partial_ord,
    "Ord" => ord::expand_deriving_ord,

    "Debug" => debug::expand_deriving_debug,

    "Default" => default::expand_deriving_default,

    "Send" => bounds::expand_deriving_unsafe_bound,
    "Sync" => bounds::expand_deriving_unsafe_bound,
    "Copy" => bounds::expand_deriving_copy,

    // deprecated
    "Encodable" => encodable::expand_deriving_encodable,
    "Decodable" => decodable::expand_deriving_decodable,
}

#[inline] // because `name` is a compile-time constant
fn warn_if_deprecated(ecx: &mut ExtCtxt, sp: Span, name: &str) {
    if let Some(replacement) = match name {
        "Encodable" => Some("RustcEncodable"),
        "Decodable" => Some("RustcDecodable"),
        _ => None,
    } {
        ecx.span_warn(sp,
                      &format!("derive({}) is deprecated in favor of derive({})",
                               name,
                               replacement));
    }
}

/// Construct a name for the inner type parameter that can't collide with any type parameters of
/// the item. This is achieved by starting with a base and then concatenating the names of all
/// other type parameters.
// FIXME(aburka): use real hygiene when that becomes possible
fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
    let mut typaram = String::from(base);
    if let Annotatable::Item(ref item) = *item {
        match item.node {
            ast::ItemKind::Struct(_, ast::Generics { ref ty_params, .. }) |
            ast::ItemKind::Enum(_, ast::Generics { ref ty_params, .. }) => {
                for ty in ty_params.iter() {
                    typaram.push_str(&ty.ident.name.as_str());
                }
            }

            _ => {}
        }
    }

    typaram
}

/// Constructs an expression that calls an intrinsic
fn call_intrinsic(cx: &ExtCtxt,
                  mut span: Span,
                  intrinsic: &str,
                  args: Vec<P<ast::Expr>>)
                  -> P<ast::Expr> {
    span.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
        call_site: span,
        callee: codemap::NameAndSpan {
            format: codemap::MacroAttribute(intern("derive")),
            span: Some(span),
            allow_internal_unstable: true,
        },
    });

    let path = cx.std_path(&["intrinsics", intrinsic]);
    let call = cx.expr_call_global(span, path, args);

    cx.expr_block(P(ast::Block {
        stmts: vec![cx.stmt_expr(call)],
        id: ast::DUMMY_NODE_ID,
        rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
        span: span,
    }))
}
<commit_msg>Do not add an empty #[derive()] list in expand_derive (fixes #37033)<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The compiler code necessary to implement the `#[derive]` extensions.

use syntax::ast::{self, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate;
use syntax::codemap;
use syntax::parse::token::{intern, intern_and_get_ident};
use syntax::ptr::P;
use syntax_pos::Span;

macro_rules! pathvec {
    ($($x:ident)::+) => (
        vec![ $( stringify!($x) ),+ ]
    )
}

macro_rules! path {
    ($($x:tt)*) => (
        ::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
    )
}

macro_rules! path_local {
    ($x:ident) => (
        ::deriving::generic::ty::Path::new_local(stringify!($x))
    )
}

macro_rules! pathvec_std {
    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
        let mut v = pathvec!($($rest)::+);
        if let Some(s) = $cx.crate_root {
            v.insert(0, s);
        }
        v
    })
}

macro_rules! path_std {
    ($($x:tt)*) => (
        ::deriving::generic::ty::Path::new( pathvec_std!( $($x)* ) )
    )
}

pub mod bounds;
pub mod clone;
pub mod encodable;
pub mod decodable;
pub mod hash;
pub mod debug;
pub mod default;
pub mod custom;

#[path="cmp/partial_eq.rs"]
pub mod partial_eq;
#[path="cmp/eq.rs"]
pub mod eq;
#[path="cmp/partial_ord.rs"]
pub mod partial_ord;
#[path="cmp/ord.rs"]
pub mod ord;

pub mod generic;

fn allow_unstable(cx: &mut ExtCtxt, span: Span, attr_name: &str) -> Span {
    Span {
        expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
            call_site: span,
            callee: codemap::NameAndSpan {
                format: codemap::MacroAttribute(intern(attr_name)),
                span: Some(span),
                allow_internal_unstable: true,
            },
        }),
        ..span
    }
}

pub fn expand_derive(cx: &mut ExtCtxt,
                 span: Span,
                 mitem: &MetaItem,
                 annotatable: Annotatable)
                 -> Vec<Annotatable> {
    debug!("expand_derive: span = {:?}", span);
    debug!("expand_derive: mitem = {:?}", mitem);
    debug!("expand_derive: annotatable input  = {:?}", annotatable);
    let mut item = match annotatable {
        Annotatable::Item(item) => item,
        other => {
            cx.span_err(span, "`derive` can only be applied to items");
            return vec![other]
        }
    };

    if mitem.value_str().is_some() {
        cx.span_err(mitem.span, "unexpected value in `derive`");
    }

    let mut traits = mitem.meta_item_list().unwrap_or(&[]).to_owned();
    if traits.is_empty() {
        cx.span_warn(mitem.span, "empty trait list in `derive`");
    }

    // First, weed out malformed #[derive]
    traits.retain(|titem| {
        if titem.word().is_none() {
            cx.span_err(titem.span, "malformed `derive` entry");
            false
        } else {
            true
        }
    });

    // Next, check for old-style #[derive(Foo)]
    //
    // These all get expanded to `#[derive_Foo]` and will get expanded first. If
    // we actually add any attributes here then we return to get those expanded
    // and then eventually we'll come back to finish off the other derive modes.
    let mut new_attributes = Vec::new();
    traits.retain(|titem| {
        let tword = titem.word().unwrap();
        let tname = tword.name();

        let derive_mode = ast::Ident::with_empty_ctxt(intern(&tname));
        let derive_mode = cx.resolver.resolve_derive_mode(derive_mode);
        if is_builtin_trait(&tname) || derive_mode.is_some() {
            return true
        }

        if !cx.ecfg.enable_custom_derive() {
            feature_gate::emit_feature_err(&cx.parse_sess,
                                           "custom_derive",
                                           titem.span,
                                           feature_gate::GateIssue::Language,
                                           feature_gate::EXPLAIN_CUSTOM_DERIVE);
        } else {
            let name = intern_and_get_ident(&format!("derive_{}", tname));
            let mitem = cx.meta_word(titem.span, name);
            new_attributes.push(cx.attribute(mitem.span, mitem));
        }
        false
    });
    if new_attributes.len() > 0 {
        item = item.map(|mut i| {
            i.attrs.extend(new_attributes);
            if traits.len() > 0 {
                let list = cx.meta_list(mitem.span,
                                        intern_and_get_ident("derive"),
                                        traits);
                i.attrs.push(cx.attribute(mitem.span, list));
            }
            i
        });
        return vec![Annotatable::Item(item)]
    }

    // Now check for macros-1.1 style custom #[derive].
    //
    // Expand each of them in order given, but *before* we expand any built-in
    // derive modes. The logic here is to:
    //
    // 1. Collect the remaining `#[derive]` annotations into a list. If
    //    there are any left, attach a `#[derive]` attribute to the item
    //    that we're currently expanding with the remaining derive modes.
    // 2. Manufacture a `#[derive(Foo)]` attribute to pass to the expander.
    // 3. Expand the current item we're expanding, getting back a list of
    //    items that replace it.
    // 4. Extend the returned list with the current list of items we've
    //    collected so far.
    // 5. Return everything!
    //
    // If custom derive extensions end up threading through the `#[derive]`
    // attribute, we'll get called again later on to continue expanding
    // those modes.
    let macros_11_derive = traits.iter()
                                 .cloned()
                                 .enumerate()
                                 .filter(|&(_, ref name)| !is_builtin_trait(&name.name().unwrap()))
                                 .next();
    if let Some((i, titem)) = macros_11_derive {
        let tname = ast::Ident::with_empty_ctxt(intern(&titem.name().unwrap()));
        let ext = cx.resolver.resolve_derive_mode(tname).unwrap();
        traits.remove(i);
        if traits.len() > 0 {
            item = item.map(|mut i| {
                let list = cx.meta_list(mitem.span,
                                        intern_and_get_ident("derive"),
                                        traits);
                i.attrs.push(cx.attribute(mitem.span, list));
                i
            });
        }
        let titem = cx.meta_list_item_word(titem.span, titem.name().unwrap());
        let mitem = cx.meta_list(titem.span,
                                 intern_and_get_ident("derive"),
                                 vec![titem]);
        let item = Annotatable::Item(item);
        return ext.expand(cx, mitem.span, &mitem, item)
    }

    // Ok, at this point we know that there are no old-style `#[derive_Foo]` nor
    // any macros-1.1 style `#[derive(Foo)]`. Expand all built-in traits here.

    // RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
    // `#[structural_match]` attribute.
    if traits.iter().filter_map(|t| t.name()).any(|t| t == "PartialEq") &&
       traits.iter().filter_map(|t| t.name()).any(|t| t == "Eq") {
        let structural_match = intern_and_get_ident("structural_match");
        let span = allow_unstable(cx, span, "derive(PartialEq, Eq)");
        let meta = cx.meta_word(span, structural_match);
        item = item.map(|mut i| {
            i.attrs.push(cx.attribute(span, meta));
            i
        });
    }

    // RFC #1521. `Clone` can assume that `Copy` types' clone implementation is
    // the same as the copy implementation.
    //
    // Add a marker attribute here picked up during #[derive(Clone)]
    if traits.iter().filter_map(|t| t.name()).any(|t| t == "Clone") &&
       traits.iter().filter_map(|t| t.name()).any(|t| t == "Copy") {
        let marker = intern_and_get_ident("rustc_copy_clone_marker");
        let span = allow_unstable(cx, span, "derive(Copy, Clone)");
        let meta = cx.meta_word(span, marker);
        item = item.map(|mut i| {
            i.attrs.push(cx.attribute(span, meta));
            i
        });
    }

    let mut items = Vec::new();
    for titem in traits.iter() {
        let tname = titem.word().unwrap().name();
        let name = intern_and_get_ident(&format!("derive({})", tname));
        let mitem = cx.meta_word(titem.span, name);

        let span = Span {
            expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
                call_site: titem.span,
                callee: codemap::NameAndSpan {
                    format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
                    span: Some(titem.span),
                    allow_internal_unstable: true,
                },
            }),
            ..titem.span
        };

        let my_item = Annotatable::Item(item);
        expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| {
            items.push(a);
        });
        item = my_item.expect_item();
    }

    items.insert(0, Annotatable::Item(item));
    return items
}

macro_rules! derive_traits {
    ($( $name:expr => $func:path, )+) => {
        pub fn is_builtin_trait(name: &str) -> bool {
            match name {
                $( $name )|+ => true,
                _ => false,
            }
        }

        fn expand_builtin(name: &str,
                          ecx: &mut ExtCtxt,
                          span: Span,
                          mitem: &MetaItem,
                          item: &Annotatable,
                          push: &mut FnMut(Annotatable)) {
            match name {
                $(
                    $name => {
                        warn_if_deprecated(ecx, span, $name);
                        $func(ecx, span, mitem, item, push);
                    }
                )*
                _ => panic!("not a builtin derive mode: {}", name),
            }
        }
    }
}

derive_traits! {
    "Clone" => clone::expand_deriving_clone,

    "Hash" => hash::expand_deriving_hash,

    "RustcEncodable" => encodable::expand_deriving_rustc_encodable,

    "RustcDecodable" => decodable::expand_deriving_rustc_decodable,

    "PartialEq" => partial_eq::expand_deriving_partial_eq,
    "Eq" => eq::expand_deriving_eq,
    "PartialOrd" => partial_ord::expand_deriving_partial_ord,
    "Ord" => ord::expand_deriving_ord,

    "Debug" => debug::expand_deriving_debug,

    "Default" => default::expand_deriving_default,

    "Send" => bounds::expand_deriving_unsafe_bound,
    "Sync" => bounds::expand_deriving_unsafe_bound,
    "Copy" => bounds::expand_deriving_copy,

    // deprecated
    "Encodable" => encodable::expand_deriving_encodable,
    "Decodable" => decodable::expand_deriving_decodable,
}

#[inline] // because `name` is a compile-time constant
fn warn_if_deprecated(ecx: &mut ExtCtxt, sp: Span, name: &str) {
    if let Some(replacement) = match name {
        "Encodable" => Some("RustcEncodable"),
        "Decodable" => Some("RustcDecodable"),
        _ => None,
    } {
        ecx.span_warn(sp,
                      &format!("derive({}) is deprecated in favor of derive({})",
                               name,
                               replacement));
    }
}

/// Construct a name for the inner type parameter that can't collide with any type parameters of
/// the item. This is achieved by starting with a base and then concatenating the names of all
/// other type parameters.
// FIXME(aburka): use real hygiene when that becomes possible
fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
    let mut typaram = String::from(base);
    if let Annotatable::Item(ref item) = *item {
        match item.node {
            ast::ItemKind::Struct(_, ast::Generics { ref ty_params, .. }) |
            ast::ItemKind::Enum(_, ast::Generics { ref ty_params, .. }) => {
                for ty in ty_params.iter() {
                    typaram.push_str(&ty.ident.name.as_str());
                }
            }

            _ => {}
        }
    }

    typaram
}

/// Constructs an expression that calls an intrinsic
fn call_intrinsic(cx: &ExtCtxt,
                  mut span: Span,
                  intrinsic: &str,
                  args: Vec<P<ast::Expr>>)
                  -> P<ast::Expr> {
    span.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
        call_site: span,
        callee: codemap::NameAndSpan {
            format: codemap::MacroAttribute(intern("derive")),
            span: Some(span),
            allow_internal_unstable: true,
        },
    });

    let path = cx.std_path(&["intrinsics", intrinsic]);
    let call = cx.expr_call_global(span, path, args);

    cx.expr_block(P(ast::Block {
        stmts: vec![cx.stmt_expr(call)],
        id: ast::DUMMY_NODE_ID,
        rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
        span: span,
    }))
}
<|endoftext|>


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

fn main() {
    if false { test(); }
}

fn test() {
    let rx = Err::<Vec<usize>, u32>(1).into_future();

    rx.map(|l: Vec<usize>| stream::iter(l.into_iter().map(|i| Ok(i))))
      .flatten_stream()
      .chunks(50)
      .buffer_unordered(5);
}

use future::{Future, IntoFuture};
mod future {
    use std::result;

    use {stream, Stream};

    pub trait Future {
        type Item;
        type Error;

        fn map<F, U>(self, _: F) -> Map<Self, F>
            where F: FnOnce(Self::Item) -> U,
                  Self: Sized,
        {
            panic!()
        }

        fn flatten_stream(self) -> FlattenStream<Self>
            where <Self as Future>::Item: stream::Stream<Error=Self::Error>,
                  Self: Sized
        {
            panic!()
        }
    }

    pub trait IntoFuture {
        type Future: Future<Item=Self::Item, Error=Self::Error>;
        type Item;
        type Error;
        fn into_future(self) -> Self::Future;
    }

    impl<F: Future> IntoFuture for F {
        type Future = F;
        type Item = F::Item;
        type Error = F::Error;

        fn into_future(self) -> F {
            panic!()
        }
    }

    impl<T, E> IntoFuture for result::Result<T, E> {
        type Future = FutureResult<T, E>;
        type Item = T;
        type Error = E;

        fn into_future(self) -> FutureResult<T, E> {
            panic!()
        }
    }

    pub struct Map<A, F> {
        _a: (A, F),
    }

    impl<U, A, F> Future for Map<A, F>
        where A: Future,
              F: FnOnce(A::Item) -> U,
    {
        type Item = U;
        type Error = A::Error;
    }

    pub struct FlattenStream<F> {
        _f: F,
    }

    impl<F> Stream for FlattenStream<F>
        where F: Future,
              <F as Future>::Item: Stream<Error=F::Error>,
    {
        type Item = <F::Item as Stream>::Item;
        type Error = <F::Item as Stream>::Error;
    }

    pub struct FutureResult<T, E> {
        _inner: (T, E),
    }

    impl<T, E> Future for FutureResult<T, E> {
        type Item = T;
        type Error = E;
    }
}

mod stream {
    use IntoFuture;

    pub trait Stream {
        type Item;
        type Error;

        fn buffer_unordered(self, amt: usize) -> BufferUnordered<Self>
            where Self::Item: IntoFuture<Error = <Self as Stream>::Error>,
                  Self: Sized
        {
            new(self, amt)
        }

        fn chunks(self, _capacity: usize) -> Chunks<Self>
            where Self: Sized
        {
            panic!()
        }
    }

    pub struct IterStream<I> {
        _iter: I,
    }

    pub fn iter<J, T, E>(_: J) -> IterStream<J::IntoIter>
        where J: IntoIterator<Item=Result<T, E>>,
    {
        panic!()
    }

    impl<I, T, E> Stream for IterStream<I>
        where I: Iterator<Item=Result<T, E>>,
    {
        type Item = T;
        type Error = E;
    }

    pub struct Chunks<S> {
        _stream: S
    }

    impl<S> Stream for Chunks<S>
        where S: Stream
    {
        type Item = Result<Vec<<S as Stream>::Item>, u32>;
        type Error = <S as Stream>::Error;
    }

    pub struct BufferUnordered<S> {
        _stream: S,
    }

    enum Slot<T> {
        Next(usize),
        _Data { _a: T },
    }

    fn new<S>(_s: S, _amt: usize) -> BufferUnordered<S>
        where S: Stream,
              S::Item: IntoFuture<Error=<S as Stream>::Error>,
    {
        (0..0).map(|_| {
            Slot::Next::<<S::Item as IntoFuture>::Future>(1)
        }).collect::<Vec<_>>();
        panic!()
    }

    impl<S> Stream for BufferUnordered<S>
        where S: Stream,
              S::Item: IntoFuture<Error=<S as Stream>::Error>,
    {
        type Item = <S::Item as IntoFuture>::Item;
        type Error = <S as Stream>::Error;
    }
}
use stream::Stream;
<|endoftext|>


<commit_before><commit_msg>Add ThreadSanitizer test case<commit_after>// Verifies that ThreadSanitizer is able to detect a data race in heap allocated
// memory block.
//
// Test case minimizes the use of the standard library to avoid its ambiguous
// status with respect to instrumentation (it could vary depending on whatever
// a function call is inlined or not).
//
// The conflicting data access is de-facto synchronized with a special TSAN
// barrier, which does not introduce synchronization from TSAN perspective, but
// is necessary to make the test robust. Without the barrier data race detection
// would occasionally fail, making test flaky.
//
// needs-sanitizer-support
// only-x86_64
//
// compile-flags: -Z sanitizer=thread -O
//
// run-fail
// error-pattern: WARNING: ThreadSanitizer: data race
// error-pattern: Location is heap block of size 4
// error-pattern: allocated by main thread

#![feature(raw_ref_op)]
#![feature(rustc_private)]
extern crate libc;

use std::mem;
use std::ptr;

static mut BARRIER: u64 = 0;

extern "C" {
    fn __tsan_testonly_barrier_init(barrier: *mut u64, count: u32);
    fn __tsan_testonly_barrier_wait(barrier: *mut u64);
}

extern "C" fn start(c: *mut libc::c_void) -> *mut libc::c_void {
    unsafe {
        let c: *mut u32 = c.cast();
        *c += 1;
        __tsan_testonly_barrier_wait(&raw mut BARRIER);
        ptr::null_mut()
    }
}

fn main() {
    unsafe {
        __tsan_testonly_barrier_init(&raw mut BARRIER, 2);
        let c: *mut u32 = Box::into_raw(Box::new(1));
        let mut t: libc::pthread_t = mem::zeroed();
        libc::pthread_create(&mut t, ptr::null(), start, c.cast());
        __tsan_testonly_barrier_wait(&raw mut BARRIER);
        *c += 1;
        libc::pthread_join(t, ptr::null_mut());
        Box::from_raw(c);
    }
}
<|endoftext|>


<commit_before>use toml::Value;
use hook::position::HookPosition;

/// Check whether the configuration is valid for the store
///
/// The passed `Value` _must be_ the `[store]` sub-tree of the configuration. Otherwise this will
/// fail.
///
/// It checks whether the configuration looks like the store wants it to be:
///
/// ```toml
/// [store]
/// pre-create-hook-aspects = [ "misc", "encryption", "version-control"]
///
/// [[aspects.misc]]
/// parallel = true
/// [[aspects.encryption]]
/// parallel = false
/// [[aspects.version-control]]
/// parallel = false
///
/// [[hooks.gnupg]]
/// aspect = "encryption"
/// key = "0x123456789"
///
/// [[hooks.git]]
/// aspect = "version-control"
/// ```
///
/// It checks:
///  * Whether all the maps are there (whether store, store.aspects, store.aspects.example are all
///  maps)
///  * Whether each aspect configuration has a "parallel = <Boolean>" setting
///  * Whether each hook congfiguration has a "aspect = <String>" setting
///
/// It does NOT check:
///  * Whether all aspects which are used in the hook configuration are also configured
///
/// No configuration is a valid configuration, as the store will use the most conservative settings
/// automatically. This has also performance impact, as all hooks run in no-parallel mode then.
/// You have been warned!
///
///
pub fn config_is_valid(config: &Option<Value>) -> bool {
    use std::collections::BTreeMap;

    if config.is_none() {
        return true;
    }

    fn has_key_with_map(v: &BTreeMap<String, Value>, key: &str) -> bool {
        v.get(key).map(|t| match t { &Value::Table(_) => true, _ => false }).unwrap_or(false)
    }

    fn has_key_with_string_ary(v: &BTreeMap<String, Value>, key: &str) -> bool {
        v.get(key)
            .map(|t| match t {
                &Value::Array(ref a) => a.iter().all(|elem| {
                    match elem {
                        &Value::String(_) => true,
                        _ => false,
                    }
                }),
                _ => false
            }).unwrap_or(false)
    }

    /// Check that
    /// * the top-level configuration
    /// * is a table
    /// * where all entries of a key `section` (eg. "hooks" or "aspects")
    ///     * Are maps
    ///     * where each has a key `key` (eg. "aspect" or "parallel")
    ///     * which fullfills constraint `f` (typecheck)
    fn check_all_inner_maps_have_key_with<F>(store_config: &BTreeMap<String, Value>,
                                             section: &str,
                                             key: &str,
                                             f: F)
        -> bool
        where F: Fn(&Value) -> bool
    {
        store_config.get(section) // The store config has the section `section`
            .map(|section_table| {
                match section_table { // which is
                    &Value::Table(ref section_table) => // a table
                        section_table
                            .values() // which has values,
                            .all(|cfg| { // and all of these values
                                match cfg {
                                    &Value::Table(ref hook_config) => { // are tables
                                        hook_config.get(key) // with a key
                                            // fullfilling this constraint
                                            .map(|hook_aspect| f(&hook_aspect))
                                            .unwrap_or(false)
                                    },
                                    _ => false,
                                }
                            }),
                    _ => false,
                }
            })
            .unwrap_or(false)
    }

    match config {
        &Some(Value::Table(ref t)) => {
            has_key_with_string_ary(t, "pre-read-hook-aspects")        &&
            has_key_with_string_ary(t, "post-read-hook-aspects")       &&
            has_key_with_string_ary(t, "pre-create-hook-aspects")      &&
            has_key_with_string_ary(t, "post-create-hook-aspects")     &&
            has_key_with_string_ary(t, "pre-retrieve-hook-aspects")    &&
            has_key_with_string_ary(t, "post-retrieve-hook-aspects")   &&
            has_key_with_string_ary(t, "pre-update-hook-aspects")      &&
            has_key_with_string_ary(t, "post-update-hook-aspects")     &&
            has_key_with_string_ary(t, "pre-delete-hook-aspects")      &&
            has_key_with_string_ary(t, "post-delete-hook-aspects")     &&

            // The section "hooks" has maps which have a key "aspect" which has a value of type
            // String
            check_all_inner_maps_have_key_with(t, "hooks", "aspect", |asp| {
                match asp { &Value::String(_) => true, _ => false }
            }) &&

            // The section "aspects" has maps which have a key "parllel" which has a value of type
            // Boolean
            check_all_inner_maps_have_key_with(t, "aspects", "parallel", |asp| {
                match asp { &Value::Boolean(_) => true, _ => false, }
            })
        }
        _ => false,
    }
}

pub fn get_pre_read_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-read-hook-aspects", value)
}

pub fn get_post_read_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-read-hook-aspects", value)
}

pub fn get_pre_create_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-create-hook-aspects", value)
}

pub fn get_post_create_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-create-hook-aspects", value)
}

pub fn get_pre_retrieve_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-retrieve-hook-aspects", value)
}

pub fn get_post_retrieve_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-retrieve-hook-aspects", value)
}

pub fn get_pre_update_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-update-hook-aspects", value)
}

pub fn get_post_update_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-update-hook-aspects", value)
}

pub fn get_pre_delete_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-delete-hook-aspects", value)
}

pub fn get_post_delete_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-delete-hook-aspects", value)
}

#[derive(Debug)]
pub struct AspectConfig {
    parallel: bool,
    config: Value,
}

impl AspectConfig {

    pub fn new(init: Value) -> AspectConfig {
        let parallel = AspectConfig::is_parallel(&init);
        AspectConfig {
            config: init,
            parallel: parallel,
        }
    }

    pub fn config(&self) -> &Value {
        &self.config
    }

    fn is_parallel(init: &Value) -> bool {
        match init {
            &Value::Table(ref t) =>
                t.get("parallel")
                    .map(|value| {
                        match value {
                            &Value::Boolean(b) => b,
                            _ => false,
                        }
                    })
                    .unwrap_or(false),
            _ => false,
        }
    }

    /// Get the aspect configuration for an aspect.
    ///
    /// Pass the store configuration object, this searches in `[aspects][<aspect_name>]`.
    ///
    /// Returns `None` if one of the keys in the chain is not available
    fn get_for(v: Value, aspect_name: &str) -> Option<AspectConfig> {
        unimplemented!()
    }

}

fn get_aspect_names_for_aspect_position(config_name: &'static str, value: &Option<Value>) -> Vec<String> {
    let mut v = vec![];

    match value {
        &Some(Value::Table(ref t)) => {
            match t.get(config_name) {
                Some(&Value::Array(ref a)) => {
                    for elem in a {
                        match elem {
                            &Value::String(ref s) => v.push(s.clone()),
                            _ => warn!("Non-String in configuration, inside '{}'", config_name),
                        }
                    }
                },
                _ => warn!("'{}' configuration key should contain Array, does not", config_name),
            };
        },
        &None => warn!("No store configuration"),
        _ => warn!("Configuration is not a table"),
    }
    v
}

<commit_msg>Implement AspectConfig::get_for()<commit_after>use toml::Value;
use hook::position::HookPosition;

/// Check whether the configuration is valid for the store
///
/// The passed `Value` _must be_ the `[store]` sub-tree of the configuration. Otherwise this will
/// fail.
///
/// It checks whether the configuration looks like the store wants it to be:
///
/// ```toml
/// [store]
/// pre-create-hook-aspects = [ "misc", "encryption", "version-control"]
///
/// [[aspects.misc]]
/// parallel = true
/// [[aspects.encryption]]
/// parallel = false
/// [[aspects.version-control]]
/// parallel = false
///
/// [[hooks.gnupg]]
/// aspect = "encryption"
/// key = "0x123456789"
///
/// [[hooks.git]]
/// aspect = "version-control"
/// ```
///
/// It checks:
///  * Whether all the maps are there (whether store, store.aspects, store.aspects.example are all
///  maps)
///  * Whether each aspect configuration has a "parallel = <Boolean>" setting
///  * Whether each hook congfiguration has a "aspect = <String>" setting
///
/// It does NOT check:
///  * Whether all aspects which are used in the hook configuration are also configured
///
/// No configuration is a valid configuration, as the store will use the most conservative settings
/// automatically. This has also performance impact, as all hooks run in no-parallel mode then.
/// You have been warned!
///
///
pub fn config_is_valid(config: &Option<Value>) -> bool {
    use std::collections::BTreeMap;

    if config.is_none() {
        return true;
    }

    fn has_key_with_map(v: &BTreeMap<String, Value>, key: &str) -> bool {
        v.get(key).map(|t| match t { &Value::Table(_) => true, _ => false }).unwrap_or(false)
    }

    fn has_key_with_string_ary(v: &BTreeMap<String, Value>, key: &str) -> bool {
        v.get(key)
            .map(|t| match t {
                &Value::Array(ref a) => a.iter().all(|elem| {
                    match elem {
                        &Value::String(_) => true,
                        _ => false,
                    }
                }),
                _ => false
            }).unwrap_or(false)
    }

    /// Check that
    /// * the top-level configuration
    /// * is a table
    /// * where all entries of a key `section` (eg. "hooks" or "aspects")
    ///     * Are maps
    ///     * where each has a key `key` (eg. "aspect" or "parallel")
    ///     * which fullfills constraint `f` (typecheck)
    fn check_all_inner_maps_have_key_with<F>(store_config: &BTreeMap<String, Value>,
                                             section: &str,
                                             key: &str,
                                             f: F)
        -> bool
        where F: Fn(&Value) -> bool
    {
        store_config.get(section) // The store config has the section `section`
            .map(|section_table| {
                match section_table { // which is
                    &Value::Table(ref section_table) => // a table
                        section_table
                            .values() // which has values,
                            .all(|cfg| { // and all of these values
                                match cfg {
                                    &Value::Table(ref hook_config) => { // are tables
                                        hook_config.get(key) // with a key
                                            // fullfilling this constraint
                                            .map(|hook_aspect| f(&hook_aspect))
                                            .unwrap_or(false)
                                    },
                                    _ => false,
                                }
                            }),
                    _ => false,
                }
            })
            .unwrap_or(false)
    }

    match config {
        &Some(Value::Table(ref t)) => {
            has_key_with_string_ary(t, "pre-read-hook-aspects")        &&
            has_key_with_string_ary(t, "post-read-hook-aspects")       &&
            has_key_with_string_ary(t, "pre-create-hook-aspects")      &&
            has_key_with_string_ary(t, "post-create-hook-aspects")     &&
            has_key_with_string_ary(t, "pre-retrieve-hook-aspects")    &&
            has_key_with_string_ary(t, "post-retrieve-hook-aspects")   &&
            has_key_with_string_ary(t, "pre-update-hook-aspects")      &&
            has_key_with_string_ary(t, "post-update-hook-aspects")     &&
            has_key_with_string_ary(t, "pre-delete-hook-aspects")      &&
            has_key_with_string_ary(t, "post-delete-hook-aspects")     &&

            // The section "hooks" has maps which have a key "aspect" which has a value of type
            // String
            check_all_inner_maps_have_key_with(t, "hooks", "aspect", |asp| {
                match asp { &Value::String(_) => true, _ => false }
            }) &&

            // The section "aspects" has maps which have a key "parllel" which has a value of type
            // Boolean
            check_all_inner_maps_have_key_with(t, "aspects", "parallel", |asp| {
                match asp { &Value::Boolean(_) => true, _ => false, }
            })
        }
        _ => false,
    }
}

pub fn get_pre_read_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-read-hook-aspects", value)
}

pub fn get_post_read_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-read-hook-aspects", value)
}

pub fn get_pre_create_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-create-hook-aspects", value)
}

pub fn get_post_create_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-create-hook-aspects", value)
}

pub fn get_pre_retrieve_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-retrieve-hook-aspects", value)
}

pub fn get_post_retrieve_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-retrieve-hook-aspects", value)
}

pub fn get_pre_update_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-update-hook-aspects", value)
}

pub fn get_post_update_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-update-hook-aspects", value)
}

pub fn get_pre_delete_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("pre-delete-hook-aspects", value)
}

pub fn get_post_delete_aspect_names(value: &Option<Value>) -> Vec<String> {
    get_aspect_names_for_aspect_position("post-delete-hook-aspects", value)
}

#[derive(Debug)]
pub struct AspectConfig {
    parallel: bool,
    config: Value,
}

impl AspectConfig {

    pub fn new(init: Value) -> AspectConfig {
        let parallel = AspectConfig::is_parallel(&init);
        AspectConfig {
            config: init,
            parallel: parallel,
        }
    }

    pub fn config(&self) -> &Value {
        &self.config
    }

    fn is_parallel(init: &Value) -> bool {
        match init {
            &Value::Table(ref t) =>
                t.get("parallel")
                    .map(|value| {
                        match value {
                            &Value::Boolean(b) => b,
                            _ => false,
                        }
                    })
                    .unwrap_or(false),
            _ => false,
        }
    }

    /// Get the aspect configuration for an aspect.
    ///
    /// Pass the store configuration object, this searches in `[aspects][<aspect_name>]`.
    ///
    /// Returns `None` if one of the keys in the chain is not available
    pub fn get_for(v: &Option<Value>, a_name: String) -> Option<AspectConfig> {
        match v {
            &Some(Value::Table(ref tabl)) => tabl.get(&a_name[..])
                .map(|asp| AspectConfig::new(asp.clone())),
            _ => None,
        }
    }

}

fn get_aspect_names_for_aspect_position(config_name: &'static str, value: &Option<Value>) -> Vec<String> {
    let mut v = vec![];

    match value {
        &Some(Value::Table(ref t)) => {
            match t.get(config_name) {
                Some(&Value::Array(ref a)) => {
                    for elem in a {
                        match elem {
                            &Value::String(ref s) => v.push(s.clone()),
                            _ => warn!("Non-String in configuration, inside '{}'", config_name),
                        }
                    }
                },
                _ => warn!("'{}' configuration key should contain Array, does not", config_name),
            };
        },
        &None => warn!("No store configuration"),
        _ => warn!("Configuration is not a table"),
    }
    v
}

<|endoftext|>


<commit_before><commit_msg>Partial commit<commit_after>use nitro::app::App;
use nitro::component::Component;
use nitro::component::Message;
use nitro::game_object::GameObject;

pub struct Spinny {

}

impl Component for Spinny {
    fn receive_message(&mut self, app : &mut App, game_object : &mut GameObject, message : &Message) {
        match *message {
            Message::Update{delta_time} => {
                //game_object.transform.add_rotation(1.0 * delta_time);
                if let Some(horizontal) = app.get_axis_value("horizontal") {
                    game_object.transform.add_x(10.0 * delta_time * horizontal);
                }
            }
            _ => {}
        }
    }
}
<|endoftext|>


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

// ignore-test will be fixed later
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir

#![feature(thread_local)]

#[thread_local]
static FOO: u8 = 3;

fn assert_static(_t: &'static u8) {}
fn main() {
     assert_static(&FOO); //[ast]~ ERROR [E0597]
                          //[mir]~^ ERROR [E0597]
}
<commit_msg>Rollup merge of #49547 - Phlosioneer:44831-borrowck-remove-ignore, r=arielb1<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.

// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir

#![feature(thread_local)]

#[thread_local]
static FOO: u8 = 3;

fn assert_static(_t: &'static u8) {}
fn main() {
     assert_static(&FOO); //[ast]~ ERROR [E0597]
                          //[mir]~^ ERROR [E0597]
}
<|endoftext|>


<commit_before><commit_msg>Add Crs type.<commit_after><|endoftext|>


<commit_before><commit_msg>missing file: /etc/passwd parsing<commit_after>use std::io::{BufferedReader,File};
use std::vec::Vec;

#[deriving(Clone)]
pub struct GECOS {
    pub name : String,
    pub location : String,
    pub telephone : String,
    pub other : Vec<String>,
}

#[deriving(Clone)]
pub struct Entry {
    pub username : String,
    pub gecos : GECOS,
    pub home : String,
    pub shell : String,
}

fn parse_gecos(s:&str) -> GECOS {
    let mut split = s.split(',').map(|x| String::from_str(x));
    let name = split.next().unwrap_or(String::from_str(""));
    let loc = split.next().unwrap_or(String::from_str(""));
    let tel = split.next().unwrap_or(String::from_str(""));
    let mut other = Vec::new();
    for o in split {
        other.push(o);
    }
    GECOS{ name:name,location:loc,telephone:tel,other:other }
}

fn parse_line(s:&str) -> Entry {
    let mut splits = s.split(':').map(|x| String::from_str(x));
    let un = splits.next().unwrap();
    // skip next three
    splits.next(); splits.next(); splits.next();
    let gecos = parse_gecos(splits.next().unwrap().as_slice());
    let home = splits.next().unwrap();
    let shell = splits.next().unwrap();
    Entry{ username:un, gecos:gecos, home:home, shell:shell }
}

fn get_all_entries() -> Vec<Entry> {
    let mut v = Vec::new();
    let pw_path = Path::new("/etc/passwd");
    let mut f = BufferedReader::new(File::open(&pw_path));
    for line in f.lines() {
        v.push(parse_line(line.unwrap().as_slice()));
    }
    return v;
}

pub fn get_entry(username : String) -> Option<Entry> {
    let passwds = get_all_entries();
    for entry in passwds.iter() {
        if entry.username == username { return Some(entry.clone()); }
    }
    None
//    Some(Entry{ username: username, gecos : g, home: home, shell:shell })
}
<|endoftext|>


<commit_before><commit_msg>Add first example<commit_after>//! Example from spec chapter 2.13.1

extern crate gerber_types;

use gerber_types::{Command};
use gerber_types::{ExtendedCode, Unit, FileAttribute, Part, Polarity,
                   ApertureDefinition, Aperture, Circle};
use gerber_types::{FunctionCode};
use gerber_types::{DCode, Operation, Coordinates, CoordinateOffset};
use gerber_types::{GCode, InterpolationMode};
use gerber_types::{MCode};
use gerber_types::GerberCode;

fn main() {
    let commands: Vec<Command> = vec![
        Command::FunctionCode(
            FunctionCode::GCode(
                GCode::Comment("Ucamco ex. 1: Two square boxes".to_string())
            )
        ),
        Command::ExtendedCode(
            ExtendedCode::CoordinateFormat(2, 5)
        ),
        Command::ExtendedCode(
            ExtendedCode::Unit(Unit::Millimeters)
        ),
        Command::ExtendedCode(
            ExtendedCode::FileAttribute(
                FileAttribute::Part(Part::Other("Only an example".to_string()))
            )
        ),
        Command::ExtendedCode(
            ExtendedCode::LoadPolarity(Polarity::Dark)
        ),
        Command::ExtendedCode(
            ExtendedCode::ApertureDefinition(
                ApertureDefinition {
                    code: 10,
                    aperture: Aperture::Circle(Circle { diameter: 0.01, hole_diameter: None }),
                }
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::SelectAperture(10)
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Move(Coordinates::new(0, 0))
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::GCode(
                GCode::InterpolationMode(InterpolationMode::Linear)
            )
        ),
        // TODO: The interpolate representation needs to take the coordinate
        // format into account!
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::new(5, 0), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_y(5), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_x(0), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_y(0), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Move(Coordinates::at_x(6))
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_x(11), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_y(5), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_x(6), None)
                )
            )
        ),
        Command::FunctionCode(
            FunctionCode::DCode(
                DCode::Operation(
                    Operation::Interpolate(Coordinates::at_y(0), None)
                )
            )
        ),
        Command::FunctionCode(FunctionCode::MCode(MCode::EndOfFile)),
    ];
    println!("{}", commands.to_code());
}
<|endoftext|>


<commit_before>#[macro_use] extern crate log;
extern crate clap;
#[macro_use] extern crate semver;
extern crate toml;
extern crate url;
#[macro_use] extern crate version;

extern crate libimaglink;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;

use std::process::exit;
use std::ops::Deref;
use std::error::Error;

use libimagrt::runtime::Runtime;
use libimagstore::error::StoreError;
use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagutil::trace::trace_error;
use libimaglink::external::ExternalLinker;
use clap::ArgMatches;
use url::Url;

mod ui;

use ui::build_ui;

fn main() {
    let name = "imag-link";
    let version = &version!()[..];
    let about = "Link entries";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "internal" => handle_internal_linking(&rt),
                "external" => handle_external_linking(&rt),
                _ => {
                    warn!("No commandline call");
                    exit(1);
                },
            }
        });
}

fn handle_internal_linking(rt: &Runtime) {
    use libimaglink::internal::InternalLinker;
    use libimagutil::trace::trace_error;

    debug!("Handle internal linking call");
    let cmd = rt.cli().subcommand_matches("internal").unwrap();

    if cmd.is_present("list") {
        debug!("List...");
        for entry in cmd.value_of("list").unwrap().split(",") {
            debug!("Listing for '{}'", entry);
            match get_entry_by_name(rt, entry) {
                Ok(e) => {
                    e.get_internal_links()
                        .map(|links| {
                            let mut i = 0;
                            for link in links.iter().map(|l| l.to_str()).filter_map(|x| x) {
                                println!("{: <3}: {}", i, link);
                                i += 1;
                            }
                        });
                },

                Err(e) => {
                    trace_error(&e);
                    break;
                },
            }
        }
        debug!("Listing ready!");
    } else {
        let mut from = {
            let mut from = get_from_entry(&rt);
            if from.is_none() {
                warn!("No 'from' entry");
                exit(1);
            }
            from.unwrap()
        };
        debug!("Link from = {:?}", from.deref());

        let mut to = {
            let mut to = get_to_entries(&rt);
            if to.is_none() {
                warn!("No 'to' entry");
                exit(1);
            }
            to.unwrap()
        };
        debug!("Link to = {:?}", to.iter().map(|f| f.deref()).collect::<Vec<&Entry>>());

        match cmd.subcommand_name() {
            Some("add") => {
                for mut to_entry in to {
                    if let Err(e) = to_entry.add_internal_link(&mut from) {
                        trace_error(&e);
                        exit(1);
                    }
                }
            },

            Some("remove") => {
                for mut to_entry in to {
                    if let Err(e) = to_entry.remove_internal_link(&mut from) {
                        trace_error(&e);
                        exit(1);
                    }
                }
            },

            _ => unreachable!(),
        };
    }
}

fn get_from_entry<'a>(rt: &'a Runtime) -> Option<FileLockEntry<'a>> {
    rt.cli()
        .subcommand_matches("internal")
        .unwrap() // safe, we know there is an "internal" subcommand"
        .subcommand_matches("add")
        .unwrap() // safe, we know there is an "add" subcommand
        .value_of("from")
        .and_then(|from_name| {
            match get_entry_by_name(rt, from_name) {
                Err(e) => {
                    debug!("We couldn't get the entry from name: '{:?}'", from_name);
                    trace_error(&e); None
                },
                Ok(e) => Some(e),
            }

        })
}

fn get_to_entries<'a>(rt: &'a Runtime) -> Option<Vec<FileLockEntry<'a>>> {
    rt.cli()
        .subcommand_matches("internal")
        .unwrap() // safe, we know there is an "internal" subcommand"
        .subcommand_matches("add")
        .unwrap() // safe, we know there is an "add" subcommand
        .values_of("to")
        .map(|values| {
            let mut v = vec![];
            for entry in values.map(|v| get_entry_by_name(rt, v)) {
                match entry {
                    Err(e) => trace_error(&e),
                    Ok(e) => v.push(e),
                }
            }
            v
        })
}

fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result<FileLockEntry<'a>, StoreError> {
    use libimagstore::storeid::build_entry_path;
    build_entry_path(rt.store(), name)
        .and_then(|path| rt.store().retrieve(path))
}

fn handle_external_linking(rt: &Runtime) {
    use libimagutil::trace::trace_error;

    let scmd       = rt.cli().subcommand_matches("external").unwrap();
    let entry_name = scmd.value_of("id").unwrap(); // enforced by clap
    let entry      = get_entry_by_name(rt, entry_name);
    if entry.is_err() {
        trace_error(&entry.err().unwrap());
        exit(1);
    }
    let mut entry = entry.unwrap();

    if scmd.is_present("add") {
        debug!("Adding link to entry!");
        add_link_to_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("remove") {
        debug!("Removing link from entry!");
        remove_link_from_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("set") {
        debug!("Setting links in entry!");
        set_links_for_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("list") {
        debug!("Listing links in entry!");
        list_links_for_entry(rt.store(), &mut entry);
        return;
    }

    panic!("Clap failed to enforce one of 'add', 'remove', 'set' or 'list'");
}

fn add_link_to_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let link = matches.value_of("add").unwrap();

    let link = Url::parse(link);
    if link.is_err() {
        debug!("URL parsing error...");
        trace_error(&link.err().unwrap());
        debug!("Exiting");
        exit(1);
    }
    let link = link.unwrap();

    if let Err(e) = entry.add_external_link(store, link) {
        debug!("Error while adding external link...");
        trace_error(&e);
    } else {
        debug!("Everything worked well");
        info!("Ok");
    }
}

fn remove_link_from_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let link = matches.value_of("remove").unwrap();

    let link = Url::parse(link);
    if link.is_err() {
        trace_error(&link.err().unwrap());
        exit(1);
    }
    let link = link.unwrap();

    if let Err(e) = entry.remove_external_link(store, link) {
        trace_error(&e);
    } else {
        info!("Ok");
    }
}

fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let links = matches
        .value_of("links")
        .map(String::from)
        .unwrap()
        .split(",")
        .map(|uri| {
            match Url::parse(uri) {
                Err(e) => {
                    warn!("Could not parse '{}' as URL, ignoring", uri);
                    trace_error(&e);
                    None
                },
                Ok(u) => Some(u),
            }
        })
        .filter_map(|x| x)
        .collect();

    if let Err(e) = entry.set_external_links(store, links) {
        trace_error(&e);
    } else {
        info!("Ok");
    }
}

fn list_links_for_entry(store: &Store, entry: &mut FileLockEntry) {
    let res = entry.get_external_links(store)
        .and_then(|links| {
            let mut i = 0;
            for link in links {
                println!("{: <3}: {}", i, link);
                i += 1;
            }
            Ok(())
        });

    match res {
        Err(e) => {
            trace_error(&e);
        },
        Ok(_) => {
            info!("Ok");
        },
    }
}

<commit_msg>Remove unused imports<commit_after>#[macro_use] extern crate log;
extern crate clap;
#[macro_use] extern crate semver;
extern crate toml;
extern crate url;
#[macro_use] extern crate version;

extern crate libimaglink;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;

use std::process::exit;
use std::ops::Deref;

use libimagrt::runtime::Runtime;
use libimagstore::error::StoreError;
use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagutil::trace::trace_error;
use libimaglink::external::ExternalLinker;
use clap::ArgMatches;
use url::Url;

mod ui;

use ui::build_ui;

fn main() {
    let name = "imag-link";
    let version = &version!()[..];
    let about = "Link entries";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    debug!("Hello. Logging was just enabled");
    debug!("I already set up the Runtime object and build the commandline interface parser.");
    debug!("Lets get rollin' ...");

    rt.cli()
        .subcommand_name()
        .map(|name| {
            match name {
                "internal" => handle_internal_linking(&rt),
                "external" => handle_external_linking(&rt),
                _ => {
                    warn!("No commandline call");
                    exit(1);
                },
            }
        });
}

fn handle_internal_linking(rt: &Runtime) {
    use libimaglink::internal::InternalLinker;
    use libimagutil::trace::trace_error;

    debug!("Handle internal linking call");
    let cmd = rt.cli().subcommand_matches("internal").unwrap();

    if cmd.is_present("list") {
        debug!("List...");
        for entry in cmd.value_of("list").unwrap().split(",") {
            debug!("Listing for '{}'", entry);
            match get_entry_by_name(rt, entry) {
                Ok(e) => {
                    e.get_internal_links()
                        .map(|links| {
                            let mut i = 0;
                            for link in links.iter().map(|l| l.to_str()).filter_map(|x| x) {
                                println!("{: <3}: {}", i, link);
                                i += 1;
                            }
                        });
                },

                Err(e) => {
                    trace_error(&e);
                    break;
                },
            }
        }
        debug!("Listing ready!");
    } else {
        let mut from = {
            let mut from = get_from_entry(&rt);
            if from.is_none() {
                warn!("No 'from' entry");
                exit(1);
            }
            from.unwrap()
        };
        debug!("Link from = {:?}", from.deref());

        let mut to = {
            let mut to = get_to_entries(&rt);
            if to.is_none() {
                warn!("No 'to' entry");
                exit(1);
            }
            to.unwrap()
        };
        debug!("Link to = {:?}", to.iter().map(|f| f.deref()).collect::<Vec<&Entry>>());

        match cmd.subcommand_name() {
            Some("add") => {
                for mut to_entry in to {
                    if let Err(e) = to_entry.add_internal_link(&mut from) {
                        trace_error(&e);
                        exit(1);
                    }
                }
            },

            Some("remove") => {
                for mut to_entry in to {
                    if let Err(e) = to_entry.remove_internal_link(&mut from) {
                        trace_error(&e);
                        exit(1);
                    }
                }
            },

            _ => unreachable!(),
        };
    }
}

fn get_from_entry<'a>(rt: &'a Runtime) -> Option<FileLockEntry<'a>> {
    rt.cli()
        .subcommand_matches("internal")
        .unwrap() // safe, we know there is an "internal" subcommand"
        .subcommand_matches("add")
        .unwrap() // safe, we know there is an "add" subcommand
        .value_of("from")
        .and_then(|from_name| {
            match get_entry_by_name(rt, from_name) {
                Err(e) => {
                    debug!("We couldn't get the entry from name: '{:?}'", from_name);
                    trace_error(&e); None
                },
                Ok(e) => Some(e),
            }

        })
}

fn get_to_entries<'a>(rt: &'a Runtime) -> Option<Vec<FileLockEntry<'a>>> {
    rt.cli()
        .subcommand_matches("internal")
        .unwrap() // safe, we know there is an "internal" subcommand"
        .subcommand_matches("add")
        .unwrap() // safe, we know there is an "add" subcommand
        .values_of("to")
        .map(|values| {
            let mut v = vec![];
            for entry in values.map(|v| get_entry_by_name(rt, v)) {
                match entry {
                    Err(e) => trace_error(&e),
                    Ok(e) => v.push(e),
                }
            }
            v
        })
}

fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result<FileLockEntry<'a>, StoreError> {
    use libimagstore::storeid::build_entry_path;
    build_entry_path(rt.store(), name)
        .and_then(|path| rt.store().retrieve(path))
}

fn handle_external_linking(rt: &Runtime) {
    use libimagutil::trace::trace_error;

    let scmd       = rt.cli().subcommand_matches("external").unwrap();
    let entry_name = scmd.value_of("id").unwrap(); // enforced by clap
    let entry      = get_entry_by_name(rt, entry_name);
    if entry.is_err() {
        trace_error(&entry.err().unwrap());
        exit(1);
    }
    let mut entry = entry.unwrap();

    if scmd.is_present("add") {
        debug!("Adding link to entry!");
        add_link_to_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("remove") {
        debug!("Removing link from entry!");
        remove_link_from_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("set") {
        debug!("Setting links in entry!");
        set_links_for_entry(rt.store(), scmd, &mut entry);
        return;
    }

    if scmd.is_present("list") {
        debug!("Listing links in entry!");
        list_links_for_entry(rt.store(), &mut entry);
        return;
    }

    panic!("Clap failed to enforce one of 'add', 'remove', 'set' or 'list'");
}

fn add_link_to_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let link = matches.value_of("add").unwrap();

    let link = Url::parse(link);
    if link.is_err() {
        debug!("URL parsing error...");
        trace_error(&link.err().unwrap());
        debug!("Exiting");
        exit(1);
    }
    let link = link.unwrap();

    if let Err(e) = entry.add_external_link(store, link) {
        debug!("Error while adding external link...");
        trace_error(&e);
    } else {
        debug!("Everything worked well");
        info!("Ok");
    }
}

fn remove_link_from_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let link = matches.value_of("remove").unwrap();

    let link = Url::parse(link);
    if link.is_err() {
        trace_error(&link.err().unwrap());
        exit(1);
    }
    let link = link.unwrap();

    if let Err(e) = entry.remove_external_link(store, link) {
        trace_error(&e);
    } else {
        info!("Ok");
    }
}

fn set_links_for_entry(store: &Store, matches: &ArgMatches, entry: &mut FileLockEntry) {
    let links = matches
        .value_of("links")
        .map(String::from)
        .unwrap()
        .split(",")
        .map(|uri| {
            match Url::parse(uri) {
                Err(e) => {
                    warn!("Could not parse '{}' as URL, ignoring", uri);
                    trace_error(&e);
                    None
                },
                Ok(u) => Some(u),
            }
        })
        .filter_map(|x| x)
        .collect();

    if let Err(e) = entry.set_external_links(store, links) {
        trace_error(&e);
    } else {
        info!("Ok");
    }
}

fn list_links_for_entry(store: &Store, entry: &mut FileLockEntry) {
    let res = entry.get_external_links(store)
        .and_then(|links| {
            let mut i = 0;
            for link in links {
                println!("{: <3}: {}", i, link);
                i += 1;
            }
            Ok(())
        });

    match res {
        Err(e) => {
            trace_error(&e);
        },
        Ok(_) => {
            info!("Ok");
        },
    }
}

<|endoftext|>


<commit_before>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let name    = "imag-todo";
    let version = &version!()[..];
    let about   = "Interface with taskwarrior";
    let ui      = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        _ => unimplemented!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin     = stdin();
        let mut stdin = stdin.lock();
        let mut line  = String::new();

        if let Err(e) = stdin.read_line(&mut line) {
            trace_error(&e);
            exit(1);
        };

        if let Ok(ttask) = import_task(&line.as_str()) {
            match serde_json::ser::to_string(&ttask) {
                Ok(val) => println!("{}", val),
                Err(e) => {
                    trace_error(&e);
                    exit(1);
                }
            }

            let uuid = *ttask.uuid();
            match ttask.into_task(rt.store()) {
                Ok(val) => {
                    println!("Task {} stored in imag", uuid);
                    val
                },
                Err(e) => {
                    trace_error(&e);
                    exit(1);
                }
            };
        } else {
            error!("No usable input");
            exit(1);
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let mut counter   = 0;
        let stdin         = stdin();
        let stdin         = stdin.lock();

        match import_tasks(stdin) {
            Ok(ttasks) => for ttask in ttasks {
                if counter % 2 == 1 {
                    // Only every second task is needed, the first one is the
                    // task before the change, and the second one after
                    // the change. The (maybe modified) second one is
                    // expected by taskwarrior.
                    match serde_json::ser::to_string(&ttask) {
                        Ok(val) => println!("{}", val),
                        Err(e) => {
                            trace_error(&e);
                            exit(1);
                        }
                    }

                    match ttask.status() {
                        &task_hookrs::status::TaskStatus::Deleted => {
                            match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
                                Ok(_) => println!("Deleted task {}", *ttask.uuid()),
                                Err(e) => {
                                    trace_error(&e);
                                    exit(1);
                                }
                            }
                        }
                        _ => {
                        }
                    } // end match ttask.status()
                } // end if c % 2
                counter += 1;
            },
            Err(e) => {
                trace_error(&e);
                exit(1);
            },
        }
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd   = rt.cli().subcommand_matches("list").unwrap();
    let mut args = Vec::new();
    let verbose  = subcmd.is_present("verbose");
    let iter     = match libimagtodo::read::get_todo_iterator(rt.store()) {
        Err(e) => {
            trace_error(&e);
            exit(1);
        }
        Ok(val) => val,
    };

    for task in iter {
        match task {
            Ok(val) => {
                let uuid = match val.flentry.get_header().read("todo.uuid") {
                    Ok(Some(u)) => u,
                    Ok(None)    => continue,
                    Err(e)      => {
                        trace_error(&e);
                        continue;
                    }
                };

                if verbose {
                    args.clear();
                    args.push(format!("uuid:{} information", uuid));

                    let tw_process = Command::new("task")
                        .stdin(Stdio::null())
                        .args(&args)
                        .spawn()
                        .unwrap_or_else(|e| {
                            trace_error(&e);
                            panic!("failed");
                        });
                    let output = tw_process
                        .wait_with_output()
                        .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));
                    let outstring = String::from_utf8(output.stdout)
                        .unwrap_or_else(|e| panic!("failed to execute: {}", e));

                    println!("{}", outstring);
                } else {
                    println!("{}", match uuid {
                        toml::Value::String(s) => s,
                        _ => {
                            error!("Unexpected type for todo.uuid: {}", uuid);
                            continue;
                        },
                    });
                }
            }
            Err(e) => {
                trace_error(&e);
                continue;
            }
        } // end match task
    } // end for
}

<commit_msg>Adapt for new interface of libimagtodo<commit_after>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagtodo::task::Task;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let name    = "imag-todo";
    let version = &version!()[..];
    let about   = "Interface with taskwarrior";
    let ui      = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        _ => unimplemented!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin     = stdin();
        let mut stdin = stdin.lock();
        let mut line  = String::new();

        if let Err(e) = stdin.read_line(&mut line) {
            trace_error(&e);
            exit(1);
        };

        if let Ok(ttask) = import_task(&line.as_str()) {
            match serde_json::ser::to_string(&ttask) {
                Ok(val) => println!("{}", val),
                Err(e) => {
                    trace_error(&e);
                    exit(1);
                }
            }

            let uuid = *ttask.uuid();
            match ttask.into_task(rt.store()) {
                Ok(val) => {
                    println!("Task {} stored in imag", uuid);
                    val
                },
                Err(e) => {
                    trace_error(&e);
                    exit(1);
                }
            };
        } else {
            error!("No usable input");
            exit(1);
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let mut counter   = 0;
        let stdin         = stdin();
        let stdin         = stdin.lock();

        match import_tasks(stdin) {
            Ok(ttasks) => for ttask in ttasks {
                if counter % 2 == 1 {
                    // Only every second task is needed, the first one is the
                    // task before the change, and the second one after
                    // the change. The (maybe modified) second one is
                    // expected by taskwarrior.
                    match serde_json::ser::to_string(&ttask) {
                        Ok(val) => println!("{}", val),
                        Err(e) => {
                            trace_error(&e);
                            exit(1);
                        }
                    }

                    match ttask.status() {
                        &task_hookrs::status::TaskStatus::Deleted => {
                            match Task::delete_by_uuid(rt.store(), *ttask.uuid()) {
                                Ok(_) => println!("Deleted task {}", *ttask.uuid()),
                                Err(e) => {
                                    trace_error(&e);
                                    exit(1);
                                }
                            }
                        }
                        _ => {
                        }
                    } // end match ttask.status()
                } // end if c % 2
                counter += 1;
            },
            Err(e) => {
                trace_error(&e);
                exit(1);
            },
        }
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd   = rt.cli().subcommand_matches("list").unwrap();
    let mut args = Vec::new();
    let verbose  = subcmd.is_present("verbose");
    let iter     = match Task::all(rt.store()) {
        Ok(iter) => iter,
        Err(e)   => {
            trace_error(&e);
            exit(1);
        },
    };

    for task in iter {
        match task {
            Ok(val) => {
                let uuid = match val.get_header().read("todo.uuid") {
                    Ok(Some(u)) => u,
                    Ok(None)    => continue,
                    Err(e)      => {
                        trace_error(&e);
                        continue;
                    }
                };

                if verbose {
                    args.clear();
                    args.push(format!("uuid:{} information", uuid));

                    let tw_process = Command::new("task")
                        .stdin(Stdio::null())
                        .args(&args)
                        .spawn()
                        .unwrap_or_else(|e| {
                            trace_error(&e);
                            panic!("failed");
                        });
                    let output = tw_process
                        .wait_with_output()
                        .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));
                    let outstring = String::from_utf8(output.stdout)
                        .unwrap_or_else(|e| panic!("failed to execute: {}", e));

                    println!("{}", outstring);
                } else {
                    println!("{}", match uuid {
                        toml::Value::String(s) => s,
                        _ => {
                            error!("Unexpected type for todo.uuid: {}", uuid);
                            continue;
                        },
                    });
                }
            }
            Err(e) => {
                trace_error(&e);
                continue;
            }
        } // end match task
    } // end for
}

<|endoftext|>


<commit_before><commit_msg>account.setSilenceMode method<commit_after><|endoftext|>


<commit_before><commit_msg>decimal has new funtion and all data needed for its calculations<commit_after>const N_DIGITS: usize = 128;
const N_BYTES: usize = N_DIGITS / 8;

#[derive(Debug, Clone, Copy)]
struct Decimal {
    digits: [u8; N_BYTES],
    exp: u8,
    neg: bool,
}

impl Decimal {
    pub fn new() -> Decimal {
        Decimal {
            digits: [0; N_BYTES],
            exp: 0,
            neg: false,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Update for latest Rust master.<commit_after><|endoftext|>


<commit_before><commit_msg>git work<commit_after><|endoftext|>


<commit_before><commit_msg>add texture class<commit_after>use std;
use utils;
use image;
use glium::texture::texture2d::Texture2d;
use glium::backend::glutin_backend::GlutinFacade;

pub struct Texture {
    pub data: Texture2d,
}

impl Texture {
    pub fn new(facade: &GlutinFacade, filename: &std::path::Path) -> Result<Texture, String> {
        let texture_path = try!(utils::get_base_dir()).join(filename);
        println!("load texture: \"{}\"", texture_path.display());

        let image = match image::open(texture_path.as_path()) {
            Ok(v) => v,
            Err(e) => return Err(format!("error load texture \"{}\": {}", texture_path.display(), e))
        };

        let texture = match Texture2d::new(facade, image) {
            Ok(v) => v,
            Err(e) => return Err(format!("error create texture \"{}\": {:?}", texture_path.display(), e))
        };

        Ok(Texture {
            data: texture,
        })
    }

}
<|endoftext|>


<commit_before><commit_msg>Crudely implement BG X/BG Y window attrib's<commit_after><|endoftext|>


<commit_before><commit_msg>Implement proper background dimensions<commit_after><|endoftext|>


<commit_before><commit_msg>Approaching a pattern I'm starting to like<commit_after><|endoftext|>


<commit_before><commit_msg>add a test for the memory leak error<commit_after>//error-pattern: the evaluated program leaked memory

fn main() {
    std::mem::forget(Box::new(42));
}
<|endoftext|>