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

//! Error Reporting for Anonymous Region Lifetime Errors.
use hir;
use infer::InferCtxt;
use ty::{self, Region};
use infer::region_inference::RegionResolutionError::*;
use infer::region_inference::RegionResolutionError;
use hir::map as hir_map;
use hir::def_id::DefId;

impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
    // This method walks the Type of the function body arguments using
    // `fold_regions()` function and returns the
    // &hir::Arg of the function argument corresponding to the anonymous
    // region and the Ty corresponding to the named region.
    // Currently only the case where the function declaration consists of
    // one named region and one anonymous region is handled.
    // Consider the example `fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32`
    // Here, we would return the hir::Arg for y, we return the type &'a
    // i32, which is the type of y but with the anonymous region replaced
    // with 'a, the corresponding bound region and is_first which is true if
    // the hir::Arg is the first argument in the function declaration.
    fn find_arg_with_anonymous_region
        (&self,
         anon_region: Region<'tcx>,
         named_region: Region<'tcx>)
         -> Option<(&hir::Arg, ty::Ty<'tcx>, ty::BoundRegion, bool)> {

        match *anon_region {
            ty::ReFree(ref free_region) => {

                let id = free_region.scope;
                let node_id = self.tcx.hir.as_local_node_id(id).unwrap();
                let body_id = self.tcx.hir.maybe_body_owned_by(node_id).unwrap();
                let body = self.tcx.hir.body(body_id);
                if let Some(tables) = self.in_progress_tables {
                    body.arguments
                        .iter()
                        .enumerate()
                        .filter_map(|(index, arg)| {
                            let ty = tables.borrow().node_id_to_type(arg.id);
                            let mut found_anon_region = false;
                            let new_arg_ty = self.tcx
                                .fold_regions(&ty, &mut false, |r, _| if *r == *anon_region {
                                    found_anon_region = true;
                                    named_region
                                } else {
                                    r
                                });
                            if found_anon_region {
                                let is_first = index == 0;
                                Some((arg, new_arg_ty, free_region.bound_region, is_first))
                            } else {
                                None
                            }
                        })
                        .next()
                } else {
                    None
                }
            }
            _ => None,

        }
    }

    // This method generates the error message for the case when
    // the function arguments consist of a named region and an anonymous
    // region and corresponds to `ConcreteFailure(..)`
    pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {

        let (span, sub, sup) = match *error {
            ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
            _ => return false, // inapplicable
        };

        // Determine whether the sub and sup consist of one named region ('a)
        // and one anonymous (elided) region. If so, find the parameter arg
        // where the anonymous region appears (there must always be one; we
        // only introduced anonymous regions in parameters) as well as a
        // version new_ty of its type where the anonymous region is replaced
        // with the named one.
        let (named, (arg, new_ty, br, is_first), scope_def_id) =
            if sub.is_named_region() && self.is_suitable_anonymous_region(sup).is_some() {
                (sub,
                 self.find_arg_with_anonymous_region(sup, sub).unwrap(),
                 self.is_suitable_anonymous_region(sup).unwrap())
            } else if sup.is_named_region() && self.is_suitable_anonymous_region(sub).is_some() {
                (sup,
                 self.find_arg_with_anonymous_region(sub, sup).unwrap(),
                 self.is_suitable_anonymous_region(sub).unwrap())
            } else {
                return false; // inapplicable
            };

        // Here, we check for the case where the anonymous region
        // is in the return type.
        // FIXME(#42703) - Need to handle certain cases here.
        let ret_ty = self.tcx.type_of(scope_def_id);
        match ret_ty.sty {
            ty::TyFnDef(_, _) => {
                let sig = ret_ty.fn_sig(self.tcx);
                let late_bound_regions = self.tcx
                    .collect_referenced_late_bound_regions(&sig.output());
                if late_bound_regions.iter().any(|r| *r == br) {
                    return false;
                } else {
                }
            }
            _ => {}
        }

        // Here we check for the case where anonymous region
        // corresponds to self and if yes, we display E0312.
        // FIXME(#42700) - Need to format self properly to
        // enable E0621 for it.
        if is_first &&
           self.tcx
               .opt_associated_item(scope_def_id)
               .map(|i| i.method_has_self_argument)
               .unwrap_or(false) {
            return false;
        }

        if let Some(simple_name) = arg.pat.simple_name() {
            struct_span_err!(self.tcx.sess,
                             span,
                             E0621,
                             "explicit lifetime required in the type of `{}`",
                             simple_name)
                    .span_label(arg.pat.span,
                                format!("consider changing the type of `{}` to `{}`",
                                        simple_name,
                                        new_ty))
                    .span_label(span, format!("lifetime `{}` required", named))
                    .emit();

        } else {
            struct_span_err!(self.tcx.sess,
                             span,
                             E0621,
                             "explicit lifetime required in parameter type")
                    .span_label(arg.pat.span,
                                format!("consider changing type to `{}`", new_ty))
                    .span_label(span, format!("lifetime `{}` required", named))
                    .emit();
        }
        return true;

    }

    // This method returns whether the given Region is Anonymous
    // and returns the DefId corresponding to the region.
    pub fn is_suitable_anonymous_region(&self, region: Region<'tcx>) -> Option<DefId> {

        match *region {
            ty::ReFree(ref free_region) => {
                match free_region.bound_region {
                    ty::BrAnon(..) => {
                        let anonymous_region_binding_scope = free_region.scope;
                        let node_id = self.tcx
                            .hir
                            .as_local_node_id(anonymous_region_binding_scope)
                            .unwrap();
                        match self.tcx.hir.find(node_id) {
                            Some(hir_map::NodeItem(..)) |
                            Some(hir_map::NodeTraitItem(..)) => {
                                // proceed ahead //
                            }
                            Some(hir_map::NodeImplItem(..)) => {
                                let container_id = self.tcx
                                    .associated_item(anonymous_region_binding_scope)
                                    .container
                                    .id();
                                if self.tcx.impl_trait_ref(container_id).is_some() {
                                    // For now, we do not try to target impls of traits. This is
                                    // because this message is going to suggest that the user
                                    // change the fn signature, but they may not be free to do so,
                                    // since the signature must match the trait.
                                    //
                                    // FIXME(#42706) -- in some cases, we could do better here.
                                    return None;
                                }
                            }
                            _ => return None, // inapplicable
                            // we target only top-level functions
                        }
                        return Some(anonymous_region_binding_scope);
                    }
                    _ => None,
                }
            }
            _ => None,
        }
    }
}
<commit_msg>code fixes for error code use warning<commit_after>// Copyright 2012-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.

//! Error Reporting for Anonymous Region Lifetime Errors.
use hir;
use infer::InferCtxt;
use ty::{self, Region};
use infer::region_inference::RegionResolutionError::*;
use infer::region_inference::RegionResolutionError;
use hir::map as hir_map;
use hir::def_id::DefId;

impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
    // This method walks the Type of the function body arguments using
    // `fold_regions()` function and returns the
    // &hir::Arg of the function argument corresponding to the anonymous
    // region and the Ty corresponding to the named region.
    // Currently only the case where the function declaration consists of
    // one named region and one anonymous region is handled.
    // Consider the example `fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32`
    // Here, we would return the hir::Arg for y, we return the type &'a
    // i32, which is the type of y but with the anonymous region replaced
    // with 'a, the corresponding bound region and is_first which is true if
    // the hir::Arg is the first argument in the function declaration.
    fn find_arg_with_anonymous_region
        (&self,
         anon_region: Region<'tcx>,
         named_region: Region<'tcx>)
         -> Option<(&hir::Arg, ty::Ty<'tcx>, ty::BoundRegion, bool)> {

        match *anon_region {
            ty::ReFree(ref free_region) => {

                let id = free_region.scope;
                let node_id = self.tcx.hir.as_local_node_id(id).unwrap();
                let body_id = self.tcx.hir.maybe_body_owned_by(node_id).unwrap();
                let body = self.tcx.hir.body(body_id);
                if let Some(tables) = self.in_progress_tables {
                    body.arguments
                        .iter()
                        .enumerate()
                        .filter_map(|(index, arg)| {
                            let ty = tables.borrow().node_id_to_type(arg.id);
                            let mut found_anon_region = false;
                            let new_arg_ty = self.tcx
                                .fold_regions(&ty, &mut false, |r, _| if *r == *anon_region {
                                    found_anon_region = true;
                                    named_region
                                } else {
                                    r
                                });
                            if found_anon_region {
                                let is_first = index == 0;
                                Some((arg, new_arg_ty, free_region.bound_region, is_first))
                            } else {
                                None
                            }
                        })
                        .next()
                } else {
                    None
                }
            }
            _ => None,

        }
    }

    // This method generates the error message for the case when
    // the function arguments consist of a named region and an anonymous
    // region and corresponds to `ConcreteFailure(..)`
    pub fn try_report_named_anon_conflict(&self, error: &RegionResolutionError<'tcx>) -> bool {

        let (span, sub, sup) = match *error {
            ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
            _ => return false, // inapplicable
        };

        // Determine whether the sub and sup consist of one named region ('a)
        // and one anonymous (elided) region. If so, find the parameter arg
        // where the anonymous region appears (there must always be one; we
        // only introduced anonymous regions in parameters) as well as a
        // version new_ty of its type where the anonymous region is replaced
        // with the named one.
        let (named, (arg, new_ty, br, is_first), scope_def_id) =
            if sub.is_named_region() && self.is_suitable_anonymous_region(sup).is_some() {
                (sub,
                 self.find_arg_with_anonymous_region(sup, sub).unwrap(),
                 self.is_suitable_anonymous_region(sup).unwrap())
            } else if sup.is_named_region() && self.is_suitable_anonymous_region(sub).is_some() {
                (sup,
                 self.find_arg_with_anonymous_region(sub, sup).unwrap(),
                 self.is_suitable_anonymous_region(sub).unwrap())
            } else {
                return false; // inapplicable
            };

        // Here, we check for the case where the anonymous region
        // is in the return type.
        // FIXME(#42703) - Need to handle certain cases here.
        let ret_ty = self.tcx.type_of(scope_def_id);
        match ret_ty.sty {
            ty::TyFnDef(_, _) => {
                let sig = ret_ty.fn_sig(self.tcx);
                let late_bound_regions = self.tcx
                    .collect_referenced_late_bound_regions(&sig.output());
                if late_bound_regions.iter().any(|r| *r == br) {
                    return false;
                } else {
                }
            }
            _ => {}
        }

        // Here we check for the case where anonymous region
        // corresponds to self and if yes, we display E0312.
        // FIXME(#42700) - Need to format self properly to
        // enable E0621 for it.
        if is_first &&
           self.tcx
               .opt_associated_item(scope_def_id)
               .map(|i| i.method_has_self_argument)
               .unwrap_or(false) {
            return false;
        }

        let (error_var, span_label_var) = if let Some(simple_name) = arg.pat.simple_name() {
            (format!("the type of `{}`", simple_name), format!("the type of `{}`", simple_name))
        } else {
            (format!("parameter type"), format!("type"))
        };

        struct_span_err!(self.tcx.sess,
                         span,
                         E0621,
                         "explicit lifetime required in {}",
                         error_var)
                .span_label(arg.pat.span,
                            format!("consider changing {} to `{}`", span_label_var, new_ty))
                .span_label(span, format!("lifetime `{}` required", named))
                .emit();

        return true;

    }

    // This method returns whether the given Region is Anonymous
    // and returns the DefId corresponding to the region.
    pub fn is_suitable_anonymous_region(&self, region: Region<'tcx>) -> Option<DefId> {

        match *region {
            ty::ReFree(ref free_region) => {
                match free_region.bound_region {
                    ty::BrAnon(..) => {
                        let anonymous_region_binding_scope = free_region.scope;
                        let node_id = self.tcx
                            .hir
                            .as_local_node_id(anonymous_region_binding_scope)
                            .unwrap();
                        match self.tcx.hir.find(node_id) {
                            Some(hir_map::NodeItem(..)) |
                            Some(hir_map::NodeTraitItem(..)) => {
                                // proceed ahead //
                            }
                            Some(hir_map::NodeImplItem(..)) => {
                                let container_id = self.tcx
                                    .associated_item(anonymous_region_binding_scope)
                                    .container
                                    .id();
                                if self.tcx.impl_trait_ref(container_id).is_some() {
                                    // For now, we do not try to target impls of traits. This is
                                    // because this message is going to suggest that the user
                                    // change the fn signature, but they may not be free to do so,
                                    // since the signature must match the trait.
                                    //
                                    // FIXME(#42706) -- in some cases, we could do better here.
                                    return None;
                                }
                            }
                            _ => return None, // inapplicable
                            // we target only top-level functions
                        }
                        return Some(anonymous_region_binding_scope);
                    }
                    _ => None,
                }
            }
            _ => None,
        }
    }
}
<|endoftext|>


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

use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let base = super::linux_base::opts();
    Ok(Target {
        llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),

        options: TargetOptions {
            features: "+soft-float".to_string(),
            max_atomic_width: Some(64),
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        }
    })
}

<commit_msg>Set max_atomic_width to 0 because there's no atomic instructions on ARMv5<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.

use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
    let base = super::linux_base::opts();
    Ok(Target {
        llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
        arch: "arm".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),

        options: TargetOptions {
            features: "+soft-float".to_string(),
            // No atomic instructions on ARMv5
            max_atomic_width: Some(0),
            abi_blacklist: super::arm_base::abi_blacklist(),
            .. base
        }
    })
}

<|endoftext|>


<commit_before>//! Elements of the WebAssembly binary format.

use std::error;
use std::fmt;
use std::io;

macro_rules! buffered_read {
	($buffer_size: expr, $length: expr, $reader: expr) => {
		{
			let mut vec_buf = Vec::new();
			let mut total_read = 0;
			let mut buf = [0u8; $buffer_size];
			while total_read < $length {
				let next_to_read = if $length - total_read > $buffer_size { $buffer_size } else { $length - total_read };
				$reader.read_exact(&mut buf[0..next_to_read])?;
				vec_buf.extend_from_slice(&buf[0..next_to_read]);
				total_read += next_to_read;
			}
			vec_buf
		}
	}
}

mod primitives;
mod module;
mod section;
mod types;
mod import_entry;
mod export_entry;
mod global_entry;
mod ops;
mod func;
mod segment;
mod index_map;
mod name_section;
mod reloc_section;

pub use self::module::{Module, peek_size, ImportCountType};
pub use self::section::{
	Section, FunctionSection, CodeSection, MemorySection, DataSection,
	ImportSection, ExportSection, GlobalSection, TypeSection, ElementSection,
	TableSection, CustomSection,
};
pub use self::import_entry::{ImportEntry, ResizableLimits, MemoryType, TableType, GlobalType, External};
pub use self::export_entry::{ExportEntry, Internal};
pub use self::global_entry::GlobalEntry;
pub use self::primitives::{
	VarUint32, VarUint7, Uint8, VarUint1, VarInt7, Uint32, VarInt32, VarInt64,
	Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
};
pub use self::types::{Type, ValueType, BlockType, FunctionType, TableElementType};
pub use self::ops::{Opcode, Opcodes, InitExpr};
pub use self::func::{Func, FuncBody, Local};
pub use self::segment::{ElementSegment, DataSegment};
pub use self::index_map::IndexMap;
pub use self::name_section::{
	NameMap, NameSection, ModuleNameSection, FunctionNameSection,
	LocalNameSection,
};

/// Deserialization from serial i/o
pub trait Deserialize : Sized {
	/// Serialization error produced by deserialization routine.
	type Error: From<io::Error>;
	/// Deserialize type from serial i/o
	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
}

/// Serialization to serial i/o. Takes self by value to consume less memory
/// (parity-wasm IR is being partially freed by filling the result buffer).
pub trait Serialize {
	/// Serialization error produced by serialization routine.
	type Error: From<io::Error>;
	/// Serialize type to serial i/o
	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
}

/// Deserialization/serialization error
#[derive(Debug, Clone)]
pub enum Error {
	/// Unexpected end of input
	UnexpectedEof,
	/// Invalid magic
	InvalidMagic,
	/// Unsupported version
	UnsupportedVersion(u32),
	/// Inconsistence between declared and actual length
	InconsistentLength {
		/// Expected length of the definition
		expected: usize,
		/// Actual length of the definition
		actual: usize
	},
	/// Other static error
	Other(&'static str),
	/// Other allocated error
	HeapOther(String),
	/// Invalid/unknown value type declaration
	UnknownValueType(i8),
	/// Invalid/unknown table element type declaration
	UnknownTableElementType(i8),
	/// Non-utf8 string
	NonUtf8String,
	/// Unknown external kind code
	UnknownExternalKind(u8),
	/// Unknown internal kind code
	UnknownInternalKind(u8),
	/// Unknown opcode encountered
	UnknownOpcode(u8),
	/// Invalid VarUint1 value
	InvalidVarUint1(u8),
	/// Invalid VarInt32 value
	InvalidVarInt32,
	/// Invalid VarInt64 value
	InvalidVarInt64,
	/// Invalid VarUint32 value
	InvalidVarUint32,
	/// Invalid VarUint64 value
	InvalidVarUint64,
	/// Inconsistent metadata
	InconsistentMetadata,
	/// Invalid section id
	InvalidSectionId(u8),
	/// Sections are out of order
	SectionsOutOfOrder,
	/// Duplicated sections
	DuplicatedSections(u8),
	/// Invalid memory reference (should be 0)
	InvalidMemoryReference(u8),
	/// Invalid table reference (should be 0)
	InvalidTableReference(u8),
	/// Unknown function form (should be 0x60)
	UnknownFunctionForm(u8),
	/// Invalid varint7 (should be in -64..63 range)
	InvalidVarInt7(u8),
	/// Number of function body entries and signatures does not match
	InconsistentCode,
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match *self {
			Error::UnexpectedEof => write!(f, "Unexpected end of input"),
			Error::InvalidMagic => write!(f, "Invalid magic number at start of file"),
			Error::UnsupportedVersion(v) => write!(f, "Unsupported wasm version {}", v),
			Error::InconsistentLength { expected, actual } => {
				write!(f, "Expected length {}, found {}", expected, actual)
			}
			Error::Other(msg) => write!(f, "{}", msg),
			Error::HeapOther(ref msg) => write!(f, "{}", msg),
			Error::UnknownValueType(ty) => write!(f, "Invalid or unknown value type {}", ty),
			Error::UnknownTableElementType(ty) => write!(f, "Unknown table element type {}", ty),
			Error::NonUtf8String => write!(f, "Non-UTF-8 string"),
			Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind),
			Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind),
			Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode),
			Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val),
			Error::InvalidVarInt7(val) => write!(f, "Not a signed 7-bit integer: {}", val),
			Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"),
			Error::InvalidVarUint32 => write!(f, "Not an unsigned 32-bit integer"),
			Error::InvalidVarInt64 => write!(f, "Not a signed 64-bit integer"),
			Error::InvalidVarUint64 => write!(f, "Not an unsigned 64-bit integer"),
			Error::InconsistentMetadata =>  write!(f, "Inconsistent metadata"),
			Error::InvalidSectionId(ref id) =>  write!(f, "Invalid section id: {}", id),
			Error::SectionsOutOfOrder =>  write!(f, "Sections out of order"),
			Error::DuplicatedSections(ref id) =>  write!(f, "Dupliated sections ({})", id),
			Error::InvalidMemoryReference(ref mem_ref) =>  write!(f, "Invalid memory reference ({})", mem_ref),
			Error::InvalidTableReference(ref table_ref) =>  write!(f, "Invalid table reference ({})", table_ref),
			Error::UnknownFunctionForm(ref form) =>  write!(f, "Unknown function form ({})", form),
			Error::InconsistentCode =>  write!(f, "Number of function body entries and signatures does not match"),
		}
	}
}

impl error::Error for Error {
	fn description(&self) -> &str {
		match *self {
			Error::UnexpectedEof => "Unexpected end of input",
			Error::InvalidMagic => "Invalid magic number at start of file",
			Error::UnsupportedVersion(_) => "Unsupported wasm version",
			Error::InconsistentLength { .. } => "Inconsistent length",
			Error::Other(msg) => msg,
			Error::HeapOther(ref msg) => &msg[..],
			Error::UnknownValueType(_) => "Invalid or unknown value type",
			Error::UnknownTableElementType(_) => "Unknown table element type",
			Error::NonUtf8String => "Non-UTF-8 string",
			Error::UnknownExternalKind(_) => "Unknown external kind",
			Error::UnknownInternalKind(_) => "Unknown internal kind",
			Error::UnknownOpcode(_) => "Unknown opcode",
			Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer",
			Error::InvalidVarInt32 => "Not a signed 32-bit integer",
			Error::InvalidVarInt7(_) => "Not a signed 7-bit integer",
			Error::InvalidVarUint32 => "Not an unsigned 32-bit integer",
			Error::InvalidVarInt64 => "Not a signed 64-bit integer",
			Error::InvalidVarUint64 => "Not an unsigned 64-bit integer",
			Error::InconsistentMetadata => "Inconsistent metadata",
			Error::InvalidSectionId(_) =>  "Invalid section id",
			Error::SectionsOutOfOrder =>  "Sections out of order",
			Error::DuplicatedSections(_) =>  "Duplicated section",
			Error::InvalidMemoryReference(_) =>  "Invalid memory reference",
			Error::InvalidTableReference(_) =>  "Invalid table reference",
			Error::UnknownFunctionForm(_) =>  "Unknown function form",
			Error::InconsistentCode =>  "Number of function body entries and signatures does not match",
		}
	}
}

impl From<io::Error> for Error {
	fn from(err: io::Error) -> Self {
		Error::HeapOther(format!("I/O Error: {}", err))
	}
}

/// Unparsed part of the module/section
pub struct Unparsed(pub Vec<u8>);

impl Deserialize for Unparsed {
	type Error = Error;

	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
		let len = VarUint32::deserialize(reader)?.into();
		let mut vec = vec![0u8; len];
		reader.read_exact(&mut vec[..])?;
		Ok(Unparsed(vec))
	}
}

impl From<Unparsed> for Vec<u8> {
	fn from(u: Unparsed) -> Vec<u8> {
		u.0
	}
}

/// Deserialize module from file.
pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
	use std::io::Read;

	let mut contents = Vec::new();
	::std::fs::File::open(p)?.read_to_end(&mut contents)?;

	deserialize_buffer(&contents)
}

/// Deserialize deserializable type from buffer.
pub fn deserialize_buffer<T: Deserialize>(contents: &[u8]) -> Result<T, T::Error> {
	let mut reader = io::Cursor::new(contents);
	let result = T::deserialize(&mut reader)?;
	if reader.position() != contents.len() as u64 {
		return Err(io::Error::from(io::ErrorKind::InvalidData).into())
	}
	Ok(result)
}

/// Create buffer with serialized value.
pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> {
	let mut buf = Vec::new();
	val.serialize(&mut buf)?;
	Ok(buf)
}

/// Serialize module to the file
pub fn serialize_to_file<P: AsRef<::std::path::Path>>(p: P, module: Module) -> Result<(), Error>
{
	let mut io = ::std::fs::File::create(p)?;
	module.serialize(&mut io)
}
<commit_msg>Make relocation section types visible to crate users.<commit_after>//! Elements of the WebAssembly binary format.

use std::error;
use std::fmt;
use std::io;

macro_rules! buffered_read {
	($buffer_size: expr, $length: expr, $reader: expr) => {
		{
			let mut vec_buf = Vec::new();
			let mut total_read = 0;
			let mut buf = [0u8; $buffer_size];
			while total_read < $length {
				let next_to_read = if $length - total_read > $buffer_size { $buffer_size } else { $length - total_read };
				$reader.read_exact(&mut buf[0..next_to_read])?;
				vec_buf.extend_from_slice(&buf[0..next_to_read]);
				total_read += next_to_read;
			}
			vec_buf
		}
	}
}

mod primitives;
mod module;
mod section;
mod types;
mod import_entry;
mod export_entry;
mod global_entry;
mod ops;
mod func;
mod segment;
mod index_map;
mod name_section;
mod reloc_section;

pub use self::module::{Module, peek_size, ImportCountType};
pub use self::section::{
	Section, FunctionSection, CodeSection, MemorySection, DataSection,
	ImportSection, ExportSection, GlobalSection, TypeSection, ElementSection,
	TableSection, CustomSection,
};
pub use self::import_entry::{ImportEntry, ResizableLimits, MemoryType, TableType, GlobalType, External};
pub use self::export_entry::{ExportEntry, Internal};
pub use self::global_entry::GlobalEntry;
pub use self::primitives::{
	VarUint32, VarUint7, Uint8, VarUint1, VarInt7, Uint32, VarInt32, VarInt64,
	Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter,
};
pub use self::types::{Type, ValueType, BlockType, FunctionType, TableElementType};
pub use self::ops::{Opcode, Opcodes, InitExpr};
pub use self::func::{Func, FuncBody, Local};
pub use self::segment::{ElementSegment, DataSegment};
pub use self::index_map::IndexMap;
pub use self::name_section::{
	NameMap, NameSection, ModuleNameSection, FunctionNameSection,
	LocalNameSection,
};
pub use self::reloc_section::{
	RelocSection, RelocationEntry,
};

/// Deserialization from serial i/o
pub trait Deserialize : Sized {
	/// Serialization error produced by deserialization routine.
	type Error: From<io::Error>;
	/// Deserialize type from serial i/o
	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error>;
}

/// Serialization to serial i/o. Takes self by value to consume less memory
/// (parity-wasm IR is being partially freed by filling the result buffer).
pub trait Serialize {
	/// Serialization error produced by serialization routine.
	type Error: From<io::Error>;
	/// Serialize type to serial i/o
	fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
}

/// Deserialization/serialization error
#[derive(Debug, Clone)]
pub enum Error {
	/// Unexpected end of input
	UnexpectedEof,
	/// Invalid magic
	InvalidMagic,
	/// Unsupported version
	UnsupportedVersion(u32),
	/// Inconsistence between declared and actual length
	InconsistentLength {
		/// Expected length of the definition
		expected: usize,
		/// Actual length of the definition
		actual: usize
	},
	/// Other static error
	Other(&'static str),
	/// Other allocated error
	HeapOther(String),
	/// Invalid/unknown value type declaration
	UnknownValueType(i8),
	/// Invalid/unknown table element type declaration
	UnknownTableElementType(i8),
	/// Non-utf8 string
	NonUtf8String,
	/// Unknown external kind code
	UnknownExternalKind(u8),
	/// Unknown internal kind code
	UnknownInternalKind(u8),
	/// Unknown opcode encountered
	UnknownOpcode(u8),
	/// Invalid VarUint1 value
	InvalidVarUint1(u8),
	/// Invalid VarInt32 value
	InvalidVarInt32,
	/// Invalid VarInt64 value
	InvalidVarInt64,
	/// Invalid VarUint32 value
	InvalidVarUint32,
	/// Invalid VarUint64 value
	InvalidVarUint64,
	/// Inconsistent metadata
	InconsistentMetadata,
	/// Invalid section id
	InvalidSectionId(u8),
	/// Sections are out of order
	SectionsOutOfOrder,
	/// Duplicated sections
	DuplicatedSections(u8),
	/// Invalid memory reference (should be 0)
	InvalidMemoryReference(u8),
	/// Invalid table reference (should be 0)
	InvalidTableReference(u8),
	/// Unknown function form (should be 0x60)
	UnknownFunctionForm(u8),
	/// Invalid varint7 (should be in -64..63 range)
	InvalidVarInt7(u8),
	/// Number of function body entries and signatures does not match
	InconsistentCode,
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		match *self {
			Error::UnexpectedEof => write!(f, "Unexpected end of input"),
			Error::InvalidMagic => write!(f, "Invalid magic number at start of file"),
			Error::UnsupportedVersion(v) => write!(f, "Unsupported wasm version {}", v),
			Error::InconsistentLength { expected, actual } => {
				write!(f, "Expected length {}, found {}", expected, actual)
			}
			Error::Other(msg) => write!(f, "{}", msg),
			Error::HeapOther(ref msg) => write!(f, "{}", msg),
			Error::UnknownValueType(ty) => write!(f, "Invalid or unknown value type {}", ty),
			Error::UnknownTableElementType(ty) => write!(f, "Unknown table element type {}", ty),
			Error::NonUtf8String => write!(f, "Non-UTF-8 string"),
			Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind),
			Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind),
			Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode),
			Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val),
			Error::InvalidVarInt7(val) => write!(f, "Not a signed 7-bit integer: {}", val),
			Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"),
			Error::InvalidVarUint32 => write!(f, "Not an unsigned 32-bit integer"),
			Error::InvalidVarInt64 => write!(f, "Not a signed 64-bit integer"),
			Error::InvalidVarUint64 => write!(f, "Not an unsigned 64-bit integer"),
			Error::InconsistentMetadata =>  write!(f, "Inconsistent metadata"),
			Error::InvalidSectionId(ref id) =>  write!(f, "Invalid section id: {}", id),
			Error::SectionsOutOfOrder =>  write!(f, "Sections out of order"),
			Error::DuplicatedSections(ref id) =>  write!(f, "Dupliated sections ({})", id),
			Error::InvalidMemoryReference(ref mem_ref) =>  write!(f, "Invalid memory reference ({})", mem_ref),
			Error::InvalidTableReference(ref table_ref) =>  write!(f, "Invalid table reference ({})", table_ref),
			Error::UnknownFunctionForm(ref form) =>  write!(f, "Unknown function form ({})", form),
			Error::InconsistentCode =>  write!(f, "Number of function body entries and signatures does not match"),
		}
	}
}

impl error::Error for Error {
	fn description(&self) -> &str {
		match *self {
			Error::UnexpectedEof => "Unexpected end of input",
			Error::InvalidMagic => "Invalid magic number at start of file",
			Error::UnsupportedVersion(_) => "Unsupported wasm version",
			Error::InconsistentLength { .. } => "Inconsistent length",
			Error::Other(msg) => msg,
			Error::HeapOther(ref msg) => &msg[..],
			Error::UnknownValueType(_) => "Invalid or unknown value type",
			Error::UnknownTableElementType(_) => "Unknown table element type",
			Error::NonUtf8String => "Non-UTF-8 string",
			Error::UnknownExternalKind(_) => "Unknown external kind",
			Error::UnknownInternalKind(_) => "Unknown internal kind",
			Error::UnknownOpcode(_) => "Unknown opcode",
			Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer",
			Error::InvalidVarInt32 => "Not a signed 32-bit integer",
			Error::InvalidVarInt7(_) => "Not a signed 7-bit integer",
			Error::InvalidVarUint32 => "Not an unsigned 32-bit integer",
			Error::InvalidVarInt64 => "Not a signed 64-bit integer",
			Error::InvalidVarUint64 => "Not an unsigned 64-bit integer",
			Error::InconsistentMetadata => "Inconsistent metadata",
			Error::InvalidSectionId(_) =>  "Invalid section id",
			Error::SectionsOutOfOrder =>  "Sections out of order",
			Error::DuplicatedSections(_) =>  "Duplicated section",
			Error::InvalidMemoryReference(_) =>  "Invalid memory reference",
			Error::InvalidTableReference(_) =>  "Invalid table reference",
			Error::UnknownFunctionForm(_) =>  "Unknown function form",
			Error::InconsistentCode =>  "Number of function body entries and signatures does not match",
		}
	}
}

impl From<io::Error> for Error {
	fn from(err: io::Error) -> Self {
		Error::HeapOther(format!("I/O Error: {}", err))
	}
}

/// Unparsed part of the module/section
pub struct Unparsed(pub Vec<u8>);

impl Deserialize for Unparsed {
	type Error = Error;

	fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
		let len = VarUint32::deserialize(reader)?.into();
		let mut vec = vec![0u8; len];
		reader.read_exact(&mut vec[..])?;
		Ok(Unparsed(vec))
	}
}

impl From<Unparsed> for Vec<u8> {
	fn from(u: Unparsed) -> Vec<u8> {
		u.0
	}
}

/// Deserialize module from file.
pub fn deserialize_file<P: AsRef<::std::path::Path>>(p: P) -> Result<Module, Error> {
	use std::io::Read;

	let mut contents = Vec::new();
	::std::fs::File::open(p)?.read_to_end(&mut contents)?;

	deserialize_buffer(&contents)
}

/// Deserialize deserializable type from buffer.
pub fn deserialize_buffer<T: Deserialize>(contents: &[u8]) -> Result<T, T::Error> {
	let mut reader = io::Cursor::new(contents);
	let result = T::deserialize(&mut reader)?;
	if reader.position() != contents.len() as u64 {
		return Err(io::Error::from(io::ErrorKind::InvalidData).into())
	}
	Ok(result)
}

/// Create buffer with serialized value.
pub fn serialize<T: Serialize>(val: T) -> Result<Vec<u8>, T::Error> {
	let mut buf = Vec::new();
	val.serialize(&mut buf)?;
	Ok(buf)
}

/// Serialize module to the file
pub fn serialize_to_file<P: AsRef<::std::path::Path>>(p: P, module: Module) -> Result<(), Error>
{
	let mut io = ::std::fs::File::create(p)?;
	module.serialize(&mut io)
}
<|endoftext|>


<commit_before>extern crate std;

pub use self::state::{ EntitiesState, Data, EntityID, ComponentID, Number, String, Boolean, List, Entity, FromProperty, Empty };
pub use self::state::{ ComponentType, NativeComponentType, EntityComponentType };
pub use self::state::{ StateError };

use std::collections::HashMap;
use lua::any;

pub mod loader;
mod state;

// TODO: ComponentID, EntityID must be associated types
pub trait EntitiesHelper {
    /// Creates a new empty entity in the state.
    fn create_entity(&mut self, name: Option<String>, visible: bool) -> EntityID;

    /// Destroys an entity.
    ///
    /// This operation will also destroy all the components owned by
    /// this entity and all components whose type is this entity.
    fn destroy_entity(&mut self, id: &EntityID) -> Result<(), StateError>;

    /// Creates a new component of a native type.
    fn create_native_component(&mut self, owner: &EntityID,
                               typename: &str, data: HashMap<String, Data>)
        -> Result<ComponentID, StateError>;

    /// Creates a new component of an entity type.
    fn create_component_from_entity(&mut self, owner: &EntityID, typename: &EntityID,
                                    data: HashMap<String, Data>)
                                    -> Result<ComponentID, StateError>;

    /// Destroys a component.
    fn destroy_component(&mut self, id: &ComponentID) -> Result<(), StateError>;

    /// Modifies an element of a component.
    fn set(&mut self, id: &ComponentID, field: &str, data: Data) -> Result<(), StateError>;

    /// Returns the type of the component.
    fn get_type(&self, id: &ComponentID)
        -> Result<ComponentType, StateError>;

    /// Returns the list of all the components in the state.
    fn get_components_list(&self)
        -> Vec<ComponentID>;

    /// Returns the list of all the components which are visible
    /// and are of the requested native type.
    fn get_visible_native_components(&self, nativetype: &str)
        -> Vec<ComponentID>;

    /// Returns the owner of the component.
    fn get_owner(&self, id: &ComponentID)
        -> Result<EntityID, StateError>;

    /// Returns the name of an entity.
    fn get_entity_name<'a>(&'a self, id: &EntityID)
        -> Result<Option<String>, StateError>;

    /// Returns the list of all entities with the given name.
    fn get_entities_by_name<'a>(&'a self, name: &str)
        -> Vec<EntityID>;

    /// Returns true if the entity is visible.
    fn is_entity_visible(&self, id: &EntityID)
        -> Result<bool, StateError>;

    /// Returns true if the component is visible.
    fn is_component_visible(&self, id: &ComponentID)
        -> Result<bool, StateError>;

    /// Sets an entity as parent of another one.
    /// When a component is destroyed, all its children are destroyed it.
    /// If the component already has a parent, it's removed.
    fn set_component_parent(&mut self, component: &ComponentID, parent: &ComponentID)
        -> Result<(), StateError>;

    /// Resets the parent of an entity, breaking the parent-child link.
    fn clear_component_parent(&mut self, component: &ComponentID);

    /// Returns the list of children of a component.
    fn get_component_children(&self, component: &ComponentID)
        -> Result<Vec<ComponentID>, StateError>;

    /// Returns an element of a component.
    fn get<'a>(&'a self, id: &ComponentID, field: &str)
        -> Result<&'a Data, StateError>;

    fn get_property_value(&self, id: &EntityID, propname: &str)
        -> Result<Data, StateError>
    {
        let value = self
            .get_components_list().move_iter()
            .filter(|c| &self.get_owner(c).unwrap() == id)
            .filter(|c| match self.get_type(c) { Ok(NativeComponentType(t)) => t.as_slice() == "property" || t.as_slice() == "propertyView", _ => false })
            .filter(|c| match self.get(c, "property") { Ok(&String(ref n)) => n.as_slice() == propname, _ => false })
            .max_by(|c| match self.get(c, "priority") { Ok(&::entities::Number(ref n)) => (((*n) * 1000f64) as int), _ => 1000 })
            .and_then(|c| {
                let cmpType = match self.get_type(&c) {
                    Ok(NativeComponentType(t)) => t.clone(),
                    _ => fail!()
                };

                match cmpType.as_slice() {
                    "property" =>
                        match self.get(&c, "value") { Ok(&FromProperty(_)) => None, Ok(n) => Some(n.clone()), _ => None },
                    "propertyView" => {
                        let script = match self.get(&c, "script") { Ok(&FromProperty(_)) => return None, Ok(&String(ref n)) => n.clone(), _ => return None };
                        match ::script::execute(self, &c, &script) {
                            Ok(any::Number(val)) => Some(Number(val)),
                            Ok(any::String(val)) => Some(String(val)),
                            Ok(any::Boolean(val)) => Some(Boolean(val)),
                            Ok(_) => unimplemented!(),
                            Err(e) => fail!("{}", e)
                        }
                    },
                    _ => fail!()
                }
            });

        match value {
            Some(v) => Ok(v),
            None => Ok(Empty)
        }
    }

    fn get_and_resolve(&self, id: &ComponentID, field: &str)
        -> Result<Data, StateError>
    {
        let propname = match try!(self.get(id, field)) {
            &FromProperty(ref p) => p,
            a => return Ok(a.clone())
        };

        let owner = try!(self.get_owner(id));

        self.get_property_value(&owner, propname.as_slice())
    }

    fn get_as_number(&self, id: &ComponentID, field: &str)
        -> Option<f64>
    {
        match self.get_and_resolve(id, field) {
            Ok(Number(n)) => Some(n),
            _ => None
        }
    }

    fn get_as_string(&self, id: &ComponentID, field: &str)
        -> Option<String>
    {
        match self.get_and_resolve(id, field) {
            Ok(String(s)) => Some(s),
            _ => None
        }
    }

    fn get_as_boolean(&self, id: &ComponentID, field: &str)
        -> Option<bool>
    {
        match self.get_and_resolve(id, field) {
            Ok(Boolean(b)) => Some(b),
            _ => None
        }
    }

    fn get_as_entity(&self, id: &ComponentID, field: &str)
        -> Option<EntityID>
    {
        match self.get_and_resolve(id, field) {
            Ok(Entity(e)) => Some(e),
            _ => None
        }
    }
}
<commit_msg>Style improvements in state trait<commit_after>extern crate std;

pub use self::state::{ EntitiesState, Data, EntityID, ComponentID, Number, String, Boolean, List, Entity, FromProperty, Empty };
pub use self::state::{ ComponentType, NativeComponentType, EntityComponentType };
pub use self::state::{ StateError };

use std::collections::HashMap;
use lua::any;

pub mod loader;
mod state;

// TODO: totally rework this trait once associated types are implemented
pub trait EntitiesHelper {
    /// Creates a new empty entity in the state.
    fn create_entity(&mut self, name: Option<String>, visible: bool) -> EntityID;

    /// Destroys an entity.
    ///
    /// This operation will also destroy all the components owned by
    /// this entity and all components whose type is this entity.
    fn destroy_entity(&mut self, id: &EntityID) -> Result<(), StateError>;

    /// Creates a new component of a native type.
    fn create_native_component(&mut self, owner: &EntityID,
                               typename: &str, data: HashMap<String, Data>)
        -> Result<ComponentID, StateError>;

    /// Creates a new component of an entity type.
    fn create_component_from_entity(&mut self, owner: &EntityID, typename: &EntityID,
                                    data: HashMap<String, Data>)
                                    -> Result<ComponentID, StateError>;

    /// Destroys a component.
    fn destroy_component(&mut self, id: &ComponentID) -> Result<(), StateError>;

    /// Modifies an element of a component.
    fn set(&mut self, id: &ComponentID, field: &str, data: Data) -> Result<(), StateError>;

    /// Returns the type of the component.
    fn get_type(&self, id: &ComponentID)
        -> Result<ComponentType, StateError>;

    /// Returns the list of all the components in the state.
    fn get_components_list(&self)
        -> Vec<ComponentID>;

    /// Returns the list of all the components which are visible
    /// and are of the requested native type.
    fn get_visible_native_components(&self, nativetype: &str)
        -> Vec<ComponentID>;

    /// Returns the owner of the component.
    fn get_owner(&self, id: &ComponentID)
        -> Result<EntityID, StateError>;

    /// Returns the name of an entity.
    fn get_entity_name<'a>(&'a self, id: &EntityID)
        -> Result<Option<String>, StateError>;

    /// Returns the list of all entities with the given name.
    fn get_entities_by_name<'a>(&'a self, name: &str)
        -> Vec<EntityID>;

    /// Returns true if the entity is visible.
    fn is_entity_visible(&self, id: &EntityID)
        -> Result<bool, StateError>;

    /// Returns true if the component is visible.
    fn is_component_visible(&self, id: &ComponentID)
        -> Result<bool, StateError>;

    /// Sets an entity as parent of another one.
    /// When a component is destroyed, all its children are destroyed it.
    /// If the component already has a parent, it's removed.
    fn set_component_parent(&mut self, component: &ComponentID, parent: &ComponentID)
        -> Result<(), StateError>;

    /// Resets the parent of an entity, breaking the parent-child link.
    fn clear_component_parent(&mut self, component: &ComponentID);

    /// Returns the list of children of a component.
    fn get_component_children(&self, component: &ComponentID)
        -> Result<Vec<ComponentID>, StateError>;

    /// Returns an element of a component.
    fn get<'a>(&'a self, id: &ComponentID, field: &str)
        -> Result<&'a Data, StateError>;

    /// Returns the value of a property of an entity.
    /// Reads the appropriate "property" or "propertyView" component.
    /// Returns Ok(Empty) if the property is not found.
    fn get_property_value(&self, id: &EntityID, propname: &str)
        -> Result<Data, StateError>
    {
        let value = self
            .get_visible_native_components("property").move_iter()
            .chain(self.get_visible_native_components("propertyView").move_iter())
            .filter(|c| &self.get_owner(c).unwrap() == id)
            .filter(|c|
                match self.get(c, "property").map(|c| c.as_string()) {
                    Ok(Some(n)) => n.as_slice() == propname,
                    _ => false
                })
            .max_by(|c|
                match self.get(c, "priority").map(|c| c.as_number()) {
                    Ok(Some(n)) => ((n * 1000f64) as int),
                    _ => 1000
                })
            .and_then(|c| {
                let cmpType = match self.get_type(&c) {
                    Ok(NativeComponentType(t)) => t.clone(),
                    _ => fail!()
                };

                match cmpType.as_slice() {
                    "property" =>
                        match self.get(&c, "value") {
                            Ok(&FromProperty(_)) => None,
                            Ok(n) => Some(n.clone()),
                            _ => None
                        },
                    "propertyView" => {
                        let script = match self.get(&c, "script") {
                            Ok(&FromProperty(_)) => return None,
                            Ok(&String(ref n)) => n.clone(),
                            _ => return None
                        };
                        match ::script::execute(self, &c, &script) {
                            Ok(any::Number(val)) => Some(Number(val)),
                            Ok(any::String(val)) => Some(String(val)),
                            Ok(any::Boolean(val)) => Some(Boolean(val)),
                            Ok(_) => unimplemented!(),
                            Err(e) => fail!("{}", e)
                        }
                    },
                    _ => fail!()
                }
            });

        match value {
            Some(v) => Ok(v),
            None => Ok(Empty)
        }
    }

    /// Gets the value of a field of the component.
    /// Resolves it if the field is "FromProperty".
    fn get_and_resolve(&self, id: &ComponentID, field: &str)
        -> Result<Data, StateError>
    {
        let propname = match try!(self.get(id, field)) {
            &FromProperty(ref p) => p,
            a => return Ok(a.clone())
        };

        let owner = try!(self.get_owner(id));

        self.get_property_value(&owner, propname.as_slice())
    }

    fn get_as_number(&self, id: &ComponentID, field: &str)
        -> Option<f64>
    {
        match self.get_and_resolve(id, field) {
            Ok(Number(n)) => Some(n),
            _ => None
        }
    }

    fn get_as_string(&self, id: &ComponentID, field: &str)
        -> Option<String>
    {
        match self.get_and_resolve(id, field) {
            Ok(String(s)) => Some(s),
            _ => None
        }
    }

    fn get_as_boolean(&self, id: &ComponentID, field: &str)
        -> Option<bool>
    {
        match self.get_and_resolve(id, field) {
            Ok(Boolean(b)) => Some(b),
            _ => None
        }
    }

    fn get_as_entity(&self, id: &ComponentID, field: &str)
        -> Option<EntityID>
    {
        match self.get_and_resolve(id, field) {
            Ok(Entity(e)) => Some(e),
            _ => None
        }
    }
}
<|endoftext|>


<commit_before>/*
* This file is part of the uutils coreutils package.
*
* (c) kwantam <kwantam@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

//! Generate a table of the multiplicative inverses of p_i mod 2^64
//! for the first 1027 odd primes (all 13 bit and smaller primes).
//! You can supply a commandline argument to override the default
//! value of 1027 for the number of entries in the table.
//!
//! 2 has no multiplicative inverse mode 2^64 because 2 | 2^64,
//! and in any case divisibility by two is trivial by checking the LSB.

#![cfg_attr(test, allow(dead_code))]

use sieve::Sieve;
use std::env::{self, args};
use std::fs::File;
use std::io::Write;
use std::num::Wrapping;
use std::path::Path;
use std::u64::MAX as MAX_U64;

#[cfg(test)]
use numeric::is_prime;

#[cfg(test)]
mod numeric;

mod sieve;

#[path = "../../mkmain.rs"]
mod mkmain;

// extended Euclid algorithm
// precondition: a does not divide 2^64
fn inv_mod_u64(a: u64) -> Option<u64> {
    let mut t = 0u64;
    let mut newt = 1u64;
    let mut r = 0u64;
    let mut newr = a;

    while newr != 0 {
        let quot = if r == 0 {
            // special case when we're just starting out
            // This works because we know that
            // a does not divide 2^64, so floor(2^64 / a) == floor((2^64-1) / a);
            MAX_U64
        } else {
            r
        } / newr;

        let (tp, Wrapping(newtp)) = (newt, Wrapping(t) - (Wrapping(quot) * Wrapping(newt)));
        t = tp;
        newt = newtp;

        let (rp, Wrapping(newrp)) = (newr, Wrapping(r) - (Wrapping(quot) * Wrapping(newr)));
        r = rp;
        newr = newrp;
    }

    if r > 1 {
        // not invertible
        return None;
    }

    Some(t)
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    mkmain::main();

    let out_dir = env::var("OUT_DIR").unwrap();
    let mut file = File::create(&Path::new(&out_dir).join("prime_table.rs")).unwrap();

    // By default, we print the multiplicative inverses mod 2^64 of the first 1k primes
    let n = args()
        .skip(1)
        .next()
        .unwrap_or_else(|| "1027".to_string())
        .parse::<usize>()
        .ok()
        .unwrap_or(1027);

    write!(file, "{}", PREAMBLE).unwrap();
    let mut cols = 3;

    // we want a total of n + 1 values
    let mut primes = Sieve::odd_primes().take(n + 1);

    // in each iteration of the for loop, we use the value yielded
    // by the previous iteration. This leaves one value left at the
    // end, which we call NEXT_PRIME.
    let mut x = primes.next().unwrap();
    for next in primes {
        // format the table
        let outstr = format!("({}, {}, {}),", x, inv_mod_u64(x).unwrap(), MAX_U64 / x);
        if cols + outstr.len() > MAX_WIDTH {
            write!(file, "\n    {}", outstr).unwrap();
            cols = 4 + outstr.len();
        } else {
            write!(file, " {}", outstr).unwrap();
            cols += 1 + outstr.len();
        }

        x = next;
    }

    write!(
        file,
        "\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n",
        x
    )
    .unwrap();
}

#[test]
fn test_inverter() {
    let num = 10000;

    let invs = Sieve::odd_primes().map(|x| inv_mod_u64(x).unwrap());
    assert!(Sieve::odd_primes().zip(invs).take(num).all(|(x, y)| {
        let Wrapping(z) = Wrapping(x) * Wrapping(y);
        is_prime(x) && z == 1
    }));
}

#[test]
fn test_generator() {
    let prime_10001 = Sieve::primes().skip(10_000).next();
    assert_eq!(prime_10001, Some(104_743));
}

const MAX_WIDTH: usize = 102;
const PREAMBLE: &str = r##"/*
* This file is part of the uutils coreutils package.
*
* (c) kwantam <kwantam@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

// *** NOTE: this file was automatically generated.
// Please do not edit by hand. Instead, modify and
// re-run src/factor/gen_tables.rs.

#[allow(clippy::unreadable_literal)]
pub const P_INVS_U64: &[(u64, u64, u64)] = &[
   "##;
<commit_msg>refactor/polish ~ fix `cargo clippy` complaints (iter_skip_next)<commit_after>/*
* This file is part of the uutils coreutils package.
*
* (c) kwantam <kwantam@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

//! Generate a table of the multiplicative inverses of p_i mod 2^64
//! for the first 1027 odd primes (all 13 bit and smaller primes).
//! You can supply a commandline argument to override the default
//! value of 1027 for the number of entries in the table.
//!
//! 2 has no multiplicative inverse mode 2^64 because 2 | 2^64,
//! and in any case divisibility by two is trivial by checking the LSB.

#![cfg_attr(test, allow(dead_code))]

use sieve::Sieve;
use std::env::{self, args};
use std::fs::File;
use std::io::Write;
use std::num::Wrapping;
use std::path::Path;
use std::u64::MAX as MAX_U64;

#[cfg(test)]
use numeric::is_prime;

#[cfg(test)]
mod numeric;

mod sieve;

#[path = "../../mkmain.rs"]
mod mkmain;

// extended Euclid algorithm
// precondition: a does not divide 2^64
fn inv_mod_u64(a: u64) -> Option<u64> {
    let mut t = 0u64;
    let mut newt = 1u64;
    let mut r = 0u64;
    let mut newr = a;

    while newr != 0 {
        let quot = if r == 0 {
            // special case when we're just starting out
            // This works because we know that
            // a does not divide 2^64, so floor(2^64 / a) == floor((2^64-1) / a);
            MAX_U64
        } else {
            r
        } / newr;

        let (tp, Wrapping(newtp)) = (newt, Wrapping(t) - (Wrapping(quot) * Wrapping(newt)));
        t = tp;
        newt = newtp;

        let (rp, Wrapping(newrp)) = (newr, Wrapping(r) - (Wrapping(quot) * Wrapping(newr)));
        r = rp;
        newr = newrp;
    }

    if r > 1 {
        // not invertible
        return None;
    }

    Some(t)
}

#[cfg_attr(test, allow(dead_code))]
fn main() {
    mkmain::main();

    let out_dir = env::var("OUT_DIR").unwrap();
    let mut file = File::create(&Path::new(&out_dir).join("prime_table.rs")).unwrap();

    // By default, we print the multiplicative inverses mod 2^64 of the first 1k primes
    let n = args()
        .nth(1)
        .unwrap_or_else(|| "1027".to_string())
        .parse::<usize>()
        .ok()
        .unwrap_or(1027);

    write!(file, "{}", PREAMBLE).unwrap();
    let mut cols = 3;

    // we want a total of n + 1 values
    let mut primes = Sieve::odd_primes().take(n + 1);

    // in each iteration of the for loop, we use the value yielded
    // by the previous iteration. This leaves one value left at the
    // end, which we call NEXT_PRIME.
    let mut x = primes.next().unwrap();
    for next in primes {
        // format the table
        let outstr = format!("({}, {}, {}),", x, inv_mod_u64(x).unwrap(), MAX_U64 / x);
        if cols + outstr.len() > MAX_WIDTH {
            write!(file, "\n    {}", outstr).unwrap();
            cols = 4 + outstr.len();
        } else {
            write!(file, " {}", outstr).unwrap();
            cols += 1 + outstr.len();
        }

        x = next;
    }

    write!(
        file,
        "\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n",
        x
    )
    .unwrap();
}

#[test]
fn test_inverter() {
    let num = 10000;

    let invs = Sieve::odd_primes().map(|x| inv_mod_u64(x).unwrap());
    assert!(Sieve::odd_primes().zip(invs).take(num).all(|(x, y)| {
        let Wrapping(z) = Wrapping(x) * Wrapping(y);
        is_prime(x) && z == 1
    }));
}

#[test]
fn test_generator() {
    let prime_10001 = Sieve::primes().skip(10_000).next();
    assert_eq!(prime_10001, Some(104_743));
}

const MAX_WIDTH: usize = 102;
const PREAMBLE: &str = r##"/*
* This file is part of the uutils coreutils package.
*
* (c) kwantam <kwantam@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

// *** NOTE: this file was automatically generated.
// Please do not edit by hand. Instead, modify and
// re-run src/factor/gen_tables.rs.

#[allow(clippy::unreadable_literal)]
pub const P_INVS_U64: &[(u64, u64, u64)] = &[
   "##;
<|endoftext|>


<commit_before>//http://rosettacode.org/wiki/Flatten_a_list

#![feature(core)]
#![feature(box_syntax)]
use std::fmt;
use Tree::{Node, Leaf};

#[derive(Debug)]
enum Tree<T>{
    Node(Vec<Tree<T>>),
    Leaf(T),
}

/// fmt::Display is implemented here for pretty printing.
impl<T> fmt::Display for Tree<T>
    where T: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
        match *self {
            Node(ref vec) => write!(f, "{}", vec),
            Leaf(ref val) => write!(f, "{}", val)
        }
    }
}

impl<T> fmt::Display for Vec<Tree<T>>
    where T: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
        let mut first = true;
        write!(f, "[");
        for x in self.iter(){
            if(!first){ write!(f, ", ");}
            write!(f, "{}", *x);
            first = false;
        }
        write!(f, "]")
    }
}

fn flatten<T>(tree: Tree<T>) -> Vec<T>{
    match tree {
        Leaf(val) => vec![val],
        Node(vec) => vec.into_iter()
                        .flat_map(|t| flatten(t).into_iter())
                        .collect()
    }
}

#[cfg(not(test))]
fn main() {
    //[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
    let list: Tree<i32> =
        Node(vec![Node(vec![Leaf(1)]),
            Leaf(2),
            Node(vec![Node(vec![Leaf(3), Leaf(4)]), Leaf(5)]),
            Node(vec![Node(vec![Node(vec![])])]),
            Node(vec![Node(vec![Node(vec![Leaf(6)])])]),
            Leaf(7),
            Leaf(8),
            Node(vec![])
            ]);

    println!("{}", list);

    let flattened = flatten(list);

    println!("{:?}", flattened);
}
<commit_msg>Add test to flatten_list and clean up warnings<commit_after>//http://rosettacode.org/wiki/Flatten_a_list

#![feature(box_syntax)]
use std::fmt;
use Tree::{Node, Leaf};

#[derive(Debug)]
enum Tree<T>{
    Node(Vec<Tree<T>>),
    Leaf(T),
}

/// fmt::Display is implemented here for pretty printing.
impl<T> fmt::Display for Tree<T>
    where T: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
        match *self {
            Node(ref vec) => write!(f, "{}", vec),
            Leaf(ref val) => write!(f, "{}", val)
        }
    }
}

impl<T> fmt::Display for Vec<Tree<T>>
    where T: fmt::Display {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut first = true;
        try!(write!(f, "["));
        for x in self.iter(){
            if !first { try!(write!(f, ", ")); }
            try!(write!(f, "{}", *x));
            first = false;
        }
        write!(f, "]")
    }
}

fn flatten<T>(tree: Tree<T>) -> Vec<T>{
    match tree {
        Leaf(val) => vec![val],
        Node(vec) => vec.into_iter()
                        .flat_map(|t| flatten(t).into_iter())
                        .collect()
    }
}

#[cfg(not(test))]
fn main() {
    //[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
    let list: Tree<i32> =
        Node(vec![Node(vec![Leaf(1)]),
            Leaf(2),
            Node(vec![Node(vec![Leaf(3), Leaf(4)]), Leaf(5)]),
            Node(vec![Node(vec![Node(vec![])])]),
            Node(vec![Node(vec![Node(vec![Leaf(6)])])]),
            Leaf(7),
            Leaf(8),
            Node(vec![])
            ]);

    println!("{}", list);

    let flattened = flatten(list);

    println!("{:?}", flattened);
}

#[test]
fn rosetta_flatten_test() {
    //[[1], 2, [[3,4], 5], [[[]]], [[[6]]], 7, 8, []]
    let list: Tree<i32> =
        Node(vec![Node(vec![Leaf(1)]),
            Leaf(2),
            Node(vec![Node(vec![Leaf(3), Leaf(4)]), Leaf(5)]),
            Node(vec![Node(vec![Node(vec![])])]),
            Node(vec![Node(vec![Node(vec![Leaf(6)])])]),
            Leaf(7),
            Leaf(8),
            Node(vec![])
            ]);

    println!("{}", list);

    let flattened = flatten(list);

    assert!(flattened == vec!(1,2,3,4,5,6,7,8))
}<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 3]>,
    index: usize,
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let i = self.index;
        let triangle = self.triangles[i];

        self.gl.draw(args.viewport(), |c, gl| {
            if i == 0 {
                clear(WHITE, gl);
            }

            let transform = c.transform.trans(0.0, 0.0);

            polygon(BLACK, &triangle, transform, gl);
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        if (self.index as i32) + 1 >= self.triangles.len() as i32 {
            self.index = 0
        } else {
            self.index += 1;
        }
    }
}

fn sub_triangles(v: &[[f64; 2]; 3]) -> [[[f64; 2]; 3]; 4] {
    let (a, b, c) = (v[0], v[1], v[2]); // Vector destructuring is not yet stable in Rust 1.3.0.
    let (sax, say, sbx, sby, scx, scy) = (
            a[0] + ((b[0] - a[0]) / 2.0),
            a[1],
            b[0] - ((b[0] - c[0]) / 2.0),
            b[1] - ((b[1] - c[1]) / 2.0),
            a[0] + ((c[0] - a[0]) / 2.0),
            a[1] - ((a[1] - c[1]) / 2.0));

    [[[sax, say], [sbx, sby], [scx, scy]],
     [[a[0], a[1]], [sax, say], [scx, scy]],
     [[sax, say], [b[0], b[1]], [sbx, sby]],
     [[scx, scy], [sbx, sby], [c[0], c[1]]]]
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 3]) -> Vec<[[f64; 2]; 3]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d => {
            let sub_tris = sub_triangles(&vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;
    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0], [500.0, 50.0]]);
    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles, index: 0};

    for e in window.events().max_fps(60).ups(60) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }

        if let Some(u) = e.update_args() {
            app.update(&u);
        }

    }
}
<commit_msg>Using a type alias<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

type Triangle = [[f64; 2]; 3];

struct App {
    gl: GlGraphics,
    triangles: Vec<Triangle>,
    index: usize,
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let i = self.index;
        let triangle = self.triangles[i];

        self.gl.draw(args.viewport(), |c, gl| {
            if i == 0 {
                clear(WHITE, gl);
            }

            let transform = c.transform.trans(0.0, 0.0);

            polygon(BLACK, &triangle, transform, gl);
        });
    }

    fn update(&mut self, args: &UpdateArgs) {
        if (self.index as i32) + 1 >= self.triangles.len() as i32 {
            self.index = 0
        } else {
            self.index += 1;
        }
    }
}

fn sub_triangles(v: &Triangle) -> [Triangle; 4] {
    let (a, b, c) = (v[0], v[1], v[2]); // Vector destructuring is not yet stable in Rust 1.3.0.
    let (sax, say, sbx, sby, scx, scy) = (
            a[0] + ((b[0] - a[0]) / 2.0),
            a[1],
            b[0] - ((b[0] - c[0]) / 2.0),
            b[1] - ((b[1] - c[1]) / 2.0),
            a[0] + ((c[0] - a[0]) / 2.0),
            a[1] - ((a[1] - c[1]) / 2.0));

    [[[sax, say], [sbx, sby], [scx, scy]],
     [[a[0], a[1]], [sax, say], [scx, scy]],
     [[sax, say], [b[0], b[1]], [sbx, sby]],
     [[scx, scy], [sbx, sby], [c[0], c[1]]]]
}

fn sierpinski(depth: i32, vertices: Triangle) -> Vec<Triangle> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d => {
            let sub_tris = sub_triangles(&vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    const FPS: u64 = 60;
    let opengl = OpenGL::V3_2;
    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0], [500.0, 50.0]]);
    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles, index: 0};

    for e in window.events().max_fps(FPS).ups(FPS) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }

        if let Some(u) = e.update_args() {
            app.update(&u);
        }

    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Library
//!
//! This library allows you to do
//! [Cap'n Proto code generation](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//! within a Cargo build. You still need the `capnp` binary (implemented in C++).
//! (If you use a package manager, try looking for a package called
//! `capnproto`.)
//!
//! In your Cargo.toml:
//!
//! ```ignore
//! [package]
//! build = "build.rs"
//!
//! [build-dependencies]
//! capnpc = "0.12"
//! ```
//!
//! In your build.rs:
//!
//! ```ignore
//! extern crate capnpc;
//!
//! fn main() {
//!     capnpc::CompilerCommand::new()
//!         .src_prefix("schema")
//!         .file("schema/foo.capnp")
//!         .file("schema/bar.capnp")
//!         .run().expect("schema compiler command");
//! }
//! ```
//!
//! This will be equivalent to executing the shell command
//!
//! ```ignore
//!   capnp compile -orust:$OUT_DIR --src-prefix=schema schema/foo.capnp schema/bar.capnp
//! ```
//!

extern crate capnp;

/// Code generated from [schema.capnp]
/// (https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
pub mod schema_capnp;

pub mod codegen;
pub mod codegen_types;
mod pointer_constants;

use std::path::{Path, PathBuf};

fn run_command(mut command: ::std::process::Command, path: &PathBuf) -> ::capnp::Result<()> {
    let mut p = command.spawn()?;
    crate::codegen::generate_code(p.stdout.take().unwrap(), path.as_path())?;
    let exit_status = p.wait()?;
    if !exit_status.success() {
        Err(::capnp::Error::failed(format!(
            "Non-success exit status: {}",
            exit_status
        )))
    } else {
        Ok(())
    }
}

/// A builder object for schema compiler commands.
pub struct CompilerCommand {
    files: Vec<PathBuf>,
    src_prefixes: Vec<PathBuf>,
    import_paths: Vec<PathBuf>,
    no_standard_import: bool,
    output_path: Option<PathBuf>,
}

impl CompilerCommand {
    /// Creates a new, empty command.
    pub fn new() -> CompilerCommand {
        CompilerCommand {
            files: Vec::new(),
            src_prefixes: Vec::new(),
            import_paths: Vec::new(),
            no_standard_import: false,
            output_path: None,
        }
    }

    /// Adds a file to be compiled.
    pub fn file<'a, P>(&'a mut self, path: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.files.push(path.as_ref().to_path_buf());
        self
    }

    /// Adds a --src-prefix flag. For all files specified for compilation that start
    /// with `prefix`, removes the prefix when computing output filenames.
    pub fn src_prefix<'a, P>(&'a mut self, prefix: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.src_prefixes.push(prefix.as_ref().to_path_buf());
        self
    }

    /// Adds an --import_path flag. Adds `dir` to the list of directories searched
    /// for absolute imports.
    pub fn import_path<'a, P>(&'a mut self, dir: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.import_paths.push(dir.as_ref().to_path_buf());
        self
    }

    /// Adds the --no-standard-import flag, indicating that the default import paths of
    /// /usr/include and /usr/local/include should not bet included.
    pub fn no_standard_import<'a>(&'a mut self) -> &'a mut CompilerCommand {
        self.no_standard_import = true;
        self
    }

    ///Sets the output directory of generated code. Default is OUT_DIR
    pub fn output_path<'a, P>(&'a mut self, path: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.output_path = Some(path.as_ref().to_path_buf());
        self
    }

    /// Runs the command. Returns an error if `OUT_DIR` or a custom output directory was not set
    /// or if `capnp compile` fails.
    pub fn run(&mut self) -> ::capnp::Result<()> {
        let mut command = ::std::process::Command::new("capnp");
        command.arg("compile").arg("-o").arg("-");

        if self.no_standard_import {
            command.arg("--no-standard-import");
        }

        for import_path in &self.import_paths {
            command.arg(&format!("--import-path={}", import_path.display()));
        }

        for src_prefix in &self.src_prefixes {
            command.arg(&format!("--src-prefix={}", src_prefix.display()));
        }

        for file in &self.files {
            command.arg(&format!("{}", file.display()));
        }

        let output_path = if let Some(output_path) = &self.output_path {
            output_path.clone()
        } else {
            // Try `OUT_DIR` by default
            PathBuf::from(::std::env::var("OUT_DIR").map_err(|error| {
                ::capnp::Error::failed(format!(
                    "Could not access `OUT_DIR` environment variable: {}. \
                     You might need to set it up or instead create you own output \
                     structure using `CompilerCommand::output_path`",
                    error
                ))
            })?)
        };

        command.stdout(::std::process::Stdio::piped());
        command.stderr(::std::process::Stdio::inherit());

        run_command(command, &output_path).map_err(|error| {
            ::capnp::Error::failed(format!(
                "Error while trying to execute `capnp compile`: {}.  \
                 Please verify that version 0.5.2 or higher of the capnp executable \
                 is installed on your system. See https://capnproto.org/install.html",
                error
            ))
        })
    }
}

#[test]
fn compiler_command_new_no_out_dir() {
    let error = CompilerCommand::new().run().unwrap_err().description;
    assert!(error.starts_with("Could not access `OUT_DIR` environment variable"));
}

#[test]
fn compiler_command_with_output_path_no_out_dir() {
    let error = CompilerCommand::new().output_path("foo").run().unwrap_err().description;
    assert!(error.starts_with("Error while trying to execute `capnp compile`"));
}
<commit_msg>fix another doc link<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Library
//!
//! This library allows you to do
//! [Cap'n Proto code generation](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins)
//! within a Cargo build. You still need the `capnp` binary (implemented in C++).
//! (If you use a package manager, try looking for a package called
//! `capnproto`.)
//!
//! In your Cargo.toml:
//!
//! ```ignore
//! [package]
//! build = "build.rs"
//!
//! [build-dependencies]
//! capnpc = "0.12"
//! ```
//!
//! In your build.rs:
//!
//! ```ignore
//! extern crate capnpc;
//!
//! fn main() {
//!     capnpc::CompilerCommand::new()
//!         .src_prefix("schema")
//!         .file("schema/foo.capnp")
//!         .file("schema/bar.capnp")
//!         .run().expect("schema compiler command");
//! }
//! ```
//!
//! This will be equivalent to executing the shell command
//!
//! ```ignore
//!   capnp compile -orust:$OUT_DIR --src-prefix=schema schema/foo.capnp schema/bar.capnp
//! ```
//!

extern crate capnp;

/// Code generated from
/// [schema.capnp](https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/schema.capnp).
pub mod schema_capnp;

pub mod codegen;
pub mod codegen_types;
mod pointer_constants;

use std::path::{Path, PathBuf};

fn run_command(mut command: ::std::process::Command, path: &PathBuf) -> ::capnp::Result<()> {
    let mut p = command.spawn()?;
    crate::codegen::generate_code(p.stdout.take().unwrap(), path.as_path())?;
    let exit_status = p.wait()?;
    if !exit_status.success() {
        Err(::capnp::Error::failed(format!(
            "Non-success exit status: {}",
            exit_status
        )))
    } else {
        Ok(())
    }
}

/// A builder object for schema compiler commands.
pub struct CompilerCommand {
    files: Vec<PathBuf>,
    src_prefixes: Vec<PathBuf>,
    import_paths: Vec<PathBuf>,
    no_standard_import: bool,
    output_path: Option<PathBuf>,
}

impl CompilerCommand {
    /// Creates a new, empty command.
    pub fn new() -> CompilerCommand {
        CompilerCommand {
            files: Vec::new(),
            src_prefixes: Vec::new(),
            import_paths: Vec::new(),
            no_standard_import: false,
            output_path: None,
        }
    }

    /// Adds a file to be compiled.
    pub fn file<'a, P>(&'a mut self, path: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.files.push(path.as_ref().to_path_buf());
        self
    }

    /// Adds a --src-prefix flag. For all files specified for compilation that start
    /// with `prefix`, removes the prefix when computing output filenames.
    pub fn src_prefix<'a, P>(&'a mut self, prefix: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.src_prefixes.push(prefix.as_ref().to_path_buf());
        self
    }

    /// Adds an --import_path flag. Adds `dir` to the list of directories searched
    /// for absolute imports.
    pub fn import_path<'a, P>(&'a mut self, dir: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.import_paths.push(dir.as_ref().to_path_buf());
        self
    }

    /// Adds the --no-standard-import flag, indicating that the default import paths of
    /// /usr/include and /usr/local/include should not bet included.
    pub fn no_standard_import<'a>(&'a mut self) -> &'a mut CompilerCommand {
        self.no_standard_import = true;
        self
    }

    ///Sets the output directory of generated code. Default is OUT_DIR
    pub fn output_path<'a, P>(&'a mut self, path: P) -> &'a mut CompilerCommand
    where
        P: AsRef<Path>,
    {
        self.output_path = Some(path.as_ref().to_path_buf());
        self
    }

    /// Runs the command. Returns an error if `OUT_DIR` or a custom output directory was not set
    /// or if `capnp compile` fails.
    pub fn run(&mut self) -> ::capnp::Result<()> {
        let mut command = ::std::process::Command::new("capnp");
        command.arg("compile").arg("-o").arg("-");

        if self.no_standard_import {
            command.arg("--no-standard-import");
        }

        for import_path in &self.import_paths {
            command.arg(&format!("--import-path={}", import_path.display()));
        }

        for src_prefix in &self.src_prefixes {
            command.arg(&format!("--src-prefix={}", src_prefix.display()));
        }

        for file in &self.files {
            command.arg(&format!("{}", file.display()));
        }

        let output_path = if let Some(output_path) = &self.output_path {
            output_path.clone()
        } else {
            // Try `OUT_DIR` by default
            PathBuf::from(::std::env::var("OUT_DIR").map_err(|error| {
                ::capnp::Error::failed(format!(
                    "Could not access `OUT_DIR` environment variable: {}. \
                     You might need to set it up or instead create you own output \
                     structure using `CompilerCommand::output_path`",
                    error
                ))
            })?)
        };

        command.stdout(::std::process::Stdio::piped());
        command.stderr(::std::process::Stdio::inherit());

        run_command(command, &output_path).map_err(|error| {
            ::capnp::Error::failed(format!(
                "Error while trying to execute `capnp compile`: {}.  \
                 Please verify that version 0.5.2 or higher of the capnp executable \
                 is installed on your system. See https://capnproto.org/install.html",
                error
            ))
        })
    }
}

#[test]
fn compiler_command_new_no_out_dir() {
    let error = CompilerCommand::new().run().unwrap_err().description;
    assert!(error.starts_with("Could not access `OUT_DIR` environment variable"));
}

#[test]
fn compiler_command_with_output_path_no_out_dir() {
    let error = CompilerCommand::new().output_path("foo").run().unwrap_err().description;
    assert!(error.starts_with("Error while trying to execute `capnp compile`"));
}
<|endoftext|>


<commit_before>//
//
//
//! Device manager "drivers"
use kernel::prelude::*;
use kernel::device_manager;

struct PciLegacyDriver;	// PCI Legacy ATA (BMDMA, all ports/IRQs legacy)
struct PciNativeDriver;	// PCI Native Mode ATA (all configured via PCI)

#[allow(non_upper_case_globals)]
static s_pci_legacy_driver: PciLegacyDriver = PciLegacyDriver;
#[allow(non_upper_case_globals)]
static s_pci_native_driver: PciNativeDriver = PciNativeDriver;

pub fn register()
{
	device_manager::register_driver(&s_pci_legacy_driver);
	device_manager::register_driver(&s_pci_native_driver);
}

impl device_manager::Driver for PciLegacyDriver
{
	fn name(&self) -> &str {
		"ata-legacy"
	}
	fn bus_type(&self) -> &str {
		"pci"
	}
	fn handles(&self, bus_dev: &device_manager::BusDevice) -> u32
	{
		let classcode = bus_dev.get_attr("class");
		// [class] [subclass] [IF] [ver]
		if classcode & 0xFFFF0500 == 0x01010000 {
			1	// Handle as weakly as possible (vendor-provided drivers bind higher)
		}
		else {
			0
		}
	}
	fn bind(&self, bus_dev: &mut device_manager::BusDevice) -> Box<device_manager::DriverInstance+'static>
	{
		let bm_io = bus_dev.bind_io(4);
		bus_dev.set_attr("bus_master", 1);
		Box::new( ::ControllerRoot::new(0x1F0, 0x3F6, 14,  0x170, 0x376, 15,  bm_io) )
	}
}

impl device_manager::Driver for PciNativeDriver
{
	fn name(&self) -> &str {
		"ata-native"
	}
	fn bus_type(&self) -> &str {
		"pci"
	}
	fn handles(&self, bus_dev: &device_manager::BusDevice) -> u32
	{
		let classcode = bus_dev.get_attr("class");
		// [class] [subclass] [IF] [ver]
		// IF ~= 0x05 means that both channels are in PCI native mode
		if classcode & 0xFFFF0500 == 0x01010500 {
			1	// Handle as weakly as possible (vendor-provided drivers bind higher)
		}
		else {
			0
		}
	}
	fn bind(&self, bus_dev: &mut device_manager::BusDevice) -> Box<device_manager::DriverInstance+'static>
	{
		let irq = bus_dev.get_irq(0);
		let io_pri = bus_dev.bind_io(0).io_base();
		let st_pri = bus_dev.bind_io(1).io_base() + 2;
		let io_sec = bus_dev.bind_io(2).io_base();
		let st_sec = bus_dev.bind_io(3).io_base() + 2;
		let bm_io = bus_dev.bind_io(4);
		Box::new( ::ControllerRoot::new(io_pri, st_pri, irq,  io_sec, st_sec, irq,  bm_io) )
	}
}

<commit_msg>Kernel/ATA - (minor) Comment a magic number<commit_after>//
//
//
//! Device manager "drivers"
use kernel::prelude::*;
use kernel::device_manager;

struct PciLegacyDriver;	// PCI Legacy ATA (BMDMA, all ports/IRQs legacy)
struct PciNativeDriver;	// PCI Native Mode ATA (all configured via PCI)

#[allow(non_upper_case_globals)]
static s_pci_legacy_driver: PciLegacyDriver = PciLegacyDriver;
#[allow(non_upper_case_globals)]
static s_pci_native_driver: PciNativeDriver = PciNativeDriver;

pub fn register()
{
	device_manager::register_driver(&s_pci_legacy_driver);
	device_manager::register_driver(&s_pci_native_driver);
}

impl device_manager::Driver for PciLegacyDriver
{
	fn name(&self) -> &str {
		"ata-legacy"
	}
	fn bus_type(&self) -> &str {
		"pci"
	}
	fn handles(&self, bus_dev: &device_manager::BusDevice) -> u32
	{
		let classcode = bus_dev.get_attr("class");
		// [class] [subclass] [IF] [ver]
		// - The 5 masks in two bits representing the channel modes
		if classcode & 0xFFFF0500 == 0x01010000 {
			1	// Handle as weakly as possible (vendor-provided drivers bind higher)
		}
		else {
			0
		}
	}
	fn bind(&self, bus_dev: &mut device_manager::BusDevice) -> Box<device_manager::DriverInstance+'static>
	{
		let bm_io = bus_dev.bind_io(4);
		bus_dev.set_attr("bus_master", 1);
		Box::new( ::ControllerRoot::new(0x1F0, 0x3F6, 14,  0x170, 0x376, 15,  bm_io) )
	}
}

impl device_manager::Driver for PciNativeDriver
{
	fn name(&self) -> &str {
		"ata-native"
	}
	fn bus_type(&self) -> &str {
		"pci"
	}
	fn handles(&self, bus_dev: &device_manager::BusDevice) -> u32
	{
		let classcode = bus_dev.get_attr("class");
		// [class] [subclass] [IF] [ver]
		// IF ~= 0x05 means that both channels are in PCI native mode
		if classcode & 0xFFFF0500 == 0x01010500 {
			1	// Handle as weakly as possible (vendor-provided drivers bind higher)
		}
		else {
			0
		}
	}
	fn bind(&self, bus_dev: &mut device_manager::BusDevice) -> Box<device_manager::DriverInstance+'static>
	{
		let irq = bus_dev.get_irq(0);
		let io_pri = bus_dev.bind_io(0).io_base();
		let st_pri = bus_dev.bind_io(1).io_base() + 2;
		let io_sec = bus_dev.bind_io(2).io_base();
		let st_sec = bus_dev.bind_io(3).io_base() + 2;
		let bm_io = bus_dev.bind_io(4);
		Box::new( ::ControllerRoot::new(io_pri, st_pri, irq,  io_sec, st_sec, irq,  bm_io) )
	}
}

<|endoftext|>