<commit_before>
use geometry::Point;
use core::rand::RngUtil;
mod geometry;

//
// Cellule
//

struct Cell {
    center: Point,
    id: uint,
    radius: float,
    velocity: [float,..3],
    acc: [float,..3],
    generation: int,
    age: int
}

pub impl Cell {
    fn new(ident: uint) -> Cell {
        let radius = 1.0;
        //let r=rand::random::<float>();
        //io::println(fmt!("%f\n", r));
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: [0.0,0.0,0.0], acc: [0.0,0.0,0.0], generation: 0, age:0}
    }

    fn move(&self, tumeur: ~Crowd, dt: float) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt));
    }

    fn replicate(&mut self, tumeur: ~Crowd, dt: float) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt));

        self.age+=1;
    }
}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

#[test]
fn test_new() {
    let cell1=Cell::new(0);
    let cell2=Cell::new(1);
    assert!(cell1.center != cell2.center);
}
//
// Population
//

struct Crowd {
    cells : ~[@Cell],
    time : float
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {
        io::println(fmt!("Population initiale : %d\n",init_pop as int));

        let mut pop : ~[@Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = @Cell::new(num);
            io::println(lonely_one.to_str());
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self) {
        for self.cells.each |cell| {
            io::println(fmt!("Cell %d has moved !", cell.id as int));
        }
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<commit_msg>Les agents sont mutables<commit_after>
use geometry::Point;
use core::rand::RngUtil;
mod geometry;

//
// Cellule
//

struct Cell {
    center: Point,
    id: uint,
    radius: float,
    velocity: [float,..3],
    acc: [float,..3],
    generation: int,
    age: int
}

pub impl Cell {
    fn new(ident: uint) -> Cell {
        let radius = 1.0;
        //let r=rand::random::<float>();
        //io::println(fmt!("%f\n", r));
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: [0.0,0.0,0.0], acc: [0.0,0.0,0.0], generation: 0, age:0}
    }

    fn move(&self, tumeur: ~Crowd, dt: float) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt));
    }

    fn replicate(&mut self, tumeur: ~Crowd, dt: float) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt));

        self.age+=1;
    }
}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

#[test]
fn test_new() {
    let cell1=Cell::new(0);
    let cell2=Cell::new(1);
    assert!(cell1.center != cell2.center);
}
//
// Population
//

struct Crowd {
    cells : ~[@mut Cell],
    time : float
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {
        io::println(fmt!("Population initiale : %d\n",init_pop as int));

        let mut pop : ~[@mut Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = @mut Cell::new(num);
            io::println(lonely_one.to_str());
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self) {
        for self.cells.each |cell| {
            io::println(fmt!("Cell %d has moved !", cell.id as int));
        }
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<|endoftext|>


<commit_before>mod array;
pub mod date_and_time;
pub mod floats;
mod integers;
mod primitives;
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "serde_json")]
mod json;
pub mod money;

/// PostgreSQL specific SQL types
///
/// Note: All types in this module can be accessed through `diesel::types`
pub mod sql_types {
    /// The `OID` SQL type. This is a PostgreSQL specific type.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`u32`][u32]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`u32`][u32]
    ///
    /// [u32]: https://doc.rust-lang.org/nightly/std/primitive.u32.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Oid;

    /// The "timestamp with time zone" SQL type, which PostgreSQL abbreviates
    /// to `timestamptz`.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`PgTimestamp`][PgTimestamp]
    /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
    /// - [`chrono::DateTime`][DateTime] with `feature = "chrono"`
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`PgTimestamp`][PgTimestamp]
    /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
    /// - [`chrono::DateTime`][DateTime] with `feature = "chrono"`
    ///
    /// [PgTimestamp]: /diesel/pg/data_types/struct.PgTimestamp.html
    /// [NaiveDateTime]: https://lifthrasiir.github.io/rust-chrono/chrono/naive/datetime/struct.NaiveDateTime.html
    /// [DateTime]: https://lifthrasiir.github.io/rust-chrono/chrono/datetime/struct.DateTime.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Timestamptz;

    /// The `Array` SQL type. This wraps another type to represent a SQL array of
    /// that type. Multidimensional arrays are not supported, nor are arrays
    /// containing null.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
    /// - [`&[T]`][slice] for any `T` which implements `ToSql<ST>`
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
    ///
    /// [Vec]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html
    /// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Array<ST>(ST);

    /// Alias for `SmallInt`
    pub type SmallSerial = ::types::SmallInt;

    /// Alias for `Integer`
    pub type Serial = ::types::Integer;

    /// Alias for `BigInt`
    pub type BigSerial = ::types::BigInt;

    #[cfg(feature = "uuid")]
    /// The `UUID` SQL type. This type can only be used with `feature = "uuid"`
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`uuid::Uuid`][Uuid]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`uuid::Uuid`][Uuid]
    ///
    /// [Vec]: https://doc.rust-lang.org/uuid/uuid/struct.Uuid.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Uuid;

    /// Alias for `Binary`, to ensure `infer_schema!` works
    pub type Bytea = ::types::Binary;

    #[doc(hidden)]
    pub type Bpchar = ::types::VarChar;

    #[cfg(feature = "serde_json")]
    /// The JSON SQL type.  This type can only be used with `feature =
    /// "serde_json"`
    ///
    /// Normally you should prefer `Jsonb` instead, for the reasons
    /// discussed there.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`serde_json::Value`][Value]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`serde_json`][Value]
    ///
    /// [Value]: https://docs.serde.rs/serde_json/value/enum.Value.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Json;

    #[cfg(feature = "serde_json")]
    /// The `jsonb` SQL type.  This type can only be used with `feature =
    /// "serde_json"`
    ///
    /// `jsonb` offers [several advantages][adv] over regular JSON:
    ///
    /// > There are two JSON data types: `json` and `jsonb`. They accept almost
    /// > identical sets of values as input. The major practical difference
    /// > is one of efficiency. The `json` data type stores an exact copy of
    /// > the input text, which processing functions must reparse on each
    /// > execution; while `jsonb` data is stored in a decomposed binary format
    /// > that makes it slightly slower to input due to added conversion
    /// > overhead, but significantly faster to process, since no reparsing
    /// > is needed. `jsonb` also supports indexing, which can be a significant
    /// > advantage.
    /// >
    /// > ...In general, most applications should prefer to store JSON data as
    /// > `jsonb`, unless there are quite specialized needs, such as legacy
    /// > assumptions about ordering of object keys.
    ///
    /// [adv]: https://www.postgresql.org/docs/9.6/static/datatype-json.html
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`serde_json::Value`][Value]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`serde_json`][Value]
    ///
    /// [Value]: https://docs.serde.rs/serde_json/value/enum.Value.html
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #![allow(dead_code)]
    /// extern crate serde_json;
    /// # #[macro_use] extern crate diesel_codegen;
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Serial,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// #[derive(Queryable)]
    /// struct Contact {
    ///     id: i32,
    ///     name: String,
    ///     address: serde_json::Value,
    /// }
    ///
    /// #[derive(Insertable)]
    /// #[table_name="contacts"]
    /// struct NewContact {
    ///     name: String,
    ///     address: serde_json::Value,
    /// }
    ///
    /// table! {
    ///     contacts {
    ///         id -> Integer,
    ///         name -> VarChar,
    ///         address -> Jsonb,
    ///     }
    /// }
    ///
    /// # fn main() {
    /// #     use self::diesel::insert;
    /// #     use self::contacts::dsl::*;
    /// #     let connection = connection_no_data();
    /// #     connection.execute("CREATE TABLE contacts (
    /// #         id SERIAL PRIMARY KEY,
    /// #         name VARCHAR NOT NULL,
    /// #         address JSONB NOT NULL
    /// #     )").unwrap();
    /// let santas_address: serde_json::Value = serde_json::from_str(r#"{
    ///     "street": "Article Circle Expressway 1",
    ///     "city": "North Pole",
    ///     "postcode": "99705",
    ///     "state": "Alaska"
    /// }"#).unwrap();
    /// let new_contact = NewContact {
    ///     name: "Claus".into(),
    ///     address: santas_address.clone()
    /// };
    /// let inserted_contact = insert(&new_contact).into(contacts)
    ///     .get_result::<Contact>(&connection).unwrap();
    /// assert_eq!(santas_address, inserted_contact.address);
    /// # }
    /// ```
    #[derive(Debug, Clone, Copy, Default)] pub struct Jsonb;

    /// The PostgreSQL [Money](https://www.postgresql.org/docs/9.1/static/datatype-money.html) type.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`PgCents`][PgCents]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`PgCents`][PgCents]
    ///
    /// [PgCents]: /diesel/pg/data_types/struct.PgCents.html
    #[derive(Debug, Clone, Copy, Default)]
    pub struct Money;
}
<commit_msg>Add doctest for `pg::sql_types::Money`.<commit_after>mod array;
pub mod date_and_time;
pub mod floats;
mod integers;
mod primitives;
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "serde_json")]
mod json;
pub mod money;

/// PostgreSQL specific SQL types
///
/// Note: All types in this module can be accessed through `diesel::types`
pub mod sql_types {
    /// The `OID` SQL type. This is a PostgreSQL specific type.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`u32`][u32]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`u32`][u32]
    ///
    /// [u32]: https://doc.rust-lang.org/nightly/std/primitive.u32.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Oid;

    /// The "timestamp with time zone" SQL type, which PostgreSQL abbreviates
    /// to `timestamptz`.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`PgTimestamp`][PgTimestamp]
    /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
    /// - [`chrono::DateTime`][DateTime] with `feature = "chrono"`
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`PgTimestamp`][PgTimestamp]
    /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
    /// - [`chrono::DateTime`][DateTime] with `feature = "chrono"`
    ///
    /// [PgTimestamp]: /diesel/pg/data_types/struct.PgTimestamp.html
    /// [NaiveDateTime]: https://lifthrasiir.github.io/rust-chrono/chrono/naive/datetime/struct.NaiveDateTime.html
    /// [DateTime]: https://lifthrasiir.github.io/rust-chrono/chrono/datetime/struct.DateTime.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Timestamptz;

    /// The `Array` SQL type. This wraps another type to represent a SQL array of
    /// that type. Multidimensional arrays are not supported, nor are arrays
    /// containing null.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
    /// - [`&[T]`][slice] for any `T` which implements `ToSql<ST>`
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`Vec<T>`][Vec] for any `T` which implements `ToSql<ST>`
    ///
    /// [Vec]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html
    /// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Array<ST>(ST);

    /// Alias for `SmallInt`
    pub type SmallSerial = ::types::SmallInt;

    /// Alias for `Integer`
    pub type Serial = ::types::Integer;

    /// Alias for `BigInt`
    pub type BigSerial = ::types::BigInt;

    #[cfg(feature = "uuid")]
    /// The `UUID` SQL type. This type can only be used with `feature = "uuid"`
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`uuid::Uuid`][Uuid]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`uuid::Uuid`][Uuid]
    ///
    /// [Vec]: https://doc.rust-lang.org/uuid/uuid/struct.Uuid.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Uuid;

    /// Alias for `Binary`, to ensure `infer_schema!` works
    pub type Bytea = ::types::Binary;

    #[doc(hidden)]
    pub type Bpchar = ::types::VarChar;

    #[cfg(feature = "serde_json")]
    /// The JSON SQL type.  This type can only be used with `feature =
    /// "serde_json"`
    ///
    /// Normally you should prefer `Jsonb` instead, for the reasons
    /// discussed there.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`serde_json::Value`][Value]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`serde_json`][Value]
    ///
    /// [Value]: https://docs.serde.rs/serde_json/value/enum.Value.html
    #[derive(Debug, Clone, Copy, Default)] pub struct Json;

    #[cfg(feature = "serde_json")]
    /// The `jsonb` SQL type.  This type can only be used with `feature =
    /// "serde_json"`
    ///
    /// `jsonb` offers [several advantages][adv] over regular JSON:
    ///
    /// > There are two JSON data types: `json` and `jsonb`. They accept almost
    /// > identical sets of values as input. The major practical difference
    /// > is one of efficiency. The `json` data type stores an exact copy of
    /// > the input text, which processing functions must reparse on each
    /// > execution; while `jsonb` data is stored in a decomposed binary format
    /// > that makes it slightly slower to input due to added conversion
    /// > overhead, but significantly faster to process, since no reparsing
    /// > is needed. `jsonb` also supports indexing, which can be a significant
    /// > advantage.
    /// >
    /// > ...In general, most applications should prefer to store JSON data as
    /// > `jsonb`, unless there are quite specialized needs, such as legacy
    /// > assumptions about ordering of object keys.
    ///
    /// [adv]: https://www.postgresql.org/docs/9.6/static/datatype-json.html
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`serde_json::Value`][Value]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`serde_json`][Value]
    ///
    /// [Value]: https://docs.serde.rs/serde_json/value/enum.Value.html
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #![allow(dead_code)]
    /// extern crate serde_json;
    /// # #[macro_use] extern crate diesel_codegen;
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Serial,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    /// #[derive(Queryable)]
    /// struct Contact {
    ///     id: i32,
    ///     name: String,
    ///     address: serde_json::Value,
    /// }
    ///
    /// #[derive(Insertable)]
    /// #[table_name="contacts"]
    /// struct NewContact {
    ///     name: String,
    ///     address: serde_json::Value,
    /// }
    ///
    /// table! {
    ///     contacts {
    ///         id -> Integer,
    ///         name -> VarChar,
    ///         address -> Jsonb,
    ///     }
    /// }
    ///
    /// # fn main() {
    /// #     use self::diesel::insert;
    /// #     use self::contacts::dsl::*;
    /// #     let connection = connection_no_data();
    /// #     connection.execute("CREATE TABLE contacts (
    /// #         id SERIAL PRIMARY KEY,
    /// #         name VARCHAR NOT NULL,
    /// #         address JSONB NOT NULL
    /// #     )").unwrap();
    /// let santas_address: serde_json::Value = serde_json::from_str(r#"{
    ///     "street": "Article Circle Expressway 1",
    ///     "city": "North Pole",
    ///     "postcode": "99705",
    ///     "state": "Alaska"
    /// }"#).unwrap();
    /// let new_contact = NewContact {
    ///     name: "Claus".into(),
    ///     address: santas_address.clone()
    /// };
    /// let inserted_contact = insert(&new_contact).into(contacts)
    ///     .get_result::<Contact>(&connection).unwrap();
    /// assert_eq!(santas_address, inserted_contact.address);
    /// # }
    /// ```
    #[derive(Debug, Clone, Copy, Default)] pub struct Jsonb;

    /// The PostgreSQL [Money](https://www.postgresql.org/docs/9.1/static/datatype-money.html) type.
    ///
    /// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
    ///
    /// - [`PgCents`][PgCents]
    ///
    /// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
    ///
    /// - [`PgCents`][PgCents]
    ///
    /// [PgCents]: /diesel/pg/data_types/struct.PgCents.html
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #![allow(dead_code)]
    /// # #[macro_use] extern crate diesel_codegen;
    /// # #[macro_use] extern crate diesel;
    /// # include!("src/doctest_setup.rs");
    /// #
    /// # table! {
    /// #     users {
    /// #         id -> Serial,
    /// #         name -> VarChar,
    /// #     }
    /// # }
    /// #
    ///
    /// use diesel::data_types::Cents;
    ///
    /// #[derive(Queryable)]
    /// struct Item {
    ///     id: i32,
    ///     name: String,
    ///     price: Cents,
    /// }
    ///
    /// #[derive(Insertable)]
    /// #[table_name="items"]
    /// struct NewItem {
    ///     name: String,
    ///     price: Cents,
    /// }
    ///
    /// table! {
    ///     items {
    ///         id -> Integer,
    ///         name -> VarChar,
    ///         price -> Money,
    ///     }
    /// }
    ///
    /// # fn main() {
    /// #     use self::diesel::insert;
    /// #     use self::items::dsl::*;
    /// #     let connection = connection_no_data();
    /// #     connection.execute("CREATE TABLE items (
    /// #         id SERIAL PRIMARY KEY,
    /// #         name VARCHAR NOT NULL,
    /// #         price MONEY NOT NULL
    /// #     )").unwrap();
    /// let new_item = NewItem {
    ///     name: "Shiny Thing".into(),
    ///     price: Cents(123456),
    /// };
    /// let inserted_item = insert(&new_item).into(items)
    ///     .get_result::<Item>(&connection).unwrap();
    /// assert_eq!(Cents(123456), inserted_item.price);
    /// # }
    /// ```
    #[derive(Debug, Clone, Copy, Default)] pub struct Money;
}
<|endoftext|>


<commit_before>use crate::utils::{last_path_segment, snippet, span_lint_and_sugg};
use rustc_hir::{GenericArg, Mutability, Ty, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use if_chain::if_chain;
use rustc_errors::Applicability;

declare_clippy_lint! {
    /// **What it does:** Checks for usage of `&Option<&T>`.
    ///
    /// **Why is this bad?** Since `&` is Copy, it's useless to have a
    /// reference on `Option<&T>`.
    ///
    /// **Known problems:** It may be irrevelent to use this lint on
    /// public API code as it will make a breaking change to apply it.
    ///
    /// **Example:**
    ///
    /// ```rust,ignore
    /// let x: &Option<&u32> = &Some(&0u32);
    /// ```
    /// Use instead:
    /// ```rust,ignore
    /// let x: Option<&u32> = Some(&0u32);
    /// ```
    pub REF_OPTION_REF,
    pedantic,
    "use `Option<&T>` instead of `&Option<&T>`"
}

declare_lint_pass!(RefOptionRef => [REF_OPTION_REF]);

impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
        if_chain! {
            if let TyKind::Rptr(_, ref mut_ty) = ty.kind;
            if mut_ty.mutbl == Mutability::Not;
            if let TyKind::Path(ref qpath) = &mut_ty.ty.kind;
            let last = last_path_segment(qpath);
            if let Some(res) = last.res;
            if let Some(def_id) = res.opt_def_id();

            if cx.tcx.is_diagnostic_item(sym!(option_type), def_id);
            if let Some(ref params) = last_path_segment(qpath).args ;
            if !params.parenthesized;
            if let Some(inner_ty) = params.args.iter().find_map(|arg| match arg {
                GenericArg::Type(inner_ty) => Some(inner_ty),
                _ => None,
            });
            if let TyKind::Rptr(_, _) = inner_ty.kind;

            then {
                span_lint_and_sugg(
                    cx,
                    REF_OPTION_REF,
                    ty.span,
                    "since & implements Copy trait, &Option<&T> can be simplifyied into Option<&T>",
                    "try",
                    format!("Option<{}>", &snippet(cx, inner_ty.span, "..")),
                    Applicability::Unspecified,
                );
            }
        }
    }
}
<commit_msg>Change Applicability to MaybeIncorrect<commit_after>use crate::utils::{last_path_segment, snippet, span_lint_and_sugg};
use rustc_hir::{GenericArg, Mutability, Ty, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

use if_chain::if_chain;
use rustc_errors::Applicability;

declare_clippy_lint! {
    /// **What it does:** Checks for usage of `&Option<&T>`.
    ///
    /// **Why is this bad?** Since `&` is Copy, it's useless to have a
    /// reference on `Option<&T>`.
    ///
    /// **Known problems:** It may be irrevelent to use this lint on
    /// public API code as it will make a breaking change to apply it.
    ///
    /// **Example:**
    ///
    /// ```rust,ignore
    /// let x: &Option<&u32> = &Some(&0u32);
    /// ```
    /// Use instead:
    /// ```rust,ignore
    /// let x: Option<&u32> = Some(&0u32);
    /// ```
    pub REF_OPTION_REF,
    pedantic,
    "use `Option<&T>` instead of `&Option<&T>`"
}

declare_lint_pass!(RefOptionRef => [REF_OPTION_REF]);

impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
        if_chain! {
            if let TyKind::Rptr(_, ref mut_ty) = ty.kind;
            if mut_ty.mutbl == Mutability::Not;
            if let TyKind::Path(ref qpath) = &mut_ty.ty.kind;
            let last = last_path_segment(qpath);
            if let Some(res) = last.res;
            if let Some(def_id) = res.opt_def_id();

            if cx.tcx.is_diagnostic_item(sym!(option_type), def_id);
            if let Some(ref params) = last_path_segment(qpath).args ;
            if !params.parenthesized;
            if let Some(inner_ty) = params.args.iter().find_map(|arg| match arg {
                GenericArg::Type(inner_ty) => Some(inner_ty),
                _ => None,
            });
            if let TyKind::Rptr(_, _) = inner_ty.kind;

            then {
                span_lint_and_sugg(
                    cx,
                    REF_OPTION_REF,
                    ty.span,
                    "since & implements Copy trait, &Option<&T> can be simplifyied into Option<&T>",
                    "try",
                    format!("Option<{}>", &snippet(cx, inner_ty.span, "..")),
                    Applicability::MaybeIncorrect,
                );
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>example: bugfix for group evaluation in calc example<commit_after><|endoftext|>


<commit_before>extern crate git2;
extern crate rustc_version;

use git2::{Repository, DescribeOptions, DescribeFormatOptions};
use std::env;
use std::path::Path;
use std::fs::File;
use std::io::{self, Write};
use std::process::exit;
use rustc_version::version_matches;

fn get_version() -> String {
  let profile = env::var("PROFILE").unwrap();
  if profile == "release" {
    String::new()
  } else {
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let repo = match Repository::open(&manifest_dir) {
      Ok(r) => r,
      Err(_) => return String::new()
    };
    let version = repo
    .describe(
      DescribeOptions::new().describe_tags().show_commit_oid_as_fallback(true)
    )
    .unwrap()
    .format(
      Some(DescribeFormatOptions::new().dirty_suffix("-dirty"))
    )
    .unwrap();
    String::from("-") + &version
  }
}

fn main() {
  if !version_matches(">= 1.8.0") {
    writeln!(&mut io::stderr(), "bins requires at least Rust 1.8.0").unwrap();
    exit(1);
  }
  let version = get_version();
  let out_dir = env::var("OUT_DIR").unwrap();
  let dest_path = Path::new(&out_dir).join("git_short_tag.rs");
  let mut f = File::create(&dest_path).unwrap();
  f.write_all(format!("
      fn git_short_tag() -> &'static str {{
          \"{}\"
      }}
  ", version).as_bytes()).unwrap();
}
<commit_msg>style(build): use rustfmt on build.rs<commit_after>extern crate git2;
extern crate rustc_version;

use git2::{DescribeFormatOptions, DescribeOptions, Repository};
use rustc_version::version_matches;
use std::env;
use std::fs::File;
use std::io::{self, Write};
use std::path::Path;
use std::process::exit;

fn get_version() -> String {
  let profile = env::var("PROFILE").unwrap();
  if profile == "release" {
    String::new()
  } else {
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let repo = match Repository::open(&manifest_dir) {
      Ok(r) => r,
      Err(_) => return String::new(),
    };
    let version = repo.describe(DescribeOptions::new().describe_tags().show_commit_oid_as_fallback(true))
      .unwrap()
      .format(Some(DescribeFormatOptions::new().dirty_suffix("-dirty")))
      .unwrap();
    String::from("-") + &version
  }
}

fn main() {
  if !version_matches(">= 1.8.0") {
    writeln!(&mut io::stderr(), "bins requires at least Rust 1.8.0").unwrap();
    exit(1);
  }
  let version = get_version();
  let out_dir = env::var("OUT_DIR").unwrap();
  let dest_path = Path::new(&out_dir).join("git_short_tag.rs");
  let mut f = File::create(&dest_path).unwrap();
  f.write_all(format!("
      fn git_short_tag() -> &'static str {{
          \"{}\"
      }}
  ",
                       version)
      .as_bytes())
    .unwrap();
}
<|endoftext|>


<commit_before>extern crate directories;

#[cfg(target_family = "unix")]
use directories::{BaseDirs, ProjectDirs};

use std::fs::{create_dir_all, File};
use std::io::{ErrorKind, Read};
use std::path::PathBuf;
use std::process::Command;

#[cfg(target_family = "unix")]
use std::fs::read_dir;
#[cfg(target_family = "unix")]
use std::io::Write;

fn generate_resources() {
    let target_path = PathBuf::from("target").join("resources");
    create_dir_all(&target_path).unwrap();

    // Icons
    let input_path = PathBuf::from("res").join("icons").join("hicolor");

    let mut compile_res = Command::new("glib-compile-resources");
    compile_res
        .arg("--generate")
        .arg(format!("--sourcedir={}", input_path.to_str().unwrap()))
        .arg(format!(
            "--target={}",
            target_path.join("icons.gresource").to_str().unwrap(),
        ))
        .arg(input_path.join("icons.gresource.xml").to_str().unwrap());

    match compile_res.status() {
        Ok(status) => {
            if !status.success() {
                panic!(format!(
                    "Failed to generate resources file for icons\n{:?}",
                    compile_res,
                ));
            }
        }
        Err(ref error) => match error.kind() {
            ErrorKind::NotFound => panic!(
                "Can't generate icon resources: command `glib-compile-resources` not available"
            ),
            _ => panic!("Error invoking `compile_res`: {}", error),
        },
    }

    // UI
    let input_path = PathBuf::from("res").join("ui");

    let mut compile_res = Command::new("glib-compile-resources");
    compile_res
        .arg("--generate")
        .arg(format!("--sourcedir={}", input_path.to_str().unwrap()))
        .arg(format!(
            "--target={}",
            target_path.join("ui.gresource").to_str().unwrap(),
        ))
        .arg(input_path.join("ui.gresource.xml").to_str().unwrap());

    match compile_res.status() {
        Ok(status) => {
            if !status.success() {
                panic!(format!(
                    "Failed to generate resources file for the UI\n{:?}",
                    compile_res,
                ));
            }
        }
        Err(ref error) => match error.kind() {
            ErrorKind::NotFound => panic!(
                "Can't generate UI resources: command `glib-compile-resources` not available"
            ),
            _ => panic!("Error invoking `compile_res`: {}", error),
        },
    }
}

fn generate_translations() {
    if let Ok(mut linguas_file) = File::open(&PathBuf::from("po").join("LINGUAS")) {
        let mut linguas = String::new();
        linguas_file
            .read_to_string(&mut linguas)
            .expect("Couldn't read po/LINGUAS as string");

        for lingua in linguas.lines() {
            let mo_path = PathBuf::from("..")
                .join("target")
                .join("locale")
                .join(lingua)
                .join("LC_MESSAGES");
            create_dir_all(&mo_path).unwrap();

            let mut msgfmt = Command::new("msgfmt");
            msgfmt
                .arg(format!(
                    "--output-file={}",
                    mo_path.join("media-toc.mo").to_str().unwrap()
                ))
                .arg("--directory=po")
                .arg(format!("{}.po", lingua));

            match msgfmt.status() {
                Ok(status) => {
                    if !status.success() {
                        panic!(format!(
                            "Failed to generate mo file for lingua {}\n{:?}",
                            lingua, msgfmt,
                        ));
                    }
                }
                Err(ref error) => match error.kind() {
                    ErrorKind::NotFound => {
                        eprintln!("Can't generate translations: command `msgfmt` not available");
                        return;
                    }
                    _ => panic!("Error invoking `msgfmt`: {}", error),
                },
            }
        }
    }
}

// FIXME: figure out macOS conventions for icons & translations
#[cfg(target_family = "unix")]
fn generate_install_script() {
    let base_dirs = BaseDirs::new().unwrap();
    // Note: `base_dirs.executable_dir()` is `None` on macOS
    if let Some(exe_dir) = base_dirs.executable_dir() {
        let project_dirs = ProjectDirs::from("org", "fengalin", env!("CARGO_PKG_NAME")).unwrap();
        let app_data_dir = project_dirs.data_dir();
        let data_dir = app_data_dir.parent().unwrap();

        match File::create(&PathBuf::from("target").join("install")) {
            Ok(mut install_file) => {
                install_file
                    .write_all(
                        format!("# User install script for {}\n", env!("CARGO_PKG_NAME"))
                            .as_bytes(),
                    )
                    .unwrap();

                install_file.write_all(b"\n# Install executable\n").unwrap();
                let exe_source_path = PathBuf::from("..")
                    .join("target")
                    .join("release")
                    .join(env!("CARGO_PKG_NAME"));
                install_file
                    .write_all(format!("mkdir -p {}\n", exe_dir.to_str().unwrap()).as_bytes())
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp {} {}\n",
                            exe_source_path.to_str().unwrap(),
                            exe_dir.join(env!("CARGO_PKG_NAME")).to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();

                install_file.write_all(b"\n# Install icons\n").unwrap();
                let icon_target_dir = data_dir.join("icons").join("hicolor");
                let entry_iter =
                    read_dir(PathBuf::from("res").join("icons").join("hicolor")).unwrap();
                for entry in entry_iter {
                    let entry = entry.unwrap();
                    let entry_path = entry.path();
                    if entry_path.is_dir() {
                        let target_dir = icon_target_dir.join(&entry.file_name());
                        install_file
                            .write_all(
                                format!("mkdir -p {}\n", target_dir.to_str().unwrap()).as_bytes(),
                            )
                            .unwrap();

                        install_file
                            .write_all(
                                format!(
                                    "cp -r {:?}/* {:?}\n",
                                    entry_path.to_str().unwrap(),
                                    target_dir,
                                )
                                .as_bytes(),
                            )
                            .unwrap();
                    }
                }

                install_file
                    .write_all(b"\n# Install translations\n")
                    .unwrap();
                install_file
                    .write_all(format!("mkdir -p {}\n", data_dir.to_str().unwrap()).as_bytes())
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp -r {} {}\n",
                            PathBuf::from("..")
                                .join("target")
                                .join("locale")
                                .to_str()
                                .unwrap(),
                            data_dir.to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();

                install_file
                    .write_all(b"\n# Install desktop file\n")
                    .unwrap();
                let desktop_target_dir = data_dir.join("applications");
                install_file
                    .write_all(
                        format!("mkdir -p {}\n", desktop_target_dir.to_str().unwrap()).as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp {} {}\n",
                            PathBuf::from("res")
                                .join(&format!("org.fengalin.{}.desktop", env!("CARGO_PKG_NAME")))
                                .to_str()
                                .unwrap(),
                            desktop_target_dir.to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
            }
            Err(err) => panic!("Couldn't create file `target/install`: {:?}", err),
        }
    }
}

// FIXME: figure out macOS conventions for icons & translations
#[cfg(target_family = "unix")]
fn generate_uninstall_script() {
    let base_dirs = BaseDirs::new().unwrap();
    // Note: `base_dirs.executable_dir()` is `None` on macOS
    if let Some(exe_dir) = base_dirs.executable_dir() {
        let project_dirs = ProjectDirs::from("org", "fengalin", env!("CARGO_PKG_NAME")).unwrap();
        let app_data_dir = project_dirs.data_dir();
        let data_dir = app_data_dir.parent().unwrap();

        match File::create(&PathBuf::from("target").join("uninstall")) {
            Ok(mut install_file) => {
                install_file
                    .write_all(
                        format!("# User uninstall script for {}\n", env!("CARGO_PKG_NAME"))
                            .as_bytes(),
                    )
                    .unwrap();

                install_file
                    .write_all(b"\n# Uninstall executable\n")
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "rm {}\n",
                            exe_dir.join(env!("CARGO_PKG_NAME")).to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(format!("rmdir -p {}\n", exe_dir.to_str().unwrap()).as_bytes())
                    .unwrap();

                install_file.write_all(b"\n# Uninstall icons\n").unwrap();
                let icon_target_dir = data_dir.join("icons").join("hicolor");
                let entry_iter =
                    read_dir(PathBuf::from("res").join("icons").join("hicolor")).unwrap();
                for entry in entry_iter {
                    let entry = entry.unwrap();
                    let entry_path = entry.path();
                    if entry_path.is_dir() {
                        let icon_target_dir = icon_target_dir
                            .join(entry_path.file_name().unwrap())
                            .join("apps");
                        let icons_subdir_iter = read_dir(entry_path.join("apps")).unwrap();
                        for icon_subdir_entry in icons_subdir_iter {
                            let icon_subdir_entry = icon_subdir_entry.unwrap();
                            install_file
                                .write_all(
                                    format!(
                                        "rm {}\n",
                                        icon_target_dir
                                            .join(icon_subdir_entry.file_name())
                                            .to_str()
                                            .unwrap(),
                                    )
                                    .as_bytes(),
                                )
                                .unwrap();
                        }

                        install_file
                            .write_all(
                                format!("rmdir -p {}\n", icon_target_dir.to_str().unwrap())
                                    .as_bytes(),
                            )
                            .unwrap();
                    }
                }

                if let Ok(mut linguas_file) = File::open(&PathBuf::from("po").join("LINGUAS")) {
                    let mut linguas = String::new();
                    linguas_file
                        .read_to_string(&mut linguas)
                        .expect("Couldn't read po/LINGUAS as string");

                    install_file
                        .write_all(b"\n# Uninstall translations\n")
                        .unwrap();
                    let locale_base_dir = data_dir.join("locale");
                    for lingua in linguas.lines() {
                        let lingua_dir = locale_base_dir.join(lingua).join("LC_MESSAGES");
                        install_file
                            .write_all(
                                format!(
                                    "rm {}\n",
                                    lingua_dir
                                        .join(&format!("{}.mo", env!("CARGO_PKG_NAME")))
                                        .to_str()
                                        .unwrap(),
                                )
                                .as_bytes(),
                            )
                            .unwrap();

                        install_file
                            .write_all(
                                format!("rmdir -p {}\n", lingua_dir.to_str().unwrap()).as_bytes(),
                            )
                            .unwrap();
                    }
                }

                install_file
                    .write_all(b"\n# Uninstall desktop file\n")
                    .unwrap();
                let desktop_target_dir = data_dir.join("applications");
                install_file
                    .write_all(
                        format!(
                            "rm {}\n",
                            desktop_target_dir
                                .join(&format!("org.fengalin.{}.desktop", env!("CARGO_PKG_NAME")))
                                .to_str()
                                .unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(
                        format!("rmdir -p {}\n", desktop_target_dir.to_str().unwrap()).as_bytes(),
                    )
                    .unwrap();
            }
            Err(err) => panic!("Couldn't create file `target/uninstall`: {:?}", err),
        }
    }
}

fn main() {
    generate_resources();
    generate_translations();

    #[cfg(target_family = "unix")]
    generate_install_script();

    #[cfg(target_family = "unix")]
    generate_uninstall_script();
}
<commit_msg>Fix locale generation path<commit_after>extern crate directories;

#[cfg(target_family = "unix")]
use directories::{BaseDirs, ProjectDirs};

use std::fs::{create_dir_all, File};
use std::io::{ErrorKind, Read};
use std::path::PathBuf;
use std::process::Command;

#[cfg(target_family = "unix")]
use std::fs::read_dir;
#[cfg(target_family = "unix")]
use std::io::Write;

fn generate_resources() {
    let target_path = PathBuf::from("target").join("resources");
    create_dir_all(&target_path).unwrap();

    // Icons
    let input_path = PathBuf::from("res").join("icons").join("hicolor");

    let mut compile_res = Command::new("glib-compile-resources");
    compile_res
        .arg("--generate")
        .arg(format!("--sourcedir={}", input_path.to_str().unwrap()))
        .arg(format!(
            "--target={}",
            target_path.join("icons.gresource").to_str().unwrap(),
        ))
        .arg(input_path.join("icons.gresource.xml").to_str().unwrap());

    match compile_res.status() {
        Ok(status) => {
            if !status.success() {
                panic!(format!(
                    "Failed to generate resources file for icons\n{:?}",
                    compile_res,
                ));
            }
        }
        Err(ref error) => match error.kind() {
            ErrorKind::NotFound => panic!(
                "Can't generate icon resources: command `glib-compile-resources` not available"
            ),
            _ => panic!("Error invoking `compile_res`: {}", error),
        },
    }

    // UI
    let input_path = PathBuf::from("res").join("ui");

    let mut compile_res = Command::new("glib-compile-resources");
    compile_res
        .arg("--generate")
        .arg(format!("--sourcedir={}", input_path.to_str().unwrap()))
        .arg(format!(
            "--target={}",
            target_path.join("ui.gresource").to_str().unwrap(),
        ))
        .arg(input_path.join("ui.gresource.xml").to_str().unwrap());

    match compile_res.status() {
        Ok(status) => {
            if !status.success() {
                panic!(format!(
                    "Failed to generate resources file for the UI\n{:?}",
                    compile_res,
                ));
            }
        }
        Err(ref error) => match error.kind() {
            ErrorKind::NotFound => panic!(
                "Can't generate UI resources: command `glib-compile-resources` not available"
            ),
            _ => panic!("Error invoking `compile_res`: {}", error),
        },
    }
}

fn generate_translations() {
    if let Ok(mut linguas_file) = File::open(&PathBuf::from("po").join("LINGUAS")) {
        let mut linguas = String::new();
        linguas_file
            .read_to_string(&mut linguas)
            .expect("Couldn't read po/LINGUAS as string");

        for lingua in linguas.lines() {
            let mo_path = PathBuf::from("target")
                .join("locale")
                .join(lingua)
                .join("LC_MESSAGES");
            create_dir_all(&mo_path).unwrap();

            let mut msgfmt = Command::new("msgfmt");
            msgfmt
                .arg(format!(
                    "--output-file={}",
                    mo_path.join("media-toc.mo").to_str().unwrap()
                ))
                .arg("--directory=po")
                .arg(format!("{}.po", lingua));

            match msgfmt.status() {
                Ok(status) => {
                    if !status.success() {
                        panic!(format!(
                            "Failed to generate mo file for lingua {}\n{:?}",
                            lingua, msgfmt,
                        ));
                    }
                }
                Err(ref error) => match error.kind() {
                    ErrorKind::NotFound => {
                        eprintln!("Can't generate translations: command `msgfmt` not available");
                        return;
                    }
                    _ => panic!("Error invoking `msgfmt`: {}", error),
                },
            }
        }
    }
}

// FIXME: figure out macOS conventions for icons & translations
#[cfg(target_family = "unix")]
fn generate_install_script() {
    let base_dirs = BaseDirs::new().unwrap();
    // Note: `base_dirs.executable_dir()` is `None` on macOS
    if let Some(exe_dir) = base_dirs.executable_dir() {
        let project_dirs = ProjectDirs::from("org", "fengalin", env!("CARGO_PKG_NAME")).unwrap();
        let app_data_dir = project_dirs.data_dir();
        let data_dir = app_data_dir.parent().unwrap();

        match File::create(&PathBuf::from("target").join("install")) {
            Ok(mut install_file) => {
                install_file
                    .write_all(
                        format!("# User install script for {}\n", env!("CARGO_PKG_NAME"))
                            .as_bytes(),
                    )
                    .unwrap();

                install_file.write_all(b"\n# Install executable\n").unwrap();
                let exe_source_path = PathBuf::from("..")
                    .join("target")
                    .join("release")
                    .join(env!("CARGO_PKG_NAME"));
                install_file
                    .write_all(format!("mkdir -p {}\n", exe_dir.to_str().unwrap()).as_bytes())
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp {} {}\n",
                            exe_source_path.to_str().unwrap(),
                            exe_dir.join(env!("CARGO_PKG_NAME")).to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();

                install_file.write_all(b"\n# Install icons\n").unwrap();
                let icon_target_dir = data_dir.join("icons").join("hicolor");
                let entry_iter =
                    read_dir(PathBuf::from("res").join("icons").join("hicolor")).unwrap();
                for entry in entry_iter {
                    let entry = entry.unwrap();
                    let entry_path = entry.path();
                    if entry_path.is_dir() {
                        let target_dir = icon_target_dir.join(&entry.file_name());
                        install_file
                            .write_all(
                                format!("mkdir -p {}\n", target_dir.to_str().unwrap()).as_bytes(),
                            )
                            .unwrap();

                        install_file
                            .write_all(
                                format!(
                                    "cp -r {:?}/* {:?}\n",
                                    entry_path.to_str().unwrap(),
                                    target_dir,
                                )
                                .as_bytes(),
                            )
                            .unwrap();
                    }
                }

                install_file
                    .write_all(b"\n# Install translations\n")
                    .unwrap();
                install_file
                    .write_all(format!("mkdir -p {}\n", data_dir.to_str().unwrap()).as_bytes())
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp -r {} {}\n",
                            PathBuf::from("target").join("locale").to_str().unwrap(),
                            data_dir.to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();

                install_file
                    .write_all(b"\n# Install desktop file\n")
                    .unwrap();
                let desktop_target_dir = data_dir.join("applications");
                install_file
                    .write_all(
                        format!("mkdir -p {}\n", desktop_target_dir.to_str().unwrap()).as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "cp {} {}\n",
                            PathBuf::from("res")
                                .join(&format!("org.fengalin.{}.desktop", env!("CARGO_PKG_NAME")))
                                .to_str()
                                .unwrap(),
                            desktop_target_dir.to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
            }
            Err(err) => panic!("Couldn't create file `target/install`: {:?}", err),
        }
    }
}

// FIXME: figure out macOS conventions for icons & translations
#[cfg(target_family = "unix")]
fn generate_uninstall_script() {
    let base_dirs = BaseDirs::new().unwrap();
    // Note: `base_dirs.executable_dir()` is `None` on macOS
    if let Some(exe_dir) = base_dirs.executable_dir() {
        let project_dirs = ProjectDirs::from("org", "fengalin", env!("CARGO_PKG_NAME")).unwrap();
        let app_data_dir = project_dirs.data_dir();
        let data_dir = app_data_dir.parent().unwrap();

        match File::create(&PathBuf::from("target").join("uninstall")) {
            Ok(mut install_file) => {
                install_file
                    .write_all(
                        format!("# User uninstall script for {}\n", env!("CARGO_PKG_NAME"))
                            .as_bytes(),
                    )
                    .unwrap();

                install_file
                    .write_all(b"\n# Uninstall executable\n")
                    .unwrap();
                install_file
                    .write_all(
                        format!(
                            "rm {}\n",
                            exe_dir.join(env!("CARGO_PKG_NAME")).to_str().unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(format!("rmdir -p {}\n", exe_dir.to_str().unwrap()).as_bytes())
                    .unwrap();

                install_file.write_all(b"\n# Uninstall icons\n").unwrap();
                let icon_target_dir = data_dir.join("icons").join("hicolor");
                let entry_iter =
                    read_dir(PathBuf::from("res").join("icons").join("hicolor")).unwrap();
                for entry in entry_iter {
                    let entry = entry.unwrap();
                    let entry_path = entry.path();
                    if entry_path.is_dir() {
                        let icon_target_dir = icon_target_dir
                            .join(entry_path.file_name().unwrap())
                            .join("apps");
                        let icons_subdir_iter = read_dir(entry_path.join("apps")).unwrap();
                        for icon_subdir_entry in icons_subdir_iter {
                            let icon_subdir_entry = icon_subdir_entry.unwrap();
                            install_file
                                .write_all(
                                    format!(
                                        "rm {}\n",
                                        icon_target_dir
                                            .join(icon_subdir_entry.file_name())
                                            .to_str()
                                            .unwrap(),
                                    )
                                    .as_bytes(),
                                )
                                .unwrap();
                        }

                        install_file
                            .write_all(
                                format!("rmdir -p {}\n", icon_target_dir.to_str().unwrap())
                                    .as_bytes(),
                            )
                            .unwrap();
                    }
                }

                if let Ok(mut linguas_file) = File::open(&PathBuf::from("po").join("LINGUAS")) {
                    let mut linguas = String::new();
                    linguas_file
                        .read_to_string(&mut linguas)
                        .expect("Couldn't read po/LINGUAS as string");

                    install_file
                        .write_all(b"\n# Uninstall translations\n")
                        .unwrap();
                    let locale_base_dir = data_dir.join("locale");
                    for lingua in linguas.lines() {
                        let lingua_dir = locale_base_dir.join(lingua).join("LC_MESSAGES");
                        install_file
                            .write_all(
                                format!(
                                    "rm {}\n",
                                    lingua_dir
                                        .join(&format!("{}.mo", env!("CARGO_PKG_NAME")))
                                        .to_str()
                                        .unwrap(),
                                )
                                .as_bytes(),
                            )
                            .unwrap();

                        install_file
                            .write_all(
                                format!("rmdir -p {}\n", lingua_dir.to_str().unwrap()).as_bytes(),
                            )
                            .unwrap();
                    }
                }

                install_file
                    .write_all(b"\n# Uninstall desktop file\n")
                    .unwrap();
                let desktop_target_dir = data_dir.join("applications");
                install_file
                    .write_all(
                        format!(
                            "rm {}\n",
                            desktop_target_dir
                                .join(&format!("org.fengalin.{}.desktop", env!("CARGO_PKG_NAME")))
                                .to_str()
                                .unwrap(),
                        )
                        .as_bytes(),
                    )
                    .unwrap();
                install_file
                    .write_all(
                        format!("rmdir -p {}\n", desktop_target_dir.to_str().unwrap()).as_bytes(),
                    )
                    .unwrap();
            }
            Err(err) => panic!("Couldn't create file `target/uninstall`: {:?}", err),
        }
    }
}

fn main() {
    generate_resources();
    generate_translations();

    #[cfg(target_family = "unix")]
    generate_install_script();

    #[cfg(target_family = "unix")]
    generate_uninstall_script();
}
<|endoftext|>


<commit_before>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);

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

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 = "-fPIC"
    }
    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());
}
<commit_msg>prevent waf from putting the static lib into lib64<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);

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

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=/");
    cmd.arg("--libdir=/lib");

    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 = "-fPIC"
    }
    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 gcc;
#[macro_use] extern crate lazy_static;
extern crate regex;
extern crate semver;

use regex::Regex;
use semver::Version;
use std::env;
use std::ffi::OsStr;
use std::io::{self, ErrorKind};
use std::path::PathBuf;
use std::process::Command;

lazy_static!{
    /// LLVM version used by this version of the crate.
    static ref CRATE_VERSION: Version = {
        let crate_version = Version::parse(env!("CARGO_PKG_VERSION"))
            .expect("Crate version is somehow not valid semver");
        Version {
            major: crate_version.major / 10,
            minor: crate_version.major % 10,
            .. crate_version
        }
    };

    /// Filesystem path to an llvm-config binary for the correct version.
    static ref LLVM_CONFIG_PATH: PathBuf = {
        // Try llvm-config via PATH first.
        if let Some(name) = locate_system_llvm_config() {
            return name.into();
        } else {
            println!("Didn't find usable system-wide LLVM.");
        }

        // Did the user give us a binary path to use? If yes, try
        // to use that and fail if it doesn't work.
        let binary_prefix_var = format!("LLVM_SYS_{}_PREFIX",
                                        env!("CARGO_PKG_VERSION_MAJOR"));
        if let Some(path) = env::var_os(&binary_prefix_var) {
            let mut pb: PathBuf = path.into();
            pb.push("bin");
            pb.push("llvm-config");

            let ver = llvm_version(&pb)
                .expect(&format!("Failed to execute {:?}", &pb));
            if is_compatible_llvm(&ver) {
                return pb;
            } else {
                panic!("LLVM binaries specified by {} are the wrong version.
                        (Found {}, need {}.)", binary_prefix_var, ver, *CRATE_VERSION);
            }
        } else {
            println!("{} not set, not using precompiled binaries", binary_prefix_var);
        }

        // No binaries. Offer to download and compile a blessed version,
        // but only with positive confirmation. It's a fairly large download,
        // takes a while and could get wiped out by a `cargo clean` so it's
        // useful if doing an install but is in general not recommended.
        let autobuild_var = format!("LLVM_SYS_{}_AUTOBUILD",
                                    env!("CARGO_PKG_VERSION_MAJOR"));
        match env::var_os(&autobuild_var) {
            Some(ref x) => {
                if x == "YES" {
                    unimplemented!();
                } else {
                    println!("{} must be exactly \"YES\" to enable autobuild (is {:?})",
                             autobuild_var, x);
                }
            }
            None => {
                println!("{} not set, will not automatically compile LLVM",
                         autobuild_var);
            }
        }

        panic!("Could not find a compatible version of LLVM");
    };
}

/// Try to find a system-wide version of llvm-config that is compatible with
/// this crate.
///
/// Returns None on failure.
fn locate_system_llvm_config() -> Option<&'static str> {
    match llvm_version("llvm-config") {
        Ok(ref version) if is_compatible_llvm(version) => {
            // Compatible version found. Nice.
            return Some("llvm-config");
        },
        Ok(version) => {
            // Version mismatch. Will try further searches, but warn that
            // we're not using the system one.
            println!("Found LLVM version {} on PATH, but need {}.",
                     version, *CRATE_VERSION);
        },
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            // Looks like we failed to execute any llvm-config. Keep
            // searching.
        },
        // Some other error, probably a weird failure. Give up.
        Err(e) => panic!("Failed to search PATH for llvm-config: {}", e),
    }

    None
}

/// Check whether the given version of LLVM is blacklisted,
/// returning `Some(reason)` if it is.
fn is_blacklisted_llvm(llvm_version: &Version) -> Option<&'static str> {
    static BLACKLIST: &'static [(u64, u64, u64, &'static str)] = &[];

    let blacklist_var = format!("LLVM_SYS_{}_IGNORE_BLACKLIST",
                                env!("CARGO_PKG_VERSION_MAJOR"));
    if let Some(x) = env::var_os(&blacklist_var) {
        if &x == "YES" {
            println!("cargo:warning=Ignoring blacklist entry for LLVM {}", llvm_version);
            return None;
        } else {
            println!("cargo:warning={} is set but not exactly \"YES\"; blacklist is still honored.",
                     &blacklist_var);
        }
    }

    for &(major, minor, patch, reason) in BLACKLIST.iter() {
        let bad_version = Version {
            major: major, minor: minor, patch: patch,
            pre: vec![], build: vec![],
        };

        if &bad_version == llvm_version {
            return Some(reason);
        }
    }
    None
}
/// Check whether the given LLVM version is compatible with this version of
/// the crate.
fn is_compatible_llvm(llvm_version: &Version) -> bool {
    if let Some(reason) = is_blacklisted_llvm(llvm_version) {
        println!("Found LLVM {}, which is blacklisted: {}", llvm_version, reason);
        return false;
    }

    let strict = env::var_os(format!("LLVM_SYS_{}_STRICT_VERSIONING",
                                     env!("CARGO_PKG_VERSION_MAJOR"))).is_some()
        || cfg!(feature="strict-versioning");
    if strict {
        llvm_version.major == CRATE_VERSION.major &&
            llvm_version.minor == CRATE_VERSION.minor
    } else {
        llvm_version.major >= CRATE_VERSION.major &&
            llvm_version.minor >= CRATE_VERSION.minor
    }
}

/// Get the output from running `llvm-config` with the given argument.
///
/// Lazily searches for or compiles LLVM as configured by the environment
/// variables.
fn llvm_config(arg: &str) -> String {
    llvm_config_ex(&*LLVM_CONFIG_PATH, arg)
        .expect("Surprising failure from llvm-config")
}

/// Invoke the specified binary as llvm-config.
///
/// Explicit version of the `llvm_config` function that bubbles errors
/// up.
fn llvm_config_ex<S: AsRef<OsStr>>(binary: S, arg: &str)
        -> io::Result<String> {
    Command::new(binary)
        .arg(arg)
        .output()
        .map(|output| String::from_utf8(output.stdout)
            .expect("Output from llvm-config was not valid UTF-8"))
}

/// Get the LLVM version using llvm-config.
fn llvm_version<S: AsRef<OsStr>>(binary: S) -> io::Result<Version> {
    let version_str = try!(llvm_config_ex(binary.as_ref(), "--version"));

    // LLVM isn't really semver and uses version suffixes to build
    // version strings like '3.8.0svn', so limit what we try to parse
    // to only the numeric bits.
    let re = Regex::new(r"^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)")
        .unwrap();
    let (start, end) = re.find(&version_str)
        .expect("Could not determine LLVM version from llvm-config.");

    Ok(Version::parse(&version_str[start..end]).unwrap())
}

#[cfg(target_env = "msvc")]
fn lib_name(name: &str) -> &str {
    assert!(name.ends_with(".lib"));
    &name[..name.len() - 4]
}

#[cfg(not(target_env = "msvc"))]
fn lib_name(name: &str) -> &str {
    assert!(name.starts_with("-l"));
    &name[2..]
}

fn add_lib(kind: &'static str, name: &str) {
    println!("cargo:rustc-link-lib={}={}", kind, name);
}

fn add_libs(kind: &'static str, flag: &'static str) {
    for name in llvm_config(flag).split_whitespace().map(lib_name) {
        add_lib(kind, name);
    }
}

fn main() {
    add_libs("dylib", "--system-libs");

    println!("cargo:rustc-link-search=native={}", llvm_config("--libdir"));

    if cfg!(target_env = "msvc") {
        // --libs returns absolute paths when
        // LLVM was built on Windows with MSVC
        add_libs("static", "--libnames");
    } else {
        add_libs("static", "--libs");
        // Determine which C++ standard library to use: LLVM's or GCC's.
        // This breaks the link step on Windows with MSVC.
        add_lib("dylib", if llvm_config("--cxxflags").contains("stdlib=libc++") {
            "c++"
        } else {
            "stdc++"
        });
    }

    // Build the extra wrapper functions.
    std::env::set_var("CFLAGS", llvm_config("--cflags").trim());
    gcc::compile_library("libtargetwrappers.a", &["wrappers/target.c"]);
}
<commit_msg>Use --link-static with llvm-config where applicable<commit_after>extern crate gcc;
#[macro_use] extern crate lazy_static;
extern crate regex;
extern crate semver;

use regex::Regex;
use semver::Version;
use std::env;
use std::ffi::OsStr;
use std::io::{self, ErrorKind};
use std::path::PathBuf;
use std::process::Command;

lazy_static!{
    /// LLVM version used by this version of the crate.
    static ref CRATE_VERSION: Version = {
        let crate_version = Version::parse(env!("CARGO_PKG_VERSION"))
            .expect("Crate version is somehow not valid semver");
        Version {
            major: crate_version.major / 10,
            minor: crate_version.major % 10,
            .. crate_version
        }
    };

    /// Filesystem path to an llvm-config binary for the correct version.
    static ref LLVM_CONFIG_PATH: PathBuf = {
        // Try llvm-config via PATH first.
        if let Some(name) = locate_system_llvm_config() {
            return name.into();
        } else {
            println!("Didn't find usable system-wide LLVM.");
        }

        // Did the user give us a binary path to use? If yes, try
        // to use that and fail if it doesn't work.
        let binary_prefix_var = format!("LLVM_SYS_{}_PREFIX",
                                        env!("CARGO_PKG_VERSION_MAJOR"));
        if let Some(path) = env::var_os(&binary_prefix_var) {
            let mut pb: PathBuf = path.into();
            pb.push("bin");
            pb.push("llvm-config");

            let ver = llvm_version(&pb)
                .expect(&format!("Failed to execute {:?}", &pb));
            if is_compatible_llvm(&ver) {
                return pb;
            } else {
                panic!("LLVM binaries specified by {} are the wrong version.
                        (Found {}, need {}.)", binary_prefix_var, ver, *CRATE_VERSION);
            }
        } else {
            println!("{} not set, not using precompiled binaries", binary_prefix_var);
        }

        // No binaries. Offer to download and compile a blessed version,
        // but only with positive confirmation. It's a fairly large download,
        // takes a while and could get wiped out by a `cargo clean` so it's
        // useful if doing an install but is in general not recommended.
        let autobuild_var = format!("LLVM_SYS_{}_AUTOBUILD",
                                    env!("CARGO_PKG_VERSION_MAJOR"));
        match env::var_os(&autobuild_var) {
            Some(ref x) => {
                if x == "YES" {
                    unimplemented!();
                } else {
                    println!("{} must be exactly \"YES\" to enable autobuild (is {:?})",
                             autobuild_var, x);
                }
            }
            None => {
                println!("{} not set, will not automatically compile LLVM",
                         autobuild_var);
            }
        }

        panic!("Could not find a compatible version of LLVM");
    };
}

/// Try to find a system-wide version of llvm-config that is compatible with
/// this crate.
///
/// Returns None on failure.
fn locate_system_llvm_config() -> Option<&'static str> {
    match llvm_version("llvm-config") {
        Ok(ref version) if is_compatible_llvm(version) => {
            // Compatible version found. Nice.
            return Some("llvm-config");
        },
        Ok(version) => {
            // Version mismatch. Will try further searches, but warn that
            // we're not using the system one.
            println!("Found LLVM version {} on PATH, but need {}.",
                     version, *CRATE_VERSION);
        },
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            // Looks like we failed to execute any llvm-config. Keep
            // searching.
        },
        // Some other error, probably a weird failure. Give up.
        Err(e) => panic!("Failed to search PATH for llvm-config: {}", e),
    }

    None
}

/// Check whether the given version of LLVM is blacklisted,
/// returning `Some(reason)` if it is.
fn is_blacklisted_llvm(llvm_version: &Version) -> Option<&'static str> {
    static BLACKLIST: &'static [(u64, u64, u64, &'static str)] = &[];

    let blacklist_var = format!("LLVM_SYS_{}_IGNORE_BLACKLIST",
                                env!("CARGO_PKG_VERSION_MAJOR"));
    if let Some(x) = env::var_os(&blacklist_var) {
        if &x == "YES" {
            println!("cargo:warning=Ignoring blacklist entry for LLVM {}", llvm_version);
            return None;
        } else {
            println!("cargo:warning={} is set but not exactly \"YES\"; blacklist is still honored.",
                     &blacklist_var);
        }
    }

    for &(major, minor, patch, reason) in BLACKLIST.iter() {
        let bad_version = Version {
            major: major, minor: minor, patch: patch,
            pre: vec![], build: vec![],
        };

        if &bad_version == llvm_version {
            return Some(reason);
        }
    }
    None
}
/// Check whether the given LLVM version is compatible with this version of
/// the crate.
fn is_compatible_llvm(llvm_version: &Version) -> bool {
    if let Some(reason) = is_blacklisted_llvm(llvm_version) {
        println!("Found LLVM {}, which is blacklisted: {}", llvm_version, reason);
        return false;
    }

    let strict = env::var_os(format!("LLVM_SYS_{}_STRICT_VERSIONING",
                                     env!("CARGO_PKG_VERSION_MAJOR"))).is_some()
        || cfg!(feature="strict-versioning");
    if strict {
        llvm_version.major == CRATE_VERSION.major &&
            llvm_version.minor == CRATE_VERSION.minor
    } else {
        llvm_version.major >= CRATE_VERSION.major &&
            llvm_version.minor >= CRATE_VERSION.minor
    }
}

/// Get the output from running `llvm-config` with the given argument.
///
/// Lazily searches for or compiles LLVM as configured by the environment
/// variables.
fn llvm_config(args: &[&str]) -> String {
    llvm_config_ex(&*LLVM_CONFIG_PATH, args)
        .expect("Surprising failure from llvm-config")
}

/// Invoke the specified binary as llvm-config.
///
/// Explicit version of the `llvm_config` function that bubbles errors
/// up.
fn llvm_config_ex<S: AsRef<OsStr>>(binary: S, args: &[&str])
        -> io::Result<String> {
    Command::new(binary)
        .args(args)
        .output()
        .map(|output| String::from_utf8(output.stdout)
            .expect("Output from llvm-config was not valid UTF-8"))
}

/// Get the LLVM version using llvm-config.
fn llvm_version<S: AsRef<OsStr>>(binary: S) -> io::Result<Version> {
    let version_str = try!(llvm_config_ex(binary.as_ref(), &["--version"]));

    // LLVM isn't really semver and uses version suffixes to build
    // version strings like '3.8.0svn', so limit what we try to parse
    // to only the numeric bits.
    let re = Regex::new(r"^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)")
        .unwrap();
    let (start, end) = re.find(&version_str)
        .expect("Could not determine LLVM version from llvm-config.");

    Ok(Version::parse(&version_str[start..end]).unwrap())
}

#[cfg(target_env = "msvc")]
fn lib_name(name: &str) -> &str {
    assert!(name.ends_with(".lib"));
    &name[..name.len() - 4]
}

#[cfg(not(target_env = "msvc"))]
fn lib_name(name: &str) -> &str {
    assert!(name.starts_with("-l"));
    &name[2..]
}

fn add_lib(kind: &'static str, name: &str) {
    println!("cargo:rustc-link-lib={}={}", kind, name);
}

fn add_libs(kind: &'static str, flags: &[&'static str]) {
    for name in llvm_config(flags).split_whitespace().map(lib_name) {
        add_lib(kind, name);
    }
}

fn main() {
    add_libs("dylib", &["--system-libs"]);

    println!("cargo:rustc-link-search=native={}", llvm_config(&["--libdir"]));

    if cfg!(target_env = "msvc") {
        // --libs returns absolute paths when
        // LLVM was built on Windows with MSVC
        add_libs("static", &["--link-static", "--libnames"]);
    } else {
        add_libs("static", &["--link-static", "--libs"]);
        // Determine which C++ standard library to use: LLVM's or GCC's.
        // This breaks the link step on Windows with MSVC.
        add_lib("dylib", if llvm_config(&["--cxxflags"]).contains("stdlib=libc++") {
            "c++"
        } else {
            "stdc++"
        });
    }

    // Build the extra wrapper functions.
    std::env::set_var("CFLAGS", llvm_config(&["--cflags"]).trim());
    gcc::compile_library("libtargetwrappers.a", &["wrappers/target.c"]);
}
<|endoftext|>


<commit_before>extern crate gcc;

fn main() {
    let mut opencv_config = gcc::Build::new();
    opencv_config
        .cpp(true)
        .file("native/opencv-wrapper.cc")
        .file("native/utils.cc")
        .include("/usr/local/include")
        .include("%OPENCV_DIR%/include")
        .include("native")
        .flag("--std=c++11");

    if cfg!(feature = "gpu") {
        opencv_config.file("native/opencv-gpu.cc");
    }

    opencv_config.compile("libopencv-wrapper.a");

    println!("cargo:rustc-link-search=native=/usr/local/lib");
    println!("cargo:rustc-link-lib=opencv_core");
    println!("cargo:rustc-link-lib=opencv_imgcodecs");
    println!("cargo:rustc-link-lib=opencv_imgproc");
    println!("cargo:rustc-link-lib=opencv_highgui");
    println!("cargo:rustc-link-lib=opencv_videoio");
    println!("cargo:rustc-link-lib=opencv_objdetect");
    println!("cargo:rustc-link-lib=opencv_video");

    if cfg!(feature = "gpu") {
        println!("cargo:rustc-link-lib=opencv_cudaobjdetect");
    }
}
<commit_msg>Fix env var use<commit_after>extern crate gcc;

fn main() {
    let mut opencv_config = gcc::Build::new();
    opencv_config
        .cpp(true)
        .file("native/opencv-wrapper.cc")
        .file("native/utils.cc")
        .include("/usr/local/include")
        .include("native")
        .flag("--std=c++11");

    if let Ok(dir) = std::env::var("OPENCV_DIR") {
        opencv_config.include(format!("{}\\include", dir));
    }

    if cfg!(feature = "gpu") {
        opencv_config.file("native/opencv-gpu.cc");
    }

    opencv_config.compile("libopencv-wrapper.a");

    println!("cargo:rustc-link-search=native=/usr/local/lib");
    println!("cargo:rustc-link-lib=opencv_core");
    println!("cargo:rustc-link-lib=opencv_imgcodecs");
    println!("cargo:rustc-link-lib=opencv_imgproc");
    println!("cargo:rustc-link-lib=opencv_highgui");
    println!("cargo:rustc-link-lib=opencv_videoio");
    println!("cargo:rustc-link-lib=opencv_objdetect");
    println!("cargo:rustc-link-lib=opencv_video");

    if cfg!(feature = "gpu") {
        println!("cargo:rustc-link-lib=opencv_cudaobjdetect");
    }
}
<|endoftext|>


<commit_before>extern crate cc;

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

fn main() {
    let mut config = cc::Build::new();
    let root_path = Path::new("vendor/tree-sitter");

    config
        .flag("-std=c99")
        .flag("-Wno-unused-parameter")
        .include(root_path.join(Path::new("src")))
        .include(root_path.join(Path::new("include")))
        .include(root_path.join(Path::new("externals/utf8proc")));

    let source_filenames = [
      "get_changed_ranges.c",
      "language.c",
      "lexer.c",
      "node.c",
      "parser.c",
      "stack.c",
      "subtree.c",
      "tree_cursor.c",
      "tree.c",
      "utf16.c",
    ];

    config.files(source_filenames.iter().map(|source_filename| {
        root_path
            .join(Path::new(&"src/runtime"))
            .join(Path::new(&source_filename))
    }));

    config.file(root_path.join(Path::new("externals/utf8proc/utf8proc.c")));

    if env::var("RUST_TREE_SITTER_TEST").is_ok() {
        let parser_dir = Path::new("fixtures/tree-sitter-rust/src");
        config
            .file(parser_dir.join("parser.c"))
            .file(parser_dir.join("scanner.c"));
    }

    config.compile("treesitter_ffi");
}
<commit_msg>Tweak build script for windows<commit_after>extern crate cc;

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

fn main() {
    let mut config = cc::Build::new();
    let root_path: PathBuf = ["vendor", "tree-sitter"].iter().collect();

    config
        .flag_if_supported("-std=c99")
        .flag_if_supported("-Wno-unused-parameter")
        .include(root_path.join("src"))
        .include(root_path.join("include"))
        .include(root_path.join("externals").join("utf8proc"));

    let source_filenames = [
      "get_changed_ranges.c",
      "language.c",
      "lexer.c",
      "node.c",
      "parser.c",
      "stack.c",
      "subtree.c",
      "tree_cursor.c",
      "tree.c",
      "utf16.c",
    ];

    config.files(source_filenames.iter().map(|source_filename| {
        root_path
            .join("src")
            .join("runtime")
            .join(&source_filename)
    }));

    config.file(root_path.join("externals").join("utf8proc").join("utf8proc.c"));

    if env::var("RUST_TREE_SITTER_TEST").is_ok() {
        let parser_dir: PathBuf = ["fixtures", "tree-sitter-rust", "src"].iter().collect();
        config
            .file(parser_dir.join("parser.c"))
            .file(parser_dir.join("scanner.c"));
    }

    config.compile("tree-sitter-runtime");
}
<|endoftext|>


<commit_before>extern crate crowbook_intl;
use crowbook_intl::{Localizer, Extractor};

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

fn main() {
//    println!("cargo:rerun-if-changed=build.rs");
//    println!("cargo:rerun-if-changed=lang/fr.po");
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src")).unwrap();
    extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/fr.po"))).unwrap();
    let out_dir_path = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&out_dir_path);
    let dest_path = out_dir.join("localize_macros.rs");
    localizer.write_macro_file(dest_path.to_str().unwrap()).unwrap();
}
<commit_msg>Make build.rs more concise<commit_after>extern crate crowbook_intl;
use crowbook_intl::{Localizer, Extractor};

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

fn main() {
//    println!("cargo:rerun-if-changed=build.rs");
//    println!("cargo:rerun-if-changed=lang/fr.po");
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src")).unwrap();
    extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/fr.po"))).unwrap();
    let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
        .join("localize_macros.rs");
    localizer.write_macro_file(dest_path).unwrap();
}
<|endoftext|>


<commit_before>use redox::Box;
use redox::fs::File;
use redox::io::*;
use redox::mem;
use redox::ops::DerefMut;
use redox::slice;
use redox::syscall::sys_yield;
use redox::String;
use redox::ToString;
use redox::to_num::ToNum;
use redox::Vec;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: isize,
    /// The y coordinate of the window
    y: isize,
    /// The width of the window
    w: usize,
    /// The height of the window
    h: usize,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Vec<u32>,
}

impl Window {
    /// Create a new window
    pub fn new(x: isize, y: isize, w: usize, h: usize, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Some(mut font_file) = File::open("file:/ui/unifont.font") {
            font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:///{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Some(file) => Some(box Window {
                x: x,
                y: y,
                w: w,
                h: h,
                t: title.to_string(),
                file: file,
                font: font,
                data: vec![0; w * h * 4],
            }),
            None => None
        }
    }

    //TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Some(path) = self.file.path() {
            //orbital://x/y/w/h/t
            let parts: Vec<&str> = path.split('/').collect();
            if let Some(x) = parts.get(3) {
                self.x = x.to_num_signed();
            }
            if let Some(y) = parts.get(4) {
                self.y = y.to_num_signed();
            }
            if let Some(w) = parts.get(5) {
                self.w = w.to_num();
            }
            if let Some(h) = parts.get(6) {
                self.h = h.to_num();
            }
        }
    }

    /// Get x
    //TODO: Sync with window movements
    pub fn x(&self) -> isize {
        self.x
    }

    /// Get y
    //TODO: Sync with window movements
    pub fn y(&self) -> isize {
        self.y
    }

    /// Get width
    pub fn width(&self) -> usize {
        self.w
    }

    /// Get height
    pub fn height(&self) -> usize {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, title: &str) {
        //TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: isize, y: isize, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as isize && y < self.h as isize {
            let offset = y as usize * self.w + x as usize;
            self.data[offset] = color.data;
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: isize, y: isize, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as isize, y + row as isize, color);
                }
            }
            offset += 1;
        }
    }

    //TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        let w = self.w;
        let h = self.h;
        self.rect(0, 0, w, h, color);
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: isize, start_y: isize, w: usize, h: usize, color: Color) {
        for y in start_y..start_y + h as isize {
            for x in start_x..start_x + w as isize {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    //TODO: Improve speed
    pub fn image(&mut self, start_x: isize, start_y: isize, w: usize, h: usize, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as isize {
            for x in start_x..start_x + w as isize {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Poll for an event
    //TODO: clean this up
    pub fn poll(&mut self) -> Option<Event> {
        let mut event = Event::new();
        let event_ptr: *mut Event = &mut event;
        loop {
            match self.file.read(&mut unsafe {
                slice::from_raw_parts_mut(event_ptr as *mut u8, mem::size_of::<Event>())
            }) {
                Some(0) => unsafe { sys_yield() },
                Some(_) => return Some(event),
                None => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.seek(SeekFrom::Start(0));
        self.file.write(& unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * mem::size_of::<u32>())
        });
        return self.file.sync();
    }

    /// Return a iterator over events
    pub fn event_iter<'a>(&'a mut self) -> EventIter<'a> {
        EventIter {
            window: self,
        }
    }
}

/// Event iterator
pub struct EventIter<'a> {
    window: &'a mut Window,
}

impl<'a> Iterator for EventIter<'a> {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.window.poll()
    }
}
<commit_msg>Fix some bugs with spawn (not all)<commit_after>use redox::Box;
use redox::fs::File;
use redox::io::*;
use redox::mem;
use redox::slice;
use redox::syscall::sys_yield;
use redox::String;
use redox::ToString;
use redox::to_num::ToNum;
use redox::Vec;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: isize,
    /// The y coordinate of the window
    y: isize,
    /// The width of the window
    w: usize,
    /// The height of the window
    h: usize,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Vec<u32>,
}

impl Window {
    /// Create a new window
    pub fn new(x: isize, y: isize, w: usize, h: usize, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Some(mut font_file) = File::open("file:/ui/unifont.font") {
            font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:///{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Some(file) => Some(box Window {
                x: x,
                y: y,
                w: w,
                h: h,
                t: title.to_string(),
                file: file,
                font: font,
                data: vec![0; w * h * 4],
            }),
            None => None
        }
    }

    //TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Some(path) = self.file.path() {
            //orbital://x/y/w/h/t
            let parts: Vec<&str> = path.split('/').collect();
            if let Some(x) = parts.get(3) {
                self.x = x.to_num_signed();
            }
            if let Some(y) = parts.get(4) {
                self.y = y.to_num_signed();
            }
            if let Some(w) = parts.get(5) {
                self.w = w.to_num();
            }
            if let Some(h) = parts.get(6) {
                self.h = h.to_num();
            }
        }
    }

    /// Get x
    //TODO: Sync with window movements
    pub fn x(&self) -> isize {
        self.x
    }

    /// Get y
    //TODO: Sync with window movements
    pub fn y(&self) -> isize {
        self.y
    }

    /// Get width
    pub fn width(&self) -> usize {
        self.w
    }

    /// Get height
    pub fn height(&self) -> usize {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, _: &str) {
        //TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: isize, y: isize, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as isize && y < self.h as isize {
            let offset = y as usize * self.w + x as usize;
            self.data[offset] = color.data;
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: isize, y: isize, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as isize, y + row as isize, color);
                }
            }
            offset += 1;
        }
    }

    //TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        let w = self.w;
        let h = self.h;
        self.rect(0, 0, w, h, color);
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: isize, start_y: isize, w: usize, h: usize, color: Color) {
        for y in start_y..start_y + h as isize {
            for x in start_x..start_x + w as isize {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    //TODO: Improve speed
    pub fn image(&mut self, start_x: isize, start_y: isize, w: usize, h: usize, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as isize {
            for x in start_x..start_x + w as isize {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Poll for an event
    //TODO: clean this up
    pub fn poll(&mut self) -> Option<Event> {
        let mut event = Event::new();
        let event_ptr: *mut Event = &mut event;
        loop {
            match self.file.read(&mut unsafe {
                slice::from_raw_parts_mut(event_ptr as *mut u8, mem::size_of::<Event>())
            }) {
                Some(0) => unsafe { sys_yield() },
                Some(_) => return Some(event),
                None => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.seek(SeekFrom::Start(0));
        self.file.write(& unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8, self.data.len() * mem::size_of::<u32>())
        });
        return self.file.sync();
    }

    /// Return a iterator over events
    pub fn event_iter<'a>(&'a mut self) -> EventIter<'a> {
        EventIter {
            window: self,
        }
    }
}

/// Event iterator
pub struct EventIter<'a> {
    window: &'a mut Window,
}

impl<'a> Iterator for EventIter<'a> {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.window.poll()
    }
}
<|endoftext|>


<commit_before>use std::process::Command;

fn main()
{
	let git_output = Command::new("git").args(&["rev-parse", "HEAD"]).output().ok();
	let rev = git_output.and_then(|o| String::from_utf8(o.stdout).ok()).unwrap_or("<none>".to_owned());
	println!("cargo:rustc-env=TINA_REVISION={}", rev);
}
<commit_msg>build.rs: Handle the case when '.git' directory is removed<commit_after>use std::process::Command;

fn main()
{
	let git_output = Command::new("git").args(&["rev-parse", "HEAD"]).output().ok();
	let rev = git_output.filter(|o| o.status.success()).and_then(|o| String::from_utf8(o.stdout).ok()).unwrap_or("<none>".to_owned());
	println!("cargo:rustc-env=TINA_REVISION={}", rev);
}
<|endoftext|>