<commit_before>#![macro_use]

macro_rules! pointwise_mul(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Mul<N, Output = N>> Mul<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn mul(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN * right.$compN),+)
            }
        }

        impl<N: MulAssign<N>> MulAssign<$t<N>> for $t<N> {
            #[inline]
            fn mul_assign(&mut self, right: $t<N>) {
                $( self.$compN *= right.$compN; )+
            }
        }
    )
);

macro_rules! pointwise_div(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Div<N, Output = N>> Div<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn div(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN / right.$compN),+)
            }
        }

        impl<N: DivAssign<N>> DivAssign<$t<N>> for $t<N> {
            #[inline]
            fn div_assign(&mut self, right: $t<N>) {
                $( self.$compN /= right.$compN; )+
            }
        }
    )
);

macro_rules! pointwise_add(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Add<N, Output = N>> Add<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn add(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN + right.$compN),+)
            }
        }

        impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
            #[inline]
            fn add_assign(&mut self, right: $t<N>) {
                $( self.$compN += right.$compN; )+
            }
        }
    )
);

macro_rules! pointwise_sub(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn sub(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN - right.$compN),+)
            }
        }

        impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
            #[inline]
            fn sub_assign(&mut self, right: $t<N>) {
                $( self.$compN -= right.$compN; )+
            }
        }
    )
);

macro_rules! pointwise_scalar_mul(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + Mul<N, Output = N>> Mul<N> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn mul(self, right: N) -> $t<N> {
                $t::new($(self.$compN * right),+)
            }
        }

        impl<N: Copy + MulAssign<N>> MulAssign<N> for $t<N> {
            #[inline]
            fn mul_assign(&mut self, right: N) {
                $( self.$compN *= right; )+
            }
        }

        impl Mul<$t<f32>> for f32 {
            type Output = $t<f32>;

            #[inline]
            fn mul(self, right: $t<f32>) -> $t<f32> {
                $t::new($(self * right.$compN),+)
            }
        }

        impl Mul<$t<f64>> for f64 {
            type Output = $t<f64>;

            #[inline]
            fn mul(self, right: $t<f64>) -> $t<f64> {
                $t::new($(self * right.$compN),+)
            }
        }
    )
);

macro_rules! pointwise_scalar_div(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + Div<N, Output = N>> Div<N> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn div(self, right: N) -> $t<N> {
                $t::new($(self.$compN / right),+)
            }
        }

        impl<N: Copy + DivAssign<N>> DivAssign<N> for $t<N> {
            #[inline]
            fn div_assign(&mut self, right: N) {
                $( self.$compN /= right; )+
            }
        }
    )
);

macro_rules! pointwise_scalar_add(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + Add<N, Output = N>> Add<N> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn add(self, right: N) -> $t<N> {
                $t::new($(self.$compN + right),+)
            }
        }

        impl<N: Copy + AddAssign<N>> AddAssign<N> for $t<N> {
            #[inline]
            fn add_assign(&mut self, right: N) {
                $( self.$compN += right; )+
            }
        }

        impl Add<$t<f32>> for f32 {
            type Output = $t<f32>;

            #[inline]
            fn add(self, right: $t<f32>) -> $t<f32> {
                $t::new($(self + right.$compN),+)
            }
        }

        impl Add<$t<f64>> for f64 {
            type Output = $t<f64>;

            #[inline]
            fn add(self, right: $t<f64>) -> $t<f64> {
                $t::new($(self + right.$compN),+)
            }
        }
    )
);

macro_rules! pointwise_scalar_sub(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + Sub<N, Output = N>> Sub<N> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn sub(self, right: N) -> $t<N> {
                $t::new($(self.$compN - right),+)
            }
        }

        impl<N: Copy + SubAssign<N>> SubAssign<N> for $t<N> {
            #[inline]
            fn sub_assign(&mut self, right: N) {
                $( self.$compN -= right; )+
            }
        }

        impl Sub<$t<f32>> for f32 {
            type Output = $t<f32>;

            #[inline]
            fn sub(self, right: $t<f32>) -> $t<f32> {
                $t::new($(self - right.$compN),+)
            }
        }

        impl Sub<$t<f64>> for f64 {
            type Output = $t<f64>;

            #[inline]
            fn sub(self, right: $t<f64>) -> $t<f64> {
                $t::new($(self - right.$compN),+)
            }
        }
    )
);

macro_rules! componentwise_neg(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Neg<Output = N> + Copy> Neg for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn neg(self) -> $t<N> {
                $t::new($(-self.$compN ),+)
            }
        }
    )
);

macro_rules! componentwise_repeat(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy> Repeat<N> for $t<N> {
            fn repeat(val: N) -> $t<N> {
                $t {
                    $($compN: val ),+
                }
            }
        }
    )
);

macro_rules! componentwise_absolute(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> {
            #[inline]
            fn abs(m: &$t<N>) -> $t<N> {
                $t::new($(::abs(&m.$compN) ),+)
            }
        }
    )
);

macro_rules! componentwise_zero(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: Zero> Zero for $t<N> {
            #[inline]
            fn zero() -> $t<N> {
                $t {
                    $($compN: ::zero() ),+
                }
            }

            #[inline]
            fn is_zero(&self) -> bool {
                $(::is_zero(&self.$compN) )&&+
            }
        }
    )
);

macro_rules! componentwise_one(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: BaseNum> One for $t<N> {
            #[inline]
            fn one() -> $t<N> {
                $t {
                    $($compN: ::one() ),+
                }
            }
        }
    )
);

// Implements Arbitrary by setting each components to Arbitrary::arbitrary.
macro_rules! componentwise_arbitrary(
    ($t: ident, $($compN: ident),+ ) => (
        #[cfg(feature="arbitrary")]
        impl<N: Arbitrary> Arbitrary for $t<N> {
            #[inline]
            fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
                $t { $($compN: Arbitrary::arbitrary(g),)* }
            }
        }
    )
);

// Implements Rand by setting each components to Rand::rand.
macro_rules! componentwise_rand(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: Rand> Rand for $t<N> {
            #[inline]
            fn rand<R: Rng>(rng: &mut R) -> $t<N> {
                $t { $($compN: Rand::rand(rng), )* }
            }
        }
    )
);

macro_rules! component_basis_element(
    ($t: ident, $($compN: ident),+ ) => (
        /*
         *
         * Element of the canonical basis.
         *
         */
        impl<N: Zero + One> $t<N> {
            $(
                /// Create the element of the canonical basis having this component set to one and
                /// all the others set to zero.
                #[inline]
                pub fn $compN() -> $t<N> {
                    let mut res: $t<N> = ::zero();

                    res.$compN = ::one();

                    res
                }
             )+
        }
    )
);

// A function to create a new element from its component values.
macro_rules! component_new(
    ($t: ident, $($compN: ident),+) => (
        impl<N> $t<N> {
            /// Creation from component values.
            #[inline]
            pub fn new($($compN: N ),+) -> $t<N> {
                $t {
                    $($compN: $compN ),+
                }
            }
        }
    );
);

macro_rules! fold_add(
    // base case
    ($x:expr) => {
        $x
    };
    // `$x` followed by at least one `$y,`
    ($x:expr, $($y:expr),+) => {
        // call min! on the tail `$y`
        Add::add($x, fold_add!($($y),+))
    }
);
<commit_msg>implement common operations for references<commit_after>#![macro_use]

macro_rules! ref_binop(
    // Symmetric to `std::ops::forward_ref_binop!`
    (impl $imp:ident, $method:ident for $t:ident; $($compN:ident),+) => {
        impl<'a, 'b, N> $imp<&'a $t<N>> for &'b $t<N> where &'b N: $imp<&'a N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: &'a $t<N>) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(&self.$compN, &right.$compN)
                    ),+
                )
            }
        }

        impl<'a, N> $imp<&'a $t<N>> for $t<N> where N: $imp<&'a N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: &'a $t<N>) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(self.$compN, &right.$compN)
                    ),+
                )
            }
        }

        impl<'a, N> $imp<$t<N>> for &'a $t<N> where &'a N: $imp<N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: $t<N>) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(&self.$compN, right.$compN)
                    ),+
                )
            }
        }
    }
);

macro_rules! pointwise_mul(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Mul<N, Output = N>> Mul<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn mul(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN * right.$compN),+)
            }
        }

        impl<N: MulAssign<N>> MulAssign<$t<N>> for $t<N> {
            #[inline]
            fn mul_assign(&mut self, right: $t<N>) {
                $( self.$compN *= right.$compN; )+
            }
        }

        ref_binop!(impl Mul, mul for $t; $($compN),+);
    )
);

macro_rules! pointwise_div(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Div<N, Output = N>> Div<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn div(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN / right.$compN),+)
            }
        }

        impl<N: DivAssign<N>> DivAssign<$t<N>> for $t<N> {
            #[inline]
            fn div_assign(&mut self, right: $t<N>) {
                $( self.$compN /= right.$compN; )+
            }
        }

        ref_binop!(impl Div, div for $t; $($compN),+);
    )
);

macro_rules! pointwise_add(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Add<N, Output = N>> Add<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn add(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN + right.$compN),+)
            }
        }

        impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
            #[inline]
            fn add_assign(&mut self, right: $t<N>) {
                $( self.$compN += right.$compN; )+
            }
        }

        ref_binop!(impl Add, add for $t; $($compN),+);
    )
);

macro_rules! pointwise_sub(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Sub<N, Output = N>> Sub<$t<N>> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn sub(self, right: $t<N>) -> $t<N> {
                $t::new($(self.$compN - right.$compN),+)
            }
        }

        impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
            #[inline]
            fn sub_assign(&mut self, right: $t<N>) {
                $( self.$compN -= right.$compN; )+
            }
        }

        ref_binop!(impl Sub, sub for $t; $($compN),+);
    )
);

macro_rules! ref_binop_scalar_exact(
    (impl $imp:ident<$lhs:ident>, $method:ident for $t:ident; $($compN:ident),+) => {
        impl $imp<$t<$lhs>> for $lhs {
            type Output = $t<$lhs>;

            #[inline]
            fn $method(self, right: $t<$lhs>) -> $t<$lhs> {
                $t::new(
                    $(
                        $imp::$method(right.$compN, self)
                    ),+
                )
            }
        }

        impl<'a, 'b> $imp<&'a $t<$lhs>> for &'b $lhs {
            type Output = $t<$lhs>;

            #[inline]
            fn $method(self, right: &'a $t<$lhs>) -> $t<$lhs> {
                $t::new(
                    $(
                        $imp::$method(right.$compN, self)
                    ),+
                )
            }
        }

        impl<'a> $imp<$t<$lhs>> for &'a $lhs {
            type Output = $t<$lhs>;

            #[inline]
            fn $method(self, right: $t<$lhs>) -> $t<$lhs> {
                $t::new(
                    $(
                        $imp::$method(right.$compN, self)
                    ),+
                )
            }
        }

        impl<'a> $imp<&'a $t<$lhs>> for $lhs {
            type Output = $t<$lhs>;

            #[inline]
            fn $method(self, right: &'a $t<$lhs>) -> $t<$lhs> {
                $t::new(
                    $(
                        $imp::$method(right.$compN, self)
                    ),+
                )
            }
        }
    };
);

macro_rules! ref_binop_scalar(
    // Symmetric to `std::ops::forward_ref_binop!`
    (impl $imp:ident, $method:ident for $t:ident; $($compN:ident),+) => {
        ref_binop_scalar_exact!(impl $imp<f32>, $method for $t; $($compN),+);
        ref_binop_scalar_exact!(impl $imp<f64>, $method for $t; $($compN),+);

        impl<N: Copy + $imp<N, Output = N>> $imp<N> for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: N) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(self.$compN, right)
                    ),+
                )
            }
        }

        impl<'a, 'b, N> $imp<&'a N> for &'b $t<N> where &'b N: $imp<&'a N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: &'a N) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(&self.$compN, &right)
                    ),+
                )
            }
        }

        impl<'a, N> $imp<N> for &'a $t<N> where for<'b> &'a N: $imp<&'b N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: N) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(&self.$compN, &right)
                    ),+
                )
            }
        }

        impl<'a, N> $imp<&'a N> for $t<N> where N: $imp<&'a N, Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self, right: &'a N) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(self.$compN, &right)
                    ),+
                )
            }
        }
    }
);

macro_rules! pointwise_scalar_mul(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + MulAssign<N>> MulAssign<N> for $t<N> {
            #[inline]
            fn mul_assign(&mut self, right: N) {
                $( self.$compN *= right; )+
            }
        }

        ref_binop_scalar!(impl Mul, mul for $t; $($compN),+);
    )
);

macro_rules! pointwise_scalar_div(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + DivAssign<N>> DivAssign<N> for $t<N> {
            #[inline]
            fn div_assign(&mut self, right: N) {
                $( self.$compN /= right; )+
            }
        }

        ref_binop_scalar!(impl Div, div for $t; $($compN),+);
    )
);

macro_rules! pointwise_scalar_add(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + AddAssign<N>> AddAssign<N> for $t<N> {
            #[inline]
            fn add_assign(&mut self, right: N) {
                $( self.$compN += right; )+
            }
        }

        ref_binop_scalar!(impl Add, add for $t; $($compN),+);
    )
);

macro_rules! pointwise_scalar_sub(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy + SubAssign<N>> SubAssign<N> for $t<N> {
            #[inline]
            fn sub_assign(&mut self, right: N) {
                $( self.$compN -= right; )+
            }
        }

        ref_binop_scalar!(impl Sub, sub for $t; $($compN),+);
    )
);

macro_rules! ref_unop(
    // Symmetric to `std::ops::forward_ref_unop!`
    (impl $imp:ident, $method:ident for $t:ident; $($compN:ident),+) => {
        impl<N: $imp<Output = N> + Copy> $imp for $t<N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(self.$compN)
                    ),+
                )
            }
        }

        impl<'a, N> $imp for &'a $t<N> where &'a N: $imp<Output = N> {
            type Output = $t<N>;

            #[inline]
            fn $method(self) -> $t<N> {
                $t::new(
                    $(
                        $imp::$method(&self.$compN)
                    ),+
                )
            }
        }
    }
);

macro_rules! componentwise_neg(
    ($t: ident, $($compN: ident),+) => (
        ref_unop!(impl Neg, neg for $t; $($compN),+);
    )
);

macro_rules! componentwise_repeat(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Copy> Repeat<N> for $t<N> {
            fn repeat(val: N) -> $t<N> {
                $t {
                    $($compN: val ),+
                }
            }
        }
    )
);

macro_rules! componentwise_absolute(
    ($t: ident, $($compN: ident),+) => (
        impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> {
            #[inline]
            fn abs(m: &$t<N>) -> $t<N> {
                $t::new($(::abs(&m.$compN) ),+)
            }
        }
    )
);

macro_rules! componentwise_zero(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: Zero> Zero for $t<N> {
            #[inline]
            fn zero() -> $t<N> {
                $t {
                    $($compN: ::zero() ),+
                }
            }

            #[inline]
            fn is_zero(&self) -> bool {
                $(::is_zero(&self.$compN) )&&+
            }
        }
    )
);

macro_rules! componentwise_one(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: BaseNum> One for $t<N> {
            #[inline]
            fn one() -> $t<N> {
                $t {
                    $($compN: ::one() ),+
                }
            }
        }
    )
);

// Implements Arbitrary by setting each components to Arbitrary::arbitrary.
macro_rules! componentwise_arbitrary(
    ($t: ident, $($compN: ident),+ ) => (
        #[cfg(feature="arbitrary")]
        impl<N: Arbitrary> Arbitrary for $t<N> {
            #[inline]
            fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
                $t { $($compN: Arbitrary::arbitrary(g),)* }
            }
        }
    )
);

// Implements Rand by setting each components to Rand::rand.
macro_rules! componentwise_rand(
    ($t: ident, $($compN: ident),+ ) => (
        impl<N: Rand> Rand for $t<N> {
            #[inline]
            fn rand<R: Rng>(rng: &mut R) -> $t<N> {
                $t { $($compN: Rand::rand(rng), )* }
            }
        }
    )
);

macro_rules! component_basis_element(
    ($t: ident, $($compN: ident),+ ) => (
        /*
         *
         * Element of the canonical basis.
         *
         */
        impl<N: Zero + One> $t<N> {
            $(
                /// Create the element of the canonical basis having this component set to one and
                /// all the others set to zero.
                #[inline]
                pub fn $compN() -> $t<N> {
                    let mut res: $t<N> = ::zero();

                    res.$compN = ::one();

                    res
                }
             )+
        }
    )
);

// A function to create a new element from its component values.
macro_rules! component_new(
    ($t: ident, $($compN: ident),+) => (
        impl<N> $t<N> {
            /// Creation from component values.
            #[inline]
            pub fn new($($compN: N ),+) -> $t<N> {
                $t {
                    $($compN: $compN ),+
                }
            }
        }
    );
);

macro_rules! fold_add(
    // base case
    ($x:expr) => {
        $x
    };
    // `$x` followed by at least one `$y,`
    ($x:expr, $($y:expr),+) => {
        // call min! on the tail `$y`
        Add::add($x, fold_add!($($y),+))
    }
);
<|endoftext|>


<commit_before>#![feature(phase)]

extern crate regex;
#[phase(plugin)] extern crate regex_macros;
extern crate gcc;
extern crate toml;

use std::collections::HashSet;
use std::default::Default;
use std::io::fs::{File,readdir};
use std::os;
use regex::Regex;

// Fetch the 'package.exclude' list from our Cargo.toml file.  We'll
// use this to decide what sources to admit.
fn get_excluded_sources(manifest: &Path) -> HashSet<String> {
    let text = File::open(manifest).read_to_string().unwrap();
    let toml = toml::Parser::new(text.as_slice()).parse().unwrap();
    let package = toml.get("package").unwrap().as_table().unwrap();
    let exclude = package.get("exclude").unwrap().as_slice().unwrap();
    exclude.iter().map(|e| {
        let str = e.as_str().unwrap();
        Path::new(str).filename_str().unwrap().to_string()
    }).collect()
}

static CC_FILE: Regex = regex!(r"\.cc\z");

// Get all the *.cc files in path that aren't excluded.
fn get_cc_files(dir: &Path, excluded: &HashSet<String>) -> Vec<Path> {
    readdir(dir).unwrap().iter().filter(|p| {
        let filename = p.filename_str().unwrap();
        CC_FILE.is_match(filename) && !excluded.contains(filename)
    }).map(|e| e.clone()).collect()
}

fn main() {
    let src = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap());
    let includes = vec![Path::new("cld2/public"), Path::new("cld2/internal")];

    // Decide what sources to build.
    let excluded = get_excluded_sources(&src.join("Cargo.toml"));
    let mut sources =
        get_cc_files(&src.join("cld2").join("internal"), &excluded);
    sources.push(src.join("src").join("wrapper.cpp"));

    // Convert the sources back to relative path &str values.
    let rel_sources: Vec<Path> = sources.iter().map(|p| {
        p.path_relative_from(&src).unwrap()
    }).collect();
    let rel_sources_str: Vec<&str> = rel_sources.iter().map(|p| {
        p.as_str().unwrap()
    }).collect();
    for s in rel_sources.iter() { println!("{}", s.display()); }

    // Run the build.
    gcc::compile_library("libcld2.a", &gcc::Config {
        include_directories: includes,
        .. Default::default()
    }, rel_sources_str.as_slice());

    // Decide how to link our C++ runtime.  Feel free to submit patches
    // to make this work on your platform.  Other likely options are "c++"
    // and "c++abi" depending on OS and compiler.
    let cxx_abi = "stdc++";
    println!("cargo:rustc-flags=-l {}", cxx_abi);
}
<commit_msg>Remove debugging println! from build.rs<commit_after>#![feature(phase)]

extern crate regex;
#[phase(plugin)] extern crate regex_macros;
extern crate gcc;
extern crate toml;

use std::collections::HashSet;
use std::default::Default;
use std::io::fs::{File,readdir};
use std::os;
use regex::Regex;

// Fetch the 'package.exclude' list from our Cargo.toml file.  We'll
// use this to decide what sources to admit.
fn get_excluded_sources(manifest: &Path) -> HashSet<String> {
    let text = File::open(manifest).read_to_string().unwrap();
    let toml = toml::Parser::new(text.as_slice()).parse().unwrap();
    let package = toml.get("package").unwrap().as_table().unwrap();
    let exclude = package.get("exclude").unwrap().as_slice().unwrap();
    exclude.iter().map(|e| {
        let str = e.as_str().unwrap();
        Path::new(str).filename_str().unwrap().to_string()
    }).collect()
}

static CC_FILE: Regex = regex!(r"\.cc\z");

// Get all the *.cc files in path that aren't excluded.
fn get_cc_files(dir: &Path, excluded: &HashSet<String>) -> Vec<Path> {
    readdir(dir).unwrap().iter().filter(|p| {
        let filename = p.filename_str().unwrap();
        CC_FILE.is_match(filename) && !excluded.contains(filename)
    }).map(|e| e.clone()).collect()
}

fn main() {
    let src = Path::new(os::getenv("CARGO_MANIFEST_DIR").unwrap());
    let includes = vec![Path::new("cld2/public"), Path::new("cld2/internal")];

    // Decide what sources to build.
    let excluded = get_excluded_sources(&src.join("Cargo.toml"));
    let mut sources =
        get_cc_files(&src.join("cld2").join("internal"), &excluded);
    sources.push(src.join("src").join("wrapper.cpp"));

    // Convert the sources back to relative path &str values.
    let rel_sources: Vec<Path> = sources.iter().map(|p| {
        p.path_relative_from(&src).unwrap()
    }).collect();
    let rel_sources_str: Vec<&str> = rel_sources.iter().map(|p| {
        p.as_str().unwrap()
    }).collect();

    // Run the build.
    gcc::compile_library("libcld2.a", &gcc::Config {
        include_directories: includes,
        .. Default::default()
    }, rel_sources_str.as_slice());

    // Decide how to link our C++ runtime.  Feel free to submit patches
    // to make this work on your platform.  Other likely options are "c++"
    // and "c++abi" depending on OS and compiler.
    let cxx_abi = "stdc++";
    println!("cargo:rustc-flags=-l {}", cxx_abi);
}
<|endoftext|>


<commit_before>#![recursion_limit = "512"]

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;

/// #[get("path")] attribute
#[proc_macro_attribute]
pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[get(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Get())
                        .to(#name), config);
            }
        }
    })
    .into()
}

/// #[post("path")] attribute
#[proc_macro_attribute]
pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[get(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Post())
                        .to(#name), config);
            }
        }
    })
    .into()
}

/// #[put("path")] attribute
#[proc_macro_attribute]
pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[get(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Put())
                        .to(#name), config);
            }
        }
    })
    .into()
}
<commit_msg>Fix copy/paste mistake in error message (#733)<commit_after>#![recursion_limit = "512"]

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;

/// #[get("path")] attribute
#[proc_macro_attribute]
pub fn get(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[get(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Get())
                        .to(#name), config);
            }
        }
    })
    .into()
}

/// #[post("path")] attribute
#[proc_macro_attribute]
pub fn post(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[post(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Post())
                        .to(#name), config);
            }
        }
    })
    .into()
}

/// #[put("path")] attribute
#[proc_macro_attribute]
pub fn put(args: TokenStream, input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(args as syn::AttributeArgs);
    if args.is_empty() {
        panic!("invalid server definition, expected: #[put(\"some path\")]");
    }

    // path
    let path = match args[0] {
        syn::NestedMeta::Literal(syn::Lit::Str(ref fname)) => {
            let fname = quote!(#fname).to_string();
            fname.as_str()[1..fname.len() - 1].to_owned()
        }
        _ => panic!("resource path"),
    };

    let ast: syn::ItemFn = syn::parse(input).unwrap();
    let name = ast.ident.clone();

    (quote! {
        #[allow(non_camel_case_types)]
        struct #name;

        impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for #name {
            fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {
                #ast
                actix_web::dev::HttpServiceFactory::register(
                    actix_web::Resource::new(#path)
                        .guard(actix_web::guard::Put())
                        .to(#name), config);
            }
        }
    })
    .into()
}
<|endoftext|>


<commit_before>use environment::Environment;
use options::Options;
use parser::ast;
use std::fs::File;
use std::fs;
use std::io::Write;

#[macro_use]
use codegen::java::*;

use errors::*;

pub trait Listeners {
    fn class_added(&self, _class: &mut ClassSpec) -> Result<()> {
        Ok(())
    }

    fn interface_added(&self,
                       _interface: &ast::InterfaceDecl,
                       _interface_spec: &mut InterfaceSpec)
                       -> Result<()> {
        Ok(())
    }

    fn sub_type_added(&self,
                      _interface: &ast::InterfaceDecl,
                      _sub_type: &ast::SubType,
                      _class: &mut ClassSpec)
                      -> Result<()> {
        Ok(())
    }
}

pub struct Processor<'a> {
    options: &'a Options,
    env: &'a Environment,
    package_prefix: Option<ast::Package>,
    object: Type,
    list: Type,
    string: Type,
    integer: Type,
    long: Type,
    float: Type,
    double: Type,
}

impl<'a> Processor<'a> {
    pub fn new(options: &'a Options,
               env: &'a Environment,
               package_prefix: Option<ast::Package>)
               -> Processor<'a> {
        Processor {
            options: options,
            env: env,
            package_prefix: package_prefix,
            object: Type::new("java.lang", "Object"),
            list: Type::new("java.util", "List"),
            string: Type::new("java.lang", "String"),
            integer: Type::new("java.lang", "Integer"),
            long: Type::new("java.lang", "Long"),
            float: Type::new("java.lang", "Float"),
            double: Type::new("java.lang", "Double"),
        }
    }

    /// Create a new FileSpec from the given package.
    fn new_file_spec(&self, package: &ast::Package) -> FileSpec {
        let package_name = self.java_package(package).parts.join(".");
        FileSpec::new(&package_name)
    }

    /// Build the java package of a given package.
    ///
    /// This includes the prefixed configured in `self.options`, if specified.
    fn java_package(&self, package: &ast::Package) -> ast::Package {
        self.package_prefix
            .clone()
            .map(|prefix| prefix.join(package))
            .unwrap_or_else(|| package.clone())
    }

    /// Convert the given type to a java type.
    fn convert_type(&self, package: &ast::Package, type_: &ast::Type) -> Result<TypeSpec> {
        let type_ = match *type_ {
            ast::Type::String => self.string.as_type_spec(),
            ast::Type::I32 => self.integer.as_type_spec(),
            ast::Type::U32 => self.integer.as_type_spec(),
            ast::Type::I64 => self.long.as_type_spec(),
            ast::Type::U64 => self.long.as_type_spec(),
            ast::Type::Array(ref type_) => {
                let argument = self.convert_type(package, type_)?;
                self.list.with_arguments(vec![argument])
            }
            ast::Type::Custom(ref string) => {
                let key = (package.clone(), string.clone());
                let _ = self.env.types.get(&key);
                let package_name = self.java_package(package).parts.join(".");
                Type::new(&package_name, string).as_type_spec()
            }
            ast::Type::Any => self.object.as_type_spec(),
            ast::Type::Float => self.float.as_type_spec(),
            ast::Type::Double => self.double.as_type_spec(),
            ast::Type::UsedType(ref used, ref custom) => {
                let package = self.env.lookup_used(package, used)?;
                let package_name = self.java_package(package).parts.join(".");
                Type::new(&package_name, custom).as_type_spec()
            }
            ref t => {
                return Err(format!("Unsupported type: {:?}", t).into());
            }
        };

        Ok(type_)
    }

    fn build_constructor(&self, class: &ClassSpec) -> ConstructorSpec {
        let mut constructor = ConstructorSpec::new(mods![Modifier::Public]);

        for field in &class.fields {
            let argument = ArgumentSpec::new(mods![Modifier::Final], &field.type_, &field.name);
            constructor.push_argument(&argument);
            constructor.push_statement(&stmt!["this.$L = $N", literal field.name.clone(), name argument]);
        }

        constructor
    }

    fn process_type<L>(&self,
                       package: &ast::Package,
                       type_: &ast::TypeDecl,
                       listeners: &L)
                       -> Result<FileSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(mods![Modifier::Public], &type_.name);

        match type_.value {
            ast::Type::Tuple(ref arguments) => {
                let mut index = 0;

                for argument in arguments {
                    let field_type = self.convert_type(package, argument)?;
                    let mods = mods![Modifier::Private, Modifier::Final];

                    let name = match index {
                        0 => "first".to_owned(),
                        1 => "second".to_owned(),
                        2 => "third".to_owned(),
                        n => format!("field{}", n),
                    };

                    index += 1;

                    let field = FieldSpec::new(mods, &field_type, &name);
                    class.push_field(&field);
                }
            }
            _ => {}
        }

        let constructor = self.build_constructor(&class);
        class.push_constructor(&constructor);

        listeners.class_added(&mut class)?;

        let mut file_spec = self.new_file_spec(package);
        file_spec.push_class(&class);

        Ok(file_spec)
    }

    fn process_message<L>(&self,
                          package: &ast::Package,
                          message: &ast::MessageDecl,
                          listeners: &L)
                          -> Result<FileSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(mods![Modifier::Public], &message.name);

        for member in &message.members {
            if let ast::MessageMember::Field(ref field, _) = *member {
                class.push_field(&self.push_field(&package, field)?);
            }
        }

        let constructor = &self.build_constructor(&class);
        class.push_constructor(constructor);

        listeners.class_added(&mut class)?;

        let mut file_spec = self.new_file_spec(package);
        file_spec.push_class(&class);

        Ok(file_spec)
    }

    fn process_interface<L>(&self,
                            package: &ast::Package,
                            interface: &ast::InterfaceDecl,
                            listeners: &L)
                            -> Result<FileSpec>
        where L: Listeners
    {
        let mut interface_spec = InterfaceSpec::new(mods![Modifier::Public], &interface.name);

        let mut interface_fields: Vec<FieldSpec> = Vec::new();

        for member in &interface.members {
            if let ast::InterfaceMember::Field(ref field, _) = *member {
                let field = self.push_field(&package, field)?;
                interface_fields.push(field);
            }
        }

        for (_, ref sub_type) in &interface.sub_types {
            let mods = mods![Modifier::Public, Modifier::Static];
            let mut class = ClassSpec::new(mods, &sub_type.name);

            for interface_field in &interface_fields {
                class.push_field(&interface_field);
            }

            for member in &sub_type.members {
                if let ast::SubTypeMember::Field(ref field) = *member {
                    let field = self.push_field(&package, field)?;
                    class.push_field(&field);
                }
            }

            let constructor = self.build_constructor(&class);
            class.push_constructor(&constructor);

            listeners.class_added(&mut class)?;
            listeners.sub_type_added(interface, sub_type, &mut class)?;

            interface_spec.push_class(&class);
        }

        let mut file_spec = self.new_file_spec(package);

        listeners.interface_added(interface, &mut interface_spec)?;

        file_spec.push_interface(&interface_spec);
        Ok(file_spec)
    }

    fn push_field(&self, package: &ast::Package, field: &ast::Field) -> Result<FieldSpec> {
        let field_type = self.convert_type(package, &field.type_)?;
        let mods = mods![Modifier::Private, Modifier::Final];
        let field = FieldSpec::new(mods, &field_type, &field.name);

        Ok(field)
    }

    pub fn process<L>(&self, listeners: &L) -> Result<()>
        where L: Listeners
    {
        let root_dir = &self.options.out_path;

        // Create target directory.
        if !root_dir.is_dir() {
            info!("Creating: {}", root_dir.display());
            fs::create_dir_all(root_dir)?;
        }

        // Process all types discovered so far.
        for (&(ref package, _), decl) in &self.env.types {
            let out_dir = self.java_package(package)
                .parts
                .iter()
                .fold(root_dir.clone(), |current, next| current.join(next));

            fs::create_dir_all(&out_dir)?;

            let full_path = out_dir.join(format!("{}.java", decl.name()));

            let file_spec = match *decl {
                ast::Decl::Interface(ref interface) => {
                    self.process_interface(package, interface, listeners)
                }
                ast::Decl::Message(ref message) => {
                    self.process_message(package, message, listeners)
                }
                ast::Decl::Type(ref type_) => self.process_type(package, type_, listeners),
            }?;

            debug!("Writing: {}", full_path.display());

            let out = file_spec.format()?;
            let mut f = File::create(full_path)?;
            let bytes = out.into_bytes();

            f.write_all(&bytes)?;
            f.flush()?;
        }

        Ok(())
    }
}
<commit_msg>generate getters<commit_after>use environment::Environment;
use options::Options;
use parser::ast;
use std::fs::File;
use std::fs;
use std::io::Write;

#[macro_use]
use codegen::java::*;

use errors::*;

fn lower_to_upper_camel(input: &str) -> String {
    let mut out = String::new();

    let mut first = true;

    for c in input.chars() {
        if first {
            for out_c in c.to_uppercase() {
                out.push(out_c);
            }

            first = false;
            continue;
        }

        out.push(c);
    }

    out
}

pub trait Listeners {
    fn class_added(&self, _class: &mut ClassSpec) -> Result<()> {
        Ok(())
    }

    fn interface_added(&self,
                       _interface: &ast::InterfaceDecl,
                       _interface_spec: &mut InterfaceSpec)
                       -> Result<()> {
        Ok(())
    }

    fn sub_type_added(&self,
                      _interface: &ast::InterfaceDecl,
                      _sub_type: &ast::SubType,
                      _class: &mut ClassSpec)
                      -> Result<()> {
        Ok(())
    }
}

pub struct Processor<'a> {
    options: &'a Options,
    env: &'a Environment,
    package_prefix: Option<ast::Package>,
    object: Type,
    list: Type,
    string: Type,
    integer: Type,
    long: Type,
    float: Type,
    double: Type,
}

impl<'a> Processor<'a> {
    pub fn new(options: &'a Options,
               env: &'a Environment,
               package_prefix: Option<ast::Package>)
               -> Processor<'a> {
        Processor {
            options: options,
            env: env,
            package_prefix: package_prefix,
            object: Type::new("java.lang", "Object"),
            list: Type::new("java.util", "List"),
            string: Type::new("java.lang", "String"),
            integer: Type::new("java.lang", "Integer"),
            long: Type::new("java.lang", "Long"),
            float: Type::new("java.lang", "Float"),
            double: Type::new("java.lang", "Double"),
        }
    }

    /// Create a new FileSpec from the given package.
    fn new_file_spec(&self, package: &ast::Package) -> FileSpec {
        let package_name = self.java_package(package).parts.join(".");
        FileSpec::new(&package_name)
    }

    /// Build the java package of a given package.
    ///
    /// This includes the prefixed configured in `self.options`, if specified.
    fn java_package(&self, package: &ast::Package) -> ast::Package {
        self.package_prefix
            .clone()
            .map(|prefix| prefix.join(package))
            .unwrap_or_else(|| package.clone())
    }

    /// Convert the given type to a java type.
    fn convert_type(&self, package: &ast::Package, type_: &ast::Type) -> Result<TypeSpec> {
        let type_ = match *type_ {
            ast::Type::String => self.string.as_type_spec(),
            ast::Type::I32 => self.integer.as_type_spec(),
            ast::Type::U32 => self.integer.as_type_spec(),
            ast::Type::I64 => self.long.as_type_spec(),
            ast::Type::U64 => self.long.as_type_spec(),
            ast::Type::Array(ref type_) => {
                let argument = self.convert_type(package, type_)?;
                self.list.with_arguments(vec![argument])
            }
            ast::Type::Custom(ref string) => {
                let key = (package.clone(), string.clone());
                let _ = self.env.types.get(&key);
                let package_name = self.java_package(package).parts.join(".");
                Type::new(&package_name, string).as_type_spec()
            }
            ast::Type::Any => self.object.as_type_spec(),
            ast::Type::Float => self.float.as_type_spec(),
            ast::Type::Double => self.double.as_type_spec(),
            ast::Type::UsedType(ref used, ref custom) => {
                let package = self.env.lookup_used(package, used)?;
                let package_name = self.java_package(package).parts.join(".");
                Type::new(&package_name, custom).as_type_spec()
            }
            ref t => {
                return Err(format!("Unsupported type: {:?}", t).into());
            }
        };

        Ok(type_)
    }

    fn build_constructor(&self, class: &ClassSpec) -> ConstructorSpec {
        let mut constructor = ConstructorSpec::new(mods![Modifier::Public]);

        for field in &class.fields {
            let argument = ArgumentSpec::new(mods![Modifier::Final], &field.type_, &field.name);
            constructor.push_argument(&argument);
            constructor.push_statement(&stmt!["this.$L = $N", literal field.name.clone(), name argument]);
        }

        constructor
    }

    fn process_type<L>(&self,
                       package: &ast::Package,
                       type_: &ast::TypeDecl,
                       listeners: &L)
                       -> Result<FileSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(mods![Modifier::Public], &type_.name);

        match type_.value {
            ast::Type::Tuple(ref arguments) => {
                let mut index = 0;

                for argument in arguments {
                    let field_type = self.convert_type(package, argument)?;
                    let mods = mods![Modifier::Private, Modifier::Final];

                    let name = match index {
                        0 => "first".to_owned(),
                        1 => "second".to_owned(),
                        2 => "third".to_owned(),
                        n => format!("field{}", n),
                    };

                    index += 1;

                    let field = FieldSpec::new(mods, &field_type, &name);
                    class.push_field(&field);
                }
            }
            _ => {}
        }

        let constructor = self.build_constructor(&class);
        class.push_constructor(&constructor);

        listeners.class_added(&mut class)?;

        let mut file_spec = self.new_file_spec(package);
        file_spec.push_class(&class);

        Ok(file_spec)
    }

    fn build_getters(&self, class: &ClassSpec) -> Result<Vec<MethodSpec>> {
        let mut result = Vec::new();

        for field in &class.fields {
            let return_type = &field.type_;
            let name = format!("get{}", lower_to_upper_camel(&field.name));
            let mut method_spec = MethodSpec::new(mods![Modifier::Public], &name);
            method_spec.returns(return_type);
            method_spec.push_statement(&stmt!["return this.$N", name field]);
            result.push(method_spec);
        }

        Ok(result)
    }

    fn process_message<L>(&self,
                          package: &ast::Package,
                          message: &ast::MessageDecl,
                          listeners: &L)
                          -> Result<FileSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(mods![Modifier::Public], &message.name);

        for member in &message.members {
            if let ast::MessageMember::Field(ref field, _) = *member {
                class.push_field(&self.push_field(&package, field)?);
            }
        }

        let constructor = &self.build_constructor(&class);
        class.push_constructor(constructor);

        for getter in self.build_getters(&class)? {
            class.push_method(&getter);
        }

        listeners.class_added(&mut class)?;

        let mut file_spec = self.new_file_spec(package);
        file_spec.push_class(&class);

        Ok(file_spec)
    }

    fn process_interface<L>(&self,
                            package: &ast::Package,
                            interface: &ast::InterfaceDecl,
                            listeners: &L)
                            -> Result<FileSpec>
        where L: Listeners
    {
        let mut interface_spec = InterfaceSpec::new(mods![Modifier::Public], &interface.name);

        let mut interface_fields: Vec<FieldSpec> = Vec::new();

        for member in &interface.members {
            if let ast::InterfaceMember::Field(ref field, _) = *member {
                let field = self.push_field(&package, field)?;
                interface_fields.push(field);
            }
        }

        for (_, ref sub_type) in &interface.sub_types {
            let mods = mods![Modifier::Public, Modifier::Static];
            let mut class = ClassSpec::new(mods, &sub_type.name);

            for interface_field in &interface_fields {
                class.push_field(&interface_field);
            }

            for member in &sub_type.members {
                if let ast::SubTypeMember::Field(ref field) = *member {
                    let field = self.push_field(&package, field)?;
                    class.push_field(&field);
                }
            }

            let constructor = self.build_constructor(&class);
            class.push_constructor(&constructor);

            listeners.class_added(&mut class)?;
            listeners.sub_type_added(interface, sub_type, &mut class)?;

            interface_spec.push_class(&class);
        }

        let mut file_spec = self.new_file_spec(package);

        listeners.interface_added(interface, &mut interface_spec)?;

        file_spec.push_interface(&interface_spec);
        Ok(file_spec)
    }

    fn push_field(&self, package: &ast::Package, field: &ast::Field) -> Result<FieldSpec> {
        let field_type = self.convert_type(package, &field.type_)?;
        let mods = mods![Modifier::Private, Modifier::Final];
        let field = FieldSpec::new(mods, &field_type, &field.name);

        Ok(field)
    }

    pub fn process<L>(&self, listeners: &L) -> Result<()>
        where L: Listeners
    {
        let root_dir = &self.options.out_path;

        // Create target directory.
        if !root_dir.is_dir() {
            info!("Creating: {}", root_dir.display());
            fs::create_dir_all(root_dir)?;
        }

        // Process all types discovered so far.
        for (&(ref package, _), decl) in &self.env.types {
            let out_dir = self.java_package(package)
                .parts
                .iter()
                .fold(root_dir.clone(), |current, next| current.join(next));

            fs::create_dir_all(&out_dir)?;

            let full_path = out_dir.join(format!("{}.java", decl.name()));

            let file_spec = match *decl {
                ast::Decl::Interface(ref interface) => {
                    self.process_interface(package, interface, listeners)
                }
                ast::Decl::Message(ref message) => {
                    self.process_message(package, message, listeners)
                }
                ast::Decl::Type(ref type_) => self.process_type(package, type_, listeners),
            }?;

            debug!("Writing: {}", full_path.display());

            let out = file_spec.format()?;
            let mut f = File::create(full_path)?;
            let bytes = out.into_bytes();

            f.write_all(&bytes)?;
            f.flush()?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::io::{self};

use core::convert::TryInto;
use lz4_flex::{compress_into, decompress_into};
/// Name of the compression scheme used in the doc store.
///
/// This name is appended to the version string of tantivy.
pub const COMPRESSION: &str = "lz4_block";

pub fn compress(uncompressed: &[u8], compressed: &mut Vec<u8>) -> io::Result<()> {
    compressed.clear();

    compressed.extend_from_slice(&[0, 0, 0, 0]);
    compress_into(uncompressed, compressed);
    let size = uncompressed.len() as u32;
    compressed[0] = size as u8;
    compressed[1] = (size >> 8) as u8;
    compressed[2] = (size >> 16) as u8;
    compressed[3] = (size >> 24) as u8;
    Ok(())
}

pub fn decompress(compressed: &[u8], decompressed: &mut Vec<u8>) -> io::Result<()> {
    decompressed.clear();
    //next lz4_flex version will support slice as input parameter.
    //this will make the usage much less ugly
    let size = compressed.get(..4).ok_or(io::ErrorKind::InvalidData)?;
    let size: &[u8; 4] = size.try_into().unwrap();
    let uncompressed_size = u32::from_le_bytes(*size) as usize;
    // reserve more than required, because blocked writes may write out of bounds, will be improved
    // with lz4_flex 1.0
    decompressed.reserve(uncompressed_size + 4 + 24);
    unsafe {
        decompressed.set_len(uncompressed_size);
    }
    decompress_into(&compressed[4..], decompressed).map_err(|_err| io::ErrorKind::InvalidData)?;
    Ok(())
}
<commit_msg>forward original error<commit_after>use std::io::{self};

use core::convert::TryInto;
use lz4_flex::{compress_into, decompress_into};
/// Name of the compression scheme used in the doc store.
///
/// This name is appended to the version string of tantivy.
pub const COMPRESSION: &str = "lz4_block";

pub fn compress(uncompressed: &[u8], compressed: &mut Vec<u8>) -> io::Result<()> {
    compressed.clear();

    compressed.extend_from_slice(&[0, 0, 0, 0]);
    compress_into(uncompressed, compressed);
    let size = uncompressed.len() as u32;
    compressed[0] = size as u8;
    compressed[1] = (size >> 8) as u8;
    compressed[2] = (size >> 16) as u8;
    compressed[3] = (size >> 24) as u8;
    Ok(())
}

pub fn decompress(compressed: &[u8], decompressed: &mut Vec<u8>) -> io::Result<()> {
    decompressed.clear();
    //next lz4_flex version will support slice as input parameter.
    //this will make the usage much less ugly
    let size = compressed.get(..4).ok_or(io::ErrorKind::InvalidData)?;
    let size: &[u8; 4] = size.try_into().unwrap();
    let uncompressed_size = u32::from_le_bytes(*size) as usize;
    // reserve more than required, because blocked writes may write out of bounds, will be improved
    // with lz4_flex 1.0
    decompressed.reserve(uncompressed_size + 4 + 24);
    unsafe {
        decompressed.set_len(uncompressed_size);
    }
    decompress_into(&compressed[4..], decompressed)
        .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err.to_string()))?;
    Ok(())
}
<|endoftext|>


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

// FIXME: This is a complete copy of `cargo/src/cargo/util/read2.rs`
// Consider unify the read2() in libstd, cargo and this to prevent further code duplication.

pub use self::imp::read2;

#[cfg(not(any(unix, windows)))]
mod imp {
    use std::io::{self, Read};
    use std::process::{ChildStdout, ChildStderr};

    pub fn read2(out_pipe: ChildStdout,
                 err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        let mut buffer = Vec::new();
        out_pipe.read_to_end(&mut buffer)?;
        data(true, &mut buffer, true);
        buffer.clear();
        err_pipe.read_to_end(&mut buffer)?;
        data(false, &mut buffer, true);
        Ok(())
    }
}

#[cfg(unix)]
mod imp {
    use std::io::prelude::*;
    use std::io;
    use std::mem;
    use std::os::unix::prelude::*;
    use std::process::{ChildStdout, ChildStderr};
    use libc;

    pub fn read2(mut out_pipe: ChildStdout,
                 mut err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        unsafe {
            libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
            libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
        }

        let mut out_done = false;
        let mut err_done = false;
        let mut out = Vec::new();
        let mut err = Vec::new();

        let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
        fds[0].fd = out_pipe.as_raw_fd();
        fds[0].events = libc::POLLIN;
        fds[1].fd = err_pipe.as_raw_fd();
        fds[1].events = libc::POLLIN;
        loop {
            // wait for either pipe to become readable using `select`
            let r = unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) };
            if r == -1 {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::Interrupted {
                    continue
                }
                return Err(err)
            }

            // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
            // EAGAIN. If we hit EOF, then this will happen because the underlying
            // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
            // this case we flip the other fd back into blocking mode and read
            // whatever's leftover on that file descriptor.
            let handle = |res: io::Result<_>| {
                match res {
                    Ok(_) => Ok(true),
                    Err(e) => {
                        if e.kind() == io::ErrorKind::WouldBlock {
                            Ok(false)
                        } else {
                            Err(e)
                        }
                    }
                }
            };
            if !out_done && fds[0].revents != 0 && handle(out_pipe.read_to_end(&mut out))? {
                out_done = true;
            }
            data(true, &mut out, out_done);
            if !err_done && fds[1].revents != 0 && handle(err_pipe.read_to_end(&mut err))? {
                err_done = true;
            }
            data(false, &mut err, err_done);

            if out_done && err_done {
                return Ok(())
            }
        }
    }
}

#[cfg(windows)]
mod imp {
    extern crate miow;
    extern crate winapi;

    use std::io;
    use std::os::windows::prelude::*;
    use std::process::{ChildStdout, ChildStderr};
    use std::slice;

    use self::miow::iocp::{CompletionPort, CompletionStatus};
    use self::miow::pipe::NamedPipe;
    use self::miow::Overlapped;
    use self::winapi::ERROR_BROKEN_PIPE;

    struct Pipe<'a> {
        dst: &'a mut Vec<u8>,
        overlapped: Overlapped,
        pipe: NamedPipe,
        done: bool,
    }

    pub fn read2(out_pipe: ChildStdout,
                 err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        let mut out = Vec::new();
        let mut err = Vec::new();

        let port = CompletionPort::new(1)?;
        port.add_handle(0, &out_pipe)?;
        port.add_handle(1, &err_pipe)?;

        unsafe {
            let mut out_pipe = Pipe::new(out_pipe, &mut out);
            let mut err_pipe = Pipe::new(err_pipe, &mut err);

            out_pipe.read()?;
            err_pipe.read()?;

            let mut status = [CompletionStatus::zero(), CompletionStatus::zero()];

            while !out_pipe.done || !err_pipe.done {
                for status in port.get_many(&mut status, None)? {
                    if status.token() == 0 {
                        out_pipe.complete(status);
                        data(true, out_pipe.dst, out_pipe.done);
                        out_pipe.read()?;
                    } else {
                        err_pipe.complete(status);
                        data(false, err_pipe.dst, err_pipe.done);
                        err_pipe.read()?;
                    }
                }
            }

            Ok(())
        }
    }

    impl<'a> Pipe<'a> {
        unsafe fn new<P: IntoRawHandle>(p: P, dst: &'a mut Vec<u8>) -> Pipe<'a> {
            Pipe {
                dst: dst,
                pipe: NamedPipe::from_raw_handle(p.into_raw_handle()),
                overlapped: Overlapped::zero(),
                done: false,
            }
        }

        unsafe fn read(&mut self) -> io::Result<()> {
            let dst = slice_to_end(self.dst);
            match self.pipe.read_overlapped(dst, self.overlapped.raw()) {
                Ok(_) => Ok(()),
                Err(e) => {
                    if e.raw_os_error() == Some(ERROR_BROKEN_PIPE as i32) {
                        self.done = true;
                        Ok(())
                    } else {
                        Err(e)
                    }
                }
            }
        }

        unsafe fn complete(&mut self, status: &CompletionStatus) {
            let prev = self.dst.len();
            self.dst.set_len(prev + status.bytes_transferred() as usize);
            if status.bytes_transferred() == 0 {
                self.done = true;
            }
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}
<commit_msg>Update compiletest's `read2` function<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// FIXME: This is a complete copy of `cargo/src/cargo/util/read2.rs`
// Consider unify the read2() in libstd, cargo and this to prevent further code duplication.

pub use self::imp::read2;

#[cfg(not(any(unix, windows)))]
mod imp {
    use std::io::{self, Read};
    use std::process::{ChildStdout, ChildStderr};

    pub fn read2(out_pipe: ChildStdout,
                 err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        let mut buffer = Vec::new();
        out_pipe.read_to_end(&mut buffer)?;
        data(true, &mut buffer, true);
        buffer.clear();
        err_pipe.read_to_end(&mut buffer)?;
        data(false, &mut buffer, true);
        Ok(())
    }
}

#[cfg(unix)]
mod imp {
    use std::io::prelude::*;
    use std::io;
    use std::mem;
    use std::os::unix::prelude::*;
    use std::process::{ChildStdout, ChildStderr};
    use libc;

    pub fn read2(mut out_pipe: ChildStdout,
                 mut err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        unsafe {
            libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
            libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
        }

        let mut out_done = false;
        let mut err_done = false;
        let mut out = Vec::new();
        let mut err = Vec::new();

        let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
        fds[0].fd = out_pipe.as_raw_fd();
        fds[0].events = libc::POLLIN;
        fds[1].fd = err_pipe.as_raw_fd();
        fds[1].events = libc::POLLIN;
        let mut nfds = 2;
        let mut errfd = 1;

        while nfds > 0 {
            // wait for either pipe to become readable using `select`
            let r = unsafe { libc::poll(fds.as_mut_ptr(), nfds, -1) };
            if r == -1 {
                let err = io::Error::last_os_error();
                if err.kind() == io::ErrorKind::Interrupted {
                    continue
                }
                return Err(err)
            }

            // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
            // EAGAIN. If we hit EOF, then this will happen because the underlying
            // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
            // this case we flip the other fd back into blocking mode and read
            // whatever's leftover on that file descriptor.
            let handle = |res: io::Result<_>| {
                match res {
                    Ok(_) => Ok(true),
                    Err(e) => {
                        if e.kind() == io::ErrorKind::WouldBlock {
                            Ok(false)
                        } else {
                            Err(e)
                        }
                    }
                }
            };
            if !err_done && fds[errfd].revents != 0 && handle(err_pipe.read_to_end(&mut err))? {
                err_done = true;
                nfds -= 1;
            }
            data(false, &mut err, err_done);
            if !out_done && fds[0].revents != 0 && handle(out_pipe.read_to_end(&mut out))? {
                out_done = true;
                fds[0].fd = err_pipe.as_raw_fd();
                errfd = 0;
                nfds -= 1;
            }
            data(true, &mut out, out_done);
        }
        Ok(())
    }
}

#[cfg(windows)]
mod imp {
    extern crate miow;
    extern crate winapi;

    use std::io;
    use std::os::windows::prelude::*;
    use std::process::{ChildStdout, ChildStderr};
    use std::slice;

    use self::miow::iocp::{CompletionPort, CompletionStatus};
    use self::miow::pipe::NamedPipe;
    use self::miow::Overlapped;
    use self::winapi::ERROR_BROKEN_PIPE;

    struct Pipe<'a> {
        dst: &'a mut Vec<u8>,
        overlapped: Overlapped,
        pipe: NamedPipe,
        done: bool,
    }

    pub fn read2(out_pipe: ChildStdout,
                 err_pipe: ChildStderr,
                 data: &mut FnMut(bool, &mut Vec<u8>, bool)) -> io::Result<()> {
        let mut out = Vec::new();
        let mut err = Vec::new();

        let port = CompletionPort::new(1)?;
        port.add_handle(0, &out_pipe)?;
        port.add_handle(1, &err_pipe)?;

        unsafe {
            let mut out_pipe = Pipe::new(out_pipe, &mut out);
            let mut err_pipe = Pipe::new(err_pipe, &mut err);

            out_pipe.read()?;
            err_pipe.read()?;

            let mut status = [CompletionStatus::zero(), CompletionStatus::zero()];

            while !out_pipe.done || !err_pipe.done {
                for status in port.get_many(&mut status, None)? {
                    if status.token() == 0 {
                        out_pipe.complete(status);
                        data(true, out_pipe.dst, out_pipe.done);
                        out_pipe.read()?;
                    } else {
                        err_pipe.complete(status);
                        data(false, err_pipe.dst, err_pipe.done);
                        err_pipe.read()?;
                    }
                }
            }

            Ok(())
        }
    }

    impl<'a> Pipe<'a> {
        unsafe fn new<P: IntoRawHandle>(p: P, dst: &'a mut Vec<u8>) -> Pipe<'a> {
            Pipe {
                dst: dst,
                pipe: NamedPipe::from_raw_handle(p.into_raw_handle()),
                overlapped: Overlapped::zero(),
                done: false,
            }
        }

        unsafe fn read(&mut self) -> io::Result<()> {
            let dst = slice_to_end(self.dst);
            match self.pipe.read_overlapped(dst, self.overlapped.raw()) {
                Ok(_) => Ok(()),
                Err(e) => {
                    if e.raw_os_error() == Some(ERROR_BROKEN_PIPE as i32) {
                        self.done = true;
                        Ok(())
                    } else {
                        Err(e)
                    }
                }
            }
        }

        unsafe fn complete(&mut self, status: &CompletionStatus) {
            let prev = self.dst.len();
            self.dst.set_len(prev + status.bytes_transferred() as usize);
            if status.bytes_transferred() == 0 {
                self.done = true;
            }
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}
<|endoftext|>


<commit_before>use crate::interchange_gen::routing_graph::*;
use crate::schema::*;
use crate::chip::Chip;
use crate::database::Database;
use crate::bba::idstring::*;

use std::convert::TryInto;

use flate2::Compression;
use flate2::write::GzEncoder;

pub fn write(c: &Chip, _db: &mut Database, ids: &mut IdStringDB, graph: &IcGraph, filename: &str) -> ::capnp::Result<()> {
    let mut m = ::capnp::message::Builder::new_default();
    {
        let mut dev = m.init_root::<DeviceResources_capnp::device::Builder>();
        dev.set_name(&c.device);
        {
            let mut tiletypes = dev.reborrow().init_tile_type_list(graph.tile_types.len().try_into().unwrap());
            for (i, (_, data)) in graph.tile_types.iter().enumerate() {
                let mut tt = tiletypes.reborrow().get(i.try_into().unwrap());
                // TODO: form a nice name from the constituent tile types
                // TODO: remove the NULL hack
                if i == graph.tiles[0].type_idx {
                    tt.set_name(ids.id("NULL").val().try_into().unwrap());
                } else {
                    tt.set_name(ids.id(&format!("tiletype_{}", i)).val().try_into().unwrap());
                }
                {
                    let mut wires = tt.reborrow().init_wires(data.wires.len().try_into().unwrap());
                    for (j, (_, wire_data)) in data.wires.iter().enumerate() {
                        wires.set(j.try_into().unwrap(),  wire_data.name.val().try_into().unwrap());
                    }
                }
                {
                    let mut pips = tt.reborrow().init_pips(data.pips.len().try_into().unwrap());
                    for (j, pip_data) in data.pips.iter().enumerate() {
                        let mut p = pips.reborrow().get(j.try_into().unwrap());
                        p.set_wire0(pip_data.src_wire.try_into().unwrap());
                        p.set_wire1(pip_data.dst_wire.try_into().unwrap());
                        p.set_directional(true);
                        p.set_buffered20(true);
                        p.set_buffered21(false);
                        p.set_conventional(());
                    }
                }
                // TODO: constant sources
            }
        }
        let mut wire_list = Vec::new();
        {
            // this wire_list is the list of wires as we create nodes, to be output as dev.wires later
            let mut nodes = dev.reborrow().init_nodes(graph.nodes.len().try_into().unwrap());
            for (i, node_data) in graph.nodes.iter().enumerate() {
                let n = nodes.reborrow().get(i.try_into().unwrap());
                let mut node_wires = n.init_wires(node_data.wires.len().try_into().unwrap());
                // write root wire
                {
                    node_wires.set(0, wire_list.len().try_into().unwrap());
                    wire_list.push((node_data.root_wire.tile_idx, node_data.root_wire.wire_idx));
                }
                let mut node_wire_idx = 1;
                // write non-root wires
                for wire in node_data.wires.iter().filter(|w| **w != node_data.root_wire) {
                    node_wires.set(node_wire_idx, wire_list.len().try_into().unwrap());
                    wire_list.push((wire.tile_idx, wire.wire_idx));
                    node_wire_idx += 1;
                }
            }
        }
        {
            let mut wires = dev.reborrow().init_wires(wire_list.len().try_into().unwrap());
            for (i, (tile_idx, wire_idx)) in wire_list.iter().enumerate() {
                let mut w = wires.reborrow().get(i.try_into().unwrap());
                // TODO: should IcGraph use IdStrings to better match what we write out?
                let tile = &graph.tiles[*tile_idx];
                w.set_tile(tile.name.val().try_into().unwrap());
                w.set_wire(graph.tile_types.value(tile.type_idx).wires.value(*wire_idx).name.val().try_into().unwrap());
            }
        }
        {
            let mut tiles = dev.reborrow().init_tile_list(graph.tiles.len().try_into().unwrap());
            for (i, tile_data) in graph.tiles.iter().enumerate() {
                let mut t = tiles.reborrow().get(i.try_into().unwrap());
                t.set_name(tile_data.name.val().try_into().unwrap());
                t.set_type(tile_data.type_idx.try_into().unwrap());
                t.set_row(tile_data.y.try_into().unwrap());
                t.set_col(tile_data.x.try_into().unwrap());
            }
        }
        {
            let mut constants = dev.reborrow().init_constants();
            constants.set_gnd_cell_type(ids.id("VLO").val().try_into().unwrap());
            constants.set_gnd_cell_pin(ids.id("Z").val().try_into().unwrap());
            constants.set_vcc_cell_type(ids.id("VHI").val().try_into().unwrap());
            constants.set_vcc_cell_pin(ids.id("Z").val().try_into().unwrap());
        }
        {
            let mut c2b = dev.reborrow().init_cell_bel_map(2);
            c2b.reborrow().get(0).set_cell(ids.id("VLO").val().try_into().unwrap());
            c2b.reborrow().get(1).set_cell(ids.id("VHI").val().try_into().unwrap());
        }
        {
            let mut strs = dev.init_str_list(ids.len().try_into().unwrap());
            for i in 0..ids.len() {
                strs.set(i.try_into().unwrap(), ids.idx_str(i));
            }
        }
    }
    let mut e = GzEncoder::new(std::fs::File::create(filename)?, Compression::default());
    ::capnp::serialize::write_message(&mut e, &m)?;
    e.finish()?;
    Ok(())
}
<commit_msg>interchange: Add dummy package<commit_after>use crate::interchange_gen::routing_graph::*;
use crate::schema::*;
use crate::chip::Chip;
use crate::database::Database;
use crate::bba::idstring::*;

use std::convert::TryInto;

use flate2::Compression;
use flate2::write::GzEncoder;

pub fn write(c: &Chip, _db: &mut Database, ids: &mut IdStringDB, graph: &IcGraph, filename: &str) -> ::capnp::Result<()> {
    let mut m = ::capnp::message::Builder::new_default();
    {
        let mut dev = m.init_root::<DeviceResources_capnp::device::Builder>();
        dev.set_name(&c.device);
        {
            let mut tiletypes = dev.reborrow().init_tile_type_list(graph.tile_types.len().try_into().unwrap());
            for (i, (_, data)) in graph.tile_types.iter().enumerate() {
                let mut tt = tiletypes.reborrow().get(i.try_into().unwrap());
                // TODO: form a nice name from the constituent tile types
                // TODO: remove the NULL hack
                if i == graph.tiles[0].type_idx {
                    tt.set_name(ids.id("NULL").val().try_into().unwrap());
                } else {
                    tt.set_name(ids.id(&format!("tiletype_{}", i)).val().try_into().unwrap());
                }
                {
                    let mut wires = tt.reborrow().init_wires(data.wires.len().try_into().unwrap());
                    for (j, (_, wire_data)) in data.wires.iter().enumerate() {
                        wires.set(j.try_into().unwrap(),  wire_data.name.val().try_into().unwrap());
                    }
                }
                {
                    let mut pips = tt.reborrow().init_pips(data.pips.len().try_into().unwrap());
                    for (j, pip_data) in data.pips.iter().enumerate() {
                        let mut p = pips.reborrow().get(j.try_into().unwrap());
                        p.set_wire0(pip_data.src_wire.try_into().unwrap());
                        p.set_wire1(pip_data.dst_wire.try_into().unwrap());
                        p.set_directional(true);
                        p.set_buffered20(true);
                        p.set_buffered21(false);
                        p.set_conventional(());
                    }
                }
                // TODO: constant sources
            }
        }
        let mut wire_list = Vec::new();
        {
            // this wire_list is the list of wires as we create nodes, to be output as dev.wires later
            let mut nodes = dev.reborrow().init_nodes(graph.nodes.len().try_into().unwrap());
            for (i, node_data) in graph.nodes.iter().enumerate() {
                let n = nodes.reborrow().get(i.try_into().unwrap());
                let mut node_wires = n.init_wires(node_data.wires.len().try_into().unwrap());
                // write root wire
                {
                    node_wires.set(0, wire_list.len().try_into().unwrap());
                    wire_list.push((node_data.root_wire.tile_idx, node_data.root_wire.wire_idx));
                }
                let mut node_wire_idx = 1;
                // write non-root wires
                for wire in node_data.wires.iter().filter(|w| **w != node_data.root_wire) {
                    node_wires.set(node_wire_idx, wire_list.len().try_into().unwrap());
                    wire_list.push((wire.tile_idx, wire.wire_idx));
                    node_wire_idx += 1;
                }
            }
        }
        {
            let mut wires = dev.reborrow().init_wires(wire_list.len().try_into().unwrap());
            for (i, (tile_idx, wire_idx)) in wire_list.iter().enumerate() {
                let mut w = wires.reborrow().get(i.try_into().unwrap());
                // TODO: should IcGraph use IdStrings to better match what we write out?
                let tile = &graph.tiles[*tile_idx];
                w.set_tile(tile.name.val().try_into().unwrap());
                w.set_wire(graph.tile_types.value(tile.type_idx).wires.value(*wire_idx).name.val().try_into().unwrap());
            }
        }
        {
            let mut tiles = dev.reborrow().init_tile_list(graph.tiles.len().try_into().unwrap());
            for (i, tile_data) in graph.tiles.iter().enumerate() {
                let mut t = tiles.reborrow().get(i.try_into().unwrap());
                t.set_name(tile_data.name.val().try_into().unwrap());
                t.set_type(tile_data.type_idx.try_into().unwrap());
                t.set_row(tile_data.y.try_into().unwrap());
                t.set_col(tile_data.x.try_into().unwrap());
            }
        }
        {
            let mut constants = dev.reborrow().init_constants();
            constants.set_gnd_cell_type(ids.id("VLO").val().try_into().unwrap());
            constants.set_gnd_cell_pin(ids.id("Z").val().try_into().unwrap());
            constants.set_vcc_cell_type(ids.id("VHI").val().try_into().unwrap());
            constants.set_vcc_cell_pin(ids.id("Z").val().try_into().unwrap());
        }
        {
            let mut c2b = dev.reborrow().init_cell_bel_map(2);
            c2b.reborrow().get(0).set_cell(ids.id("VLO").val().try_into().unwrap());
            c2b.reborrow().get(1).set_cell(ids.id("VHI").val().try_into().unwrap());
        }
        {
            let mut packages = dev.reborrow().init_packages(1);
            packages.reborrow().get(0).set_name(ids.id("QFN72").val().try_into().unwrap());
            // TODO: all packages and pin map
        }
        {
            let mut strs = dev.init_str_list(ids.len().try_into().unwrap());
            for i in 0..ids.len() {
                strs.set(i.try_into().unwrap(), ids.idx_str(i));
            }
        }
    }
    let mut e = GzEncoder::new(std::fs::File::create(filename)?, Compression::default());
    ::capnp::serialize::write_message(&mut e, &m)?;
    e.finish()?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate user32;
extern crate winapi;
extern crate kernel32;
extern crate libc;
extern crate gdi32;
use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
use std::mem;

use self::winapi::winuser::*;
use self::winapi::windef::*;
use self::winapi::minwindef::*;
use self::winapi::wingdi::*;
use self::winapi::winnt::*;

struct MyBitmapType {
    info: BITMAPINFO
}

static mut GLOBAL_RUNNING: bool = true;
static mut WIN32_BITMAP_INFO: MyBitmapType = MyBitmapType {
    info: BITMAPINFO {
        bmiHeader: BITMAPINFOHEADER {
            biSize: 0,
            biWidth: 0,
            biHeight: 0,
            biPlanes: 1,
            biBitCount: 32,
            biCompression: BI_RGB,
            biSizeImage: 0,
            biXPelsPerMeter: 0,
            biYPelsPerMeter: 0,
            biClrUsed: 0,
            biClrImportant: 0
        } ,
        bmiColors: []
    }
};

static mut BITMAP_MEMORY: LPVOID = 0 as LPVOID;

unsafe fn win32_resize_dib_section(width: i32, height: i32) -> () {

    WIN32_BITMAP_INFO.info.bmiHeader.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
    WIN32_BITMAP_INFO.info.bmiHeader.biWidth = width;
    WIN32_BITMAP_INFO.info.bmiHeader.biHeight = -height; //Top-down coord

    let bytes_per_pixel = 4;
    let bitmap_memory_size = (width*height)*bytes_per_pixel;

    if BITMAP_MEMORY != 0 as LPVOID {
        kernel32::VirtualFree(BITMAP_MEMORY, 0 as u64, MEM_RELEASE);
    }

    BITMAP_MEMORY = kernel32::VirtualAlloc(0 as LPVOID, bitmap_memory_size as u64, MEM_COMMIT, PAGE_READWRITE);

    let pitch = width*bytes_per_pixel;
    let mut row: *mut u8 = BITMAP_MEMORY as *mut u8;
    for y in 0..height {
        let mut pixel: *mut u32 = row as *mut u32;
        for x in 0..width {
            //*pixel = 255 << 16; //red
            *pixel = ((x as u32) << 0) + ((y as u32) << 8);  //green
            // *pixel = 255 << 0; //blue
            pixel = pixel.offset(1);

        };
        row = row.offset(pitch as isize);
    };

}

unsafe fn win32_update_window(device_context: HDC, window_width: i32, window_height: i32) {
    gdi32::StretchDIBits(device_context,
        0, 0, WIN32_BITMAP_INFO.info.bmiHeader.biWidth, WIN32_BITMAP_INFO.info.bmiHeader.biHeight.abs(), //We have a negative value for this to specify top-down bitmap
        0, 0, window_width, window_height,
        BITMAP_MEMORY,
        &WIN32_BITMAP_INFO.info,
        DIB_RGB_COLORS,
        SRCCOPY);
}

pub fn main() {

    unsafe {
        WIN32_BITMAP_INFO.info.bmiHeader.biWidth = 1080;
        WIN32_BITMAP_INFO.info.bmiHeader.biHeight = 640;
    }

    let window_class_name = to_wide_string("RustHeroWindowClass").as_ptr();
    let h_instance = unsafe {
        kernel32::GetModuleHandleW(0 as winapi::winnt::LPCWSTR)
    };

    let mut window = WNDCLASSW {
        style: CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
        lpfnWndProc: Some(winproc),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_instance,
        hIcon: unsafe { user32::LoadIconW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hCursor: unsafe { user32::LoadCursorW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hbrBackground: 0 as HBRUSH,
        lpszMenuName: to_wide_string("RustHeroMenu").as_ptr(),
        lpszClassName: window_class_name
    };

    let ret = unsafe { //TODO: Can we use Options to get rid of all these unsafes?
        user32::RegisterClassW(&mut window)
    };

    if ret == 0 {
        println!("Registering the window class failed.");
        return
    }

    unsafe {
         let window_handle = user32::CreateWindowExW(
            0,
            window_class_name,
            to_wide_string("Rust Hero").as_ptr(),
            WS_VISIBLE|WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            0 as HWND,
            0 as HMENU,
            h_instance,
            0 as LPVOID
        );

        if window_handle.is_null() {
            println!("Failed to create window.");
            return;
        }

        let device_context = user32::GetDC(window_handle);

        while GLOBAL_RUNNING {
            let mut msg: MSG = mem::uninitialized();
            while user32::PeekMessageW(&mut msg, window_handle,0,0,PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }

            // win32_update_window(device_context, )
        }
    }
}

fn to_wide_string(str: &str) -> Vec<u16> {
    OsStr::new(str).encode_wide().chain(once(0)).collect()
}

 pub unsafe extern "system" fn winproc(hwnd :HWND, msg :UINT, w_param :WPARAM, l_param :LPARAM) -> LRESULT {
        match msg {
            WM_SIZE => {
                println!("WM_SIZE");
                let mut client_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut client_rect);
                win32_resize_dib_section(client_rect.right - client_rect.left, client_rect.bottom - client_rect.top);
            },
            WM_CLOSE => {  GLOBAL_RUNNING = false;  },
            WM_DESTROY => { GLOBAL_RUNNING = false; },
            WM_ACTIVATEAPP => { println!("WM_ACTIVATEAPP"); },
            WM_PAINT => {
                let mut paint: PAINTSTRUCT = mem::uninitialized();
                let hdc = user32::BeginPaint(hwnd, &mut paint);
                let mut client_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut client_rect);
                win32_update_window(hdc, client_rect.right, client_rect.bottom);
                user32::EndPaint(hwnd, &paint);
            },
            _ => { return user32::DefWindowProcW(hwnd, msg, w_param, l_param); }
        };
        0
    }<commit_msg>Made it animate<commit_after>extern crate user32;
extern crate winapi;
extern crate kernel32;
extern crate libc;
extern crate gdi32;
use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
use std::mem;

use self::winapi::winuser::*;
use self::winapi::windef::*;
use self::winapi::minwindef::*;
use self::winapi::wingdi::*;
use self::winapi::winnt::*;

struct MyBitmapType {
    info: BITMAPINFO,
    bytes_per_pixel: i32,
    width: i32,
    height: i32
}

static mut GLOBAL_RUNNING: bool = true;
static mut WIN32_BITMAP_INFO: MyBitmapType = MyBitmapType {
    info: BITMAPINFO {
        bmiHeader: BITMAPINFOHEADER {
            biSize: 0,
            biWidth: 0,
            biHeight: 0,
            biPlanes: 1,
            biBitCount: 32,
            biCompression: BI_RGB,
            biSizeImage: 0,
            biXPelsPerMeter: 0,
            biYPelsPerMeter: 0,
            biClrUsed: 0,
            biClrImportant: 0
        } ,
        bmiColors: []
    },
    bytes_per_pixel: 4,
    width: 0,
    height: 0
};

static mut BITMAP_MEMORY: LPVOID = 0 as LPVOID;

unsafe fn win32_resize_dib_section(width: i32, height: i32) -> () {
    WIN32_BITMAP_INFO.width = width;
    WIN32_BITMAP_INFO.height = height;
    WIN32_BITMAP_INFO.info.bmiHeader.biWidth = width;
    WIN32_BITMAP_INFO.info.bmiHeader.biHeight = -height; //Top-down coord

    let bitmap_memory_size = (width*height)*WIN32_BITMAP_INFO.bytes_per_pixel;

    if BITMAP_MEMORY != 0 as LPVOID {
        kernel32::VirtualFree(BITMAP_MEMORY, 0 as u64, MEM_RELEASE);
    }

    BITMAP_MEMORY = kernel32::VirtualAlloc(0 as LPVOID, bitmap_memory_size as u64, MEM_COMMIT, PAGE_READWRITE);

    draw_weird_gradient(128,128);

}

unsafe fn draw_weird_gradient(x_offset: u32, y_offset: u32) {
    let width = WIN32_BITMAP_INFO.width;
    let height = WIN32_BITMAP_INFO.height;
    let bytes_per_pixel = WIN32_BITMAP_INFO.bytes_per_pixel;

    let pitch = width*bytes_per_pixel;
    let mut row: *mut u8 = BITMAP_MEMORY as *mut u8;
    for y in 0..height {
        let mut pixel: *mut u32 = row as *mut u32;
        for x in 0..width {
            *pixel = ((x as u32 + x_offset) << 0 ) + ((y as u32 + y_offset) << 8);
            pixel = pixel.offset(1);

        };
        row = row.offset(pitch as isize);
    };
}

unsafe fn win32_update_window(device_context: HDC, window_width: i32, window_height: i32) {
    gdi32::StretchDIBits(device_context,
        0, 0, WIN32_BITMAP_INFO.width, WIN32_BITMAP_INFO.height,
        0, 0, window_width, window_height,
        BITMAP_MEMORY,
        &WIN32_BITMAP_INFO.info,
        DIB_RGB_COLORS,
        SRCCOPY);
}

pub fn main() {

    unsafe {
        WIN32_BITMAP_INFO.info.bmiHeader.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
        WIN32_BITMAP_INFO.info.bmiHeader.biWidth = 1080;
        WIN32_BITMAP_INFO.info.bmiHeader.biHeight = 640;
    }

    let window_class_name = to_wide_string("RustHeroWindowClass").as_ptr();
    let h_instance = unsafe {
        kernel32::GetModuleHandleW(0 as winapi::winnt::LPCWSTR)
    };

    let mut window = WNDCLASSW {
        style: CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
        lpfnWndProc: Some(winproc),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_instance,
        hIcon: unsafe { user32::LoadIconW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hCursor: unsafe { user32::LoadCursorW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hbrBackground: 0 as HBRUSH,
        lpszMenuName: to_wide_string("RustHeroMenu").as_ptr(),
        lpszClassName: window_class_name
    };

    let ret = unsafe { //TODO: Can we use Options to get rid of all these unsafes?
        user32::RegisterClassW(&mut window)
    };

    if ret == 0 {
        println!("Registering the window class failed.");
        return
    }

    unsafe {
         let window_handle = user32::CreateWindowExW(
            0,
            window_class_name,
            to_wide_string("Rust Hero").as_ptr(),
            WS_VISIBLE|WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            0 as HWND,
            0 as HMENU,
            h_instance,
            0 as LPVOID
        );

        if window_handle.is_null() {
            println!("Failed to create window.");
            return;
        }

        let device_context = user32::GetDC(window_handle);
        let mut window_rect: RECT = mem::uninitialized();
        user32::GetClientRect(window_handle, &mut window_rect);

        let mut x = 0;
        let mut y = 0;
        while GLOBAL_RUNNING {
            let mut msg: MSG = mem::uninitialized();
            while user32::PeekMessageW(&mut msg, window_handle,0,0,PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }

            x += 1;
            y += 1;
            draw_weird_gradient(x,y);
            win32_update_window(device_context, window_rect.right, window_rect.bottom);
        }
    }
}

fn to_wide_string(str: &str) -> Vec<u16> {
    OsStr::new(str).encode_wide().chain(once(0)).collect()
}

 pub unsafe extern "system" fn winproc(hwnd :HWND, msg :UINT, w_param :WPARAM, l_param :LPARAM) -> LRESULT {
        match msg {
            WM_SIZE => {
                println!("WM_SIZE");
                let mut window_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut window_rect);
                win32_resize_dib_section(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
            },
            WM_CLOSE => {  GLOBAL_RUNNING = false;  },
            WM_DESTROY => { GLOBAL_RUNNING = false; },
            WM_ACTIVATEAPP => { println!("WM_ACTIVATEAPP"); },
            WM_PAINT => {
                println!("WM_PAINT");
                let mut paint: PAINTSTRUCT = mem::uninitialized();
                let hdc = user32::BeginPaint(hwnd, &mut paint);
                let mut window_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut window_rect);
                win32_update_window(hdc, window_rect.right, window_rect.bottom);
                user32::EndPaint(hwnd, &paint);
            },
            _ => { return user32::DefWindowProcW(hwnd, msg, w_param, l_param); }
        };
        0
    }<|endoftext|>


<commit_before>use prelude::*;

use BytesError;

use winapi::shared::guiddef;

impl Uuid {
    /// Attempts to create a [`Uuid`] from a winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    fn from_guid(guid: guiddef::GUID) -> Result<Uuid, BytesError> {
        Uuid::from_fields(
            guid.Data1 as u32,
            guid.Data2 as u16,
            guid.Data3 as u16,
            &(guid.Data4 as [u8; 8]),
        )
    }

    /// Converts a [`Uuid`] into a little endian winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    fn to_guid(&self) -> guiddef::GUID {
        let (data1, data2, data3, data4) = self.to_fields_le();

        guiddef::GUID {
            Data1: data1,
            Data2: data2,
            Data3: data3,
            Data4: data4,
        }
    }
}
<commit_msg>Add tests and fix to_guid<commit_after>use prelude::*;

use BytesError;

use winapi::shared::guiddef;

impl Uuid {
    /// Attempts to create a [`Uuid`] from a winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    fn from_guid(guid: guiddef::GUID) -> Result<Uuid, BytesError> {
        Uuid::from_fields(
            guid.Data1 as u32,
            guid.Data2 as u16,
            guid.Data3 as u16,
            &(guid.Data4 as [u8; 8]),
        )
    }

    /// Converts a [`Uuid`] into a little endian winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    fn to_guid(&self) -> guiddef::GUID {
        let (data1, data2, data3, data4) = self.as_fields();

        guiddef::GUID {
            Data1: data1,
            Data2: data2,
            Data3: data3,
            Data4: *data4,
        }
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use std::str::FromStr;
    use winapi::shared::guiddef;

    #[test]
    fn test_to_uuid() {
        let uuid = Uuid::from_str("735d359d-4bc4-4e07-8c49-eb3e99a048dc").unwrap();
        let guid = uuid.to_guid();
        assert_eq!(Ok(uuid), Uuid::from_guid(guid));
    }

    #[test]
    fn test_from_guid() {
        let guid = guiddef::GUID {
            Data1: 0x4a35229d,
            Data2: 0x5527,
            Data3: 0x4f30,
            Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
        };

        let uuid = Uuid::from_guid(guid).unwrap();
        assert_eq!("4a35229d-5527-4f30-8647-9dc54e1ee1e8", uuid.to_hyphenated().to_string());
        assert_eq!(Ok(uuid), Uuid::from_guid(guid));
    }
}<|endoftext|>