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

// Exercise the unused_mut attribute in some positive and negative cases

#![allow(unused_assignments)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![deny(unused_mut)]

fn main() {
    // negative cases
    let mut a = 3; //~ ERROR: variable does not need to be mutable
    let mut a = 2; //~ ERROR: variable does not need to be mutable
    let mut b = 3; //~ ERROR: variable does not need to be mutable
    let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
    let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
    let mut a; //~ ERROR: variable does not need to be mutable
    a = 3;

    let mut b; //~ ERROR: variable does not need to be mutable
    if true {
        b = 3;
    } else {
        b = 4;
    }

    match 30 {
        mut x => {} //~ ERROR: variable does not need to be mutable
    }
    match (30, 2) {
      (mut x, 1) | //~ ERROR: variable does not need to be mutable
      (mut x, 2) |
      (mut x, 3) => {
      }
      _ => {}
    }

    let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
    fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable

    // positive cases
    let mut a = 2;
    a = 3;
    let mut a = Vec::new();
    a.push(3);
    let mut a = Vec::new();
    callback(|| {
        a.push(3);
    });
    let (mut a, b) = (1, 2);
    a = 34;

    match 30 {
        mut x => {
            x = 21;
        }
    }

    match (30, 2) {
      (mut x, 1) |
      (mut x, 2) |
      (mut x, 3) => {
        x = 21
      }
      _ => {}
    }

    let x = |mut y: isize| y = 32;
    fn nothing(mut foo: isize) { foo = 37; }

    // leading underscore should avoid the warning, just like the
    // unused variable lint.
    let mut _allowed = 1;
}

fn callback<F>(f: F) where F: FnOnce() {}

// make sure the lint attribute can be turned off
#[allow(unused_mut)]
fn foo(mut a: isize) {
    let mut a = 3;
    let mut b = vec![2];
}
<commit_msg>Added tests for bugs fixed.<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Exercise the unused_mut attribute in some positive and negative cases

#![allow(unused_assignments)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![deny(unused_mut)]

fn main() {
    // negative cases
    let mut a = 3; //~ ERROR: variable does not need to be mutable
    let mut a = 2; //~ ERROR: variable does not need to be mutable
    let mut b = 3; //~ ERROR: variable does not need to be mutable
    let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
    let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
    let mut a; //~ ERROR: variable does not need to be mutable
    a = 3;

    let mut b; //~ ERROR: variable does not need to be mutable
    if true {
        b = 3;
    } else {
        b = 4;
    }

    match 30 {
        mut x => {} //~ ERROR: variable does not need to be mutable
    }
    match (30, 2) {
      (mut x, 1) | //~ ERROR: variable does not need to be mutable
      (mut x, 2) |
      (mut x, 3) => {
      }
      _ => {}
    }

    let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
    fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable

    let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
    *a = 4;

    let mut a = 5;
    let mut b = (&mut a,);
    *b.0 = 4; //~^ ERROR: variable does not need to be mutable

    fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
        &mut arg[..] //~^ ERROR: variable does not need to be mutable
    }

    let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
    v.push(());

    // positive cases
    let mut a = 2;
    a = 3;
    let mut a = Vec::new();
    a.push(3);
    let mut a = Vec::new();
    callback(|| {
        a.push(3);
    });
    let (mut a, b) = (1, 2);
    a = 34;

    match 30 {
        mut x => {
            x = 21;
        }
    }

    match (30, 2) {
      (mut x, 1) |
      (mut x, 2) |
      (mut x, 3) => {
        x = 21
      }
      _ => {}
    }

    let x = |mut y: isize| y = 32;
    fn nothing(mut foo: isize) { foo = 37; }

    // leading underscore should avoid the warning, just like the
    // unused variable lint.
    let mut _allowed = 1;
}

fn callback<F>(f: F) where F: FnOnce() {}

// make sure the lint attribute can be turned off
#[allow(unused_mut)]
fn foo(mut a: isize) {
    let mut a = 3;
    let mut b = vec![2];
}
<|endoftext|>


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

use dom::attr::{Attr, AttrHelpers, AttrValue};
use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::HTMLTableElementBinding;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCaptionElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast};
use dom::bindings::js::{JSRef, Rootable, Temporary};
use dom::document::Document;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmltablecaptionelement::HTMLTableCaptionElement;
use dom::node::{Node, NodeHelpers, NodeTypeId};
use dom::virtualmethods::VirtualMethods;

use util::str::{self, DOMString, LengthOrPercentageOrAuto};

use cssparser::RGBA;
use string_cache::Atom;

use std::cell::Cell;

#[dom_struct]
pub struct HTMLTableElement {
    htmlelement: HTMLElement,
    background_color: Cell<Option<RGBA>>,
    border: Cell<Option<u32>>,
    cellspacing: Cell<Option<u32>>,
    width: Cell<LengthOrPercentageOrAuto>,
}

impl HTMLTableElementDerived for EventTarget {
    fn is_htmltableelement(&self) -> bool {
        *self.type_id() ==
            EventTargetTypeId::Node(
                NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement)))
    }
}

impl HTMLTableElement {
    fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
                     -> HTMLTableElement {
        HTMLTableElement {
            htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableElement,
                                                    localName,
                                                    prefix,
                                                    document),
            background_color: Cell::new(None),
            border: Cell::new(None),
            cellspacing: Cell::new(None),
            width: Cell::new(LengthOrPercentageOrAuto::Auto),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
               -> Temporary<HTMLTableElement> {
        let element = HTMLTableElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLTableElementBinding::Wrap)
    }
}

impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> {
    //  https://www.whatwg.org/html/#dom-table-caption
    fn GetCaption(self) -> Option<Temporary<HTMLTableCaptionElement>> {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        node.children()
            .map(|c| c.root())
            .filter_map(|c| {
                HTMLTableCaptionElementCast::to_ref(c.r()).map(Temporary::from_rooted)
            })
            .next()
    }

    // https://www.whatwg.org/html/#dom-table-caption
    fn SetCaption(self, new_caption: Option<JSRef<HTMLTableCaptionElement>>) {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        let old_caption = self.GetCaption();

        match old_caption {
            Some(htmlelem) => {
                let htmlelem_root = htmlelem.root();
                let old_caption_node: JSRef<Node> = NodeCast::from_ref(htmlelem_root.r());
                assert!(node.RemoveChild(old_caption_node).is_ok());
            }
            None => ()
        }

        new_caption.map(|caption| {
            let new_caption_node: JSRef<Node> = NodeCast::from_ref(caption);
            assert!(node.AppendChild(new_caption_node).is_ok());
        });
    }
}

pub trait HTMLTableElementHelpers {
    fn get_background_color(&self) -> Option<RGBA>;
    fn get_border(&self) -> Option<u32>;
    fn get_cellspacing(&self) -> Option<u32>;
    fn get_width(&self) -> LengthOrPercentageOrAuto;
}

impl HTMLTableElementHelpers for HTMLTableElement {
    fn get_background_color(&self) -> Option<RGBA> {
        self.background_color.get()
    }

    fn get_border(&self) -> Option<u32> {
        self.border.get()
    }

    fn get_cellspacing(&self) -> Option<u32> {
        self.cellspacing.get()
    }

    fn get_width(&self) -> LengthOrPercentageOrAuto {
        self.width.get()
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> {
    fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
        let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
        Some(htmlelement as &VirtualMethods)
    }

    fn after_set_attr(&self, attr: JSRef<Attr>) {
        if let Some(ref s) = self.super_type() {
            s.after_set_attr(attr);
        }

        match attr.local_name() {
            &atom!("bgcolor") => {
                self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
            }
            &atom!("border") => {
                // According to HTML5 § 14.3.9, invalid values map to 1px.
                self.border.set(Some(str::parse_unsigned_integer(attr.value()
                                                                     .chars()).unwrap_or(1)))
            }
            &atom!("cellspacing") => {
                self.cellspacing.set(str::parse_unsigned_integer(attr.value().chars()))
            }
            &atom!("width") => self.width.set(str::parse_length(&attr.value())),
            _ => ()
        }
    }

    fn before_remove_attr(&self, attr: JSRef<Attr>) {
        if let Some(ref s) = self.super_type() {
            s.before_remove_attr(attr);
        }

        match attr.local_name() {
            &atom!("bgcolor") => self.background_color.set(None),
            &atom!("border") => self.border.set(None),
            &atom!("cellspacing") => self.cellspacing.set(None),
            &atom!("width") => self.width.set(LengthOrPercentageOrAuto::Auto),
            _ => ()
        }
    }

    fn parse_plain_attribute(&self, local_name: &Atom, value: DOMString) -> AttrValue {
        match local_name {
            &atom!("border") => AttrValue::from_u32(value, 1),
            _ => self.super_type().unwrap().parse_plain_attribute(local_name, value),
        }
    }
}

<commit_msg>Use if let in HTMLTableElement::SetCaption.<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 dom::attr::{Attr, AttrHelpers, AttrValue};
use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::HTMLTableElementBinding;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCaptionElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast};
use dom::bindings::js::{JSRef, Rootable, Temporary, OptionalRootable, RootedReference};
use dom::document::Document;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmltablecaptionelement::HTMLTableCaptionElement;
use dom::node::{Node, NodeHelpers, NodeTypeId};
use dom::virtualmethods::VirtualMethods;

use util::str::{self, DOMString, LengthOrPercentageOrAuto};

use cssparser::RGBA;
use string_cache::Atom;

use std::cell::Cell;

#[dom_struct]
pub struct HTMLTableElement {
    htmlelement: HTMLElement,
    background_color: Cell<Option<RGBA>>,
    border: Cell<Option<u32>>,
    cellspacing: Cell<Option<u32>>,
    width: Cell<LengthOrPercentageOrAuto>,
}

impl HTMLTableElementDerived for EventTarget {
    fn is_htmltableelement(&self) -> bool {
        *self.type_id() ==
            EventTargetTypeId::Node(
                NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement)))
    }
}

impl HTMLTableElement {
    fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
                     -> HTMLTableElement {
        HTMLTableElement {
            htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableElement,
                                                    localName,
                                                    prefix,
                                                    document),
            background_color: Cell::new(None),
            border: Cell::new(None),
            cellspacing: Cell::new(None),
            width: Cell::new(LengthOrPercentageOrAuto::Auto),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>)
               -> Temporary<HTMLTableElement> {
        let element = HTMLTableElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLTableElementBinding::Wrap)
    }
}

impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> {
    //  https://www.whatwg.org/html/#dom-table-caption
    fn GetCaption(self) -> Option<Temporary<HTMLTableCaptionElement>> {
        let node: JSRef<Node> = NodeCast::from_ref(self);
        node.children()
            .map(|c| c.root())
            .filter_map(|c| {
                HTMLTableCaptionElementCast::to_ref(c.r()).map(Temporary::from_rooted)
            })
            .next()
    }

    // https://www.whatwg.org/html/#dom-table-caption
    fn SetCaption(self, new_caption: Option<JSRef<HTMLTableCaptionElement>>) {
        let node: JSRef<Node> = NodeCast::from_ref(self);

        if let Some(ref caption) = self.GetCaption().root() {
            assert!(node.RemoveChild(NodeCast::from_ref(caption.r())).is_ok());
        }

        if let Some(caption) = new_caption {
            assert!(node.AppendChild(NodeCast::from_ref(caption)).is_ok());
        }
    }
}

pub trait HTMLTableElementHelpers {
    fn get_background_color(&self) -> Option<RGBA>;
    fn get_border(&self) -> Option<u32>;
    fn get_cellspacing(&self) -> Option<u32>;
    fn get_width(&self) -> LengthOrPercentageOrAuto;
}

impl HTMLTableElementHelpers for HTMLTableElement {
    fn get_background_color(&self) -> Option<RGBA> {
        self.background_color.get()
    }

    fn get_border(&self) -> Option<u32> {
        self.border.get()
    }

    fn get_cellspacing(&self) -> Option<u32> {
        self.cellspacing.get()
    }

    fn get_width(&self) -> LengthOrPercentageOrAuto {
        self.width.get()
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> {
    fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> {
        let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self);
        Some(htmlelement as &VirtualMethods)
    }

    fn after_set_attr(&self, attr: JSRef<Attr>) {
        if let Some(ref s) = self.super_type() {
            s.after_set_attr(attr);
        }

        match attr.local_name() {
            &atom!("bgcolor") => {
                self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
            }
            &atom!("border") => {
                // According to HTML5 § 14.3.9, invalid values map to 1px.
                self.border.set(Some(str::parse_unsigned_integer(attr.value()
                                                                     .chars()).unwrap_or(1)))
            }
            &atom!("cellspacing") => {
                self.cellspacing.set(str::parse_unsigned_integer(attr.value().chars()))
            }
            &atom!("width") => self.width.set(str::parse_length(&attr.value())),
            _ => ()
        }
    }

    fn before_remove_attr(&self, attr: JSRef<Attr>) {
        if let Some(ref s) = self.super_type() {
            s.before_remove_attr(attr);
        }

        match attr.local_name() {
            &atom!("bgcolor") => self.background_color.set(None),
            &atom!("border") => self.border.set(None),
            &atom!("cellspacing") => self.cellspacing.set(None),
            &atom!("width") => self.width.set(LengthOrPercentageOrAuto::Auto),
            _ => ()
        }
    }

    fn parse_plain_attribute(&self, local_name: &Atom, value: DOMString) -> AttrValue {
        match local_name {
            &atom!("border") => AttrValue::from_u32(value, 1),
            _ => self.super_type().unwrap().parse_plain_attribute(local_name, value),
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>test that creating a 2nd mutable ref from a NonNull invalidates the first<commit_after>use std::ptr::NonNull;

fn main() { unsafe {
    let x = &mut 0;
    let mut ptr1 = NonNull::from(x);
    let mut ptr2 = ptr1.clone();
    let raw1 = ptr1.as_mut();
    let _raw2 = ptr2.as_mut();
    let _val = *raw1; //~ ERROR borrow stack
} }
<|endoftext|>


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

use syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::{c_int, c_char};
use std::ffi::CString;

pub fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        use std::sync::Once;
        static INIT: Once = Once::new();
        static mut POISONED: bool = false;
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED = true;
            }

            configure_llvm(sess);
        });

        if POISONED {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features must be known to LLVM or the feature
// detection code will walk past the end of the feature array,
// leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];

const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
                                                 "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
                                                 "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
                                                 "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let target_machine = create_target_machine(sess);

    let whitelist = match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        _ => &[],
    };

    let mut features = Vec::new();
    for feat in whitelist {
        assert_eq!(feat.chars().last(), Some('\0'));
        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
            features.push(Symbol::intern(&feat[..feat.len() - 1]));
        }
    }
    features
}

pub fn print_version() {
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub fn print(req: PrintRequest, sess: &Session) {
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}

pub fn enable_llvm_debug() {
    unsafe { llvm::LLVMRustSetDebug(1); }
}
<commit_msg>Use AtomicBool instead of a 'static mut' for LLVM init posioning<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.

use syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::{c_int, c_char};
use std::ffi::CString;

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

pub fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        static POISONED: AtomicBool = AtomicBool::new(false);
        static INIT: Once = Once::new();
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED.store(true, Ordering::SeqCst);
            }

            configure_llvm(sess);
        });

        if POISONED.load(Ordering::SeqCst) {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features must be known to LLVM or the feature
// detection code will walk past the end of the feature array,
// leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\0"];

const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
                                                 "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
                                                 "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
                                                 "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let target_machine = create_target_machine(sess);

    let whitelist = match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        _ => &[],
    };

    let mut features = Vec::new();
    for feat in whitelist {
        assert_eq!(feat.chars().last(), Some('\0'));
        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
            features.push(Symbol::intern(&feat[..feat.len() - 1]));
        }
    }
    features
}

pub fn print_version() {
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub fn print(req: PrintRequest, sess: &Session) {
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}

pub fn enable_llvm_debug() {
    unsafe { llvm::LLVMRustSetDebug(1); }
}
<|endoftext|>


<commit_before><commit_msg>renamed some floating-point constants<commit_after><|endoftext|>


<commit_before>/**
    The layout task. Performs layout on the DOM, builds display lists and sends them to be
    rendered.
*/

use au = gfx::geometry;
use au::au;
use content::content_task;
use core::dvec::DVec;
use css::resolve::apply::apply_style;
use css::values::Stylesheet;
use dl = gfx::display_list;
use dom::event::{Event, ReflowEvent};
use dom::node::{Node, LayoutData};
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::render_task;
use gfx::render_layers::RenderLayer;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use opt = core::option;
use render_task::RenderTask;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache;
use servo_text::font_cache::FontCache;
use std::arc::ARC;
use std::net::url::Url;
use core::util::replace;

use layout::traverse::*;
use comm::*;
use task::*;

pub type LayoutTask = comm::Chan<Msg>;

pub enum LayoutQuery {
    ContentBox(Node)
}

pub type LayoutQueryResponse = Result<LayoutQueryResponse_, ()>;

enum LayoutQueryResponse_ {
    ContentSize(Size2D<int>)
}

pub enum Msg {
    BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>, pipes::Chan<()>),
    QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
    ExitMsg
}

fn LayoutTask(render_task: RenderTask,
              img_cache_task: ImageCacheTask) -> LayoutTask {
    do spawn_listener::<Msg> |from_content| {
        Layout(render_task, img_cache_task.clone(), from_content).start();
    }
}

struct Layout {
    render_task: RenderTask,
    image_cache_task: ImageCacheTask,
    local_image_cache: @LocalImageCache,
    from_content: comm::Port<Msg>,

    font_cache: @FontCache,
    // This is used to root auxilliary RCU reader data
    layout_refs: DVec<@LayoutData>
}

fn Layout(render_task: RenderTask,
         image_cache_task: ImageCacheTask,
         from_content: comm::Port<Msg>) -> Layout {

    Layout {
        render_task: render_task,
        image_cache_task: image_cache_task.clone(),
        local_image_cache: @LocalImageCache(move image_cache_task),
        from_content: from_content,
        font_cache: FontCache(),
        layout_refs: DVec()
    }
}

impl Layout {

    fn handle_query(query: LayoutQuery,
                    reply_chan: comm::Chan<LayoutQueryResponse>) {
        match query {
            ContentBox(node) => {
                // TODO: extract me to a method when I get sibling arms
                let response = match node.aux(|a| copy *a).flow {
                    None => Err(()),
                    Some(flow) => {
                        let start_val : Option<Rect<au>> = None;
                        let rect = do flow.foldl_boxes_for_node(node, start_val) |acc, box| {
                            match acc {
                                Some(acc) => Some(acc.union(&box.content_box())),
                                None => Some(box.content_box())
                            }
                        };

                        match rect {
                            None => Err(()),
                            Some(rect) => {
                                let size = Size2D(au::to_px(rect.size.width),
                                                  au::to_px(rect.size.height));
                                Ok(ContentSize(move size))
                            }
                        }
                    }
                };

                reply_chan.send(response)
            }
        }
    }

    fn start() {
        while self.handle_request() {
            // loop indefinitely
        }
    }

    fn handle_request() -> bool {

        match self.from_content.recv() {
            QueryMsg(query, chan) => self.handle_query(query, chan),
            ExitMsg => {
                debug!("layout: ExitMsg received");
                return false
            },
            BuildMsg(node, styles, doc_url, to_content, window_size, join_chan) => {
                debug!("layout: received layout request for: %s", doc_url.to_str());
                debug!("layout: parsed Node tree");
                debug!("%?", node.dump());

                // Reset the image cache
                self.local_image_cache.next_round(self.make_on_image_available_cb(to_content));

                let screen_size = Size2D(au::from_px(window_size.width as int),
                                         au::from_px(window_size.height as int));

                let layout_ctx = LayoutContext {
                    image_cache: self.local_image_cache,
                    font_cache: self.font_cache,
                    doc_url: doc_url,
                    screen_size: Rect(Point2D(au(0), au(0)), screen_size)
                };

                let layout_root: @FlowContext = do util::time::time("layout: tree construction") {
                    // TODO: this is dumb. we don't need 3 separate traversals.
                    node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs);
                    node.recompute_style_for_subtree(&layout_ctx, &styles);
                    /* resolve styles (convert relative values) down the node tree */
                    apply_style(&layout_ctx, node);

                    let builder = LayoutTreeBuilder();
                    let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
                                                                                node) {
                        Ok(root) => root,
                        Err(*) => fail ~"Root flow should always exist"
                    };

                    debug!("layout: constructed Flow tree");
                    debug!("%?", layout_root.dump());

                    layout_root
                };

                do util::time::time("layout: main layout") {
                    /* perform layout passes over the flow tree */
                    do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) }
                    do layout_root.traverse_preorder  |f| { f.assign_widths(&layout_ctx) }
                    do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) }
                }

                do util::time::time("layout: display list building") {
                    let dlist = DVec();
                    let builder = dl::DisplayListBuilder {
                        ctx: &layout_ctx,
                    };
                    let render_layer = RenderLayer {
                        display_list: move dlist,
                        size: Size2D(au::to_px(screen_size.width) as uint,
                                     au::to_px(screen_size.height) as uint)
                    };

                    // TODO: set options on the builder before building
                    // TODO: be smarter about what needs painting
                    layout_root.build_display_list(&builder, &copy layout_root.d().position,
                                                   &render_layer.display_list);
                    self.render_task.send(render_task::RenderMsg(move render_layer));
                } // time(layout: display list building)

                // Tell content we're done
                join_chan.send(());

            } // BuildMsg
        } // match

        true
    }

    // When images can't be loaded in time to display they trigger
    // this callback in some task somewhere. This w
    fn make_on_image_available_cb(to_content: comm::Chan<Event>) -> ~fn(ImageResponseMsg) {
        let f: ~fn(ImageResponseMsg) = |_msg| {
            to_content.send(ReflowEvent)
        };
        return f;
    }
}

<commit_msg>Refactor layout_task a little<commit_after>/**
    The layout task. Performs layout on the DOM, builds display lists and sends them to be
    rendered.
*/

use au = gfx::geometry;
use au::au;
use content::content_task;
use core::dvec::DVec;
use css::resolve::apply::apply_style;
use css::values::Stylesheet;
use dl = gfx::display_list;
use dom::event::{Event, ReflowEvent};
use dom::node::{Node, LayoutData};
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::render_task;
use gfx::render_layers::RenderLayer;
use layout::box::RenderBox;
use layout::box_builder::LayoutTreeBuilder;
use layout::context::LayoutContext;
use opt = core::option;
use render_task::RenderTask;
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
use resource::local_image_cache::LocalImageCache;
use servo_text::font_cache::FontCache;
use std::arc::ARC;
use std::net::url::Url;
use core::util::replace;

use layout::traverse::*;
use comm::*;
use task::*;

pub type LayoutTask = comm::Chan<Msg>;

pub enum LayoutQuery {
    ContentBox(Node)
}

pub type LayoutQueryResponse = Result<LayoutQueryResponse_, ()>;

enum LayoutQueryResponse_ {
    ContentSize(Size2D<int>)
}

pub enum Msg {
    BuildMsg(Node, ARC<Stylesheet>, Url, comm::Chan<Event>, Size2D<uint>, pipes::Chan<()>),
    QueryMsg(LayoutQuery, comm::Chan<LayoutQueryResponse>),
    ExitMsg
}

fn LayoutTask(render_task: RenderTask,
              img_cache_task: ImageCacheTask) -> LayoutTask {
    do spawn_listener::<Msg> |from_content| {
        Layout(render_task, img_cache_task.clone(), from_content).start();
    }
}

struct Layout {
    render_task: RenderTask,
    image_cache_task: ImageCacheTask,
    local_image_cache: @LocalImageCache,
    from_content: comm::Port<Msg>,

    font_cache: @FontCache,
    // This is used to root auxilliary RCU reader data
    layout_refs: DVec<@LayoutData>
}

fn Layout(render_task: RenderTask,
         image_cache_task: ImageCacheTask,
         from_content: comm::Port<Msg>) -> Layout {

    Layout {
        render_task: render_task,
        image_cache_task: image_cache_task.clone(),
        local_image_cache: @LocalImageCache(move image_cache_task),
        from_content: from_content,
        font_cache: FontCache(),
        layout_refs: DVec()
    }
}

impl Layout {

    fn start() {
        while self.handle_request() {
            // loop indefinitely
        }
    }

    fn handle_request() -> bool {

        match self.from_content.recv() {
            BuildMsg(move node, move styles, move doc_url,
                     move to_content, move window_size, move join_chan) => {
                self.handle_build(node, styles, doc_url, to_content, window_size, join_chan);
            }
            QueryMsg(query, chan) => self.handle_query(query, chan),
            ExitMsg => {
                debug!("layout: ExitMsg received");
                return false
            }
        }

        true
    }

    fn handle_build(node: Node, styles: ARC<Stylesheet>, doc_url: Url,
                    to_content: comm::Chan<Event>, window_size: Size2D<uint>,
                    join_chan: pipes::Chan<()>) {
        debug!("layout: received layout request for: %s", doc_url.to_str());
        debug!("layout: parsed Node tree");
        debug!("%?", node.dump());

        // Reset the image cache
        self.local_image_cache.next_round(self.make_on_image_available_cb(to_content));

        let screen_size = Size2D(au::from_px(window_size.width as int),
                                 au::from_px(window_size.height as int));

        let layout_ctx = LayoutContext {
            image_cache: self.local_image_cache,
            font_cache: self.font_cache,
            doc_url: doc_url,
            screen_size: Rect(Point2D(au(0), au(0)), screen_size)
        };

        let layout_root: @FlowContext = do util::time::time("layout: tree construction") {
            // TODO: this is dumb. we don't need 3 separate traversals.
            node.initialize_style_for_subtree(&layout_ctx, &self.layout_refs);
            node.recompute_style_for_subtree(&layout_ctx, &styles);
            /* resolve styles (convert relative values) down the node tree */
            apply_style(&layout_ctx, node);

            let builder = LayoutTreeBuilder();
            let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
                                                                          node) {
                Ok(root) => root,
                Err(*) => fail ~"Root flow should always exist"
            };

            debug!("layout: constructed Flow tree");
            debug!("%?", layout_root.dump());

            layout_root
        };

        do util::time::time("layout: main layout") {
            /* perform layout passes over the flow tree */
            do layout_root.traverse_postorder |f| { f.bubble_widths(&layout_ctx) }
            do layout_root.traverse_preorder  |f| { f.assign_widths(&layout_ctx) }
            do layout_root.traverse_postorder |f| { f.assign_height(&layout_ctx) }
        }

        do util::time::time("layout: display list building") {
            let dlist = DVec();
            let builder = dl::DisplayListBuilder {
                ctx: &layout_ctx,
            };
            let render_layer = RenderLayer {
                display_list: move dlist,
                size: Size2D(au::to_px(screen_size.width) as uint,
                             au::to_px(screen_size.height) as uint)
            };

            // TODO: set options on the builder before building
            // TODO: be smarter about what needs painting
            layout_root.build_display_list(&builder, &copy layout_root.d().position,
                                           &render_layer.display_list);
            self.render_task.send(render_task::RenderMsg(move render_layer));
        } // time(layout: display list building)

        // Tell content we're done
        join_chan.send(());

    }

    fn handle_query(query: LayoutQuery,
                    reply_chan: comm::Chan<LayoutQueryResponse>) {
        match query {
            ContentBox(node) => {
                // TODO: extract me to a method when I get sibling arms
                let response = match node.aux(|a| copy *a).flow {
                    None => Err(()),
                    Some(flow) => {
                        let start_val : Option<Rect<au>> = None;
                        let rect = do flow.foldl_boxes_for_node(node, start_val) |acc, box| {
                            match acc {
                                Some(acc) => Some(acc.union(&box.content_box())),
                                None => Some(box.content_box())
                            }
                        };

                        match rect {
                            None => Err(()),
                            Some(rect) => {
                                let size = Size2D(au::to_px(rect.size.width),
                                                  au::to_px(rect.size.height));
                                Ok(ContentSize(move size))
                            }
                        }
                    }
                };

                reply_chan.send(response)
            }
        }
    }

    // When images can't be loaded in time to display they trigger
    // this callback in some task somewhere. This w
    fn make_on_image_available_cb(to_content: comm::Chan<Event>) -> ~fn(ImageResponseMsg) {
        let f: ~fn(ImageResponseMsg) = |_msg| {
            to_content.send(ReflowEvent)
        };
        return f;
    }
}

<|endoftext|>


<commit_before><commit_msg>refactor(tests): Be more explicit about publish stderr<commit_after><|endoftext|>


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

// Issue #7580

// error-pattern:fail works
#[feature(globs)];

use std::*;

fn main() {
    str::with_capacity(10); // avoid an unused import message

    fail!("fail works")
}
<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;
use git2::{Reference as GitReference, Repository, Error as Git2Error};

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::error::CustomData as HECD;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagerror::trace::trace_error;
use libimagerror::into::IntoError;

use vcs::git::result::Result;
use vcs::git::error::MapErrInto;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::GitHookError as GHE;
use vcs::git::runtime::Runtime;

pub struct CreateHook {
    storepath: PathBuf,

    runtime: Runtime,

    position: HookPosition,
}

impl CreateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> CreateHook {
        CreateHook {
            runtime: Runtime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for CreateHook {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "CreateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for CreateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_create"
    }

    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for CreateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for CreateHook {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;

        debug!("[GIT CREATE HOOK]: {:?}", id);

        debug!("[GIT CREATE HOOK]: Ensuring branch checkout");
        try!(self
             .runtime
             .ensure_cfg_branch_is_checked_out()
             .map_err(Box::new)
             .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e)));
        debug!("[GIT CREATE HOOK]: Branch checked out");

        self.runtime
            .config_value_or_err()
            .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't get Value object from config"); e })
            .and_then(|cfg| {
                debug!("[GIT CREATE HOOK]: Getting repository");
                self.runtime
                    .repository()
                    .map(|r| (r, cfg))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't fetch Repository"); e })
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg)| {
                repo.signature()
                    .map(|s| (repo, cfg, s))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't fetch Signature"); e })
                    .map_err_into(GHEK::RepositorySignatureFetchingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig)| {
                repo.index()
                    .map(|idx| (repo, cfg, sig, idx))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't fetch Index"); e })
                    .map_err_into(GHEK::RepositoryIndexFetchingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, mut idx)| {
                id.strip_prefix(&self.storepath)
                    .map_err_into(GHEK::StoreIdStripError)
                    .and_then(|id| idx.add_path(&id).map_err_into(GHEK::RepositoryPathAddingError))
                    .map(|_| (repo, cfg, sig, idx))
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't add Path: {:?}", e); e })
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, mut idx)| {
                idx.write_tree()
                    .map(|oid| (repo, cfg, sig, idx, oid))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't write Tree"); e })
                    .map_err_into(GHEK::RepositoryTreeWritingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, idx, oid)| {
                repo.find_tree(oid)
                    .map(|tree| (repo, cfg, sig, idx, oid, tree))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't find Tree"); e })
                    .map_err_into(GHEK::RepositoryTreeFindingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, idx, oid, tree)| {
                let cmtmsg = commit_message(cfg, StoreAction::Create);
                repo.find_commit(oid)
                    .map(|cmt| (repo, sig, tree, cmt, cmtmsg))
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't find Commit"); e })
                    .map_err_into(GHEK::RepositoryCommitFindingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, sig, tree, cmt, commitmsg)| {
                repo.commit(Some("HEAD"), &sig, &sig, &commitmsg[..], &tree, &[&cmt])
                    .map_err(|e| { debug!("[GIT CREATE HOOK]: Couldn't create Commit"); e })
                    .map_err_into(GHEK::RepositoryCommittingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .map(|_| ())
    }

}

<commit_msg>Refactor to use Result::map_dbg_err_str()<commit_after>use std::path::PathBuf;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;
use git2::{Reference as GitReference, Repository, Error as Git2Error};

use libimagstore::storeid::StoreId;
use libimagstore::hook::Hook;
use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::error::CustomData as HECD;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagerror::trace::trace_error;
use libimagerror::into::IntoError;
use libimagutil::debug_result::*;

use vcs::git::result::Result;
use vcs::git::error::MapErrInto;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::GitHookError as GHE;
use vcs::git::runtime::Runtime;

pub struct CreateHook {
    storepath: PathBuf,

    runtime: Runtime,

    position: HookPosition,
}

impl CreateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> CreateHook {
        CreateHook {
            runtime: Runtime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for CreateHook {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "CreateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?}",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for CreateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_create"
    }

    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for CreateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for CreateHook {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;

        debug!("[GIT CREATE HOOK]: {:?}", id);

        debug!("[GIT CREATE HOOK]: Ensuring branch checkout");
        try!(self
             .runtime
             .ensure_cfg_branch_is_checked_out()
             .map_err(Box::new)
             .map_err(|e| HEK::HookExecutionError.into_error_with_cause(e)));
        debug!("[GIT CREATE HOOK]: Branch checked out");

        self.runtime
            .config_value_or_err()
            .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't get Value object from config")
            .and_then(|cfg| {
                debug!("[GIT CREATE HOOK]: Getting repository");
                self.runtime
                    .repository()
                    .map(|r| (r, cfg))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Repository")
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg)| {
                repo.signature()
                    .map(|s| (repo, cfg, s))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Signature")
                    .map_err_into(GHEK::RepositorySignatureFetchingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig)| {
                repo.index()
                    .map(|idx| (repo, cfg, sig, idx))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Index")
                    .map_err_into(GHEK::RepositoryIndexFetchingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, mut idx)| {
                id.strip_prefix(&self.storepath)
                    .map_err_into(GHEK::StoreIdStripError)
                    .and_then(|id| idx.add_path(&id).map_err_into(GHEK::RepositoryPathAddingError))
                    .map(|_| (repo, cfg, sig, idx))
                    .map_err_into(GHEK::RepositoryError)
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't add Path: {:?}")
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, mut idx)| {
                idx.write_tree()
                    .map(|oid| (repo, cfg, sig, idx, oid))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't write Tree")
                    .map_err_into(GHEK::RepositoryTreeWritingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, idx, oid)| {
                repo.find_tree(oid)
                    .map(|tree| (repo, cfg, sig, idx, oid, tree))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't find Tree")
                    .map_err_into(GHEK::RepositoryTreeFindingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, cfg, sig, idx, oid, tree)| {
                let cmtmsg = commit_message(cfg, StoreAction::Create);
                repo.find_commit(oid)
                    .map(|cmt| (repo, sig, tree, cmt, cmtmsg))
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't find Commit")
                    .map_err_into(GHEK::RepositoryCommitFindingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .and_then(|(repo, sig, tree, cmt, commitmsg)| {
                repo.commit(Some("HEAD"), &sig, &sig, &commitmsg[..], &tree, &[&cmt])
                    .map_dbg_err_str("[GIT CREATE HOOK]: Couldn't create Commit")
                    .map_err_into(GHEK::RepositoryCommittingError)
                    .map_err_into(GHEK::RepositoryError)
                    .map_err(|e| e.into())
            })
            .map(|_| ())
    }

}

<|endoftext|>


<commit_before><commit_msg>add importobj.rs<commit_after>use std;
use material;
use std::rc::Rc;
use genmesh::Polygon;
use utils::get_full_path;
use cgmath::{Vector, Vector2, Vector3};
use mesh::{Model, Mesh, Vertex};
use obj::{Obj, Material, IndexTuple, load};
use memory::cast_to;

pub struct ModelObj<'a> {
    model_dir: std::path::PathBuf,
    map: std::collections::HashMap<IndexTuple, u32>,
    model: Model,
    position_buffer: &'a [Vector3<f32>],
    normal_buffer: &'a [Vector3<f32>],
    tex_buffer: &'a [Vector2<f32>],
}

impl<'a> ModelObj<'a> {
    fn get_index(&mut self, index: IndexTuple) -> u32 {
        let zero2 = Vector2::new(0.0_f32, 0.0_f32);
        let zero3 = Vector3::new(0.0_f32, 0.0_f32, 0.0_f32);
        if self.map.get(&index).is_none() {
            self.model.vertex_buffer.push(
                Vertex::new(
                    &self.position_buffer[index.0],
                    &match index.1 {
                        Some(t) => self.tex_buffer[t],
                        None => zero2,
                    },
                    &match index.2 {
                        Some(n) => self.normal_buffer[n],
                        None => zero3,
                    }));
        };
        let len = self.model.vertex_buffer.len() as u32 - 1;
        self.map.entry(index).or_insert(len).clone()
    }

    fn parse(&mut self, model_obj: &Obj<Rc<Material>>) -> Result<(), String> {
        for object in model_obj.object_iter() {
            for group in object.group_iter() {
                let mut mesh = Mesh::new();
                for polygon in group.indices() {
                    match polygon {
                        &Polygon::PolyTri(p) => {
                            let ind0 = self.get_index(p.x);
                            let ind1 = self.get_index(p.y);
                            let ind2 = self.get_index(p.z);
                            mesh.index_buffer.push(ind0);
                            mesh.index_buffer.push(ind1);
                            mesh.index_buffer.push(ind2);
                        },
                        &Polygon::PolyQuad(p) => {
                            let ind0 = self.get_index(p.x);
                            let ind1 = self.get_index(p.y);
                            let ind2 = self.get_index(p.z);
                            let ind3 = self.get_index(p.w);
                            mesh.index_buffer.push(ind0);
                            mesh.index_buffer.push(ind1);
                            mesh.index_buffer.push(ind2);
                            mesh.index_buffer.push(ind0);
                            mesh.index_buffer.push(ind2);
                            mesh.index_buffer.push(ind3);
                        },
                    };
                }
                let material = group.material.clone();
                mesh.material_id = match material {
                    Some(m) => {
                        let mut mat = material::Material::new();
                        match m.ka {
                            Some(v) => mat.ambient = Vector3::new(v[0], v[1], v[2]).mul_s(255.0_f32),
                            None => {},
                        };
                        match m.kd {
                            Some(v) => mat.diffuse = Vector3::new(v[0], v[1], v[2]).mul_s(255.0_f32),
                            None => {},
                        };
                        match m.ks {
                            Some(v) => mat.specular = Vector3::new(v[0], v[1], v[2]).mul_s(255.0_f32),
                            None => {},
                        };
                        match m.map_kd {
                            Some(ref path) => try!(mat.texture_from_dir(&self.model_dir, &path)),
                            None => {},
                        };
                        mat.calc_ambient_intensity();
                        self.model.material_list.push(mat);
                        self.model.material_list.len() - 1
                    },
                    None => 0,
                };
                self.model.mesh_list.push(mesh);
            }
        }

        Ok(())
    }

    pub fn load(filename: &str) -> Result<Model, String> {
        let filepath = try!(get_full_path(filename));
        let mut model_dir = std::path::PathBuf::from(filepath.clone());
        if !model_dir.pop() {
            return Err(format!("not found parent dir for filepath {}", filepath));
        }

        let model_obj: Obj<Rc<Material>> = load(std::path::Path::new(&filepath)).unwrap();
        let mut this = ModelObj {
            model_dir: model_dir,
            map: std::collections::HashMap::<IndexTuple, u32>::new(),
            model: Model::new(),
            position_buffer: cast_to(model_obj.position()),
            normal_buffer: cast_to(model_obj.normal()),
            tex_buffer: cast_to(model_obj.texture()),
        };

        let mut def_mat = material::Material::new();
        def_mat.diffuse = Vector3::new(255.0_f32, 0.0_f32, 0.0_f32);
        def_mat.ambient = Vector3::new(255.0_f32, 0.0_f32, 0.0_f32);
        this.model.material_list.push(def_mat);

        try!(this.parse(&model_obj));

        Ok(this.model)
    }
}
<|endoftext|>


<commit_before><commit_msg>Forgot to change a number. Cannot test build like usual because of Rust breaking changes.<commit_after><|endoftext|>


<commit_before><commit_msg>Log when we back off.<commit_after><|endoftext|>


<commit_before><commit_msg>Add debug output<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for rectangles case<commit_after>use std::cmp::Ordering;

#[derive(Debug, PartialEq, Eq)]
struct Rectangle {
    x: usize,
    y: usize,
    dx: usize,
    dy: usize,
}

impl Rectangle {
    fn new(x: usize, y: usize, dx: usize, dy: usize) -> Rectangle {
        Rectangle {
            x: x,
            y: y,
            dx: dx,
            dy: dy,
        }
    }

    fn segments(&self) -> [usize; 4] {
        [self.x, self.y, self.dx, self.dy]
    }
}

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

impl Ord for Rectangle {
    fn cmp(&self, other: &Rectangle) -> Ordering {
        self.segments().cmp(&other.segments())
    }
}

#[derive(Debug, PartialEq)]
struct Point {
    x: usize,
    y: usize,
}

#[inline]
fn get_corners(board: &[char], width: usize) -> Vec<Point> {
    board
        .iter()
        .enumerate()
        .filter_map(|(i, &c)| if c == '+' {
            Some(Point {
                x: i % width,
                y: i / width,
            })
        } else {
            None
        })
        .collect()
}

#[inline]
fn get_rectangles(corners: &[Point]) -> Vec<Rectangle> {
    let mut rectangles = Vec::new();

    for i in 0..corners.len() {
        for j in i..corners.len() {
            let pa = &corners[i];
            let pb = &corners[j];

            if pa.x == pb.x || pa.y == pb.y {
                continue;
            }

            if !corners.contains(&Point { x: pa.x, y: pb.y }) ||
                !corners.contains(&Point { x: pb.x, y: pa.y })
            {
                continue;
            }

            let (x, dx) = if pa.x > pb.x {
                (pb.x, pa.x - pb.x)
            } else {
                (pa.x, pb.x - pa.x)
            };

            rectangles.push(Rectangle::new(x, pa.y, dx, pb.y - pa.y));
        }
    }

    rectangles
}

#[inline]
fn is_rectangle(rectangle: &Rectangle, board: &[char], width: usize) -> bool {
    let r = (1..rectangle.dx).any(|i| {
        let m = rectangle.y * width + rectangle.x + i;
        let n = (rectangle.y + rectangle.dy) * width + rectangle.x + i;
        (board[m] != '-' && board[m] != '+') || (board[n] != '-' && board[n] != '+')
    });

    if r {
        return false;
    }

    let r = (1..rectangle.dy).any(|i| {
        let m = (rectangle.y + i) * width + rectangle.x;
        let n = (rectangle.y + i) * width + rectangle.x + rectangle.dx;
        (board[m] != '|' && board[m] != '+') || (board[n] != '|' && board[n] != '+')
    });

    if r {
        return false;
    }

    true
}

pub fn count(text: &[&str]) -> usize {
    let height = text.len();
    if height == 0 {
        return 0;
    }

    let width = text[0].len();
    if width < 2 {
        return 0;
    }

    let board = text.iter().flat_map(|s| s.chars()).collect::<Vec<_>>();

    let corners = get_corners(&board, width);

    let mut rectangles = get_rectangles(&corners);

    rectangles.sort();
    rectangles.dedup();
    rectangles
        .iter()
        .filter(|x| is_rectangle(x, &board, width))
        .count()
}
<|endoftext|>


<commit_before><commit_msg>Implement Process Detection in the ArgumentSplitter<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Percent and Time display<commit_after><|endoftext|>


<commit_before><commit_msg>Add support for recording bind descriptor set commands to arbitrary command buffers<commit_after><|endoftext|>


<commit_before><commit_msg>Borrowed pointers<commit_after>fn plus_one(x: &int) -> int {
  *x + 1
}

fn main() {
  let x: @int = @10;
  let y: ~int = ~10;

  println(plus_one(x).to_str());
  println(plus_one(y).to_str());
}

<|endoftext|>


<commit_before><commit_msg>works<commit_after><|endoftext|>


<commit_before><commit_msg>Use more fine-granular function as Runtime::ignore_ids() was removed<commit_after><|endoftext|>


<commit_before><commit_msg>Minor<commit_after><|endoftext|>


<commit_before><commit_msg>Don't reuse PathBuilder after calling finish()<commit_after><|endoftext|>


<commit_before><commit_msg>First attempt at rust!<commit_after>// TODO
// impl ToGeojson for ....
// generic number instead of f64 for position?
// rename Position to Pos

extern crate serialize;

use std::collections::TreeMap;
use serialize::json::ToJson;
use serialize::json;

/*
 * Position
 * GeoJSON Format Specification § 2.1.1
 * http://geojson.org/geojson-spec.html#positions
 */
pub struct Position(Vec<f64>);

impl ToJson for Position {
    fn to_json(&self) -> json::Json {
        let &Position(ref nums) = self;
        nums.to_json()
    }
}

/*
 * Point
 * GeoJSON Format Specification § 2.1.2
 * http://geojson.org/geojson-spec.html#point
 */
pub struct Point {
    coordinates: Position,
}

impl ToJson for Point {
    fn to_json(&self) -> json::Json {
        let mut d = TreeMap::new();
        d.insert("type".to_string(), json::String("Point".to_string()));
        d.insert("coordinates".to_string(), self.coordinates.to_json());
        d.to_json()
    }
}

/*
 * MultiPoint
 * GeoJSON Format Specification § 2.1.3
 * http://geojson.org/geojson-spec.html#multipoint
 */
pub struct MultiPoint {
    coordinates: Vec<Position>,
}

fn main() {
    let point = Point {
        coordinates: Position(vec![1., 2., 3.]),
    };

    let j: json::Json = point.to_json();
    let s: String = j.to_pretty_str();

    println!("{}", s);
}
<|endoftext|>


<commit_before><commit_msg>Add debug and trace output<commit_after><|endoftext|>


<commit_before><commit_msg>Add function to get relative file path<commit_after><|endoftext|>


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

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::fs::OpenOptions;
use std::path::{Path, PathBuf};

use serde_json;

use devicemapper::{devnode_to_devno, Device, Sectors};

use stratis::{ErrorEnum, StratisError, StratisResult};

use super::super::super::types::{BlockDevTier, DevUuid, PoolUuid};

use super::super::serde_structs::{BackstoreSave, BlockDevSave, PoolSave};

use super::blockdev::StratBlockDev;
use super::device::{blkdev_size, is_stratis_device};
use super::metadata::BDA;
use super::util::get_stratis_block_devices;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a map of devices to devnodes for each pool.
pub fn find_all() -> StratisResult<HashMap<PoolUuid, HashMap<Device, PathBuf>>> {
    let mut pool_map = HashMap::new();

    for devnode in get_stratis_block_devices()? {
        match devnode_to_devno(&devnode)? {
            None => continue,
            Some(devno) => {
                is_stratis_device(&devnode)?.and_then(|pool_uuid| {
                    pool_map
                        .entry(pool_uuid)
                        .or_insert_with(HashMap::new)
                        .insert(Device::from(devno), devnode)
                });
            }
        }
    }
    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
#[allow(implicit_hasher)]
pub fn get_metadata(
    pool_uuid: PoolUuid,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<Option<PoolSave>> {
    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes.values() {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?;
        if let Some(bda) = bda {
            if bda.pool_uuid() == pool_uuid {
                bdas.push((devnode, bda));
            }
        }
    }

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = {
        match bdas.iter()
            .filter_map(|&(_, ref bda)| bda.last_update_time())
            .max()
        {
            Some(time) => time,
            None => return Ok(None),
        }
    };

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in bdas.iter()
        .filter(|&&(_, ref bda)| bda.last_update_time() == Some(most_recent_time))
    {
        let poolsave = OpenOptions::new()
            .read(true)
            .open(devnode)
            .ok()
            .and_then(|mut f| bda.load_state(&mut f).ok())
            .and_then(|opt| opt)
            .and_then(|data| serde_json::from_slice(&data).ok());

        if poolsave.is_some() {
            return Ok(poolsave);
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data successfully read";
    Err(StratisError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get all the blockdevs corresponding to this pool that can be obtained from
/// the given devices.
/// Returns an error if a BDA can not be read or can not be found on any
/// blockdev in devnodes.
/// Returns an error if the blockdevs obtained do not match the metadata.
/// Returns a tuple, of which the first are the data devs, and the second
/// are the devs that support the cache tier.
/// Precondition: Every device in devnodes has already been determined to
/// belong to the pool with the specified pool uuid.
#[allow(implicit_hasher)]
pub fn get_blockdevs(
    pool_uuid: PoolUuid,
    backstore_save: &BackstoreSave,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<(Vec<StratBlockDev>, Vec<StratBlockDev>)> {
    let recorded_data_map: HashMap<DevUuid, (usize, &BlockDevSave)> = backstore_save
        .data_devs
        .iter()
        .enumerate()
        .map(|(i, bds)| (bds.uuid, (i, bds)))
        .collect();

    let recorded_cache_map: HashMap<DevUuid, (usize, &BlockDevSave)> =
        match backstore_save.cache_devs {
            Some(ref cache_devs) => cache_devs
                .iter()
                .enumerate()
                .map(|(i, bds)| (bds.uuid, (i, bds)))
                .collect(),
            None => HashMap::new(),
        };

    let mut segment_table: HashMap<DevUuid, Vec<(Sectors, Sectors)>> = HashMap::new();
    for seg in &backstore_save.data_segments {
        segment_table
            .entry(seg.0)
            .or_insert_with(Vec::default)
            .push((seg.1, seg.2))
    }
    if let Some(ref segs) = backstore_save.cache_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }
    if let Some(ref segs) = backstore_save.meta_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }

    // Construct a single StratBlockDev. Return the tier to which the
    // blockdev has been found to belong. Returns an error if the block
    // device has shrunk, no metadata can be found for the block device,
    // or it is impossible to set up the device because the recorded
    // allocation information is impossible.
    fn get_blockdev(
        device: Device,
        devnode: &Path,
        bda: BDA,
        data_map: &HashMap<DevUuid, (usize, &BlockDevSave)>,
        cache_map: &HashMap<DevUuid, (usize, &BlockDevSave)>,
        segment_table: &HashMap<DevUuid, Vec<(Sectors, Sectors)>>,
    ) -> StratisResult<(BlockDevTier, StratBlockDev)> {
        // Return an error if apparent size of Stratis block device appears to
        // have decreased since metadata was recorded or if size of block
        // device could not be obtained.
        blkdev_size(&OpenOptions::new().read(true).open(devnode)?).and_then(|actual_size| {
            let actual_size_sectors = actual_size.sectors();
            let recorded_size = bda.dev_size();
            if actual_size_sectors < recorded_size {
                let err_msg = format!(
                    "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had recorded size ({}), but actual size is less at ({})",
                    device,
                    devnode.display(),
                    bda.pool_uuid(),
                    bda.dev_uuid(),
                    recorded_size,
                    actual_size
                );
                Err(StratisError::Engine(ErrorEnum::Error, err_msg))
            } else {
                Ok(())
            }
        })?;

        let dev_uuid = bda.dev_uuid();

        // Locate the device in the metadata using its uuid. Return the device
        // metadata and whether it was a cache or a datadev.
        let (tier, (_, bd_save)) = data_map
            .get(&dev_uuid)
            .map(|bd_save| (BlockDevTier::Data, bd_save))
            .or_else(|| {
                cache_map
                    .get(&dev_uuid)
                    .map(|bd_save| (BlockDevTier::Cache, bd_save))
            })
            .ok_or_else(|| {
                let err_msg = format!(
                        "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had no record in pool metadata",
                        device,
                        devnode.display(),
                        bda.pool_uuid(),
                        bda.dev_uuid()
                    );
                StratisError::Engine(ErrorEnum::NotFound, err_msg)
            })?;

        // This should always succeed since the actual size is at
        // least the recorded size, so all segments should be
        // available to be allocated. If this fails, the most likely
        // conclusion is metadata corruption.
        let segments = segment_table.get(&dev_uuid);
        Ok((
            tier,
            StratBlockDev::new(
                device,
                devnode.to_owned(),
                bda,
                segments.unwrap_or(&vec![]),
                bd_save.user_info.clone(),
                bd_save.hardware_info.clone(),
            )?,
        ))
    }

    let (mut datadevs, mut cachedevs) = (vec![], vec![]);
    for (device, devnode) in devnodes {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?.ok_or_else(|| {
            StratisError::Engine(ErrorEnum::NotFound,
                                                 format!("Device {} with devnode {} was previously determined to belong to pool with uuid {} but no BDA was found",
                                                 device,
                                                 devnode.display(),
                                                 pool_uuid))
        })?;

        get_blockdev(
            *device,
            devnode,
            bda,
            &recorded_data_map,
            &recorded_cache_map,
            &segment_table,
        ).map(|(tier, blockdev)| {
            match tier {
                BlockDevTier::Data => &mut datadevs,
                BlockDevTier::Cache => &mut cachedevs,
            }.push(blockdev)
        })?;
    }

    // Verify that datadevs found match datadevs recorded.
    let current_data_uuids: HashSet<_> = datadevs.iter().map(|b| b.uuid()).collect();
    let recorded_data_uuids: HashSet<_> = recorded_data_map.keys().cloned().collect();
    if current_data_uuids != recorded_data_uuids {
        let err_msg = "Recorded data dev UUIDs != discovered datadev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if datadevs.len() != current_data_uuids.len() {
        let err_msg = "Duplicate data devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    // Verify that cachedevs found match cachedevs recorded.
    let current_cache_uuids: HashSet<_> = cachedevs.iter().map(|b| b.uuid()).collect();
    let recorded_cache_uuids: HashSet<_> = recorded_cache_map.keys().cloned().collect();
    if current_cache_uuids != recorded_cache_uuids {
        let err_msg = "Recorded cache dev UUIDs != discovered cachedev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if cachedevs.len() != current_cache_uuids.len() {
        let err_msg = "Duplicate cache devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok((datadevs, cachedevs))
}
<commit_msg>Make explicit the type of the elements of two Vecs<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/.

// Code to handle initial setup steps for a pool.
// Initial setup steps are steps that do not alter the environment.

use std::collections::{HashMap, HashSet};
use std::fs::OpenOptions;
use std::path::{Path, PathBuf};

use serde_json;

use devicemapper::{devnode_to_devno, Device, Sectors};

use stratis::{ErrorEnum, StratisError, StratisResult};

use super::super::super::types::{BlockDevTier, DevUuid, PoolUuid};

use super::super::serde_structs::{BackstoreSave, BlockDevSave, PoolSave};

use super::blockdev::StratBlockDev;
use super::device::{blkdev_size, is_stratis_device};
use super::metadata::BDA;
use super::util::get_stratis_block_devices;

/// Find all Stratis devices.
///
/// Returns a map of pool uuids to a map of devices to devnodes for each pool.
pub fn find_all() -> StratisResult<HashMap<PoolUuid, HashMap<Device, PathBuf>>> {
    let mut pool_map = HashMap::new();

    for devnode in get_stratis_block_devices()? {
        match devnode_to_devno(&devnode)? {
            None => continue,
            Some(devno) => {
                is_stratis_device(&devnode)?.and_then(|pool_uuid| {
                    pool_map
                        .entry(pool_uuid)
                        .or_insert_with(HashMap::new)
                        .insert(Device::from(devno), devnode)
                });
            }
        }
    }
    Ok(pool_map)
}

/// Get the most recent metadata from a set of Devices for a given pool UUID.
/// Returns None if no metadata found for this pool.
#[allow(implicit_hasher)]
pub fn get_metadata(
    pool_uuid: PoolUuid,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<Option<PoolSave>> {
    // Get pairs of device nodes and matching BDAs
    // If no BDA, or BDA UUID does not match pool UUID, skip.
    // If there is an error reading the BDA, error. There could have been
    // vital information on that BDA, for example, it may have contained
    // the newest metadata.
    let mut bdas = Vec::new();
    for devnode in devnodes.values() {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?;
        if let Some(bda) = bda {
            if bda.pool_uuid() == pool_uuid {
                bdas.push((devnode, bda));
            }
        }
    }

    // Most recent time should never be None if this was a properly
    // created pool; this allows for the method to be called in other
    // circumstances.
    let most_recent_time = {
        match bdas.iter()
            .filter_map(|&(_, ref bda)| bda.last_update_time())
            .max()
        {
            Some(time) => time,
            None => return Ok(None),
        }
    };

    // Try to read from all available devnodes that could contain most
    // recent metadata. In the event of errors, continue to try until all are
    // exhausted.
    for &(devnode, ref bda) in bdas.iter()
        .filter(|&&(_, ref bda)| bda.last_update_time() == Some(most_recent_time))
    {
        let poolsave = OpenOptions::new()
            .read(true)
            .open(devnode)
            .ok()
            .and_then(|mut f| bda.load_state(&mut f).ok())
            .and_then(|opt| opt)
            .and_then(|data| serde_json::from_slice(&data).ok());

        if poolsave.is_some() {
            return Ok(poolsave);
        }
    }

    // If no data has yet returned, we have an error. That is, we should have
    // some metadata, because we have a most recent time, but we failed to
    // get any.
    let err_str = "timestamp indicates data was written, but no data successfully read";
    Err(StratisError::Engine(ErrorEnum::NotFound, err_str.into()))
}

/// Get all the blockdevs corresponding to this pool that can be obtained from
/// the given devices.
/// Returns an error if a BDA can not be read or can not be found on any
/// blockdev in devnodes.
/// Returns an error if the blockdevs obtained do not match the metadata.
/// Returns a tuple, of which the first are the data devs, and the second
/// are the devs that support the cache tier.
/// Precondition: Every device in devnodes has already been determined to
/// belong to the pool with the specified pool uuid.
#[allow(implicit_hasher)]
pub fn get_blockdevs(
    pool_uuid: PoolUuid,
    backstore_save: &BackstoreSave,
    devnodes: &HashMap<Device, PathBuf>,
) -> StratisResult<(Vec<StratBlockDev>, Vec<StratBlockDev>)> {
    let recorded_data_map: HashMap<DevUuid, (usize, &BlockDevSave)> = backstore_save
        .data_devs
        .iter()
        .enumerate()
        .map(|(i, bds)| (bds.uuid, (i, bds)))
        .collect();

    let recorded_cache_map: HashMap<DevUuid, (usize, &BlockDevSave)> =
        match backstore_save.cache_devs {
            Some(ref cache_devs) => cache_devs
                .iter()
                .enumerate()
                .map(|(i, bds)| (bds.uuid, (i, bds)))
                .collect(),
            None => HashMap::new(),
        };

    let mut segment_table: HashMap<DevUuid, Vec<(Sectors, Sectors)>> = HashMap::new();
    for seg in &backstore_save.data_segments {
        segment_table
            .entry(seg.0)
            .or_insert_with(Vec::default)
            .push((seg.1, seg.2))
    }
    if let Some(ref segs) = backstore_save.cache_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }
    if let Some(ref segs) = backstore_save.meta_segments {
        for seg in segs {
            segment_table
                .entry(seg.0)
                .or_insert_with(Vec::default)
                .push((seg.1, seg.2))
        }
    }

    // Construct a single StratBlockDev. Return the tier to which the
    // blockdev has been found to belong. Returns an error if the block
    // device has shrunk, no metadata can be found for the block device,
    // or it is impossible to set up the device because the recorded
    // allocation information is impossible.
    fn get_blockdev(
        device: Device,
        devnode: &Path,
        bda: BDA,
        data_map: &HashMap<DevUuid, (usize, &BlockDevSave)>,
        cache_map: &HashMap<DevUuid, (usize, &BlockDevSave)>,
        segment_table: &HashMap<DevUuid, Vec<(Sectors, Sectors)>>,
    ) -> StratisResult<(BlockDevTier, StratBlockDev)> {
        // Return an error if apparent size of Stratis block device appears to
        // have decreased since metadata was recorded or if size of block
        // device could not be obtained.
        blkdev_size(&OpenOptions::new().read(true).open(devnode)?).and_then(|actual_size| {
            let actual_size_sectors = actual_size.sectors();
            let recorded_size = bda.dev_size();
            if actual_size_sectors < recorded_size {
                let err_msg = format!(
                    "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had recorded size ({}), but actual size is less at ({})",
                    device,
                    devnode.display(),
                    bda.pool_uuid(),
                    bda.dev_uuid(),
                    recorded_size,
                    actual_size
                );
                Err(StratisError::Engine(ErrorEnum::Error, err_msg))
            } else {
                Ok(())
            }
        })?;

        let dev_uuid = bda.dev_uuid();

        // Locate the device in the metadata using its uuid. Return the device
        // metadata and whether it was a cache or a datadev.
        let (tier, (_, bd_save)) = data_map
            .get(&dev_uuid)
            .map(|bd_save| (BlockDevTier::Data, bd_save))
            .or_else(|| {
                cache_map
                    .get(&dev_uuid)
                    .map(|bd_save| (BlockDevTier::Cache, bd_save))
            })
            .ok_or_else(|| {
                let err_msg = format!(
                        "Stratis device with device number {}, devnode {}, pool UUID {} and device UUID {} had no record in pool metadata",
                        device,
                        devnode.display(),
                        bda.pool_uuid(),
                        bda.dev_uuid()
                    );
                StratisError::Engine(ErrorEnum::NotFound, err_msg)
            })?;

        // This should always succeed since the actual size is at
        // least the recorded size, so all segments should be
        // available to be allocated. If this fails, the most likely
        // conclusion is metadata corruption.
        let segments = segment_table.get(&dev_uuid);
        Ok((
            tier,
            StratBlockDev::new(
                device,
                devnode.to_owned(),
                bda,
                segments.unwrap_or(&vec![]),
                bd_save.user_info.clone(),
                bd_save.hardware_info.clone(),
            )?,
        ))
    }

    let (mut datadevs, mut cachedevs): (Vec<StratBlockDev>, Vec<StratBlockDev>) = (vec![], vec![]);
    for (device, devnode) in devnodes {
        let bda = BDA::load(&mut OpenOptions::new().read(true).open(devnode)?)?.ok_or_else(|| {
            StratisError::Engine(ErrorEnum::NotFound,
                                                 format!("Device {} with devnode {} was previously determined to belong to pool with uuid {} but no BDA was found",
                                                 device,
                                                 devnode.display(),
                                                 pool_uuid))
        })?;

        get_blockdev(
            *device,
            devnode,
            bda,
            &recorded_data_map,
            &recorded_cache_map,
            &segment_table,
        ).map(|(tier, blockdev)| {
            match tier {
                BlockDevTier::Data => &mut datadevs,
                BlockDevTier::Cache => &mut cachedevs,
            }.push(blockdev)
        })?;
    }

    // Verify that datadevs found match datadevs recorded.
    let current_data_uuids: HashSet<_> = datadevs.iter().map(|b| b.uuid()).collect();
    let recorded_data_uuids: HashSet<_> = recorded_data_map.keys().cloned().collect();
    if current_data_uuids != recorded_data_uuids {
        let err_msg = "Recorded data dev UUIDs != discovered datadev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if datadevs.len() != current_data_uuids.len() {
        let err_msg = "Duplicate data devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    // Verify that cachedevs found match cachedevs recorded.
    let current_cache_uuids: HashSet<_> = cachedevs.iter().map(|b| b.uuid()).collect();
    let recorded_cache_uuids: HashSet<_> = recorded_cache_map.keys().cloned().collect();
    if current_cache_uuids != recorded_cache_uuids {
        let err_msg = "Recorded cache dev UUIDs != discovered cachedev UUIDs";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    if cachedevs.len() != current_cache_uuids.len() {
        let err_msg = "Duplicate cache devices found in environment";
        return Err(StratisError::Engine(ErrorEnum::Invalid, err_msg.into()));
    }

    Ok((datadevs, cachedevs))
}
<|endoftext|>


<commit_before>use std::io::fs;
use std::io;

use colours::{Plain, Style, Black, Red, Green, Yellow, Blue, Purple, Cyan};
use column::{Column, Permissions, FileName, FileSize, User, Group};
use format::{formatBinaryBytes, formatDecimalBytes};
use unix::{get_user_name, get_group_name};

// Each file is definitely going to get `stat`ted at least once, if
// only to determine what kind of file it is, so carry the `stat`
// result around with the file for safe keeping.
pub struct File<'a> {
    pub name: &'a str,
    pub ext:  Option<&'a str>,
    pub path: &'a Path,
    pub stat: io::FileStat,
}

impl<'a> File<'a> {
    pub fn from_path(path: &'a Path) -> File<'a> {
        let filename: &str = path.filename_str().unwrap();

        // We have to use lstat here instad of file.stat(), as it
        // doesn't follow symbolic links. Otherwise, the stat() call
        // will fail if it encounters a link that's target is
        // non-existent.
        let stat: io::FileStat = match fs::lstat(path) {
            Ok(stat) => stat,
            Err(e) => fail!("Couldn't stat {}: {}", filename, e),
        };

        return File {
            path: path,
            stat: stat,
            name: filename,
            ext:  File::ext(filename),
        };
    }

    fn ext(name: &'a str) -> Option<&'a str> {
        let re = regex!(r"\.(.+)$");
        re.captures(name).map(|caps| caps.at(1))
    }

    pub fn is_dotfile(&self) -> bool {
        self.name.starts_with(".")
    }

    pub fn display(&self, column: &Column) -> StrBuf {
        match *column {
            Permissions => self.permissions(),
            FileName => self.file_colour().paint(self.name.as_slice()),
            FileSize(si) => self.file_size(si),
            User => get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str()),
            Group => get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
        }
    }

    fn file_size(&self, si: bool) -> StrBuf {
        let sizeStr = if si {
            formatBinaryBytes(self.stat.size)
        } else {
            formatDecimalBytes(self.stat.size)
        };

        return if self.stat.kind == io::TypeDirectory {
            Green.normal()
        } else {
            Green.bold()
        }.paint(sizeStr.as_slice());
    }

    fn type_char(&self) -> StrBuf {
        return match self.stat.kind {
            io::TypeFile => ".".to_strbuf(),
            io::TypeDirectory => Blue.paint("d"),
            io::TypeNamedPipe => Yellow.paint("|"),
            io::TypeBlockSpecial => Purple.paint("s"),
            io::TypeSymlink => Cyan.paint("l"),
            _ => "?".to_owned(),
        }
    }

    fn file_colour(&self) -> Style {
        if self.stat.kind == io::TypeDirectory {
            Blue.normal()
        } else if self.stat.perm.contains(io::UserExecute) {
            Green.normal()
        } else if self.name.ends_with("~") {
            Black.bold()
        } else {
            Plain
        }
    }

    fn permissions(&self) -> StrBuf {
        let bits = self.stat.perm;
        return format!("{}{}{}{}{}{}{}{}{}{}",
            self.type_char(),
            bit(bits, io::UserRead, "r", Yellow.bold()),
            bit(bits, io::UserWrite, "w", Red.bold()),
            bit(bits, io::UserExecute, "x", Green.bold().underline()),
            bit(bits, io::GroupRead, "r", Yellow.normal()),
            bit(bits, io::GroupWrite, "w", Red.normal()),
            bit(bits, io::GroupExecute, "x", Green.normal()),
            bit(bits, io::OtherRead, "r", Yellow.normal()),
            bit(bits, io::OtherWrite, "w", Red.normal()),
            bit(bits, io::OtherExecute, "x", Green.normal()),
       );
    }
}

fn bit(bits: io::FilePermission, bit: io::FilePermission, other: &'static str, style: Style) -> StrBuf {
    if bits.contains(bit) {
        style.paint(other.as_slice())
    } else {
        Black.bold().paint("-".as_slice())
    }
}
<commit_msg>Add colouring for media and compressed files<commit_after>use std::io::fs;
use std::io;

use colours::{Plain, Style, Black, Red, Green, Yellow, Blue, Purple, Cyan};
use column::{Column, Permissions, FileName, FileSize, User, Group};
use format::{formatBinaryBytes, formatDecimalBytes};
use unix::{get_user_name, get_group_name};

static MEDIA_TYPES: &'static [&'static str] = &[
    "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
    "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
    "svg", "pdf", "stl", "eps", "dvi", "ps" ];

static COMPRESSED_TYPES: &'static [&'static str] = &[
    "zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
    "iso", "dmg", "tc", "rar", "par" ];

// Each file is definitely going to get `stat`ted at least once, if
// only to determine what kind of file it is, so carry the `stat`
// result around with the file for safe keeping.
pub struct File<'a> {
    pub name: &'a str,
    pub ext:  Option<&'a str>,
    pub path: &'a Path,
    pub stat: io::FileStat,
}

impl<'a> File<'a> {
    pub fn from_path(path: &'a Path) -> File<'a> {
        let filename: &str = path.filename_str().unwrap();

        // We have to use lstat here instad of file.stat(), as it
        // doesn't follow symbolic links. Otherwise, the stat() call
        // will fail if it encounters a link that's target is
        // non-existent.
        let stat: io::FileStat = match fs::lstat(path) {
            Ok(stat) => stat,
            Err(e) => fail!("Couldn't stat {}: {}", filename, e),
        };

        return File {
            path: path,
            stat: stat,
            name: filename,
            ext:  File::ext(filename),
        };
    }

    fn ext(name: &'a str) -> Option<&'a str> {
        let re = regex!(r"\.(.+)$");
        re.captures(name).map(|caps| caps.at(1))
    }

    pub fn is_dotfile(&self) -> bool {
        self.name.starts_with(".")
    }

    pub fn display(&self, column: &Column) -> StrBuf {
        match *column {
            Permissions => self.permissions(),
            FileName => self.file_colour().paint(self.name.as_slice()),
            FileSize(si) => self.file_size(si),
            User => get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str()),
            Group => get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
        }
    }

    fn file_size(&self, si: bool) -> StrBuf {
        let sizeStr = if si {
            formatBinaryBytes(self.stat.size)
        } else {
            formatDecimalBytes(self.stat.size)
        };

        return if self.stat.kind == io::TypeDirectory {
            Green.normal()
        } else {
            Green.bold()
        }.paint(sizeStr.as_slice());
    }

    fn type_char(&self) -> StrBuf {
        return match self.stat.kind {
            io::TypeFile => ".".to_strbuf(),
            io::TypeDirectory => Blue.paint("d"),
            io::TypeNamedPipe => Yellow.paint("|"),
            io::TypeBlockSpecial => Purple.paint("s"),
            io::TypeSymlink => Cyan.paint("l"),
            _ => "?".to_owned(),
        }
    }

    fn file_colour(&self) -> Style {
        if self.stat.kind == io::TypeDirectory {
            Blue.normal()
        }
        else if self.stat.perm.contains(io::UserExecute) {
            Green.bold()
        }
        else if self.name.ends_with("~") {
            Black.bold()
        }
        else if self.name.starts_with("README") {
            Yellow.bold().underline()
        }
        else if self.ext.is_some() && MEDIA_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Purple.normal()
        }
        else if self.ext.is_some() && COMPRESSED_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Red.normal()
        }
        else {
            Plain
        }
    }

    fn permissions(&self) -> StrBuf {
        let bits = self.stat.perm;
        return format!("{}{}{}{}{}{}{}{}{}{}",
            self.type_char(),
            bit(bits, io::UserRead, "r", Yellow.bold()),
            bit(bits, io::UserWrite, "w", Red.bold()),
            bit(bits, io::UserExecute, "x", Green.bold().underline()),
            bit(bits, io::GroupRead, "r", Yellow.normal()),
            bit(bits, io::GroupWrite, "w", Red.normal()),
            bit(bits, io::GroupExecute, "x", Green.normal()),
            bit(bits, io::OtherRead, "r", Yellow.normal()),
            bit(bits, io::OtherWrite, "w", Red.normal()),
            bit(bits, io::OtherExecute, "x", Green.normal()),
       );
    }
}

fn bit(bits: io::FilePermission, bit: io::FilePermission, other: &'static str, style: Style) -> StrBuf {
    if bits.contains(bit) {
        style.paint(other.as_slice())
    } else {
        Black.bold().paint("-".as_slice())
    }
}
<|endoftext|>


<commit_before><commit_msg>tests: add test for empty <><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.

// Test that empty type parameter list (<>) is synonymous with
// no type parameters at all

struct S<>;
trait T<> {}
enum E<> { V }
impl<> T<> for S<> {}
impl T for E {}
fn foo<>() {}
fn bar() {}

fn main() {
    let _ = S;
    let _ = S::<>;
    let _ = E::V;
    let _ = E::<>::V;
    foo();
    foo::<>();

    // Test that we can supply <> to non generic things
    bar::<>();
    let _: i32<>;
}
<|endoftext|>