<commit_before>use std::ops::Mul;

use types::structs::PgInterval;

pub trait MicroIntervalDsl: Sized + From<i32> + Mul<Self, Output=Self> {
    fn microseconds(self) -> PgInterval;

    fn milliseconds(self) -> PgInterval {
        (self * 1000.into()).microseconds()
    }

    fn seconds(self) -> PgInterval {
        (self * 1000.into()).milliseconds()
    }

    fn minutes(self) -> PgInterval {
        (self * 60.into()).seconds()
    }

    fn hours(self) -> PgInterval {
        (self * 60.into()).minutes()
    }

    fn microsecond(self) -> PgInterval {
        self.microseconds()
    }

    fn millisecond(self) -> PgInterval {
        self.milliseconds()
    }

    fn second(self) -> PgInterval {
        self.seconds()
    }

    fn minute(self) -> PgInterval {
        self.minutes()
    }

    fn hour(self) -> PgInterval {
        self.hours()
    }
}

pub trait DayAndMonthIntervalDsl: Sized + From<i32> + Mul<Self, Output=Self>  {
    fn days(self) -> PgInterval;
    fn months(self) -> PgInterval;

    fn weeks(self) -> PgInterval {
        (self * 7.into()).days()
    }

    fn years(self) -> PgInterval {
        (self * 12.into()).months()
    }

    fn day(self) -> PgInterval {
        self.days()
    }

    fn week(self) -> PgInterval {
        self.weeks()
    }

    fn month(self) -> PgInterval {
        self.months()
    }

    fn year(self) -> PgInterval {
        self.years()
    }
}

impl MicroIntervalDsl for i64 {
    fn microseconds(self) -> PgInterval {
        PgInterval::from_microseconds(self)
    }
}

impl MicroIntervalDsl for f64 {
    fn microseconds(self) -> PgInterval {
        (self.round() as i64).microseconds()
    }
}

impl DayAndMonthIntervalDsl for i32 {
    fn days(self) -> PgInterval {
        PgInterval::from_days(self)
    }

    fn months(self) -> PgInterval {
        PgInterval::from_months(self)
    }
}

impl DayAndMonthIntervalDsl for f64 {
    fn days(self) -> PgInterval {
        let fractional_days = (self.fract() * 86_400.0).seconds();
        PgInterval::from_days(self.trunc() as i32) + fractional_days
    }

    fn months(self) -> PgInterval {
        let fractional_months = (self.fract() * 30.0).days();
        PgInterval::from_months(self.trunc() as i32) + fractional_months
    }

    fn years(self) -> PgInterval {
        ((self * 12.0).trunc() as i32).months()
    }
}

#[cfg(test)]
mod tests {
    extern crate dotenv;
    extern crate quickcheck;
    use self::quickcheck::quickcheck;
    use super::*;
    use connection::Connection;
    use types;
    use types::structs::PgInterval;

    macro_rules! test_fn {
        ($tpe:ty, $test_name:ident, $units:ident) => {
            fn $test_name(val: $tpe) -> bool {
                let dotenv_path = ::std::env::current_dir()
                    .and_then(|a| Ok(a.join("../.env"))).unwrap();
                dotenv::from_path(dotenv_path.as_path()).ok();

                let connection_url = ::std::env::var("DATABASE_URL").ok()
                    .expect("DATABASE_URL must be set in order to run tests");
                let connection = Connection::establish(&connection_url).unwrap();

                let query = format!(concat!("SELECT '{} ", stringify!($units), "'::interval"), val);
                let res: PgInterval = connection.query_sql::<types::Interval, _>(&query)
                    .unwrap().nth(0).unwrap();
                let val = val.$units();
                val.months == res.months &&
                    val.days == res.days &&
                    (val.microseconds - res.microseconds).abs() <= 1
            }

            quickcheck($test_name as fn($tpe) -> bool);
        }
    }

    #[test]
    fn micro_intervals_match_pg_values_i64() {
        test_fn!(i64, test_microseconds, microseconds);
        test_fn!(i64, test_milliseconds, milliseconds);
        test_fn!(i64, test_seconds, seconds);
        test_fn!(i64, test_minutes, minutes);
        test_fn!(i64, test_hours, hours);
    }

    #[test]
    fn micro_intervals_match_pg_values_f64() {
        test_fn!(f64, test_microseconds, microseconds);
        test_fn!(f64, test_milliseconds, milliseconds);
        test_fn!(f64, test_seconds, seconds);
        test_fn!(f64, test_minutes, minutes);
        test_fn!(f64, test_hours, hours);
    }

    #[test]
    fn day_and_month_intervals_match_pg_values_i32() {
        test_fn!(i32, test_days, days);
        test_fn!(i32, test_weeks, weeks);
        test_fn!(i32, test_months, months);
        test_fn!(i32, test_years, years);
    }

    #[test]
    fn day_and_month_intervals_match_pg_values_f64() {
        test_fn!(f64, test_days, days);
        test_fn!(f64, test_weeks, weeks);
        test_fn!(f64, test_months, months);
        test_fn!(f64, test_years, years);
    }
}
<commit_msg>Add times fn to allow tests to build on stable and beta<commit_after>use std::ops::Mul;

use types::structs::PgInterval;

pub trait MicroIntervalDsl: Sized + Mul<Self, Output=Self> {
    fn microseconds(self) -> PgInterval;

    fn milliseconds(self) -> PgInterval {
        (self.times(1000)).microseconds()
    }

    fn seconds(self) -> PgInterval {
        (self.times(1000)).milliseconds()
    }

    fn minutes(self) -> PgInterval {
        (self.times(60)).seconds()
    }

    fn hours(self) -> PgInterval {
        (self.times(60)).minutes()
    }

    fn microsecond(self) -> PgInterval {
        self.microseconds()
    }

    fn millisecond(self) -> PgInterval {
        self.milliseconds()
    }

    fn second(self) -> PgInterval {
        self.seconds()
    }

    fn minute(self) -> PgInterval {
        self.minutes()
    }

    fn hour(self) -> PgInterval {
        self.hours()
    }

    fn times(self, x: i32) -> Self;
}

pub trait DayAndMonthIntervalDsl: Sized + Mul<Self, Output=Self>  {
    fn days(self) -> PgInterval;
    fn months(self) -> PgInterval;

    fn weeks(self) -> PgInterval {
        (self.times(7)).days()
    }

    fn years(self) -> PgInterval {
        (self.times(12)).months()
    }

    fn day(self) -> PgInterval {
        self.days()
    }

    fn week(self) -> PgInterval {
        self.weeks()
    }

    fn month(self) -> PgInterval {
        self.months()
    }

    fn year(self) -> PgInterval {
        self.years()
    }

    fn times(self, x: i32) -> Self;
}

impl MicroIntervalDsl for i64 {
    fn microseconds(self) -> PgInterval {
        PgInterval::from_microseconds(self)
    }

    fn times(self, x: i32) -> i64 {
        self * x as i64
    }
}

impl MicroIntervalDsl for f64 {
    fn microseconds(self) -> PgInterval {
        (self.round() as i64).microseconds()
    }

    fn times(self, x: i32) -> f64 {
        self * x as f64
    }
}

impl DayAndMonthIntervalDsl for i32 {
    fn days(self) -> PgInterval {
        PgInterval::from_days(self)
    }

    fn months(self) -> PgInterval {
        PgInterval::from_months(self)
    }

    fn times(self, x: i32) -> i32 {
        self * x as i32
    }
}

impl DayAndMonthIntervalDsl for f64 {
    fn days(self) -> PgInterval {
        let fractional_days = (self.fract() * 86_400.0).seconds();
        PgInterval::from_days(self.trunc() as i32) + fractional_days
    }

    fn months(self) -> PgInterval {
        let fractional_months = (self.fract() * 30.0).days();
        PgInterval::from_months(self.trunc() as i32) + fractional_months
    }

    fn years(self) -> PgInterval {
        ((self * 12.0).trunc() as i32).months()
    }

    fn times(self, x: i32) -> f64 {
        self * x as f64
    }
}

#[cfg(test)]
mod tests {
    extern crate dotenv;
    extern crate quickcheck;
    use self::quickcheck::quickcheck;
    use super::*;
    use connection::Connection;
    use types;
    use types::structs::PgInterval;

    macro_rules! test_fn {
        ($tpe:ty, $test_name:ident, $units:ident) => {
            fn $test_name(val: $tpe) -> bool {
                let dotenv_path = ::std::env::current_dir()
                    .and_then(|a| Ok(a.join("../.env"))).unwrap();
                dotenv::from_path(dotenv_path.as_path()).ok();

                let connection_url = ::std::env::var("DATABASE_URL").ok()
                    .expect("DATABASE_URL must be set in order to run tests");
                let connection = Connection::establish(&connection_url).unwrap();

                let query = format!(concat!("SELECT '{} ", stringify!($units), "'::interval"), val);
                let res: PgInterval = connection.query_sql::<types::Interval, _>(&query)
                    .unwrap().nth(0).unwrap();
                let val = val.$units();
                val.months == res.months &&
                    val.days == res.days &&
                    (val.microseconds - res.microseconds).abs() <= 1
            }

            quickcheck($test_name as fn($tpe) -> bool);
        }
    }

    #[test]
    fn micro_intervals_match_pg_values_i64() {
        test_fn!(i64, test_microseconds, microseconds);
        test_fn!(i64, test_milliseconds, milliseconds);
        test_fn!(i64, test_seconds, seconds);
        test_fn!(i64, test_minutes, minutes);
        test_fn!(i64, test_hours, hours);
    }

    #[test]
    fn micro_intervals_match_pg_values_f64() {
        test_fn!(f64, test_microseconds, microseconds);
        test_fn!(f64, test_milliseconds, milliseconds);
        test_fn!(f64, test_seconds, seconds);
        test_fn!(f64, test_minutes, minutes);
        test_fn!(f64, test_hours, hours);
    }

    #[test]
    fn day_and_month_intervals_match_pg_values_i32() {
        test_fn!(i32, test_days, days);
        test_fn!(i32, test_weeks, weeks);
        test_fn!(i32, test_months, months);
        test_fn!(i32, test_years, years);
    }

    #[test]
    fn day_and_month_intervals_match_pg_values_f64() {
        test_fn!(f64, test_days, days);
        test_fn!(f64, test_weeks, weeks);
        test_fn!(f64, test_months, months);
        test_fn!(f64, test_years, years);
    }
}
<|endoftext|>


<commit_before>use std::fmt;

use cards::card::{Card, Rank, Suit};

#[derive(Debug)]
pub struct Deck(pub Vec<Card>);

impl Deck {
    pub fn new() -> Deck {
        let mut cards: Vec<Card> = Vec::with_capacity(52);
        let ranks: Vec<Rank> = vec![Rank::Ace,
                                    Rank::Two,
                                    Rank::Three,
                                    Rank::Four,
                                    Rank::Five,
                                    Rank::Six,
                                    Rank::Seven,
                                    Rank::Eight,
                                    Rank::Nine,
                                    Rank::Ten,
                                    Rank::Jack,
                                    Rank::Queen,
                                    Rank::King];
        let suits: Vec<Suit> = vec![Suit::Clubs, Suit::Spades, Suit::Diamonds, Suit::Hearts];

        for suit in suits.into_iter() {
            for &rank in ranks.iter() {
                cards.push(Card { rank: rank, suit: suit });
            }
        }

        Deck(cards)
    }
}

impl fmt::Display for Deck {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        for card in self.0.iter() {
            write!(formatter, "\n{}", card)?;
        }

        write!(formatter, "")
    }
}<commit_msg>Finish deck module functions. Need to add tests.<commit_after>use std::fmt;

use rand::{self, Rng};

use cards::card::{Card, Rank, Suit};

#[derive(Debug)]
pub struct Deck(pub Vec<Card>);

impl Deck {
    pub fn new() -> Deck {
        let mut cards: Vec<Card> = Vec::with_capacity(52);
        let ranks: Vec<Rank> = vec![Rank::Ace,
                                    Rank::Two,
                                    Rank::Three,
                                    Rank::Four,
                                    Rank::Five,
                                    Rank::Six,
                                    Rank::Seven,
                                    Rank::Eight,
                                    Rank::Nine,
                                    Rank::Ten,
                                    Rank::Jack,
                                    Rank::Queen,
                                    Rank::King];
        let suits: Vec<Suit> = vec![Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spades];

        for suit in suits.into_iter() {
            for &rank in ranks.iter() {
                cards.push(Card {
                    rank: rank,
                    suit: suit,
                });
            }
        }

        Deck(cards)
    }
}

impl Deck {
    pub fn shuffle(&mut self) {
        let mut rng = rand::thread_rng();

        rng.shuffle(&mut self.0);
    }

    pub fn deal(&mut self) -> Option<Card> {
        self.0.pop()
    }
}

impl fmt::Display for Deck {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        for card in self.0.iter() {
            write!(formatter, "\n{}", card)?;
        }

        write!(formatter, "")
    }
}<|endoftext|>


<commit_before>//! Internal library for data-encoding-macro
//!
//! Do **not** use this library. Use [data-encoding-macro] instead.
//!
//! This library is for internal use by data-encoding-macro because procedural
//! macros require a separate crate.
//!
//! [data-encoding-macro]: https://crates.io/crates/data-encoding-macro

#![warn(unused_results)]

use proc_macro::token_stream::IntoIter;
use proc_macro::{TokenStream, TokenTree};
use std::collections::HashMap;

use data_encoding::{BitOrder, Encoding, Specification, Translate, Wrap};

fn parse_op(tokens: &mut IntoIter, op: char, key: &str) {
    match tokens.next() {
        Some(TokenTree::Punct(ref x)) if x.as_char() == op => (),
        _ => panic!("expected {:?} after {}", op, key),
    }
}

fn parse_map(mut tokens: IntoIter) -> HashMap<String, TokenTree> {
    let mut map = HashMap::new();
    while let Some(key) = tokens.next() {
        let key = match key {
            TokenTree::Ident(ident) => format!("{}", ident),
            _ => panic!("expected key got {}", key),
        };
        parse_op(&mut tokens, ':', &key);
        let value = match tokens.next() {
            None => panic!("expected value for {}", key),
            Some(value) => value,
        };
        parse_op(&mut tokens, ',', &key);
        let _ = map.insert(key, value);
    }
    map
}

fn get_string(map: &mut HashMap<String, TokenTree>, key: &str) -> String {
    let node = match map.remove(key) {
        None => return String::new(),
        Some(node) => node,
    };
    match syn::parse::<syn::LitStr>(node.into()) {
        Ok(result) => result.value(),
        _ => panic!("expected string for {}", key),
    }
}

fn get_usize(map: &mut HashMap<String, TokenTree>, key: &str) -> usize {
    let node = match map.remove(key) {
        None => return 0,
        Some(node) => node,
    };
    let literal = match node {
        TokenTree::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match literal.to_string().parse() {
        Ok(result) => result,
        Err(error) => panic!("expected usize for {}: {}", key, error),
    }
}

fn get_padding(map: &mut HashMap<String, TokenTree>) -> Option<char> {
    let node = match map.remove("padding") {
        None => return None,
        Some(node) => node,
    };
    if let Ok(result) = syn::parse::<syn::LitChar>(node.clone().into()) {
        return Some(result.value());
    }
    match syn::parse::<syn::Ident>(node.into()) {
        Ok(ref result) if result == "None" => None,
        _ => panic!("expected None or char for padding"),
    }
}

fn get_bool(map: &mut HashMap<String, TokenTree>, key: &str) -> Option<bool> {
    let node = match map.remove(key) {
        None => return None,
        Some(node) => node,
    };
    match syn::parse::<syn::LitBool>(node.into()) {
        Ok(result) => Some(result.value),
        _ => panic!("expected bool for padding"),
    }
}

fn get_bit_order(map: &mut HashMap<String, TokenTree>) -> BitOrder {
    let node = match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(node) => node,
    };
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match node {
        TokenTree::Ident(ref ident) if format!("{}", ident) == msb => {
            BitOrder::MostSignificantFirst
        }
        TokenTree::Ident(ref ident) if format!("{}", ident) == lsb => {
            BitOrder::LeastSignificantFirst
        }
        _ => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}

fn check_present<T>(hash_map: &HashMap<String, T>, key: &str) {
    if !hash_map.contains_key(key) {
        panic!("{} is required", key);
    }
}

fn get_encoding(mut hash_map: &mut HashMap<String, TokenTree>) -> Encoding {
    check_present(hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(&mut hash_map, "symbols"),
        bit_order: get_bit_order(&mut hash_map),
        check_trailing_bits: get_bool(&mut hash_map, "check_trailing_bits").unwrap_or(true),
        padding: get_padding(&mut hash_map),
        ignore: get_string(&mut hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(&mut hash_map, "wrap_width"),
            separator: get_string(&mut hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(&mut hash_map, "translate_from"),
            to: get_string(&mut hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}

fn check_empty<T>(hash_map: HashMap<String, T>) {
    if !hash_map.is_empty() {
        panic!("Unexpected keys {:?}", hash_map.keys());
    }
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_new_encoding(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_empty(hash_map);
    format!("{:?}", encoding.internal_implementation()).parse().unwrap()
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_array(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&hash_map, "name");
    let name = get_string(&mut hash_map, "name");
    check_present(&hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    let output = encoding.decode(input.as_bytes()).unwrap();
    format!("{}: [u8; {}] = {:?};", name, output.len(), output).parse().unwrap()
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_slice(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    format!("{:?}", encoding.decode(input.as_bytes()).unwrap()).parse().unwrap()
}
<commit_msg>lib/macro/internal: fix clippy warnings<commit_after>//! Internal library for data-encoding-macro
//!
//! Do **not** use this library. Use [data-encoding-macro] instead.
//!
//! This library is for internal use by data-encoding-macro because procedural
//! macros require a separate crate.
//!
//! [data-encoding-macro]: https://crates.io/crates/data-encoding-macro

#![warn(unused_results)]

use proc_macro::token_stream::IntoIter;
use proc_macro::{TokenStream, TokenTree};
use std::collections::HashMap;

use data_encoding::{BitOrder, Encoding, Specification, Translate, Wrap};

fn parse_op(tokens: &mut IntoIter, op: char, key: &str) {
    match tokens.next() {
        Some(TokenTree::Punct(ref x)) if x.as_char() == op => (),
        _ => panic!("expected {:?} after {}", op, key),
    }
}

fn parse_map(mut tokens: IntoIter) -> HashMap<String, TokenTree> {
    let mut map = HashMap::new();
    while let Some(key) = tokens.next() {
        let key = match key {
            TokenTree::Ident(ident) => format!("{}", ident),
            _ => panic!("expected key got {}", key),
        };
        parse_op(&mut tokens, ':', &key);
        let value = match tokens.next() {
            None => panic!("expected value for {}", key),
            Some(value) => value,
        };
        parse_op(&mut tokens, ',', &key);
        let _ = map.insert(key, value);
    }
    map
}

fn get_string(map: &mut HashMap<String, TokenTree>, key: &str) -> String {
    let node = match map.remove(key) {
        None => return String::new(),
        Some(node) => node,
    };
    match syn::parse::<syn::LitStr>(node.into()) {
        Ok(result) => result.value(),
        _ => panic!("expected string for {}", key),
    }
}

fn get_usize(map: &mut HashMap<String, TokenTree>, key: &str) -> usize {
    let node = match map.remove(key) {
        None => return 0,
        Some(node) => node,
    };
    let literal = match node {
        TokenTree::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match literal.to_string().parse() {
        Ok(result) => result,
        Err(error) => panic!("expected usize for {}: {}", key, error),
    }
}

fn get_padding(map: &mut HashMap<String, TokenTree>) -> Option<char> {
    let node = match map.remove("padding") {
        None => return None,
        Some(node) => node,
    };
    if let Ok(result) = syn::parse::<syn::LitChar>(node.clone().into()) {
        return Some(result.value());
    }
    match syn::parse::<syn::Ident>(node.into()) {
        Ok(ref result) if result == "None" => None,
        _ => panic!("expected None or char for padding"),
    }
}

fn get_bool(map: &mut HashMap<String, TokenTree>, key: &str) -> Option<bool> {
    let node = match map.remove(key) {
        None => return None,
        Some(node) => node,
    };
    match syn::parse::<syn::LitBool>(node.into()) {
        Ok(result) => Some(result.value),
        _ => panic!("expected bool for padding"),
    }
}

fn get_bit_order(map: &mut HashMap<String, TokenTree>) -> BitOrder {
    let node = match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(node) => node,
    };
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match node {
        TokenTree::Ident(ref ident) if format!("{}", ident) == msb => {
            BitOrder::MostSignificantFirst
        }
        TokenTree::Ident(ref ident) if format!("{}", ident) == lsb => {
            BitOrder::LeastSignificantFirst
        }
        _ => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}

fn check_present<T>(hash_map: &HashMap<String, T>, key: &str) {
    assert!(hash_map.contains_key(key), "{} is required", key);
}

fn get_encoding(hash_map: &mut HashMap<String, TokenTree>) -> Encoding {
    check_present(hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(hash_map, "symbols"),
        bit_order: get_bit_order(hash_map),
        check_trailing_bits: get_bool(hash_map, "check_trailing_bits").unwrap_or(true),
        padding: get_padding(hash_map),
        ignore: get_string(hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(hash_map, "wrap_width"),
            separator: get_string(hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(hash_map, "translate_from"),
            to: get_string(hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}

fn check_empty<T>(hash_map: HashMap<String, T>) {
    assert!(hash_map.is_empty(), "Unexpected keys {:?}", hash_map.keys());
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_new_encoding(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_empty(hash_map);
    format!("{:?}", encoding.internal_implementation()).parse().unwrap()
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_array(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&hash_map, "name");
    let name = get_string(&mut hash_map, "name");
    check_present(&hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    let output = encoding.decode(input.as_bytes()).unwrap();
    format!("{}: [u8; {}] = {:?};", name, output.len(), output).parse().unwrap()
}

#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_slice(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    format!("{:?}", encoding.decode(input.as_bytes()).unwrap()).parse().unwrap()
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::{str, ptr};
use std::ffi::{CStr, CString};
use std::thread;
use std::net::TcpStream;
use std::sync::mpsc::{channel, Sender, Receiver};

use super::libc::{c_int, c_char};
use super::simple_stream::bstream::Bstream;

extern "C" {
    fn register_writer_tx(tx: *mut Sender<Vec<u8>>);
    fn register_stop_tx(tx: *mut Sender<()>);
}

/// Connects to the provided address, (eg "123.123.123.123:3000") and registers
/// the on data received handler
#[no_mangle]
pub extern "C" fn connect(address: *const c_char,
    handler: extern fn(*const c_char, c_int),
    on_connect_handler: extern fn(),
    on_disconnect_handler: extern fn()) -> c_int {

    unsafe {
        on_connect_handler();
        on_disconnect_handler();
    }

    1 as c_int

    // let mut r_address;
    // unsafe {
    //     r_address = CStr::from_ptr(address);
    // }
    // let s_address = r_address.to_bytes();
    // let host_address = match str::from_utf8(s_address) {
    //     Ok(safe_str) => safe_str,
    //     Err(_) => {
    //         println!("Invalid host address");
    //         return -1 as c_int;
    //     }
    // };
    //
    // // Create and register a way to kill this client
    // let (k_tx, kill_rx): (Sender<()>, Receiver<()>) = channel();
    // let kill_tx = k_tx.clone();
    // let mut k_tx_ptr = Box::new(k_tx);
    // unsafe {
    //     register_stop_tx(&mut *k_tx_ptr);
    // }
    //
    // // Writer thread's channel
    // let (w_tx, w_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = channel();
    // let mut w_tx_ptr = Box::new(w_tx);
    // unsafe {
    //     register_writer_tx(&mut *w_tx_ptr);
    // }
    //
    // let result = TcpStream::connect(host_address);
    // if result.is_err() {
    //     println!("Error connecting to {} - {}", host_address, result.unwrap_err());
    //     return -1 as c_int;
    // }
    // println!("Connected");
    // on_connect_handler();
    //
    // let stream = result.unwrap();
    // let client = Bstream::new(stream);
    //
    // let r_client = client.clone();
    // let r_kill_tx = kill_tx.clone();
    //
    // let w_client = client.clone();
    // let w_kill_tx = kill_tx.clone();
    //
    // // Start the reader thread
    // thread::Builder::new()
    //     .name("ReaderThread".to_string())
    //     .spawn(move||{
    //         reader_thread(r_client, handler, r_kill_tx)
    //     }).unwrap();
    //
    // // Start the writer thread
    // thread::Builder::new()
    //     .name("WriterThread".to_string())
    //     .spawn(move||{
    //         writer_thread(w_rx, w_client, w_kill_tx)
    //     }).unwrap();
    //
    // // Wait for the kill signal
    // match kill_rx.recv() {
    //     Ok(_) => { }
    //     Err(e) => {
    //         println!("Error on kill channel: {}", e);
    //         return -1 as c_int;
    //     }
    // };
    // on_disconnect_handler();
    //
    // // Exit out in standard C fashion
    // 0 as c_int
}

/// Writes the complete contents of buffer to the server
/// Returns -1 on error
#[no_mangle]
pub extern "C" fn send_to_writer(w_tx: *mut Sender<Vec<u8>>,
                                 buffer: *const c_char,
                                 count: c_int,
                                 k_tx: *mut Sender<()>) -> c_int {
    if count < 1 {
        println!("Error - count must be greater than zero");
        return -1 as c_int;
    }

    let num_elts = count as usize;
    let mut n_buffer = Vec::<u8>::with_capacity(num_elts);
    for x in 0..num_elts as isize {
        unsafe {
            n_buffer.push(ptr::read(buffer.offset(x)) as u8);
        }
    }

    unsafe {
        match (*w_tx).send(n_buffer) {
            Ok(_) => { }
            Err(e) => {
                println!("Error sending buffer: {}", e);
                let _ = (*k_tx).send(());
                return -1 as c_int;
            }
        };
    }

    0 as c_int
}

/// Forever listens to incoming data and when a complete message is received,
/// the passed callback is hit
fn reader_thread(client: Bstream,
                 event_handler: extern fn(*const c_char, c_int),
                 kill_tx: Sender<()>) {

    let mut reader = client.clone();
    loop {
        match reader.read() {
            Ok(buffer) => {
                // Launch the handler in a new thread
                thread::Builder::new()
                    .name("Reader-Worker".to_string())
                    .spawn(move||{
                        let slice = &buffer[..];
                        let c_buffer = CString::new(slice).unwrap();
                        event_handler(c_buffer.as_ptr(), buffer.len() as c_int);
                    }).unwrap();
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Reader thread finished");
    let _ = kill_tx.send(());
}

/// Forever listens to Receiver<Vec<u8>> waiting on messages to come in
/// Once available, blocks until the entire message has been written
fn writer_thread(rx: Receiver<Vec<u8>>, client: Bstream, kill_tx: Sender<()>) {
    let mut writer = client.clone();
    loop {
        match rx.recv() {
            Ok(ref mut buffer) => {
                match writer.write(buffer) {
                    Ok(_) => { }
                    Err(e) => {
                        println!("Error: {}", e);
                        break;
                    }
                };
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Writer thread finished");
    let _ = kill_tx.send(());
}
<commit_msg>Debugging<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::{str, ptr};
use std::ffi::{CStr, CString};
use std::thread;
use std::net::TcpStream;
use std::sync::mpsc::{channel, Sender, Receiver};

use super::libc::{c_int, c_char};
use super::simple_stream::bstream::Bstream;

extern "C" {
    fn register_writer_tx(tx: *mut Sender<Vec<u8>>);
    fn register_stop_tx(tx: *mut Sender<()>);
}

/// Connects to the provided address, (eg "123.123.123.123:3000") and registers
/// the on data received handler
#[no_mangle]
pub extern "C" fn connect(address: *const c_char,
    handler: extern fn(*const c_char, c_int),
    on_connect_handler: extern fn(),
    on_disconnect_handler: extern fn()) -> c_int {

        let mut buffer = Vec::<u8>::with_capacity(2);
        buffer.push(65u8);
        buffer.push(65u8);

        let slice = &buffer[..];
        let c_buffer = CString::new(slice).unwrap();
        handler(c_buffer.as_ptr(), buffer.len() as c_int);

    unsafe {
        on_connect_handler();
        on_disconnect_handler();
        handler(c_buffer.as_ptr(), buffer.len() as c_int);
    }

    1 as c_int

    // let mut r_address;
    // unsafe {
    //     r_address = CStr::from_ptr(address);
    // }
    // let s_address = r_address.to_bytes();
    // let host_address = match str::from_utf8(s_address) {
    //     Ok(safe_str) => safe_str,
    //     Err(_) => {
    //         println!("Invalid host address");
    //         return -1 as c_int;
    //     }
    // };
    //
    // // Create and register a way to kill this client
    // let (k_tx, kill_rx): (Sender<()>, Receiver<()>) = channel();
    // let kill_tx = k_tx.clone();
    // let mut k_tx_ptr = Box::new(k_tx);
    // unsafe {
    //     register_stop_tx(&mut *k_tx_ptr);
    // }
    //
    // // Writer thread's channel
    // let (w_tx, w_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = channel();
    // let mut w_tx_ptr = Box::new(w_tx);
    // unsafe {
    //     register_writer_tx(&mut *w_tx_ptr);
    // }
    //
    // let result = TcpStream::connect(host_address);
    // if result.is_err() {
    //     println!("Error connecting to {} - {}", host_address, result.unwrap_err());
    //     return -1 as c_int;
    // }
    // println!("Connected");
    // on_connect_handler();
    //
    // let stream = result.unwrap();
    // let client = Bstream::new(stream);
    //
    // let r_client = client.clone();
    // let r_kill_tx = kill_tx.clone();
    //
    // let w_client = client.clone();
    // let w_kill_tx = kill_tx.clone();
    //
    // // Start the reader thread
    // thread::Builder::new()
    //     .name("ReaderThread".to_string())
    //     .spawn(move||{
    //         reader_thread(r_client, handler, r_kill_tx)
    //     }).unwrap();
    //
    // // Start the writer thread
    // thread::Builder::new()
    //     .name("WriterThread".to_string())
    //     .spawn(move||{
    //         writer_thread(w_rx, w_client, w_kill_tx)
    //     }).unwrap();
    //
    // // Wait for the kill signal
    // match kill_rx.recv() {
    //     Ok(_) => { }
    //     Err(e) => {
    //         println!("Error on kill channel: {}", e);
    //         return -1 as c_int;
    //     }
    // };
    // on_disconnect_handler();
    //
    // // Exit out in standard C fashion
    // 0 as c_int
}

/// Writes the complete contents of buffer to the server
/// Returns -1 on error
#[no_mangle]
pub extern "C" fn send_to_writer(w_tx: *mut Sender<Vec<u8>>,
                                 buffer: *const c_char,
                                 count: c_int,
                                 k_tx: *mut Sender<()>) -> c_int {
    if count < 1 {
        println!("Error - count must be greater than zero");
        return -1 as c_int;
    }

    let num_elts = count as usize;
    let mut n_buffer = Vec::<u8>::with_capacity(num_elts);
    for x in 0..num_elts as isize {
        unsafe {
            n_buffer.push(ptr::read(buffer.offset(x)) as u8);
        }
    }

    unsafe {
        match (*w_tx).send(n_buffer) {
            Ok(_) => { }
            Err(e) => {
                println!("Error sending buffer: {}", e);
                let _ = (*k_tx).send(());
                return -1 as c_int;
            }
        };
    }

    0 as c_int
}

/// Forever listens to incoming data and when a complete message is received,
/// the passed callback is hit
fn reader_thread(client: Bstream,
                 event_handler: extern fn(*const c_char, c_int),
                 kill_tx: Sender<()>) {

    let mut reader = client.clone();
    loop {
        match reader.read() {
            Ok(buffer) => {
                // Launch the handler in a new thread
                thread::Builder::new()
                    .name("Reader-Worker".to_string())
                    .spawn(move||{
                        let slice = &buffer[..];
                        let c_buffer = CString::new(slice).unwrap();
                        event_handler(c_buffer.as_ptr(), buffer.len() as c_int);
                    }).unwrap();
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Reader thread finished");
    let _ = kill_tx.send(());
}

/// Forever listens to Receiver<Vec<u8>> waiting on messages to come in
/// Once available, blocks until the entire message has been written
fn writer_thread(rx: Receiver<Vec<u8>>, client: Bstream, kill_tx: Sender<()>) {
    let mut writer = client.clone();
    loop {
        match rx.recv() {
            Ok(ref mut buffer) => {
                match writer.write(buffer) {
                    Ok(_) => { }
                    Err(e) => {
                        println!("Error: {}", e);
                        break;
                    }
                };
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Writer thread finished");
    let _ = kill_tx.send(());
}
<|endoftext|>


<commit_before>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::{str, ptr};
use std::ffi::{CStr, CString};
use std::thread;
use std::net::TcpStream;
use std::sync::mpsc::{channel, Sender, Receiver};

use super::libc::{c_int, c_char};
use super::simple_stream::bstream::Bstream;

extern "C" {
    fn register_writer_tx(tx: *mut Sender<Vec<u8>>);
    fn register_stop_tx(tx: *mut Sender<()>);
}

/// Connects to the provided address, (eg "123.123.123.123:3000") and registers
/// the on data received handler
#[no_mangle]
pub extern "C" fn connect(address: *const c_char,
    handler: extern fn(*const c_char, c_int),
    on_connect_handler: extern fn(),
    on_disconnect_handler: extern fn()) -> c_int {

    let mut r_address;
    unsafe {
        r_address = CStr::from_ptr(address);
    }
    let s_address = r_address.to_bytes();
    let host_address = match str::from_utf8(s_address) {
        Ok(safe_str) => safe_str,
        Err(_) => {
            println!("Invalid host address");
            return -1 as c_int;
        }
    };

    // Create and register a way to kill this client
    let (k_tx, kill_rx): (Sender<()>, Receiver<()>) = channel();
    let kill_tx = k_tx.clone();
    let mut k_tx_ptr = Box::new(k_tx);
    unsafe {
        register_stop_tx(&mut *k_tx_ptr);
    }

    // Writer thread's channel
    let (w_tx, w_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = channel();
    let mut w_tx_ptr = Box::new(w_tx);
    unsafe {
        register_writer_tx(&mut *w_tx_ptr);
    }

    let result = TcpStream::connect(host_address);
    if result.is_err() {
        println!("Error connecting to {} - {}", host_address, result.unwrap_err());
        return -1 as c_int;
    }
    println!("Connected");
    on_connect_handler();

    let stream = result.unwrap();
    let client = Bstream::new(stream);

    let r_client = client.clone();
    let r_kill_tx = kill_tx.clone();

    let w_client = client.clone();
    let w_kill_tx = kill_tx.clone();

    // Start the reader thread
    thread::Builder::new()
        .name("ReaderThread".to_string())
        .spawn(move||{
            reader_thread(r_client, handler, r_kill_tx)
        }).unwrap();

    // Start the writer thread
    thread::Builder::new()
        .name("WriterThread".to_string())
        .spawn(move||{
            writer_thread(w_rx, w_client, w_kill_tx)
        }).unwrap();

    // Wait for the kill signal
    match kill_rx.recv() {
        Ok(_) => { }
        Err(e) => {
            println!("Error on kill channel: {}", e);
            return -1 as c_int;
        }
    };
    on_disconnect_handler();

    // Exit out in standard C fashion
    0 as c_int
}

/// Writes the complete contents of buffer to the server
/// Returns -1 on error
#[no_mangle]
pub extern "C" fn send_to_writer(w_tx: *mut Sender<Vec<u8>>,
                                 buffer: *const c_char,
                                 count: c_int,
                                 k_tx: *mut Sender<()>) -> c_int {
    if count < 1 {
        println!("Error - count must be greater than zero");
        return -1 as c_int;
    }

    let num_elts = count as usize;
    let mut n_buffer = Vec::<u8>::with_capacity(num_elts);
    for x in 0..num_elts as isize {
        unsafe {
            n_buffer.push(ptr::read(buffer.offset(x)) as u8);
        }
    }

    unsafe {
        match (*w_tx).send(n_buffer) {
            Ok(_) => { }
            Err(e) => {
                println!("Error sending buffer: {}", e);
                let _ = (*k_tx).send(());
                return -1 as c_int;
            }
        };
    }

    0 as c_int
}

/// Forever listens to incoming data and when a complete message is received,
/// the passed callback is hit
fn reader_thread(client: Bstream,
                 event_handler: extern fn(*const c_char, c_int),
                 kill_tx: Sender<()>) {

    let mut reader = client.clone();
    loop {
        match reader.read() {
            Ok(buffer) => {
                // Launch the handler in a new thread
                thread::Builder::new()
                    .name("Reader-Worker".to_string())
                    .spawn(move||{
                        let slice = &buffer[..];
                        let c_buffer = CString::new(slice).unwrap();
                        event_handler(c_buffer.as_ptr(), buffer.len() as c_int);
                    }).unwrap();
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Reader thread finished");
    let _ = kill_tx.send(());
}

/// Forever listens to Receiver<Vec<u8>> waiting on messages to come in
/// Once available, blocks until the entire message has been written
fn writer_thread(rx: Receiver<Vec<u8>>, client: Bstream, kill_tx: Sender<()>) {
    let mut writer = client.clone();
    loop {
        match rx.recv() {
            Ok(ref mut buffer) => {
                match writer.write(buffer) {
                    Ok(_) => { }
                    Err(e) => {
                        println!("Error: {}", e);
                        break;
                    }
                };
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Writer thread finished");
    let _ = kill_tx.send(());
}
<commit_msg>Debugging stuff<commit_after>// Copyright 2015 Nathan Sizemore <nathanrsizemore@gmail.com>
//
// This Source Code Form is subject to the
// terms of the Mozilla Public License, v.
// 2.0. If a copy of the MPL was not
// distributed with this file, You can
// obtain one at
// http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible
// With Secondary Licenses", as defined by
// the Mozilla Public License, v. 2.0.

use std::{str, ptr};
use std::ffi::{CStr, CString};
use std::thread;
use std::net::TcpStream;
use std::sync::mpsc::{channel, Sender, Receiver};

use super::libc::{c_int, c_char};
use super::simple_stream::bstream::Bstream;

extern "C" {
    fn register_writer_tx(tx: *mut Sender<Vec<u8>>);
    fn register_stop_tx(tx: *mut Sender<()>);
}

/// Connects to the provided address, (eg "123.123.123.123:3000") and registers
/// the on data received handler
#[no_mangle]
pub extern "C" fn connect(address: *const c_char,
    handler: extern fn(*const c_char, c_int),
    on_connect_handler: extern fn(),
    on_disconnect_handler: extern fn()) -> c_int {

    1 as c_int;

    // let mut r_address;
    // unsafe {
    //     r_address = CStr::from_ptr(address);
    // }
    // let s_address = r_address.to_bytes();
    // let host_address = match str::from_utf8(s_address) {
    //     Ok(safe_str) => safe_str,
    //     Err(_) => {
    //         println!("Invalid host address");
    //         return -1 as c_int;
    //     }
    // };
    //
    // // Create and register a way to kill this client
    // let (k_tx, kill_rx): (Sender<()>, Receiver<()>) = channel();
    // let kill_tx = k_tx.clone();
    // let mut k_tx_ptr = Box::new(k_tx);
    // unsafe {
    //     register_stop_tx(&mut *k_tx_ptr);
    // }
    //
    // // Writer thread's channel
    // let (w_tx, w_rx): (Sender<Vec<u8>>, Receiver<Vec<u8>>) = channel();
    // let mut w_tx_ptr = Box::new(w_tx);
    // unsafe {
    //     register_writer_tx(&mut *w_tx_ptr);
    // }
    //
    // let result = TcpStream::connect(host_address);
    // if result.is_err() {
    //     println!("Error connecting to {} - {}", host_address, result.unwrap_err());
    //     return -1 as c_int;
    // }
    // println!("Connected");
    // on_connect_handler();
    //
    // let stream = result.unwrap();
    // let client = Bstream::new(stream);
    //
    // let r_client = client.clone();
    // let r_kill_tx = kill_tx.clone();
    //
    // let w_client = client.clone();
    // let w_kill_tx = kill_tx.clone();
    //
    // // Start the reader thread
    // thread::Builder::new()
    //     .name("ReaderThread".to_string())
    //     .spawn(move||{
    //         reader_thread(r_client, handler, r_kill_tx)
    //     }).unwrap();
    //
    // // Start the writer thread
    // thread::Builder::new()
    //     .name("WriterThread".to_string())
    //     .spawn(move||{
    //         writer_thread(w_rx, w_client, w_kill_tx)
    //     }).unwrap();
    //
    // // Wait for the kill signal
    // match kill_rx.recv() {
    //     Ok(_) => { }
    //     Err(e) => {
    //         println!("Error on kill channel: {}", e);
    //         return -1 as c_int;
    //     }
    // };
    // on_disconnect_handler();
    //
    // // Exit out in standard C fashion
    // 0 as c_int
}

/// Writes the complete contents of buffer to the server
/// Returns -1 on error
#[no_mangle]
pub extern "C" fn send_to_writer(w_tx: *mut Sender<Vec<u8>>,
                                 buffer: *const c_char,
                                 count: c_int,
                                 k_tx: *mut Sender<()>) -> c_int {
    if count < 1 {
        println!("Error - count must be greater than zero");
        return -1 as c_int;
    }

    let num_elts = count as usize;
    let mut n_buffer = Vec::<u8>::with_capacity(num_elts);
    for x in 0..num_elts as isize {
        unsafe {
            n_buffer.push(ptr::read(buffer.offset(x)) as u8);
        }
    }

    unsafe {
        match (*w_tx).send(n_buffer) {
            Ok(_) => { }
            Err(e) => {
                println!("Error sending buffer: {}", e);
                let _ = (*k_tx).send(());
                return -1 as c_int;
            }
        };
    }

    0 as c_int
}

/// Forever listens to incoming data and when a complete message is received,
/// the passed callback is hit
fn reader_thread(client: Bstream,
                 event_handler: extern fn(*const c_char, c_int),
                 kill_tx: Sender<()>) {

    let mut reader = client.clone();
    loop {
        match reader.read() {
            Ok(buffer) => {
                // Launch the handler in a new thread
                thread::Builder::new()
                    .name("Reader-Worker".to_string())
                    .spawn(move||{
                        let slice = &buffer[..];
                        let c_buffer = CString::new(slice).unwrap();
                        event_handler(c_buffer.as_ptr(), buffer.len() as c_int);
                    }).unwrap();
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Reader thread finished");
    let _ = kill_tx.send(());
}

/// Forever listens to Receiver<Vec<u8>> waiting on messages to come in
/// Once available, blocks until the entire message has been written
fn writer_thread(rx: Receiver<Vec<u8>>, client: Bstream, kill_tx: Sender<()>) {
    let mut writer = client.clone();
    loop {
        match rx.recv() {
            Ok(ref mut buffer) => {
                match writer.write(buffer) {
                    Ok(_) => { }
                    Err(e) => {
                        println!("Error: {}", e);
                        break;
                    }
                };
            }
            Err(e) => {
                println!("Error: {}", e);
                break;
            }
        };
    }
    println!("Writer thread finished");
    let _ = kill_tx.send(());
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate groonga_sys as ffi;

use std::ffi::CStr;
use std::str;
use std::path::Path;
use std::ptr;
use std::mem;
use std::result::Result::{Ok, Err};
use ffi::groonga;

macro_rules! convert_cstr_to_str {
    ($cstr:expr) => {
        {
            let slice = CStr::from_ptr($cstr);
            let result = str::from_utf8(slice.to_bytes());
            match result {
                Ok(v) => return v,
                Err(_) => return "",
            }
        }
    };
}

pub fn groonga_init() -> libc::c_int {
    unsafe {
        return groonga::grn_init();
    }
}

pub fn groonga_fin() -> libc::c_int {
    unsafe {
        return groonga::grn_fin();
    }
}

pub fn groonga_ctx_open(rc: libc::c_int) -> *mut groonga::grn_ctx {
    unsafe {
        return groonga::grn_ctx_open(rc);
    }
}

pub fn groonga_ctx_close(ctx: *mut groonga::grn_ctx) -> libc::c_int {
    unsafe {
        return groonga::grn_ctx_close(ctx);
    }
}

pub fn groonga_db_use(ctx: *mut groonga::grn_ctx, dbpath: &str) -> *mut groonga::grn_obj {
    unsafe {
        let c_dbpath = convert_str_to_cstr(dbpath);
        let path = Path::new(dbpath);
        let path_displayable = path.display();
        let db_ctx;
        if path.exists() {
            println!("{} exists. Creating db is skipped.", path_displayable);
            db_ctx = groonga::grn_db_open(ctx, c_dbpath);
        } else {
            db_ctx = groonga::grn_db_create(ctx, c_dbpath, ::std::mem::zeroed());
        };
        return db_ctx;
    }
}

pub fn groonga_execute_command(ctx: *mut groonga::grn_ctx,
                               command: &str)
                               -> Result<String, String> {
    unsafe {
        let command_length = command.len() as u32;
        let c_command = convert_str_to_cstr(command);
        let flag = 0;
        let _ = groonga::grn_ctx_send(ctx, c_command, command_length, flag);
        let mut output_ptr: *mut libc::c_char = ptr::null_mut();
        let received_len: *mut libc::c_uint =
            libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut libc::c_uint;
        let received_flag: *mut libc::c_int =
            libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut libc::c_int;
        let _ = groonga::grn_ctx_recv(ctx, &mut output_ptr, received_len, received_flag);
        if output_ptr.is_null() {
            return Err("Couldn't get result.".to_string());
        }
        let out = CStr::from_ptr(&mut *output_ptr).to_string_lossy().into_owned();
        libc::free(received_len as *mut libc::c_void);
        libc::free(received_flag as *mut libc::c_void);
        return Ok(out);
    }
}

pub fn get_groonga_version() -> &'static str {
    unsafe {
        return convert_cstr_to_str!(groonga::grn_get_version());
    }
}

pub fn convert_str_to_cstr(s: &str) -> *mut libc::c_char {
    let string = s.to_string();
    let bytes = string.into_bytes();
    let mut x: Vec<libc::c_char> = bytes.into_iter().map(|w| w as libc::c_char).collect();
    let slice = x.as_mut_slice();
    return slice.as_mut_ptr();
}
<commit_msg>Simplify to construct *mut c_char manupilation<commit_after>extern crate libc;
extern crate groonga_sys as ffi;

use std::ffi::{CString, CStr};
use std::str;
use std::path::Path;
use std::ptr;
use std::mem;
use std::result::Result::{Ok, Err};
use ffi::groonga;

macro_rules! convert_cstr_to_str {
    ($cstr:expr) => {
        {
            let slice = CStr::from_ptr($cstr);
            let result = str::from_utf8(slice.to_bytes());
            match result {
                Ok(v) => return v,
                Err(_) => return "",
            }
        }
    };
}

pub fn groonga_init() -> libc::c_int {
    unsafe {
        return groonga::grn_init();
    }
}

pub fn groonga_fin() -> libc::c_int {
    unsafe {
        return groonga::grn_fin();
    }
}

pub fn groonga_ctx_open(rc: libc::c_int) -> *mut groonga::grn_ctx {
    unsafe {
        return groonga::grn_ctx_open(rc);
    }
}

pub fn groonga_ctx_close(ctx: *mut groonga::grn_ctx) -> libc::c_int {
    unsafe {
        return groonga::grn_ctx_close(ctx);
    }
}

pub fn groonga_db_use(ctx: *mut groonga::grn_ctx, dbpath: &str) -> *mut groonga::grn_obj {
    unsafe {
        let c_dbpath = convert_str_to_cstr(dbpath);
        let path = Path::new(dbpath);
        let path_displayable = path.display();
        let db_ctx;
        if path.exists() {
            println!("{} exists. Creating db is skipped.", path_displayable);
            db_ctx = groonga::grn_db_open(ctx, c_dbpath);
        } else {
            db_ctx = groonga::grn_db_create(ctx, c_dbpath, ::std::mem::zeroed());
        };
        return db_ctx;
    }
}

pub fn groonga_execute_command(ctx: *mut groonga::grn_ctx,
                               command: &str)
                               -> Result<String, String> {
    unsafe {
        let command_length = command.len() as u32;
        let c_command = convert_str_to_cstr(command);
        let flag = 0;
        let _ = groonga::grn_ctx_send(ctx, c_command, command_length, flag);
        let mut output_ptr: *mut libc::c_char = ptr::null_mut();
        let received_len: *mut libc::c_uint =
            libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut libc::c_uint;
        let received_flag: *mut libc::c_int =
            libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut libc::c_int;
        let _ = groonga::grn_ctx_recv(ctx, &mut output_ptr, received_len, received_flag);
        if output_ptr.is_null() {
            return Err("Couldn't get result.".to_string());
        }
        let out = CStr::from_ptr(&mut *output_ptr).to_string_lossy().into_owned();
        libc::free(received_len as *mut libc::c_void);
        libc::free(received_flag as *mut libc::c_void);
        return Ok(out);
    }
}

pub fn get_groonga_version() -> &'static str {
    unsafe {
        return convert_cstr_to_str!(groonga::grn_get_version());
    }
}

pub fn convert_str_to_cstr(s: &str) -> *mut libc::c_char {
    let cstr = CString::new(s).unwrap();
    let ptr = cstr.into_raw();
    return ptr;
}
<|endoftext|>


<commit_before>use std::env;
use std::path::{PathBuf, Path};

fn main() {
    let target = env::var("TARGET").unwrap();
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    let mut lib_dir = manifest_dir.clone();
    let mut dll_dir = manifest_dir.clone();
    if target == "x86_64-pc-windows-msvc" {
        lib_dir.push("msvc");
        lib_dir.push("lib");
        lib_dir.push("64");
        dll_dir.push("msvc");
        dll_dir.push("dll");
        dll_dir.push("64");
    }
    else if target == "x86_64-pc-windows-gnu" {
        lib_dir.push("gnu");
        lib_dir.push("lib");
        lib_dir.push("64");
        dll_dir.push("gnu");
        dll_dir.push("dll");
        dll_dir.push("64");
    }
    else if target == "i686-pc-windows-msvc" {
        lib_dir.push("msvc");
        lib_dir.push("lib");
        lib_dir.push("32");
        dll_dir.push("msvc");
        dll_dir.push("dll");
        dll_dir.push("32");
    }
    else if target == "i686-pc-windows-gnu" {
        lib_dir.push("gnu");
        lib_dir.push("lib");
        lib_dir.push("32");
        dll_dir.push("gnu");
        dll_dir.push("dll");
        dll_dir.push("32");
    }
    if target.contains("pc-windows") {
        println!("cargo:rustc-link-search=static={}", lib_dir.display());
        for entry in std::fs::read_dir(dll_dir).expect("Can't read DLL dir")  {
            let entry_path = entry.expect("Invalid fs entry").path();
            let file_name_result = entry_path.file_name();
            let mut new_file_path = manifest_dir.clone();
            if let Some(file_name) = file_name_result {
                new_file_path.push(file_name.to_str().unwrap());
                std::fs::copy(&entry_path, new_file_path.as_path()).expect("Can't copy from DLL dir");
            }
        }
    }
}
<commit_msg>Fix gnu path<commit_after>use std::env;
use std::path::PathBuf;

fn main() {
    let target = env::var("TARGET").unwrap();
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    let mut lib_dir = manifest_dir.clone();
    let mut dll_dir = manifest_dir.clone();
    if target == "x86_64-pc-windows-msvc" {
        lib_dir.push("msvc");
        lib_dir.push("lib");
        lib_dir.push("64");
        dll_dir.push("msvc");
        dll_dir.push("dll");
        dll_dir.push("64");
    }
    else if target == "x86_64-pc-windows-gnu" {
        lib_dir.push("gnu-mingw");
        lib_dir.push("lib");
        lib_dir.push("64");
        dll_dir.push("gnu-mingw");
        dll_dir.push("dll");
        dll_dir.push("64");
    }
    else if target == "i686-pc-windows-msvc" {
        lib_dir.push("msvc");
        lib_dir.push("lib");
        lib_dir.push("32");
        dll_dir.push("msvc");
        dll_dir.push("dll");
        dll_dir.push("32");
    }
    else if target == "i686-pc-windows-gnu" {
        lib_dir.push("gnu-mingw");
        lib_dir.push("lib");
        lib_dir.push("32");
        dll_dir.push("gnu-mingw");
        dll_dir.push("dll");
        dll_dir.push("32");
    }
    if target.contains("pc-windows") {
        println!("cargo:rustc-link-search=static={}", lib_dir.display());
        for entry in std::fs::read_dir(dll_dir).expect("Can't read DLL dir")  {
            let entry_path = entry.expect("Invalid fs entry").path();
            let file_name_result = entry_path.file_name();
            let mut new_file_path = manifest_dir.clone();
            if let Some(file_name) = file_name_result {
                new_file_path.push(file_name.to_str().unwrap());
                std::fs::copy(&entry_path, new_file_path.as_path()).expect("Can't copy from DLL dir");
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::path::PathBuf;
use std::fs::metadata;
use std::process::Command;

fn get_path() -> Option<String> {
    for (key, val) in env::vars() {
        if key == "PATH" {
            return Some(val)
        }
    }
    None
}

fn get_matlab_path(ml_output: &str) -> Option<&str> {
    for line in ml_output.split("\n") {
        let mut it = line.split("=");
        match (it.next(), it.next()) {
            (Some("LD_LIBRARY_PATH"), Some(p)) => {
                return Some(p)
            },
            _ => {
            },
        }
    }
    None
}

fn main() {
    let mut matched = false;

    for (key, val) in env::vars() {
        match (&key[..], &val[..], matched) {
            ("MATLAB_LIB_PATH", _, true) |
                ("OCTAVE_LIB_PATH", _, true) => {
                    panic!("Please specify only MATLAB_LIB_PATH or OCTAVE_LIB_PATH");
            },
            ("MATLAB_LIB_PATH", path, false) => {
                println!("cargo:rustc-link-search={}", path);
                println!("cargo:rustc-cfg=matlab");
                matched = true;
            },
            ("OCTAVE_LIB_PATH", path, false) => {
                println!("cargo:rustc-link-search={}", path);
                println!("cargo:rustc-cfg=octave");
                matched = true;
            },
            _ => { }
        };
    }

    if let (Some(path), false) = (get_path(), matched) {
        for path_item in path.split(":") {
            // look for octave-config
            let mut oct_path = PathBuf::from(path_item);
            oct_path.push("octave-config");
            if let Ok(_) = metadata(&oct_path) {
                if let Ok(output) = Command::new(&oct_path).arg("--print").arg("OCTLIBDIR").output() {
                    if let Ok(txt) = String::from_utf8(output.stdout) {
                        println!("cargo:rustc-link-search={}", txt);
                        println!("cargo:rustc-cfg=octave");
                        matched = true;
                    }
                }
            }

            if matched  {
                break;
            }

            // look for matlab
            let mut matlab_path = PathBuf::from(path_item);
            matlab_path.push("matlab");
            if let Ok(_) = metadata(&matlab_path) {
                if let Ok(output) = Command::new(&matlab_path).arg("-e").output() {
                    if let Ok(txt) = String::from_utf8(output.stdout) {
                        if let Some(p) = get_matlab_path(&txt) {
                            println!("cargo:rustc-link-search={}", p);
                            println!("cargo:rustc-cfg=matlab");
                            matched = true;
                        }
                    }
                }
            }
        }
    }

    if !matched {
        panic!("Please set either MATLAB_LIB_PATH or OCTAVE_LIB_PATH");
    }
}

<commit_msg>hacks around weird matlab setup<commit_after>use std::env;
use std::path::PathBuf;
use std::fs::metadata;
use std::process::Command;

fn get_path() -> Option<String> {
    for (key, val) in env::vars() {
        if key == "PATH" {
            return Some(val)
        }
    }
    None
}

fn get_matlab_path(ml_output: &str) -> Option<&str> {
    for line in ml_output.split("\n") {
        let mut it = line.split("=");
        match (it.next(), it.next()) {
            (Some("MATLAB"), Some(p)) => {
                return Some(p)
            },
            _ => {
            },
        }
    }
    None
}

fn main() {
    let mut matched = false;

    for (key, val) in env::vars() {
        match (&key[..], &val[..], matched) {
            ("MATLAB_LIB_PATH", _, true) |
                ("OCTAVE_LIB_PATH", _, true) => {
                    panic!("Please specify only MATLAB_LIB_PATH or OCTAVE_LIB_PATH");
            },
            ("MATLAB_LIB_PATH", path, false) => {
                println!("cargo:rustc-link-search={}", path);
                println!("cargo:rustc-cfg=matlab");
                matched = true;
            },
            ("OCTAVE_LIB_PATH", path, false) => {
                println!("cargo:rustc-link-search={}", path);
                println!("cargo:rustc-cfg=octave");
                matched = true;
            },
            _ => { }
        };
    }

    if let (Some(path), false) = (get_path(), matched) {
        for path_item in path.split(":") {
            // look for octave-config
            let mut oct_path = PathBuf::from(path_item);
            oct_path.push("octave-config");
            if let Ok(_) = metadata(&oct_path) {
                if let Ok(output) = Command::new(&oct_path).arg("--print").arg("OCTLIBDIR").output() {
                    if let Ok(txt) = String::from_utf8(output.stdout) {
                        println!("cargo:rustc-link-search={}", txt);
                        println!("cargo:rustc-cfg=octave");
                        matched = true;
                    }
                }
            }

            if matched  {
                break;
            }

            // look for matlab
            let mut matlab_path = PathBuf::from(path_item);
            matlab_path.push("matlab");
            if let Ok(_) = metadata(&matlab_path) {
                if let Ok(output) = Command::new(&matlab_path).arg("-e").output() {
                    if let Ok(txt) = String::from_utf8(output.stdout) {
                        if let Some(p) = get_matlab_path(&txt) {
                            println!("cargo:rustc-link-search={}/bin/glnxa64/", p);
                            println!("cargo:rustc-cfg=matlab");
                            matched = true;
                        }
                    }
                }
            }
        }
    }

    if !matched {
        panic!("Please set either MATLAB_LIB_PATH or OCTAVE_LIB_PATH");
    }
}

<|endoftext|>


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

#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
extern crate proc_macro2;

use std::env;
use std::path::Path;

#[cfg(feature = "dummy_match_byte")]
mod codegen {
    use std::path::Path;
    pub fn main() {}
}

#[cfg(not(feature = "dummy_match_byte"))]
#[path = "build/match_byte.rs"]
mod match_byte;

#[cfg(not(feature = "dummy_match_byte"))]
mod codegen {
    use match_byte;
    use std::env;
    use std::path::Path;
    use std::thread::Builder;

    pub fn main() {
        let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

        let input = Path::new(&manifest_dir).join("src/tokenizer.rs");
        let output = Path::new(&env::var("OUT_DIR").unwrap()).join("tokenizer.rs");
        println!("cargo:rerun-if-changed={}", input.display());

        // We have stack overflows on Servo's CI.
        let handle = Builder::new().stack_size(128 * 1024 * 1024).spawn(move || {
            match_byte::expand(&input, &output);
        }).unwrap();

        handle.join().unwrap();
    }
}

fn main() {
    if std::mem::size_of::<Option<bool>>() == 1 {
        // https://github.com/rust-lang/rust/pull/45225
        println!("cargo:rustc-cfg=rustc_has_pr45225")
    }

    codegen::main();
}
<commit_msg>Auto merge of #231 - servo:build-rs-warn, r=SimonSapin<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
extern crate proc_macro2;

#[cfg(feature = "dummy_match_byte")]
mod codegen {
    use std::path::Path;
    pub fn main() {}
}

#[cfg(not(feature = "dummy_match_byte"))]
#[path = "build/match_byte.rs"]
mod match_byte;

#[cfg(not(feature = "dummy_match_byte"))]
mod codegen {
    use match_byte;
    use std::env;
    use std::path::Path;
    use std::thread::Builder;

    pub fn main() {
        let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

        let input = Path::new(&manifest_dir).join("src/tokenizer.rs");
        let output = Path::new(&env::var("OUT_DIR").unwrap()).join("tokenizer.rs");
        println!("cargo:rerun-if-changed={}", input.display());

        // We have stack overflows on Servo's CI.
        let handle = Builder::new().stack_size(128 * 1024 * 1024).spawn(move || {
            match_byte::expand(&input, &output);
        }).unwrap();

        handle.join().unwrap();
    }
}

fn main() {
    if std::mem::size_of::<Option<bool>>() == 1 {
        // https://github.com/rust-lang/rust/pull/45225
        println!("cargo:rustc-cfg=rustc_has_pr45225")
    }

    codegen::main();
}
<|endoftext|>


<commit_before>extern crate syn;
extern crate walkdir;

use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use syn::visit::Visitor;

fn main() {
    // Parse all .rs files to collect everything which implements Command.
    // This code won't work properly with lib.rs or mod.rs.
    let mut commands = Vec::new();

    for entry in walkdir::WalkDir::new("src")
            .into_iter()
            .filter_map(|e| e.ok())
            .filter(|e| !e.file_type().is_dir()) {
        let mut path = String::new();

        for name in entry.path().with_extension("").iter().skip(1) {
            path.push_str(&format!("::{}", name.to_str().unwrap()));
        }

        commands.extend(get_commands(entry.path())
                            .into_iter()
                            .map(|c| format!("{}::{}", &path, c)))
    }

    let command_array = make_array(commands);

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("command_array.rs");
    let mut f = File::create(&dest_path).unwrap();
    write!(f, "{}", command_array).unwrap();

    // Output OUT_DIR for rustdoc in Travis
    let mut f = File::create("out_dir").unwrap();
    write!(f, "{}", out_dir).unwrap();
}

fn get_commands(path: &Path) -> Vec<String> {
    let mut source = String::new();
    File::open(path)
        .unwrap()
        .read_to_string(&mut source)
        .unwrap();

    let _crate = syn::parse_crate(&source).expect("Error parsing the code");

    let mut visitor = CommandVisitor::new();
    visitor.visit_crate(&_crate);

    visitor.commands
}

fn make_array(commands: Vec<String>) -> String {
    let mut buf = format!("pub static COMMANDS: [&Command; {}] = [", commands.len());

    let mut iter = commands.into_iter();

    if let Some(first) = iter.next() {
        buf.push_str(&format!("&{}", first));
    }

    for command in iter {
        buf.push_str(&format!(", &{}", command));
    }

    buf.push_str("];");

    buf
}

struct CommandVisitor {
    commands: Vec<String>,
}

impl CommandVisitor {
    fn new() -> Self {
        Self { commands: Vec::new() }
    }
}

impl Visitor for CommandVisitor {
    fn visit_mac(&mut self, mac: &syn::Mac) {
        if mac.path == "command".into() {
            if let Some(&syn::TokenTree::Delimited(ref delimited)) = mac.tts.iter().next() {
                if let Some(&syn::TokenTree::Token(ref token)) = delimited.tts.iter().next() {
                    if let &syn::Token::Ident(ref ident) = token {
                        self.commands.push(ident.as_ref().to_owned());
                    }
                }
            }
        }

        syn::visit::walk_mac(self, mac);
    }
}
<commit_msg>Remove expect from syn parsing<commit_after>extern crate syn;
extern crate walkdir;

use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use syn::visit::Visitor;

fn main() {
    // Parse all .rs files to collect everything which implements Command.
    // This code won't work properly with lib.rs or mod.rs.
    let mut commands = Vec::new();

    for entry in walkdir::WalkDir::new("src")
            .into_iter()
            .filter_map(|e| e.ok())
            .filter(|e| !e.file_type().is_dir()) {
        let mut path = String::new();

        for name in entry.path().with_extension("").iter().skip(1) {
            path.push_str(&format!("::{}", name.to_str().unwrap()));
        }

        commands.extend(get_commands(entry.path())
                            .into_iter()
                            .map(|c| format!("{}::{}", &path, c)))
    }

    let command_array = make_array(commands);

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("command_array.rs");
    let mut f = File::create(&dest_path).unwrap();
    write!(f, "{}", command_array).unwrap();

    // Output OUT_DIR for rustdoc in Travis
    let mut f = File::create("out_dir").unwrap();
    write!(f, "{}", out_dir).unwrap();
}

fn get_commands(path: &Path) -> Vec<String> {
    let mut source = String::new();
    File::open(path)
        .unwrap()
        .read_to_string(&mut source)
        .unwrap();

    if let Ok(_crate) = syn::parse_crate(&source) {
        let mut visitor = CommandVisitor::new();
        visitor.visit_crate(&_crate);

        visitor.commands
    } else {
        Vec::new()
    }
}

fn make_array(commands: Vec<String>) -> String {
    let mut buf = format!("pub static COMMANDS: [&Command; {}] = [", commands.len());

    let mut iter = commands.into_iter();

    if let Some(first) = iter.next() {
        buf.push_str(&format!("&{}", first));
    }

    for command in iter {
        buf.push_str(&format!(", &{}", command));
    }

    buf.push_str("];");

    buf
}

struct CommandVisitor {
    commands: Vec<String>,
}

impl CommandVisitor {
    fn new() -> Self {
        Self { commands: Vec::new() }
    }
}

impl Visitor for CommandVisitor {
    fn visit_mac(&mut self, mac: &syn::Mac) {
        if mac.path == "command".into() {
            if let Some(&syn::TokenTree::Delimited(ref delimited)) = mac.tts.iter().next() {
                if let Some(&syn::TokenTree::Token(ref token)) = delimited.tts.iter().next() {
                    if let &syn::Token::Ident(ref ident) = token {
                        self.commands.push(ident.as_ref().to_owned());
                    }
                }
            }
        }

        syn::visit::walk_mac(self, mac);
    }
}
<|endoftext|>


<commit_before>#![feature(core)]

use std::env;
use std::path::Path;
use std::process::{Stdio, Command};

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let dst = Path::new(out_dir.as_slice());

    setup();
    configure();
    build();
    install(&dst);
    clean();
    println!("cargo:rustc-flags=-L {} -l static=termbox", dst.join("lib").display());
}

fn setup() {
    let mut cmd = Command::new("git");
    cmd.arg("clone");
    cmd.arg("https://github.com/nsf/termbox");
    cmd.arg(".termbox");
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(manifest_dir.as_slice());
    cmd.current_dir(&cargo_dir);

    run(&mut cmd);
}

fn clean() {
    let mut cmd = Command::new("rm");
    cmd.arg("-rf");
    cmd.arg(".termbox");
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(manifest_dir.as_slice());
    cmd.current_dir(&cargo_dir);
    run(&mut cmd);
}

fn configure() {
    let mut cmd = waf();
    cmd.arg("configure");
    cmd.arg("--prefix=/");

    let target = env::var("TARGET").unwrap();
    let mut cflags;
    if target.as_slice().contains("i686") {
        cflags = "-m32"
    } else if target.as_slice().contains("x86_64") {
        cflags = "-m64 -fPIC"
    } else {
        cflags = ""
    }
    println!("waf configure: setting CFLAGS to: `{}`", cflags);
    env::set_var("CFLAGS", cflags);

    run(&mut cmd);
    env::remove_var("CFLAGS");
}

fn build() {
    let mut cmd = waf();
    cmd.arg("build");
    cmd.arg("--targets=termbox_static");
    run(&mut cmd);
}

fn install(dst: &Path) {
    let mut cmd = waf();
    cmd.arg("install");
    cmd.arg("--targets=termbox_static");
    cmd.arg(format!("--destdir={}", dst.display()));
    run(&mut cmd);
}

fn waf() -> Command {
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(manifest_dir.as_slice());
    let termbox_dir = cargo_dir.join(".termbox");
    let mut cmd = Command::new("./waf");
    cmd.current_dir(&termbox_dir);
    cmd
}

fn run(cmd: &mut Command) {
    println!("running: {:?}", cmd);
    assert!(cmd.stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .status()
                .unwrap()
                .success());
}
<commit_msg>Remove as_slice calls.<commit_after>use std::env;
use std::path::Path;
use std::process::{Stdio, Command};

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let dst = Path::new(&out_dir);

    setup();
    configure();
    build();
    install(&dst);
    clean();
    println!("cargo:rustc-flags=-L {} -l static=termbox", dst.join("lib").display());
}

fn setup() {
    let mut cmd = Command::new("git");
    cmd.arg("clone");
    cmd.arg("https://github.com/nsf/termbox");
    cmd.arg(".termbox");
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(&manifest_dir);
    cmd.current_dir(&cargo_dir);

    run(&mut cmd);
}

fn clean() {
    let mut cmd = Command::new("rm");
    cmd.arg("-rf");
    cmd.arg(".termbox");
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(&manifest_dir);
    cmd.current_dir(&cargo_dir);
    run(&mut cmd);
}

fn configure() {
    let mut cmd = waf();
    cmd.arg("configure");
    cmd.arg("--prefix=/");

    let target = env::var("TARGET").unwrap();
    let mut cflags;
    if target.contains("i686") {
        cflags = "-m32"
    } else if target.contains("x86_64") {
        cflags = "-m64 -fPIC"
    } else {
        cflags = ""
    }
    println!("waf configure: setting CFLAGS to: `{}`", cflags);
    env::set_var("CFLAGS", cflags);

    run(&mut cmd);
    env::remove_var("CFLAGS");
}

fn build() {
    let mut cmd = waf();
    cmd.arg("build");
    cmd.arg("--targets=termbox_static");
    run(&mut cmd);
}

fn install(dst: &Path) {
    let mut cmd = waf();
    cmd.arg("install");
    cmd.arg("--targets=termbox_static");
    cmd.arg(format!("--destdir={}", dst.display()));
    run(&mut cmd);
}

fn waf() -> Command {
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let cargo_dir = Path::new(&manifest_dir);
    let termbox_dir = cargo_dir.join(".termbox");
    let mut cmd = Command::new("./waf");
    cmd.current_dir(&termbox_dir);
    cmd
}

fn run(cmd: &mut Command) {
    println!("running: {:?}", cmd);
    assert!(cmd.stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .status()
                .unwrap()
                .success());
}
<|endoftext|>


<commit_before>extern crate cc;

use std::env;
use std::path::PathBuf;

fn main() {
    cc::Build::new()
        .cpp(true)
        .opt_level(0)
        .include("llvm/headers")
        .flag_if_supported("-pedantic")
        .flag_if_supported("-std=c++11")
        .flag_if_supported("-fno-rtti")
        .flag_if_supported("-Wno-unused-parameter")
        .define("_GLIBCXX_USE_CXX11_ABI", "0")
        .file("llvm/find-external-refs.cpp")
        .file("llvm/internalize.cpp")
        .file("llvm/rename-globals.cpp")
        .file("llvm/helpers/visitors.cpp")
        .compile("librust-ptx-llvm-stuff.a");

    link_rustc_llvm_lib();
}

fn link_rustc_llvm_lib() {
    match find_rustc_llvm_lib() {
        Some(path) => {
            let location = path.as_path().parent().unwrap().to_str().unwrap();
            let name = path.as_path().file_stem().unwrap().to_str().unwrap();

            let libname = match name.starts_with("lib") {
                true => &name[3..],
                false => name,
            };

            println!("cargo:rustc-link-search=native={}", location);
            println!("cargo:rustc-link-lib=dylib={}", libname);
        }

        None => {
            unreachable!();
        }
    }
}

fn find_rustc_llvm_lib() -> Option<PathBuf> {
    let lib_path = env::var("LD_LIBRARY_PATH").unwrap();

    for libdir in lib_path.split(':').map(|path| PathBuf::from(path)) {
        if let Ok(entries) = libdir.read_dir() {
            let mut matching_entries = entries.filter(|entry| {
                entry
                    .as_ref()
                    .unwrap()
                    .path()
                    .file_stem()
                    .unwrap()
                    .to_str()
                    .unwrap()
                    .starts_with("librustc_llvm")
            });

            if let Some(entry) = matching_entries.nth(0) {
                return Some(entry.unwrap().path());
            }
        }
    }

    None
}
<commit_msg>Don't rely on LD_LIBRARY_PATH to fix macOS build<commit_after>extern crate cc;

use std::env;
use std::path::PathBuf;

fn main() {
    cc::Build::new()
        .cpp(true)
        .opt_level(0)
        .include("llvm/headers")
        .flag_if_supported("-pedantic")
        .flag_if_supported("-std=c++11")
        .flag_if_supported("-fno-rtti")
        .flag_if_supported("-Wno-unused-parameter")
        .define("_GLIBCXX_USE_CXX11_ABI", "0")
        .file("llvm/find-external-refs.cpp")
        .file("llvm/internalize.cpp")
        .file("llvm/rename-globals.cpp")
        .file("llvm/helpers/visitors.cpp")
        .compile("librust-ptx-llvm-stuff.a");

    link_rustc_llvm_lib();
}

fn link_rustc_llvm_lib() {
    match find_rustc_llvm_lib() {
        Some(path) => {
            let location = path.as_path().parent().unwrap().to_str().unwrap();
            let name = path.as_path().file_stem().unwrap().to_str().unwrap();

            let libname = match name.starts_with("lib") {
                true => &name[3..],
                false => name,
            };

            println!("cargo:rustc-link-search=native={}", location);
            println!("cargo:rustc-link-lib=dylib={}", libname);
        }

        None => {
            unreachable!("Unable to get location of 'librustc_llvm'.");
        }
    }
}

fn find_rustc_llvm_lib() -> Option<PathBuf> {
    let rustup_home = env::var("RUSTUP_HOME")
        .expect("Unable to get 'RUSTUP_HOME' env variable. Do you have rustup installed?");

    let rustup_toolchain = env::var("RUSTUP_TOOLCHAIN")
        .expect("Unable to get 'RUSTUP_TOOLCHAIN' env variable. Do you have rustup installed?");

    let rustc_libs_path = PathBuf::from(format!(
        "{root}/toolchains/{toolchain}/lib/",
        root = rustup_home,
        toolchain = rustup_toolchain
    ));

    if let Ok(entries) = rustc_libs_path.read_dir() {
        let mut matching_entries = entries.filter(|entry| {
            entry
                .as_ref()
                .unwrap()
                .path()
                .file_stem()
                .unwrap()
                .to_str()
                .unwrap()
                .starts_with("librustc_llvm")
        });

        if let Some(entry) = matching_entries.nth(0) {
            return Some(entry.unwrap().path());
        }
    }

    None
}
<|endoftext|>


<commit_before>extern crate resp;
extern crate rusqlite;
extern crate time;
extern crate libc;

use std::io::{Write, BufReader, BufWriter};
use std::net::{TcpStream};
use std::sync::{Arc, Mutex, Condvar};
use std::os::unix::io::AsRawFd;
use self::resp::{Decoder, Value};

use commands;
use parser;
use monitor;

pub struct Connection {
    sqlite_connection_mutex: Arc<Mutex<rusqlite::Connection>>,
    monitor: monitor::Monitor,
    push_notification: Arc<(Mutex<bool>, Condvar)>,
    stream: Option<TcpStream>,
}

pub trait Connectionable {
    fn get_push_notification(&self) -> Arc<(Mutex<bool>, Condvar)>;
    fn get_sqlite_connection_mutex(&self) -> &Arc<Mutex<rusqlite::Connection>>;
    fn is_stream_alive(&self) -> bool;
    fn send_to_command_log(&self, command: String);
}

impl Connectionable for Connection {
    fn get_push_notification(&self) -> Arc<(Mutex<bool>, Condvar)> { self.push_notification.clone() }
    fn get_sqlite_connection_mutex(&self) -> &Arc<Mutex<rusqlite::Connection>> { &self.sqlite_connection_mutex }

    fn is_stream_alive(&self) -> bool {
        let fd = self.borrow_stream().as_raw_fd();

        unsafe {
            let mut pollfd = libc::pollfd { fd: fd, events: libc::POLLIN, revents: 0 };
            libc::poll(&mut pollfd, 1, 0);

            pollfd.revents & libc::POLLHUP == 0
        }
    }

    fn send_to_command_log(&self, command: String) {
        self.monitor.send(command);
    }
}

impl Connection {
    pub fn new(sqlite_connection_mutex: Arc<Mutex<rusqlite::Connection>>, monitor: monitor::Monitor, push_notification: Arc<(Mutex<bool>, Condvar)>) -> Connection {
        Connection {
            sqlite_connection_mutex: sqlite_connection_mutex,
            monitor: monitor,
            push_notification: push_notification,
            stream: None,
        }
    }

    fn borrow_stream(&self) -> &TcpStream {
        match self.stream {
            Some(ref stream) => stream,
            None => panic!()
        }
    }

    pub fn run(&mut self, stream: TcpStream) {
        self.stream = Some(stream);

        let stream = self.borrow_stream();
        let reader = BufReader::new(stream);
        let mut writer = BufWriter::new(stream);
        let mut decoder = Decoder::with_buf_bulk(reader);

        loop {
            match decoder.decode() {
                Ok(value) => {
                    let (result, action) = self.handle_input(value);
                    writer.write(&result.encode()).unwrap();
                    writer.flush().unwrap();

                    match action {
                        commands::Action::HangUp => break,
                        commands::Action::StartMonitor => {
                            self.run_monitor(writer);
                            break;
                        }
                        _ => {}
                    };
                }

                _ => break
            }
        }
    }

    fn run_monitor(&self, mut writer: BufWriter<&TcpStream>) {
       let listener = self.monitor.listen();

       loop {
           match listener.recv() {
               Some(data) => {
                   let value = Value::String(data);
                   writer.write(&value.encode()).unwrap();
                   writer.flush().unwrap();
               }

               _ => break
           }
       }
    }

    fn handle_input(&self, ref value: Value) -> (Value, commands::Action) {
        match parser::parse_command(value) {
            Ok((name, arguments)) => {
                let mut command = commands::Command {
                    name:       name,
                    arguments:  arguments,
                    connection: self as &Connectionable,
                };

                command.execute()
            }

            Err(error) => (Value::Error(format!("ERR {}", error)), commands::Action::Continue)
        }
    }
}
<commit_msg>Gracefully handle clients hanging up on us<commit_after>extern crate resp;
extern crate rusqlite;
extern crate time;
extern crate libc;

use std::io::{Write, BufReader, BufWriter};
use std::net::{TcpStream};
use std::sync::{Arc, Mutex, Condvar};
use std::os::unix::io::AsRawFd;
use self::resp::{Decoder, Value};

use commands;
use parser;
use monitor;

pub struct Connection {
    sqlite_connection_mutex: Arc<Mutex<rusqlite::Connection>>,
    monitor: monitor::Monitor,
    push_notification: Arc<(Mutex<bool>, Condvar)>,
    stream: Option<TcpStream>,
}

pub trait Connectionable {
    fn get_push_notification(&self) -> Arc<(Mutex<bool>, Condvar)>;
    fn get_sqlite_connection_mutex(&self) -> &Arc<Mutex<rusqlite::Connection>>;
    fn is_stream_alive(&self) -> bool;
    fn send_to_command_log(&self, command: String);
}

impl Connectionable for Connection {
    fn get_push_notification(&self) -> Arc<(Mutex<bool>, Condvar)> { self.push_notification.clone() }
    fn get_sqlite_connection_mutex(&self) -> &Arc<Mutex<rusqlite::Connection>> { &self.sqlite_connection_mutex }

    fn is_stream_alive(&self) -> bool {
        let fd = self.borrow_stream().as_raw_fd();

        unsafe {
            let mut pollfd = libc::pollfd { fd: fd, events: libc::POLLIN, revents: 0 };
            libc::poll(&mut pollfd, 1, 0);

            pollfd.revents & libc::POLLHUP == 0
        }
    }

    fn send_to_command_log(&self, command: String) {
        self.monitor.send(command);
    }
}

impl Connection {
    pub fn new(sqlite_connection_mutex: Arc<Mutex<rusqlite::Connection>>, monitor: monitor::Monitor, push_notification: Arc<(Mutex<bool>, Condvar)>) -> Connection {
        Connection {
            sqlite_connection_mutex: sqlite_connection_mutex,
            monitor: monitor,
            push_notification: push_notification,
            stream: None,
        }
    }

    fn borrow_stream(&self) -> &TcpStream {
        match self.stream {
            Some(ref stream) => stream,
            None => panic!()
        }
    }

    pub fn run(&mut self, stream: TcpStream) {
        self.stream = Some(stream);

        let stream = self.borrow_stream();
        let reader = BufReader::new(stream);
        let mut writer = BufWriter::new(stream);
        let mut decoder = Decoder::with_buf_bulk(reader);

        loop {
            match decoder.decode() {
                Ok(value) => {
                    let (result, action) = self.handle_input(value);
                    if writer.write(&result.encode()).is_err() { break; }
                    if writer.flush().is_err() { break; }

                    match action {
                        commands::Action::HangUp => break,
                        commands::Action::StartMonitor => {
                            self.run_monitor(writer);
                            break;
                        }
                        _ => {}
                    };
                }

                _ => break
            }
        }
    }

    fn run_monitor(&self, mut writer: BufWriter<&TcpStream>) {
       let listener = self.monitor.listen();

       loop {
           match listener.recv() {
               Some(data) => {
                   let value = Value::String(data);
                   if writer.write(&value.encode()).is_err() { break; }
                   if writer.flush().is_err() { break; }
               }

               _ => break
           }
       }
    }

    fn handle_input(&self, ref value: Value) -> (Value, commands::Action) {
        match parser::parse_command(value) {
            Ok((name, arguments)) => {
                let mut command = commands::Command {
                    name:       name,
                    arguments:  arguments,
                    connection: self as &Connectionable,
                };

                command.execute()
            }

            Err(error) => (Value::Error(format!("ERR {}", error)), commands::Action::Continue)
        }
    }
}
<|endoftext|>