<commit_before>#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Param {
    Short(char),
    Long(String),
}

pub trait IntoParam {
    fn into_param(self) -> Param;
}

impl IntoParam for &'static str {
    fn into_param(self) -> Param {
        Param::Long(self.to_owned())
    }
}

impl IntoParam for char {
    fn into_param(self) -> Param {
        Param::Short(self)
    }
}

use std::collections::HashMap;

/// Our homebrewed Arg Parser
///
/// Yes, it would be nice to use an Arg Parser library but we don't have that
/// kind of luxury with our current std crate implementation for Redox
#[derive(Clone, Debug, Default)]
pub struct ArgParser {
    flags: HashMap<Param, bool>,
    opts:  HashMap<Param, Option<String>>,
    pub args: Vec<String>,
}

impl ArgParser {
    /// Create a new ArgParser object
    pub fn new(flag_cap: usize, opt_cap: usize) -> Self {
        ArgParser {
            flags: HashMap::with_capacity(flag_cap),
            opts: HashMap::with_capacity(opt_cap),
            args: Vec::new(),
        }
    }

    /// Builder method for adding both short and long flags
    pub fn add_flag(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.flags.insert(Param::Short(short), false);
        }
        if !long.is_empty() {
            self.flags.insert(Param::Long(long.to_owned()), false);
        }
        self
    }

    /// Builder method for adding both short and long opts
    pub fn add_opt(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.opts.insert(Param::Short(short), None);
        }
        if !long.is_empty() {
            self.opts.insert(Param::Long(long.to_owned()), None);
        }
        self
    }

    /// Check if a flag has been used
    pub fn enabled_flag<F: IntoParam>(&self, flag: F) -> bool {
        *self.flags.get(&flag.into_param()).unwrap_or(&false)
    }

    /// Start parsing user inputted args for which flags are used
    pub fn initialize<A: Iterator<Item=String>>(&mut self, args: A) {
        let mut args = args.skip(1);
        while let Some(mut arg) = args.next() {
            if arg.starts_with("--") {
                // Remove both dashes
                arg.remove(0);
                arg.remove(0);
                if let Some(i) = arg.find('=') {
                    let (lhs, rhs) = arg.split_at(i);
                    if let Some(opt) = self.opts.get_mut(&Param::Long(lhs.to_owned())) {
                        *opt = Some(rhs.to_owned());
                    }
                }
                else {
                    if let Some(flag) = self.flags.get_mut(&Param::Long(arg)) {
                        *flag = true;
                    }
                }
            }
            else if arg.starts_with("-") {
                for ch in arg[1..].chars() {
                    if let Some(switch) = self.flags.get_mut(&Param::Short(ch)) {
                        *switch = true;
                    }
                    if let Some(value) = self.opts.get_mut(&Param::Short(ch)) {
                        *value = args.next();
                    }
                }
            }
            else {
                self.args.push(arg);
            }
        }
    }

    pub fn set_flag<F: IntoParam>(&mut self, flag: F, state: bool) {
        if let Some(switch) = self.flags.get_mut(&flag.into_param()) {
            *switch = state;
        }
    }

    pub fn set_opt<O: IntoParam>(&mut self, opt: O, state: Option<String>) {
        if let Some(value) = self.opts.get_mut(&opt.into_param()) {
            *value = state;
        }
    }

    pub fn has_opt<O: IntoParam>(&mut self, opt: O) -> bool {
        if let Some(&Some(_)) = self.opts.get(&opt.into_param()) {
            return true;
        }
        false
    }
}

pub fn to_human_readable_string(size: u64) -> String {
    if size < 1024 {
        return format!("{}", size);
    }

    static UNITS: [&'static str; 7] = ["", "K", "M", "G", "T", "P", "E"];

    let sizef = size as f64;
    let digit_groups = (sizef.log10() / 1024f64.log10()) as i32;
    format!("{:.1}{}",
            sizef / 1024f64.powf(digit_groups as f64),
            UNITS[digit_groups as usize])
}
<commit_msg>Remove what was not true<commit_after>#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Param {
    Short(char),
    Long(String),
}

pub trait IntoParam {
    fn into_param(self) -> Param;
}

impl IntoParam for &'static str {
    fn into_param(self) -> Param {
        Param::Long(self.to_owned())
    }
}

impl IntoParam for char {
    fn into_param(self) -> Param {
        Param::Short(self)
    }
}

use std::collections::HashMap;

/// Our homebrewed Arg Parser
#[derive(Clone, Debug, Default)]
pub struct ArgParser {
    flags: HashMap<Param, bool>,
    opts:  HashMap<Param, Option<String>>,
    pub args: Vec<String>,
}

impl ArgParser {
    /// Create a new ArgParser object
    pub fn new(flag_cap: usize, opt_cap: usize) -> Self {
        ArgParser {
            flags: HashMap::with_capacity(flag_cap),
            opts: HashMap::with_capacity(opt_cap),
            args: Vec::new(),
        }
    }

    /// Builder method for adding both short and long flags
    pub fn add_flag(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.flags.insert(Param::Short(short), false);
        }
        if !long.is_empty() {
            self.flags.insert(Param::Long(long.to_owned()), false);
        }
        self
    }

    /// Builder method for adding both short and long opts
    pub fn add_opt(mut self, short: &str, long: &str) -> Self {
        if let Some(short) = short.chars().next() {
            self.opts.insert(Param::Short(short), None);
        }
        if !long.is_empty() {
            self.opts.insert(Param::Long(long.to_owned()), None);
        }
        self
    }

    /// Check if a flag has been used
    pub fn enabled_flag<F: IntoParam>(&self, flag: F) -> bool {
        *self.flags.get(&flag.into_param()).unwrap_or(&false)
    }

    /// Start parsing user inputted args for which flags are used
    pub fn initialize<A: Iterator<Item=String>>(&mut self, args: A) {
        let mut args = args.skip(1);
        while let Some(mut arg) = args.next() {
            if arg.starts_with("--") {
                // Remove both dashes
                arg.remove(0);
                arg.remove(0);
                if let Some(i) = arg.find('=') {
                    let (lhs, rhs) = arg.split_at(i);
                    if let Some(opt) = self.opts.get_mut(&Param::Long(lhs.to_owned())) {
                        *opt = Some(rhs.to_owned());
                    }
                }
                else {
                    if let Some(flag) = self.flags.get_mut(&Param::Long(arg)) {
                        *flag = true;
                    }
                }
            }
            else if arg.starts_with("-") {
                for ch in arg[1..].chars() {
                    if let Some(switch) = self.flags.get_mut(&Param::Short(ch)) {
                        *switch = true;
                    }
                    if let Some(value) = self.opts.get_mut(&Param::Short(ch)) {
                        *value = args.next();
                    }
                }
            }
            else {
                self.args.push(arg);
            }
        }
    }

    pub fn set_flag<F: IntoParam>(&mut self, flag: F, state: bool) {
        if let Some(switch) = self.flags.get_mut(&flag.into_param()) {
            *switch = state;
        }
    }

    pub fn set_opt<O: IntoParam>(&mut self, opt: O, state: Option<String>) {
        if let Some(value) = self.opts.get_mut(&opt.into_param()) {
            *value = state;
        }
    }

    pub fn has_opt<O: IntoParam>(&mut self, opt: O) -> bool {
        if let Some(&Some(_)) = self.opts.get(&opt.into_param()) {
            return true;
        }
        false
    }
}

pub fn to_human_readable_string(size: u64) -> String {
    if size < 1024 {
        return format!("{}", size);
    }

    static UNITS: [&'static str; 7] = ["", "K", "M", "G", "T", "P", "E"];

    let sizef = size as f64;
    let digit_groups = (sizef.log10() / 1024f64.log10()) as i32;
    format!("{:.1}{}",
            sizef / 1024f64.powf(digit_groups as f64),
            UNITS[digit_groups as usize])
}
<|endoftext|>


<commit_before>//#![deny(warnings)]
#![feature(try_from)]
#![feature(conservative_impl_trait)]
#[macro_use]
extern crate cfg_if;
extern crate r2d2;
extern crate url;
#[macro_use]
extern crate dao_codegen;
extern crate dao;
cfg_if! {if #[cfg(feature = "with-postgres")]{
    extern crate r2d2_postgres;
    extern crate postgres;
    #[macro_use]
    extern crate postgres_shared;
    mod pg;
}}
extern crate uuid;
extern crate chrono;

mod pool;
mod platform;
mod error;
mod database;

pub use pool::Pool;
pub use database::Database;
pub use dao::Dao;
pub use dao::Value;
pub use dao::Rows;
pub use error::DbError;

#[cfg(test)]
mod test{
    use super::*;
    use dao::{FromDao, ToDao};

    #[test]
    fn derive_fromdao_and_todao() {
        #[derive(Debug, PartialEq, FromDao, ToDao)]
        struct User{
            id: i32,
            username: String,
            active: Option<bool>,
        }

        let user = User{ id: 1, username: "ivanceras".into(), active: Some(true) };
        println!("user: {:#?}", user);
        let dao = user.to_dao();
        let mut expected_dao = Dao::new();
        expected_dao.insert("id", 1);
        expected_dao.insert("username", "ivanceras".to_string());
        expected_dao.insert("active", true);

        assert_eq!(expected_dao, dao);

        println!("dao: {:#?}", dao);
        let from_dao = User::from_dao(&dao);
        println!("from_dao: {:#?}", from_dao);
        assert_eq!(from_dao, user);
    }
}
<commit_msg>shorten code using T::Error<commit_after>#![deny(warnings)]
#![feature(try_from)]
#![feature(conservative_impl_trait)]
#[macro_use]
extern crate cfg_if;
extern crate r2d2;
extern crate url;

#[cfg(test)]
#[macro_use]
extern crate dao_codegen;
extern crate dao;
cfg_if! {if #[cfg(feature = "with-postgres")]{
    extern crate r2d2_postgres;
    extern crate postgres;
    #[macro_use]
    extern crate postgres_shared;
    mod pg;
}}
extern crate uuid;
extern crate chrono;

mod pool;
mod platform;
mod error;
mod database;

pub use pool::Pool;
pub use database::Database;
pub use dao::Dao;
pub use dao::Value;
pub use dao::Rows;
pub use error::DbError;

#[cfg(test)]
mod test{
    use super::*;
    use dao::{FromDao, ToDao};

    #[test]
    fn derive_fromdao_and_todao() {
        #[derive(Debug, PartialEq, FromDao, ToDao)]
        struct User{
            id: i32,
            username: String,
            active: Option<bool>,
        }

        let user = User{ id: 1, username: "ivanceras".into(), active: Some(true) };
        println!("user: {:#?}", user);
        let dao = user.to_dao();
        let mut expected_dao = Dao::new();
        expected_dao.insert("id", 1);
        expected_dao.insert("username", "ivanceras".to_string());
        expected_dao.insert("active", true);

        assert_eq!(expected_dao, dao);

        println!("dao: {:#?}", dao);
        let from_dao = User::from_dao(&dao);
        println!("from_dao: {:#?}", from_dao);
        assert_eq!(from_dao, user);
    }
}
<|endoftext|>


<commit_before>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! an adjacency list graph with undirected or directed edges and arbitrary
//! associated data.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an hashmap-backed graph with undirected edges and only allows simple node
//! identifiers (such as integers or references).

extern crate fixedbitset;

pub use graph::Graph;
pub use graphmap::GraphMap;

pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};
pub use EdgeDirection::{Outgoing, Incoming};

mod scored;
pub mod algo;
#[cfg(feature = "generate")]
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod dot;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;
#[cfg(feature = "quickcheck")]
pub mod quickcheck;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    /// Return the opposite `EdgeDirection`.
    #[inline]
    pub fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub enum Directed { }

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub enum Undirected { }

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<E> {
    type NodeId;
    fn into_weighted_edge(self) -> (Self::NodeId, Self::NodeId, E);
}

impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix)
    where E: Default
{
    type NodeId = Ix;

    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix, E)
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        self
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for (Ix, Ix, &'a E)
    where E: Clone
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (a, b, c) = self;
        (a, b, c.clone())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}
<commit_msg>Remove `pub` from `quickcheck` module<commit_after>
//! **petgraph** is a graph data structure library.
//!
//! The most prominent type is [`Graph`](./graph/struct.Graph.html) which is
//! an adjacency list graph with undirected or directed edges and arbitrary
//! associated data.
//!
//! Petgraph also provides [`GraphMap`](./graphmap/struct.GraphMap.html) which
//! is an hashmap-backed graph with undirected edges and only allows simple node
//! identifiers (such as integers or references).

extern crate fixedbitset;

pub use graph::Graph;
pub use graphmap::GraphMap;

pub use visit::{
    Bfs,
    BfsIter,
    Dfs,
    DfsIter,
};
pub use EdgeDirection::{Outgoing, Incoming};

mod scored;
pub mod algo;
#[cfg(feature = "generate")]
pub mod generate;
pub mod graphmap;
pub mod graph;
pub mod dot;
pub mod visit;
pub mod unionfind;
mod dijkstra;
mod isomorphism;
mod traits_graph;
#[cfg(feature = "quickcheck")]
mod quickcheck;

// Index into the NodeIndex and EdgeIndex arrays
/// Edge direction
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub enum EdgeDirection {
    /// An `Outgoing` edge is an outward edge *from* the current node.
    Outgoing = 0,
    /// An `Incoming` edge is an inbound edge *to* the current node.
    Incoming = 1
}

impl EdgeDirection {
    /// Return the opposite `EdgeDirection`.
    #[inline]
    pub fn opposite(&self) -> EdgeDirection {
        match *self {
            Outgoing => Incoming,
            Incoming => Outgoing,
        }
    }
}

/// Marker type for a directed graph.
#[derive(Copy, Clone, Debug)]
pub enum Directed { }

/// Marker type for an undirected graph.
#[derive(Copy, Clone, Debug)]
pub enum Undirected { }

/// A graph's edge type determines whether is has directed edges or not.
pub trait EdgeType {
    fn is_directed() -> bool;
}

impl EdgeType for Directed {
    #[inline]
    fn is_directed() -> bool { true }
}

impl EdgeType for Undirected {
    #[inline]
    fn is_directed() -> bool { false }
}

/// Convert an element like `(i, j)` or `(i, j, w)` into
/// a triple of source, target, edge weight.
///
/// For `Graph::from_edges` and `GraphMap::from_edges`.
pub trait IntoWeightedEdge<E> {
    type NodeId;
    fn into_weighted_edge(self) -> (Self::NodeId, Self::NodeId, E);
}

impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix)
    where E: Default
{
    type NodeId = Ix;

    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (s, t) = self;
        (s, t, E::default())
    }
}

impl<Ix, E> IntoWeightedEdge<E> for (Ix, Ix, E)
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        self
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for (Ix, Ix, &'a E)
    where E: Clone
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (a, b, c) = self;
        (a, b, c.clone())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix)
    where Ix: Copy, E: Default
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        let (s, t) = *self;
        (s, t, E::default())
    }
}

impl<'a, Ix, E> IntoWeightedEdge<E> for &'a (Ix, Ix, E)
    where Ix: Copy, E: Clone
{
    type NodeId = Ix;
    fn into_weighted_edge(self) -> (Ix, Ix, E) {
        self.clone()
    }
}
<|endoftext|>


<commit_before>//! ArrayFire is a high performance software library for parallel computing with
//! an easy-to-use API. ArrayFire abstracts away much of the details of
//! programming parallel architectures by providing a high-level container object,
//! the [Array](./struct.Array.html), that represents data stored on a CPU, GPU, FPGA,
//! or other type of accelerator. This abstraction permits developers to write
//! massively parallel applications in a high-level language where they need
//! not be concerned about low-level optimizations that are frequently required to
//! achieve high throughput on most parallel architectures.

//! This crate provides Rust bindings for the ArrayFire library. Given below table shows
//! the rust bindings compatability with ArrayFire upstream.  If you find any bugs,
//! please report them on [github](https://github.com/arrayfire/arrayfire-rust/issues).
//!
//! | arrayfire-rust crate | ArrayFire Upstream |
//! |:--------------------:|:------------------:|
//! |         M.m.p1       |      M.m.p2        |
//!
//! Only, Major(M) & Minor(m) version numbers need to match. *p1* and *p2*
//! are patch/fix updates for `arrayfire-rust` & `ArrayFire` respectively,
//! and they don't need to match.
//!
//! Please go through our [tutorials](./book/index.html) book for more explanations on how to
//! use ArrayFire to speedup your code.

#![doc(
    html_logo_url = "http://www.arrayfire.com/logos/arrayfire_logo_symbol.png",
    html_favicon_url = "http://www.rust-lang.org/favicon.ico",
    html_root_url = "http://arrayfire.org/arrayfire-rust/arrayfire/index.html"
)]
#![warn(missing_docs)]
#![allow(non_camel_case_types)]

#[macro_use]
extern crate lazy_static;

pub use crate::array::*;
mod array;

#[cfg(feature = "algorithm")]
pub use crate::algorithm::*;
#[cfg(feature = "algorithm")]
mod algorithm;

#[cfg(feature = "arithmetic")]
pub use crate::arith::*;
#[cfg(feature = "arithmetic")]
mod arith;

pub use crate::backend::*;
mod backend;

#[cfg(feature = "blas")]
pub use crate::blas::*;
#[cfg(feature = "blas")]
mod blas;

#[cfg(feature = "data")]
pub use crate::data::*;
#[cfg(feature = "data")]
mod data;

pub use crate::device::*;
mod device;

pub use crate::defines::*;
mod defines;

pub use crate::dim4::Dim4;
mod dim4;

pub use crate::error::{handle_error_general, register_error_handler, Callback, ErrorCallback};
mod error;

#[cfg(feature = "indexing")]
pub use crate::index::*;
#[cfg(feature = "indexing")]
mod index;

#[cfg(feature = "indexing")]
pub use crate::seq::Seq;
#[cfg(feature = "indexing")]
mod seq;

#[cfg(feature = "graphics")]
pub use crate::graphics::Window;
#[cfg(feature = "graphics")]
mod graphics;

#[cfg(feature = "image")]
pub use crate::image::*;
#[cfg(feature = "image")]
mod image;

#[cfg(feature = "lapack")]
pub use crate::lapack::*;
#[cfg(feature = "lapack")]
mod lapack;

#[cfg(feature = "macros")]
mod macros;
mod num;

#[cfg(feature = "random")]
pub use crate::random::*;
#[cfg(feature = "random")]
mod random;

#[cfg(feature = "signal")]
pub use crate::signal::*;
#[cfg(feature = "signal")]
mod signal;

#[cfg(feature = "sparse")]
pub use crate::sparse::*;
#[cfg(feature = "sparse")]
mod sparse;

#[cfg(feature = "statistics")]
pub use crate::statistics::*;
#[cfg(feature = "statistics")]
mod statistics;

pub use crate::util::{get_size, HasAfEnum, ImplicitPromote};
pub use crate::util::{ComplexFloating, FloatingPoint, RealFloating, RealNumber};
pub use crate::util::{CovarianceComputable, EdgeComputable, MedianComputable, MomentsComputable};
pub use crate::util::{GrayRGBConvertible, ImageFilterType, ImageNativeType, Scanable};
mod util;

#[cfg(feature = "vision")]
pub use crate::vision::*;
#[cfg(feature = "vision")]
mod vision;

// headers that are not exposed through rust wrapper are given follows:
// compatible.h
// constants.h
// complex.h
// cuda.h
// opencl.h
<commit_msg>Link to book on gh-pages so that docs.rs works<commit_after>//! ArrayFire is a high performance software library for parallel computing with
//! an easy-to-use API. ArrayFire abstracts away much of the details of
//! programming parallel architectures by providing a high-level container object,
//! the [Array](./struct.Array.html), that represents data stored on a CPU, GPU, FPGA,
//! or other type of accelerator. This abstraction permits developers to write
//! massively parallel applications in a high-level language where they need
//! not be concerned about low-level optimizations that are frequently required to
//! achieve high throughput on most parallel architectures.

//! This crate provides Rust bindings for the ArrayFire library. Given below table shows
//! the rust bindings compatability with ArrayFire upstream.  If you find any bugs,
//! please report them on [github](https://github.com/arrayfire/arrayfire-rust/issues).
//!
//! | arrayfire-rust crate | ArrayFire Upstream |
//! |:--------------------:|:------------------:|
//! |         M.m.p1       |      M.m.p2        |
//!
//! Only, Major(M) & Minor(m) version numbers need to match. *p1* and *p2*
//! are patch/fix updates for `arrayfire-rust` & `ArrayFire` respectively,
//! and they don't need to match.
//!
//! Please go through our [tutorials](http://arrayfire.org/arrayfire-rust/arrayfire/book/index.html)
//! book for more explanations on how to use ArrayFire to speedup your code.

#![doc(
    html_logo_url = "http://www.arrayfire.com/logos/arrayfire_logo_symbol.png",
    html_favicon_url = "http://www.rust-lang.org/favicon.ico",
    html_root_url = "http://arrayfire.org/arrayfire-rust/arrayfire/index.html"
)]
#![warn(missing_docs)]
#![allow(non_camel_case_types)]

#[macro_use]
extern crate lazy_static;

pub use crate::array::*;
mod array;

#[cfg(feature = "algorithm")]
pub use crate::algorithm::*;
#[cfg(feature = "algorithm")]
mod algorithm;

#[cfg(feature = "arithmetic")]
pub use crate::arith::*;
#[cfg(feature = "arithmetic")]
mod arith;

pub use crate::backend::*;
mod backend;

#[cfg(feature = "blas")]
pub use crate::blas::*;
#[cfg(feature = "blas")]
mod blas;

#[cfg(feature = "data")]
pub use crate::data::*;
#[cfg(feature = "data")]
mod data;

pub use crate::device::*;
mod device;

pub use crate::defines::*;
mod defines;

pub use crate::dim4::Dim4;
mod dim4;

pub use crate::error::{handle_error_general, register_error_handler, Callback, ErrorCallback};
mod error;

#[cfg(feature = "indexing")]
pub use crate::index::*;
#[cfg(feature = "indexing")]
mod index;

#[cfg(feature = "indexing")]
pub use crate::seq::Seq;
#[cfg(feature = "indexing")]
mod seq;

#[cfg(feature = "graphics")]
pub use crate::graphics::Window;
#[cfg(feature = "graphics")]
mod graphics;

#[cfg(feature = "image")]
pub use crate::image::*;
#[cfg(feature = "image")]
mod image;

#[cfg(feature = "lapack")]
pub use crate::lapack::*;
#[cfg(feature = "lapack")]
mod lapack;

#[cfg(feature = "macros")]
mod macros;
mod num;

#[cfg(feature = "random")]
pub use crate::random::*;
#[cfg(feature = "random")]
mod random;

#[cfg(feature = "signal")]
pub use crate::signal::*;
#[cfg(feature = "signal")]
mod signal;

#[cfg(feature = "sparse")]
pub use crate::sparse::*;
#[cfg(feature = "sparse")]
mod sparse;

#[cfg(feature = "statistics")]
pub use crate::statistics::*;
#[cfg(feature = "statistics")]
mod statistics;

pub use crate::util::{get_size, HasAfEnum, ImplicitPromote};
pub use crate::util::{ComplexFloating, FloatingPoint, RealFloating, RealNumber};
pub use crate::util::{CovarianceComputable, EdgeComputable, MedianComputable, MomentsComputable};
pub use crate::util::{GrayRGBConvertible, ImageFilterType, ImageNativeType, Scanable};
mod util;

#[cfg(feature = "vision")]
pub use crate::vision::*;
#[cfg(feature = "vision")]
mod vision;

// headers that are not exposed through rust wrapper are given follows:
// compatible.h
// constants.h
// complex.h
// cuda.h
// opencl.h
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self,
                         cmd: &'a mut Command)
                         -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            let mut split = raw.split(';');
            let name = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let username = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let email = format!("{}@{}", username, domain);

            Ok(Author {
              name: name.into(),
              email: email,
            })
          })
      })
      .collect()
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.config.get("active").unwrap(), "jh".to_string());

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.config.get("active").unwrap(), "jh+nn".to_string());
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data.borrow().get(name.into()).cloned().ok_or("".into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<commit_msg>add rotate_active<commit_after>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_active(&self) -> Result<Vec<String>> {
    self.config
      .get("active")
      .map(|active| active.split('+').map(|s| s.into()).collect())
  }

  pub fn rotate_active(&self) -> Result<()> {
    self.get_active().and_then(|active| {
      let mut inits: Vec<_> = active.iter().map(String::as_ref).collect();
      if !inits.is_empty() {
        let author = inits.remove(0);
        inits.push(author);
      }
      self.set_active(&inits[..])
    })
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            let mut split = raw.split(';');
            let name = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let username = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let email = format!("{}@{}", username, domain);

            Ok(Author {
              name: name.into(),
              email: email,
            })
          })
      })
      .collect()
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh"]);

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh", "nn"]);
  }

  #[test]
  fn rotate_active() {
    let config = MockConfig::new(&[("active", "jh+nn"),
                                   ("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.rotate_active().unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["nn", "jh"]);
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data.borrow().get(name.into()).cloned().ok_or("".into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<|endoftext|>


<commit_before>// (c) 2015 Joost Yervante Damad <joost@damad.be>

// loosely based on https://github.com/cgaebel/sexp

use std::fmt;
use std::str::FromStr;

use std::fs::File;
use std::io::prelude::*;

pub enum Atom {
  S(String),
  Q(String),
  I(i64),
  F(f64),
}

pub enum Sexp {
  Atom(Atom),
  Empty,
  List(Vec<Sexp>),
}

pub struct Error {
    msg: &'static str,
    line: usize,
    lpos: usize,
}

type Err = Box<Error>;
type ERes<T> = Result<T, Err>;

fn err<T>(msg: &'static str, state: &ParseState) -> ERes<T> {
    Err(Box::new(Error { msg: msg, line: state.line, lpos: state.lpos }))
}

struct ParseState {
    pos: usize,
    line: usize,
    lpos: usize,
    vec: Vec<char>,
    len: usize,
}

impl ParseState {
    fn peek(&self) -> ERes<char> {
        if self.pos >= self.len {
            return err("end of document reached", self)
        }
        Ok(self.vec[self.pos])
    }
    fn peek_option(&self) -> Option<char> {
        if self.pos >= self.len {
            return None
        }
        Some(self.vec[self.pos])
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Parse Error {}:{}: {}", self.line, self.lpos, self.msg)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Parse Error {}:{}: {}", self.line, self.lpos, self.msg)
    }
}

impl fmt::Display for Atom {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Atom::S(ref s) => write!(f, "{}", s),
      Atom::Q(ref s) => write!(f, "\"{}\"", s),
      Atom::I(i)     => write!(f, "{}", i),
      Atom::F(d)     => write!(f, "{}", d),
    }
  }
}

impl fmt::Display for Sexp {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Sexp::Atom(ref a) => write!(f, "{}", a),
      Sexp::List(ref xs) => {
        try!(write!(f, "("));
        for (i, x) in xs.iter().enumerate() {
          let s = if i == 0 { "" } else { " " };
          try!(write!(f, "{}{}", s, x));
        }
        write!(f, ")")
      },
      Sexp::Empty => write!(f, ""),
    }
  }
}

fn parse_list(state: &mut ParseState) -> ERes<Sexp> {
    println!("list");
    state.pos += 1;
    state.lpos += 1;
    let mut l: Vec<Sexp> = Vec::new();
    loop {
        match try!(state.peek()) {
            ')' => {
                state.pos += 1;
                state.lpos += 1;
                break;
            }
            _ => {
                l.push(try!(parse_sexp(state)));
            }
        }
    }
    println!("Found list");
    Ok(Sexp::List(l))
}

fn parse_quoted_string(state: &mut ParseState) -> ERes<Atom> {
    println!("qstring");
    state.pos += 1;
    state.lpos += 1;
    let mut s = String::new();
    loop {
        match state.vec[state.pos] {
            '"' => {
                state.pos += 1;
                state.lpos += 1;
                break
            }
            '\r' | '\n' => {
                s.push(state.vec[state.pos]);
                state.pos += 1;
                state.lpos = 0;
                state.line += 1;
                }
            x => {
                s.push(x);
                state.pos += 1;
                state.lpos += 1;
            }
        }
    }
    println!("Found quoted string {}", s);
    Ok(Atom::Q(s))
}

fn parse_string(state: &mut ParseState) -> ERes<Atom> {
    println!("string");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\t' | '\r' | '\n' | ')' => break,
                    '"' => return err("unexpected \" in string", state),
                    x => s.push(x),
                }
            }
            None => {
                break;
            }
        }
        state.pos += 1;
        state.lpos += 1;
    }
    println!("Found string {}", s);
    Ok(Atom::S(s))
}

fn parse_number(state: &mut ParseState) -> ERes<Atom> {
    println!("number");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\r' | '\n' | '\t' | ')' => {
                        break
                    },
                    '0' ... '9' | '.' | '-' => {
                        s.push(state.vec[state.pos])
                    },
                    _ => {
                        return err("unexpected char in number", state)
                    },
                }
            }
            None => {
                break
            }
        }
        state.pos += 1;
        state.lpos += 1;
    }
    println!("Found number {}", s);
    let s2: &str = &s[..];
    if s.contains('.') {
        Ok(Atom::F(f64::from_str(s2).unwrap()))
    } else {
        Ok(Atom::I(i64::from_str(s2).unwrap()))
    }
}

fn parse_atom(state: &mut ParseState) -> ERes<Sexp> {
    println!("atom");
    let a = match state.vec[state.pos] {
        '"' => {
            try!(parse_quoted_string(state))
        }
        '0' ... '9' | '.' | '-' => {
            try!(parse_number(state))
        }
        _ => {
            try!(parse_string(state))
        }
    };
    Ok(Sexp::Atom(a))
}

fn parse_sexp(state: &mut ParseState) -> ERes<Sexp> {
    loop {
        match state.vec[state.pos] {
            '(' => {
                return parse_list(state)
            }
            '\n' => {
                state.pos += 1;
                state.lpos = 0;
                state.line += 1;
            }
            ' ' | '\t' => {
                state.pos += 1;
                state.lpos += 1;
            }
            ')' => {
                return err("unmatched )", state)
            }
            _ => {
                return parse_atom(state)
            }
        }
    }
}

fn parse(data: &str) -> ERes<Sexp> {
    if data.len() == 0 {
        Ok(Sexp::Empty)
    } else {
        let vec: Vec<char> = data.chars().collect();
        let len = vec.len();
        let state = &mut ParseState { pos: 0, line: 1, lpos: 0, vec: vec, len: len };
        parse_sexp(state)
    }
}

fn read_file(name: &str) -> Result<String,std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> Sexp {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Sexp {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

#[allow(dead_code)]
fn check_parse(s: &str) {
    let e = parse_str(s);
    let t = format!("{}", e);
    assert_eq!(s, t);
}

#[test]
fn test_empty() { check_parse("") }

#[test]
fn test_minimal() { check_parse("()") }

#[test]
fn test_string() { check_parse("hello") }

#[test]
fn test_number() { check_parse("1.3") }

#[test]
#[should_panic(expected="Parse Error 1:1: end of document reached")]
fn test_invalid1() { parse_str("("); }

#[test]
#[should_panic(expected="Parse Error 1:0: unmatched )")]
fn test_invalid2() { parse_str(")"); }
<commit_msg>simplify state management<commit_after>// (c) 2015 Joost Yervante Damad <joost@damad.be>

// loosely based on https://github.com/cgaebel/sexp

use std::fmt;
use std::str::FromStr;

use std::fs::File;
use std::io::prelude::*;

pub enum Atom {
  S(String),
  Q(String),
  I(i64),
  F(f64),
}

pub enum Sexp {
  Atom(Atom),
  Empty,
  List(Vec<Sexp>),
}

pub struct Error {
    msg: &'static str,
    line: usize,
    lpos: usize,
}

type Err = Box<Error>;
type ERes<T> = Result<T, Err>;

fn err<T>(msg: &'static str, state: &ParseState) -> ERes<T> {
    Err(Box::new(Error { msg: msg, line: state.line, lpos: state.lpos }))
}

struct ParseState {
    pos: usize,
    line: usize,
    lpos: usize,
    vec: Vec<char>,
    len: usize,
}

impl ParseState {
    fn peek(&self) -> ERes<char> {
        if self.pos >= self.len {
            return err("end of document reached", self)
        }
        Ok(self.vec[self.pos])
    }
    fn peek_option(&self) -> Option<char> {
        if self.pos >= self.len {
            return None
        }
        Some(self.vec[self.pos])
    }
    fn next(&mut self) -> ERes<()> {
        if self.pos >= self.len {
            return err("end of document reached", self)
        }
        let c = self.vec[self.pos];
        self.pos += 1;
        match c {
            '\r' | '\n' => {
                self.lpos = 0;
                self.line += 1;
            }
            _ => {
                self.lpos += 1;
            }
        }
        Ok(())
    }

    fn take(&mut self) -> ERes<char> {
        let c = try!(self.peek());
        try!(self.next());
        Ok(c)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Parse Error {}:{}: {}", self.line, self.lpos, self.msg)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Parse Error {}:{}: {}", self.line, self.lpos, self.msg)
    }
}

impl fmt::Display for Atom {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Atom::S(ref s) => write!(f, "{}", s),
      Atom::Q(ref s) => write!(f, "\"{}\"", s),
      Atom::I(i)     => write!(f, "{}", i),
      Atom::F(d)     => write!(f, "{}", d),
    }
  }
}

impl fmt::Display for Sexp {
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
    match *self {
      Sexp::Atom(ref a) => write!(f, "{}", a),
      Sexp::List(ref xs) => {
        try!(write!(f, "("));
        for (i, x) in xs.iter().enumerate() {
          let s = if i == 0 { "" } else { " " };
          try!(write!(f, "{}{}", s, x));
        }
        write!(f, ")")
      },
      Sexp::Empty => write!(f, ""),
    }
  }
}

fn parse_list(state: &mut ParseState) -> ERes<Sexp> {
    println!("list");
    try!(state.next()); // skip (
    let mut l: Vec<Sexp> = Vec::new();
    loop {
        match try!(state.peek()) {
            ')' => {
                try!(state.next());
                break;
            }
            _ => {
                l.push(try!(parse_sexp(state)));
            }
        }
    }
    println!("Found list");
    Ok(Sexp::List(l))
}

fn parse_quoted_string(state: &mut ParseState) -> ERes<Atom> {
    println!("qstring");
    try!(state.next()); // skip "
    let mut s = String::new();
    loop {
        match try!(state.peek()) {
            '"' => {
                try!(state.next());
                break
            }
            x @ '\r' | x @ '\n' => {
                s.push(x);
                try!(state.next());
                }
            x => {
                s.push(x);
                try!(state.next());
            }
        }
    }
    println!("Found quoted string {}", s);
    Ok(Atom::Q(s))
}

fn parse_string(state: &mut ParseState) -> ERes<Atom> {
    println!("string");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\t' | '\r' | '\n' | ')' => break,
                    '"' => return err("unexpected \" in string", state),
                    x => s.push(x),
                }
            }
            None => {
                break;
            }
        }
        try!(state.next())
    }
    println!("Found string {}", s);
    Ok(Atom::S(s))
}

fn parse_number(state: &mut ParseState) -> ERes<Atom> {
    println!("number");
    let mut s = String::new();
    loop {
        match state.peek_option() {
            Some(x) => {
                match x {
                    ' ' | '\r' | '\n' | '\t' | ')' => {
                        break
                    },
                    '0' ... '9' | '.' | '-' => {
                        s.push(state.vec[state.pos])
                    },
                    _ => {
                        return err("unexpected char in number", state)
                    },
                }
            }
            None => {
                break
            }
        }
        try!(state.next())
    }
    println!("Found number {}", s);
    let s2: &str = &s[..];
    if s.contains('.') {
        Ok(Atom::F(f64::from_str(s2).unwrap()))
    } else {
        Ok(Atom::I(i64::from_str(s2).unwrap()))
    }
}

fn parse_atom(state: &mut ParseState) -> ERes<Sexp> {
    println!("atom");
    let a = match try!(state.peek()) {
        '"' => {
            try!(parse_quoted_string(state))
        }
        '0' ... '9' | '.' | '-' => {
            try!(parse_number(state))
        }
        _ => {
            try!(parse_string(state))
        }
    };
    Ok(Sexp::Atom(a))
}

fn parse_sexp(state: &mut ParseState) -> ERes<Sexp> {
    loop {
        match try!(state.peek()) {
            '(' => {
                return parse_list(state)
            }
            ' ' | '\t' | '\r' | '\n' => {
                try!(state.next());
            }
            ')' => {
                return err("unmatched )", state)
            }
            _ => {
                return parse_atom(state)
            }
        }
    }
}

fn parse(data: &str) -> ERes<Sexp> {
    if data.len() == 0 {
        Ok(Sexp::Empty)
    } else {
        let vec: Vec<char> = data.chars().collect();
        let len = vec.len();
        let state = &mut ParseState { pos: 0, line: 1, lpos: 0, vec: vec, len: len };
        parse_sexp(state)
    }
}

fn read_file(name: &str) -> Result<String,std::io::Error> {
    let mut f = try!(File::open(name));
    let mut s = String::new();
    try!(f.read_to_string(&mut s));
    Ok(s)
}

pub fn parse_str(s: &str) -> Sexp {
    parse(s).unwrap()
}

pub fn parse_file(name: &str) -> Sexp {
    let s = read_file(name).unwrap();
    parse(&s[..]).unwrap()
}

#[allow(dead_code)]
fn check_parse(s: &str) {
    let e = parse_str(s);
    let t = format!("{}", e);
    assert_eq!(s, t);
}

#[test]
fn test_empty() { check_parse("") }

#[test]
fn test_minimal() { check_parse("()") }

#[test]
fn test_string() { check_parse("hello") }

#[test]
fn test_qstring() { check_parse("\"hello\"") }

#[test]
fn test_number() { check_parse("1.3") }

#[test]
#[should_panic(expected="Parse Error 1:1: end of document reached")]
fn test_invalid1() { parse_str("("); }

#[test]
#[should_panic(expected="Parse Error 1:0: unmatched )")]
fn test_invalid2() { parse_str(")"); }
<|endoftext|>


<commit_before>//! A memory-safer wrapper around system dynamic library loading primitives.
//!
//! Using this library allows loading [dynamic libraries](struct.Library.html) (also known as
//! shared libraries) as well as use functions and static variables these libraries contain.
//!
//! While the library does expose a cross-platform interface to load a library and find stuff
//! inside it, little is done to paper over the platform differences, especially where library
//! loading is involved. The documentation for each function will attempt to document such
//! differences on the best-effort basis.
//!
//! Less safe, platform specific bindings are also available. See the
//! [`os::platform`](os/index.html) module for details.
//!
//! # Usage
//!
//! Add dependency to this library to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! libloading = "0.4"
//! ```
//!
//! Then inside your project
//!
//! ```no_run
//! extern crate libloading as lib;
//!
//! fn call_dynamic() -> lib::Result<u32> {
//!     let lib = lib::Library::new("/path/to/liblibrary.so")?;
//!     unsafe {
//!         let func: lib::Symbol<unsafe extern fn() -> u32> = lib.get(b"my_func")?;
//!         Ok(func())
//!     }
//! }
//! ```
//!
//! The compiler will ensure that the loaded `function` will not outlive the `Library` it comes
//! from, preventing a common cause of undefined behaviour and memory safety problems.
use std::ffi::OsStr;
use std::fmt;
use std::ops;
use std::marker;

#[cfg(unix)]
#[macro_use]
extern crate lazy_static;

#[cfg(unix)]
use self::os::unix as imp;
#[cfg(windows)]
use self::os::windows as imp;

pub mod os;
pub mod changelog;
mod util;

pub type Result<T> = ::std::io::Result<T>;

/// A loaded dynamic library.
pub struct Library(imp::Library);

impl Library {
    /// Find and load a dynamic library.
    ///
    /// The `filename` argument may be any of:
    ///
    /// * A library filename;
    /// * Absolute path to the library;
    /// * Relative (to the current working directory) path to the library.
    ///
    /// ## Thread-safety
    ///
    /// The implementation strives to be as MT-safe as sanely possible, however due to certain
    /// error-handling related resources not always being safe, this library is not MT-safe either.
    ///
    /// * On Windows Vista and earlier error handling falls back to [`SetErrorMode`], which is not
    ///   MT-safe. MT-scenarios involving this function may cause a traditional data race;
    /// * On some UNIX targets `dlerror` might not be MT-safe, resulting in garbage error messages
    ///   in certain MT-scenarios.
    ///
    /// [`SetErrorMode`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
    ///
    /// Calling this function from multiple threads is not safe if used in conjunction with
    /// path-less filename and library search path is modified (`SetDllDirectory` function on
    /// Windows, `{DY,}LD_LIBRARY_PATH` environment variable on UNIX).
    ///
    /// ## Platform-specific behaviour
    ///
    /// When a plain library filename is supplied, locations where library is searched for is
    /// platform specific and cannot be adjusted in a portable manner.
    ///
    /// ### Windows
    ///
    /// If the `filename` specifies a library filename without path and with extension omitted,
    /// `.dll` extension is implicitly added. This behaviour may be suppressed by appending a
    /// trailing `.` to the `filename`.
    ///
    /// If the library contains thread local variables (MSVC’s `_declspec(thread)`, Rust’s
    /// `#[thread_local]` attributes), loading the library will fail on versions prior to Windows
    /// Vista.
    ///
    /// ## Tips
    ///
    /// Distributing your dynamic libraries under a filename common to all platforms (e.g.
    /// `awesome.module`) allows to avoid code which has to account for platform’s conventional
    /// library filenames.
    ///
    /// Strive to specify absolute or relative path to your library, unless system-wide libraries
    /// are being loaded.  Platform-dependent library search locations combined with various quirks
    /// related to path-less filenames may cause flaky code.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::Library;
    /// // Any of the following are valid.
    /// let _ = Library::new("/path/to/awesome.module").unwrap();
    /// let _ = Library::new("../awesome.module").unwrap();
    /// let _ = Library::new("libsomelib.so.1").unwrap();
    /// ```
    pub fn new<P: AsRef<OsStr>>(filename: P) -> Result<Library> {
        imp::Library::new(filename).map(From::from)
    }

    /// Get a pointer to function or static variable by symbol name.
    ///
    /// The `symbol` may not contain any null bytes, with an exception of last byte. A null
    /// terminated `symbol` may avoid a string allocation in some cases.
    ///
    /// Symbol is interpreted as-is; no mangling is done. This means that symbols like `x::y` are
    /// most likely invalid.
    ///
    /// ## Unsafety
    ///
    /// Pointer to a value of arbitrary type is returned. Using a value with wrong type is
    /// undefined.
    ///
    /// ## Platform-specific behaviour
    ///
    /// On Linux and Windows, a TLS variable acts just like any regular static variable. OS X uses
    /// some sort of lazy initialization scheme, which makes loading TLS variables this way
    /// impossible. Using a TLS variable loaded this way on OS X is undefined behaviour.
    ///
    /// ## Examples
    ///
    /// Given a loaded library:
    ///
    /// ```no_run
    /// # use ::libloading::Library;
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// ```
    ///
    /// Loading and using a function looks like this:
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// # let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let awesome_function: Symbol<unsafe extern fn(f64) -> f64> =
    ///         lib.get(b"awesome_function\0").unwrap();
    ///     awesome_function(0.42);
    /// }
    /// ```
    ///
    /// A static variable may also be loaded and inspected:
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// # let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let awesome_variable: Symbol<*mut f64> = lib.get(b"awesome_variable\0").unwrap();
    ///     **awesome_variable = 42.0;
    /// };
    /// ```
    pub unsafe fn get<'lib, T>(&'lib self, symbol: &[u8]) -> Result<Symbol<'lib, T>> {
        self.0.get(symbol).map(|from| Symbol::from_raw(from, self))
    }
}

impl fmt::Debug for Library {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl From<imp::Library> for Library {
    fn from(lib: imp::Library) -> Library {
        Library(lib)
    }
}

impl From<Library> for imp::Library {
    fn from(lib: Library) -> imp::Library {
        lib.0
    }
}

unsafe impl Send for Library {}
unsafe impl Sync for Library {}

/// Symbol from a library.
///
/// This type is a safeguard against using dynamically loaded symbols after a `Library` is
/// unloaded. Primary method to create an instance of a `Symbol` is via `Library::get`.
///
/// Due to implementation of the `Deref` trait, an instance of `Symbol` may be used as if it was a
/// function or variable directly, without taking care to “extract” function or variable manually
/// most of the time.
///
/// See [`Library::get`] for details.
///
/// [`Library::get`]: ./struct.Library.html#method.get
pub struct Symbol<'lib, T: 'lib> {
    inner: imp::Symbol<T>,
    pd: marker::PhantomData<&'lib T>
}

impl<'lib, T> Symbol<'lib, T> {
    /// Extract the wrapped `os::platform::Symbol`.
    ///
    /// ## Unsafety
    /// Using this function relinquishes all the lifetime guarantees. It is up to programmer to
    /// ensure the resulting `Symbol` is not used past the lifetime of the `Library` this symbol
    /// was loaded from.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<*mut u32> = lib.get(b"symbol\0").unwrap();
    ///     let symbol = symbol.into_raw();
    /// }
    /// ```
    pub unsafe fn into_raw(self) -> imp::Symbol<T> {
        self.inner
    }

    /// Wrap the `os::platform::Symbol` into this safe wrapper.
    ///
    /// Note that, in order to create association between the symbol and the library this symbol
    /// came from, this function requires reference to the library provided.
    ///
    /// ## Unsafety
    ///
    /// It is invalid to provide a reference to any other value other than the library the `sym`
    /// was loaded from. Doing so invalidates any lifetime guarantees.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<*mut u32> = lib.get(b"symbol\0").unwrap();
    ///     let symbol = symbol.into_raw();
    ///     let symbol = Symbol::from_raw(symbol, &lib);
    /// }
    /// ```
    pub unsafe fn from_raw<L>(sym: imp::Symbol<T>, _: &'lib L) -> Symbol<'lib, T> {
        Symbol {
            inner: sym,
            pd: marker::PhantomData
        }
    }
}

impl<'lib, T> Symbol<'lib, Option<T>> {
    /// Lift Option out of the symbol.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<Option<*mut u32>> = lib.get(b"symbol\0").unwrap();
    ///     let symbol: Symbol<*mut u32> = symbol.lift_option().expect("static is not null");
    /// }
    /// ```
    pub fn lift_option(self) -> Option<Symbol<'lib, T>> {
        self.inner.lift_option().map(|is| Symbol {
            inner: is,
            pd: marker::PhantomData,
        })
    }
}

impl<'lib, T> Clone for Symbol<'lib, T> {
    fn clone(&self) -> Symbol<'lib, T> {
        Symbol {
            inner: self.inner.clone(),
            pd: marker::PhantomData
        }
    }
}

// FIXME: implement FnOnce for callable stuff instead.
impl<'lib, T> ops::Deref for Symbol<'lib, T> {
    type Target = T;
    fn deref(&self) -> &T {
        ops::Deref::deref(&self.inner)
    }
}

impl<'lib, T> fmt::Debug for Symbol<'lib, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

unsafe impl<'lib, T: Send> Send for Symbol<'lib, T> {}
unsafe impl<'lib, T: Sync> Sync for Symbol<'lib, T> {}
<commit_msg>Stubs for unsupported platforms<commit_after>//! A memory-safer wrapper around system dynamic library loading primitives.
//!
//! Using this library allows loading [dynamic libraries](struct.Library.html) (also known as
//! shared libraries) as well as use functions and static variables these libraries contain.
//!
//! While the library does expose a cross-platform interface to load a library and find stuff
//! inside it, little is done to paper over the platform differences, especially where library
//! loading is involved. The documentation for each function will attempt to document such
//! differences on the best-effort basis.
//!
//! Less safe, platform specific bindings are also available. See the
//! [`os::platform`](os/index.html) module for details.
//!
//! # Usage
//!
//! Add dependency to this library to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! libloading = "0.4"
//! ```
//!
//! Then inside your project
//!
//! ```no_run
//! extern crate libloading as lib;
//!
//! fn call_dynamic() -> lib::Result<u32> {
//!     let lib = lib::Library::new("/path/to/liblibrary.so")?;
//!     unsafe {
//!         let func: lib::Symbol<unsafe extern fn() -> u32> = lib.get(b"my_func")?;
//!         Ok(func())
//!     }
//! }
//! ```
//!
//! The compiler will ensure that the loaded `function` will not outlive the `Library` it comes
//! from, preventing a common cause of undefined behaviour and memory safety problems.
use std::ffi::OsStr;
use std::fmt;
use std::ops;
use std::marker;

#[cfg(unix)]
#[macro_use]
extern crate lazy_static;

#[cfg(unix)]
use self::os::unix as imp;
#[cfg(windows)]
use self::os::windows as imp;

// When running on an unsupported OS, libloading will compile but panic on any calls.
#[cfg(not(any(unix, windows)))]
mod imp {
    use std::{fmt, marker};
    use std::ffi::OsStr;

    pub struct Library;

    impl Library {
        pub fn new<P: AsRef<OsStr>>(_filename: P) -> ::Result<Self> {
            unimplemented!()
        }

        pub unsafe fn get<T>(&self, _symbol: &[u8]) -> ::Result<Symbol<T>> {
            unimplemented!()
        }
    }

    impl fmt::Debug for Library {
        fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result {
            unimplemented!()
        }
    }

    pub struct Symbol<T>(marker::PhantomData<T>);

    impl<T> Symbol<Option<T>> {
        pub fn lift_option(self) -> Option<Symbol<T>> {
            unimplemented!()
        }
    }

    impl<T> Clone for Symbol<T> {
        fn clone(&self) -> Self {
            unimplemented!()
        }
    }

    impl<T> fmt::Debug for Symbol<T> {
        fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
            unimplemented!()
        }
    }

    impl<T> ::std::ops::Deref for Symbol<T> {
        type Target = T;
        fn deref(&self) -> &T {
            unimplemented!()
        }
    }
}

pub mod os;
pub mod changelog;
mod util;

pub type Result<T> = ::std::io::Result<T>;

/// A loaded dynamic library.
pub struct Library(imp::Library);

impl Library {
    /// Find and load a dynamic library.
    ///
    /// The `filename` argument may be any of:
    ///
    /// * A library filename;
    /// * Absolute path to the library;
    /// * Relative (to the current working directory) path to the library.
    ///
    /// ## Thread-safety
    ///
    /// The implementation strives to be as MT-safe as sanely possible, however due to certain
    /// error-handling related resources not always being safe, this library is not MT-safe either.
    ///
    /// * On Windows Vista and earlier error handling falls back to [`SetErrorMode`], which is not
    ///   MT-safe. MT-scenarios involving this function may cause a traditional data race;
    /// * On some UNIX targets `dlerror` might not be MT-safe, resulting in garbage error messages
    ///   in certain MT-scenarios.
    ///
    /// [`SetErrorMode`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621(v=vs.85).aspx
    ///
    /// Calling this function from multiple threads is not safe if used in conjunction with
    /// path-less filename and library search path is modified (`SetDllDirectory` function on
    /// Windows, `{DY,}LD_LIBRARY_PATH` environment variable on UNIX).
    ///
    /// ## Platform-specific behaviour
    ///
    /// When a plain library filename is supplied, locations where library is searched for is
    /// platform specific and cannot be adjusted in a portable manner.
    ///
    /// ### Windows
    ///
    /// If the `filename` specifies a library filename without path and with extension omitted,
    /// `.dll` extension is implicitly added. This behaviour may be suppressed by appending a
    /// trailing `.` to the `filename`.
    ///
    /// If the library contains thread local variables (MSVC’s `_declspec(thread)`, Rust’s
    /// `#[thread_local]` attributes), loading the library will fail on versions prior to Windows
    /// Vista.
    ///
    /// ## Tips
    ///
    /// Distributing your dynamic libraries under a filename common to all platforms (e.g.
    /// `awesome.module`) allows to avoid code which has to account for platform’s conventional
    /// library filenames.
    ///
    /// Strive to specify absolute or relative path to your library, unless system-wide libraries
    /// are being loaded.  Platform-dependent library search locations combined with various quirks
    /// related to path-less filenames may cause flaky code.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::Library;
    /// // Any of the following are valid.
    /// let _ = Library::new("/path/to/awesome.module").unwrap();
    /// let _ = Library::new("../awesome.module").unwrap();
    /// let _ = Library::new("libsomelib.so.1").unwrap();
    /// ```
    pub fn new<P: AsRef<OsStr>>(filename: P) -> Result<Library> {
        imp::Library::new(filename).map(From::from)
    }

    /// Get a pointer to function or static variable by symbol name.
    ///
    /// The `symbol` may not contain any null bytes, with an exception of last byte. A null
    /// terminated `symbol` may avoid a string allocation in some cases.
    ///
    /// Symbol is interpreted as-is; no mangling is done. This means that symbols like `x::y` are
    /// most likely invalid.
    ///
    /// ## Unsafety
    ///
    /// Pointer to a value of arbitrary type is returned. Using a value with wrong type is
    /// undefined.
    ///
    /// ## Platform-specific behaviour
    ///
    /// On Linux and Windows, a TLS variable acts just like any regular static variable. OS X uses
    /// some sort of lazy initialization scheme, which makes loading TLS variables this way
    /// impossible. Using a TLS variable loaded this way on OS X is undefined behaviour.
    ///
    /// ## Examples
    ///
    /// Given a loaded library:
    ///
    /// ```no_run
    /// # use ::libloading::Library;
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// ```
    ///
    /// Loading and using a function looks like this:
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// # let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let awesome_function: Symbol<unsafe extern fn(f64) -> f64> =
    ///         lib.get(b"awesome_function\0").unwrap();
    ///     awesome_function(0.42);
    /// }
    /// ```
    ///
    /// A static variable may also be loaded and inspected:
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// # let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let awesome_variable: Symbol<*mut f64> = lib.get(b"awesome_variable\0").unwrap();
    ///     **awesome_variable = 42.0;
    /// };
    /// ```
    pub unsafe fn get<'lib, T>(&'lib self, symbol: &[u8]) -> Result<Symbol<'lib, T>> {
        self.0.get(symbol).map(|from| Symbol::from_raw(from, self))
    }
}

impl fmt::Debug for Library {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl From<imp::Library> for Library {
    fn from(lib: imp::Library) -> Library {
        Library(lib)
    }
}

impl From<Library> for imp::Library {
    fn from(lib: Library) -> imp::Library {
        lib.0
    }
}

unsafe impl Send for Library {}
unsafe impl Sync for Library {}

/// Symbol from a library.
///
/// This type is a safeguard against using dynamically loaded symbols after a `Library` is
/// unloaded. Primary method to create an instance of a `Symbol` is via `Library::get`.
///
/// Due to implementation of the `Deref` trait, an instance of `Symbol` may be used as if it was a
/// function or variable directly, without taking care to “extract” function or variable manually
/// most of the time.
///
/// See [`Library::get`] for details.
///
/// [`Library::get`]: ./struct.Library.html#method.get
pub struct Symbol<'lib, T: 'lib> {
    inner: imp::Symbol<T>,
    pd: marker::PhantomData<&'lib T>
}

impl<'lib, T> Symbol<'lib, T> {
    /// Extract the wrapped `os::platform::Symbol`.
    ///
    /// ## Unsafety
    /// Using this function relinquishes all the lifetime guarantees. It is up to programmer to
    /// ensure the resulting `Symbol` is not used past the lifetime of the `Library` this symbol
    /// was loaded from.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<*mut u32> = lib.get(b"symbol\0").unwrap();
    ///     let symbol = symbol.into_raw();
    /// }
    /// ```
    pub unsafe fn into_raw(self) -> imp::Symbol<T> {
        self.inner
    }

    /// Wrap the `os::platform::Symbol` into this safe wrapper.
    ///
    /// Note that, in order to create association between the symbol and the library this symbol
    /// came from, this function requires reference to the library provided.
    ///
    /// ## Unsafety
    ///
    /// It is invalid to provide a reference to any other value other than the library the `sym`
    /// was loaded from. Doing so invalidates any lifetime guarantees.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<*mut u32> = lib.get(b"symbol\0").unwrap();
    ///     let symbol = symbol.into_raw();
    ///     let symbol = Symbol::from_raw(symbol, &lib);
    /// }
    /// ```
    pub unsafe fn from_raw<L>(sym: imp::Symbol<T>, _: &'lib L) -> Symbol<'lib, T> {
        Symbol {
            inner: sym,
            pd: marker::PhantomData
        }
    }
}

impl<'lib, T> Symbol<'lib, Option<T>> {
    /// Lift Option out of the symbol.
    ///
    /// ## Examples
    ///
    /// ```no_run
    /// # use ::libloading::{Library, Symbol};
    /// let lib = Library::new("/path/to/awesome.module").unwrap();
    /// unsafe {
    ///     let symbol: Symbol<Option<*mut u32>> = lib.get(b"symbol\0").unwrap();
    ///     let symbol: Symbol<*mut u32> = symbol.lift_option().expect("static is not null");
    /// }
    /// ```
    pub fn lift_option(self) -> Option<Symbol<'lib, T>> {
        self.inner.lift_option().map(|is| Symbol {
            inner: is,
            pd: marker::PhantomData,
        })
    }
}

impl<'lib, T> Clone for Symbol<'lib, T> {
    fn clone(&self) -> Symbol<'lib, T> {
        Symbol {
            inner: self.inner.clone(),
            pd: marker::PhantomData
        }
    }
}

// FIXME: implement FnOnce for callable stuff instead.
impl<'lib, T> ops::Deref for Symbol<'lib, T> {
    type Target = T;
    fn deref(&self) -> &T {
        ops::Deref::deref(&self.inner)
    }
}

impl<'lib, T> fmt::Debug for Symbol<'lib, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.inner.fmt(f)
    }
}

unsafe impl<'lib, T: Send> Send for Symbol<'lib, T> {}
unsafe impl<'lib, T: Sync> Sync for Symbol<'lib, T> {}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! Combinatorial phantom types for discrete mathematics.
//!
//! All discrete spaces has the following functions:
//!
//! ~~~ignore
//!     fn count(dim) -> uint;
//!     fn to_index(dim, pos) -> uint;
//!     fn to_pos(dim, index, &mut pos);
//! ~~~
//!
//! This makes it possible to allocate to solve tasks as:
//!
//! - Allocate enough memory for the space
//! - Read and write data
//! - Convert from and to natural numbers
//! - Iterate through the space
//! - Pick a random object of the space
//!
//! Iterating through the space can be done simply
//! by counting from zero up to the size of the space.
//!
//! Phantom types are used because they represents the general spaces.
//! For example, we can represent a general two-dimensional space,
//! instead of binding the type to the size.
//!
//! For any constructed space, there is a dimension and position type.
//! The dimension and position types are compositions,
//! given by the type of the constructed space.

use std::marker::PhantomData;

pub use construct::Construct;
pub use count::Count;
pub use to_index::ToIndex;
pub use to_pos::ToPos;
pub use power_set::PowerSet;
pub use dimension_n::DimensionN;
pub use dimension::Dimension;
pub use pair::Pair;
pub use eq_pair::EqPair;
pub use neq_pair::NeqPair;
pub use permutation::Permutation;
pub use context::Context;
pub use directed_context::DirectedContext;

mod construct;
mod count;
mod to_index;
mod to_pos;
mod power_set;
mod dimension_n;
mod dimension;
mod pair;
mod eq_pair;
mod neq_pair;
mod permutation;
mod context;
mod directed_context;

/// Used by the final subspace.
#[derive(Copy, Clone)]
pub struct Data;
/// Used to nest a subspace.
pub struct Subspace<T>(PhantomData<T>);
/// Used to combine the dimensional and position types.
pub struct Of<T>(PhantomData<T>);

#[cfg(test)]
pub fn does_count<T, U>()
    where
        T: Count<U>
{}

#[cfg(test)]
pub fn does_to_index<T, U, V>()
    where
        T: ToIndex<U, V>
{}

#[cfg(test)]
pub fn does_to_pos<T, U, V>()
    where
        T: ToPos<U, V>
{}

#[cfg(test)]
pub fn is_complete<T, U, V, W>()
    where
        T: Count<U> + ToIndex<U, V> + ToPos<U, W>
{
    does_count::<T, U>();
    does_to_index::<T, U, V>();
    does_to_pos::<T, U, W>();
}
<commit_msg>Changed "uint" => "size"<commit_after>#![deny(missing_docs)]

//! Combinatorial phantom types for discrete mathematics.
//!
//! All discrete spaces has the following functions:
//!
//! ~~~ignore
//! fn count(dim) -> usize;
//! fn to_index(dim, pos) -> usize;
//! fn to_pos(dim, index, &mut pos);
//! ~~~
//!
//! This makes it possible to allocate to solve tasks as:
//!
//! - Allocate enough memory for the space
//! - Read and write data
//! - Convert from and to natural numbers
//! - Iterate through the space
//! - Pick a random object of the space
//!
//! Iterating through the space can be done simply
//! by counting from zero up to the size of the space.
//!
//! Phantom types are used because they represents the general spaces.
//! For example, we can represent a general two-dimensional space,
//! instead of binding the type to the size.
//!
//! For any constructed space, there is a dimension and position type.
//! The dimension and position types are compositions,
//! given by the type of the constructed space.

use std::marker::PhantomData;

pub use construct::Construct;
pub use count::Count;
pub use to_index::ToIndex;
pub use to_pos::ToPos;
pub use power_set::PowerSet;
pub use dimension_n::DimensionN;
pub use dimension::Dimension;
pub use pair::Pair;
pub use eq_pair::EqPair;
pub use neq_pair::NeqPair;
pub use permutation::Permutation;
pub use context::Context;
pub use directed_context::DirectedContext;

mod construct;
mod count;
mod to_index;
mod to_pos;
mod power_set;
mod dimension_n;
mod dimension;
mod pair;
mod eq_pair;
mod neq_pair;
mod permutation;
mod context;
mod directed_context;

/// Used by the final subspace.
#[derive(Copy, Clone)]
pub struct Data;
/// Used to nest a subspace.
pub struct Subspace<T>(PhantomData<T>);
/// Used to combine the dimensional and position types.
pub struct Of<T>(PhantomData<T>);

#[cfg(test)]
pub fn does_count<T, U>()
    where
        T: Count<U>
{}

#[cfg(test)]
pub fn does_to_index<T, U, V>()
    where
        T: ToIndex<U, V>
{}

#[cfg(test)]
pub fn does_to_pos<T, U, V>()
    where
        T: ToPos<U, V>
{}

#[cfg(test)]
pub fn is_complete<T, U, V, W>()
    where
        T: Count<U> + ToIndex<U, V> + ToPos<U, W>
{
    does_count::<T, U>();
    does_to_index::<T, U, V>();
    does_to_pos::<T, U, W>();
}
<|endoftext|>


<commit_before>//#![crate_type="dylib"]
#![feature(asm, libc, question_mark, panic_handler)]

#![allow(dead_code)] // yells about consts otherwise
#![allow(unused_variables)]

/// Dryad --- the world's first non-functional, yet-to-be-implemented, might be impossible or more likely inefficient --- parallel, dynamic linker.
/// Many, many thanks to Mutabah, durka42, aatch, tilpner, niconii, bluss, steveklabnik, ubsan and so many others on the IRC channel for answering my stupid questions.

#[cfg(not(feature = "no_color"))]
#[macro_use] extern crate colorify;

#[macro_use] extern crate syscall;

pub extern crate goblin;

#[cfg(target_arch = "x86_64")]
pub use goblin::elf64 as elf;

#[cfg(target_arch = "x86")]
pub use goblin::elf32 as elf;

mod auxv;
mod kernel_block;
#[macro_use] mod utils;
mod image;

mod loader;
mod tls;
pub mod runtime;
pub mod linker;
pub mod gdb;

use kernel_block::KernelBlock;
use linker::Linker;
use utils::*;

extern crate libc;

extern {
    /// ELF abi requires `_start`; this must be in assembly because we need
    /// the raw stack pointer as the argument to `_dryad_init`;
    /// i.e., kernel calls symbol `_start` on dynamic linker with the kernel argument block, etc.,
    /// which in our case then calls _back_ into `dryad_init` with the pointer to the raw arguments that form the kernel block
    /// see `arch/x86/asm.s`
    fn _start();
}

#[no_mangle]
pub extern fn dryad_init (raw_args: *const u64) -> u64 {

    // the linker is currently tied to the lifetime of the kernel block... but really it's static
    let block = KernelBlock::new(raw_args);
    let linker_base = block.getauxval(auxv::AT_BASE).unwrap();
    let entry  = block.getauxval(auxv::AT_ENTRY).unwrap();

    let start_addr = _start as *const u64 as u64;
    if start_addr == entry {
        utils::set_panic();
        // because it's _tradition_
        // (https://fossies.org/dox/glibc-2.22/rtld_8c_source.html)
        // line 786:
        // > Ho ho.  We are not the program interpreter!  We are the program itself!
        println!("-=|dryad====-");
        println!("Ho ho.  We are not the program interpreter!  We are the program itself!");
        let ret = {
            if block.argc >= 2 {
                let binary = str_at(block.argv[1], 0);
                println!("binary: {:?}", binary);
                let elf = elf::Elf::from_path(::std::path::Path::new(binary)).expect(&format!("Cannot load binary {}", binary));
                println!("{:#?}", elf);
                0
            } else {
                println!("usage: dryad <path/to/bin>");
                1
            }
        };
        _exit(ret);
        return 0xd47ad // to make compiler happy
    }

    match Linker::new(linker_base, &block) {
        Ok (dryad) => {
            if let Err(msg) = dryad.link(&block) {
                println!("{}", msg);
                _exit(1);
                0xd47ad
            } else {
                entry
            }
        },
        Err (msg) => {
            // relocating self failed somehow; we try to write the error message and exit
            write(&msg);
            _exit(1);
            0xd47ad
        }
    }
}
<commit_msg>linker: remove panic_handler feature gate<commit_after>//#![crate_type="dylib"]
#![feature(asm, libc, question_mark)]

#![allow(dead_code)] // yells about consts otherwise
#![allow(unused_variables)]

/// Dryad --- the world's first non-functional, yet-to-be-implemented, might be impossible or more likely inefficient --- parallel, dynamic linker.
/// Many, many thanks to Mutabah, durka42, aatch, tilpner, niconii, bluss, steveklabnik, ubsan and so many others on the IRC channel for answering my stupid questions.

#[cfg(not(feature = "no_color"))]
#[macro_use] extern crate colorify;

#[macro_use] extern crate syscall;

pub extern crate goblin;

#[cfg(target_arch = "x86_64")]
pub use goblin::elf64 as elf;

#[cfg(target_arch = "x86")]
pub use goblin::elf32 as elf;

mod auxv;
mod kernel_block;
#[macro_use] mod utils;
mod image;

mod loader;
mod tls;
pub mod runtime;
pub mod linker;
pub mod gdb;

use kernel_block::KernelBlock;
use linker::Linker;
use utils::*;

extern crate libc;

extern {
    /// ELF abi requires `_start`; this must be in assembly because we need
    /// the raw stack pointer as the argument to `_dryad_init`;
    /// i.e., kernel calls symbol `_start` on dynamic linker with the kernel argument block, etc.,
    /// which in our case then calls _back_ into `dryad_init` with the pointer to the raw arguments that form the kernel block
    /// see `arch/x86/asm.s`
    fn _start();
}

#[no_mangle]
pub extern fn dryad_init (raw_args: *const u64) -> u64 {

    // the linker is currently tied to the lifetime of the kernel block... but really it's static
    let block = KernelBlock::new(raw_args);
    let linker_base = block.getauxval(auxv::AT_BASE).unwrap();
    let entry  = block.getauxval(auxv::AT_ENTRY).unwrap();

    let start_addr = _start as *const u64 as u64;
    if start_addr == entry {
        utils::set_panic();
        // because it's _tradition_
        // (https://fossies.org/dox/glibc-2.22/rtld_8c_source.html)
        // line 786:
        // > Ho ho.  We are not the program interpreter!  We are the program itself!
        println!("-=|dryad====-");
        println!("Ho ho.  We are not the program interpreter!  We are the program itself!");
        let ret = {
            if block.argc >= 2 {
                let binary = str_at(block.argv[1], 0);
                println!("binary: {:?}", binary);
                let elf = elf::Elf::from_path(::std::path::Path::new(binary)).expect(&format!("Cannot load binary {}", binary));
                println!("{:#?}", elf);
                0
            } else {
                println!("usage: dryad <path/to/bin>");
                1
            }
        };
        _exit(ret);
        return 0xd47ad // to make compiler happy
    }

    match Linker::new(linker_base, &block) {
        Ok (dryad) => {
            if let Err(msg) = dryad.link(&block) {
                println!("{}", msg);
                _exit(1);
                0xd47ad
            } else {
                entry
            }
        },
        Err (msg) => {
            // relocating self failed somehow; we try to write the error message and exit
            write(&msg);
            _exit(1);
            0xd47ad
        }
    }
}
<|endoftext|>


<commit_before>/// Explicitly precompute a method's arguments before the call so that borrowck sees them the same
/// way that trans does.
///
/// Examples
/// =======
///
/// ```
/// # #[macro_use] extern crate unborrow;
/// # fn main() {
/// let mut v = vec![1, 2, 3];
///
/// // this line would cause an error because borrowck consider `v` borrowed by `reserve`
/// // during its parameter list
/// // v.reserve(v.capacity()); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.reserve(v.capacity()));
/// assert!(v.capacity() >= 6);
/// assert_eq!(v, [1, 2, 3]);
///
/// // similar to the above, both v.len()-1 and v[0]+41 require borrowing `v` and we can't
/// // do that while borrowck thinks is is mutably borrowed by `insert`
/// // v.insert(v.len() - 1, v[0] + 41); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.insert(v.len() - 1, v[0] + 41));
/// assert_eq!(v, [1, 2, 42, 3]);
/// # }
/// ```
#[macro_export]
macro_rules! unborrow {
    // =========================================================================================================
    // PRIVATE RULES

    // This rule fires when we have parsed all the arguments.
    // It just falls through to output stage.
    // (FIXME could fold the output rule into this one to reduce recursion)
    (@parse () -> ($names:tt $lets:tt) $($obj:ident).+) => {
        unborrow!(@out $names $lets $($obj).+)
    };

    // Parse an argument and continue parsing
    // This is the key rule, assigning a name for the argument and generating the let statement.
    (@parse ($arg:expr, $($rest:tt)*) -> ([$($names:ident),*] [$($lets:stmt);*]) $($obj:ident).+) => {
        unborrow!(@parse ($($rest)*) -> ([$($names,)* arg] [$($lets;)* let arg = $arg]) $($obj).+)
        //                                            ^                    ^
        // Right here an ident is created out of thin air using hygiene.
        // Every time the macro recurses, we get a new syntax context, so "arg" is actually a new identifier!
    };

    // Output stage.
    // Assembles the let statements and variable names into a block which computes the arguments,
    // calls the method, and returns its result.
    (@out [$($names:ident),*] [$($lets:stmt);*] $($obj:ident).+) => {{
        $($lets;)*
        $($obj).+($($names),*)
    }};

    // =========================================================================================================
    // PUBLIC RULES

    // Macro entry point.
    ($($obj:ident).+ ($($args:expr),*)) => {
        unborrow!(@parse ($($args,)*) -> ([] []) $($obj).+)
        //                |               |  |   ^ info about the method call, saved for later
        //                |               |  ^ generated let statements
        //                |               ^ generated argument names
        //                ^ arguments to be parsed
    }
}

<commit_msg>Reverted macro pass-through changes and added a test<commit_after>/// Explicitly precompute a method's arguments before the call so that borrowck sees them the same
/// way that trans does.
///
/// Examples
/// =======
///
/// ```
/// # #[macro_use] extern crate unborrow;
/// # fn main() {
/// let mut v = vec![1, 2, 3];
///
/// // this line would cause an error because borrowck consider `v` borrowed by `reserve`
/// // during its parameter list
/// // v.reserve(v.capacity()); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.reserve(v.capacity()));
/// assert!(v.capacity() >= 6);
/// assert_eq!(v, [1, 2, 3]);
///
/// // similar to the above, both v.len()-1 and v[0]+41 require borrowing `v` and we can't
/// // do that while borrowck thinks is is mutably borrowed by `insert`
/// // v.insert(v.len() - 1, v[0] + 41); //~ERROR cannot borrow `v`
/// // but wrap the call in unborrow!() and it works!
/// unborrow!(v.insert(v.len() - 1, v[0] + 41));
/// assert_eq!(v, [1, 2, 42, 3]);
///
/// // it also works for nested objects!
/// struct Wrapper { v: Vec<i32> }
/// let mut w = Wrapper { v: vec![1, 2, 3] };
/// unborrow!(w.v.reserve(w.v.capacity()));
///
/// # }
/// ```
#[macro_export]
macro_rules! unborrow {
    // =========================================================================================================
    // PRIVATE RULES

    // This rule fires when we have parsed all the arguments.
    // It just falls through to output stage.
    // (FIXME could fold the output rule into this one to reduce recursion)
    (@parse () -> ($names:tt $lets:tt) $($thru:tt)*) => {
        unborrow!(@out $names $lets $($thru)*)
    };

    // Parse an argument and continue parsing
    // This is the key rule, assigning a name for the argument and generating the let statement.
    (@parse ($arg:expr, $($rest:tt)*) -> ([$($names:ident),*] [$($lets:stmt);*]) $($thru:tt)*) => {
        unborrow!(@parse ($($rest)*) -> ([$($names,)* arg] [$($lets;)* let arg = $arg]) $($thru)*)
        //                                            ^                    ^
        // Right here an ident is created out of thin air using hygiene.
        // Every time the macro recurses, we get a new syntax context, so "arg" is actually a new identifier!
    };

    // Output stage.
    // Assembles the let statements and variable names into a block which computes the arguments,
    // calls the method, and returns its result.
    (@out [$($names:ident),*] [$($lets:stmt);*] $($obj:ident).+) => {{
        $($lets;)*
        $($obj).+($($names),*)
    }};

    // =========================================================================================================
    // PUBLIC RULES

    // Macro entry point.
    ($($obj:ident).+ ($($args:expr),*)) => {
        unborrow!(@parse ($($args,)*) -> ([] []) $($obj).+)
        //                |               |  |   ^ info about the method call, saved for later
        //                |               |  ^ generated let statements
        //                |               ^ generated argument names
        //                ^ arguments to be parsed
    }
}

<|endoftext|>


<commit_before>extern crate hyper;

pub mod requests;

#[cfg(test)]
mod test {
    use super::requests;

    #[test]
    fn test_get() {
        let res = requests::get("http://httpbin.org/get").unwrap();
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_post() {
        let res = requests::post("http://httpbin.org/post").unwrap();
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_put() {
        let res = requests::put("http://httpbin.org/put").unwrap();
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_head() {
        let res = requests::head("http://httpbin.org/get").unwrap();
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_detele() {
        let res = requests::delete("http://httpbin.org/delete").unwrap();
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }
}
<commit_msg>Add Response.url tests<commit_after>extern crate hyper;

pub mod requests;

#[cfg(test)]
mod test {
    use super::requests;

    #[test]
    fn test_get() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = requests::get(URL).unwrap();
        assert_eq!(res.url, URL);
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_post() {
        const URL: &'static str = "http://httpbin.org/post";
        let res = requests::post(URL).unwrap();
        assert_eq!(res.url, URL);
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_put() {
        const URL: &'static str = "http://httpbin.org/put";
        let res = requests::put(URL).unwrap();
        assert_eq!(res.url, URL);
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_head() {
        const URL: &'static str = "http://httpbin.org/get";
        let res = requests::head(URL).unwrap();
        assert_eq!(res.url, URL);
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }

    #[test]
    fn test_detele() {
        const URL: &'static str = "http://httpbin.org/delete";
        let res = requests::delete(URL).unwrap();
        assert_eq!(res.url, URL);
        assert_eq!(res.status_code, 200);
        assert_eq!(res.reason, "OK");
    }
}
<|endoftext|>