<commit_before>use std;
use std::{fmt::{Display, Formatter, Result}, ops::{Add, Sub}};

use cgmath::BaseFloat;
use gfx;

gfx_defines! {
  constant TileMapData {
    data: [f32; 4] = "data",
  }

  constant TilemapSettings {
    world_size: [f32; 2] = "u_WorldSize",
    tilesheet_size: [f32; 2] = "u_TilesheetSize",
  }

  vertex VertexData {
    pos: [f32; 2] = "a_Pos",
    uv: [f32; 2] = "a_BufPos",
  }

  constant CharacterSheet {
    x_div: f32 = "x_div",
    y_div: f32 = "y_div",
    row_idx: u32 = "a_row",
    index: f32 = "a_index",
  }

  constant Position {
    position: [f32; 2] = "a_position",
  }

  constant Rotation {
    rotation: f32 = "a_rotation",
  }

  constant Time {
    time_modulo: f32 = "a_time",
  }

  pipeline bullet_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    position_cb: gfx::ConstantBuffer<Position> = "b_BulletPosition",
    rotation_cb: gfx::ConstantBuffer<Rotation> = "b_BulletRotation",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline critter_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    position_cb: gfx::ConstantBuffer<Position> = "b_CharacterPosition",
    character_sprite_cb: gfx::ConstantBuffer<CharacterSheet> = "b_CharacterSprite",
    charactersheet: gfx::TextureSampler<[f32; 4]> = "t_CharacterSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline tilemap_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_TileMapPosition",
    time_passed_cb: gfx::ConstantBuffer<Time> = "b_TimeModulo",
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    tilemap: gfx::ConstantBuffer<TileMapData> = "b_TileMap",
    tilemap_cb: gfx::ConstantBuffer<TilemapSettings> = "b_PsLocals",
    tilesheet: gfx::TextureSampler<[f32; 4]> = "t_TileSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline static_element_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_StaticElementPosition",
    time_passed_cb: gfx::ConstantBuffer<Time> = "b_TimeModulo",
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    static_element_sheet: gfx::TextureSampler<[f32; 4]> = "t_StaticElementSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline text_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_TextPosition",
    text_sheet: gfx::TextureSampler<[f32; 4]> = "t_TextSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  constant Projection {
    model: [[f32; 4]; 4] = "u_Model",
    view: [[f32; 4]; 4] = "u_View",
    proj: [[f32; 4]; 4] = "u_Proj",
  }
}

impl Time {
  pub fn new(time_passed: u64) -> Time {
    let time_modulo = (time_passed % 89) as f32;
    Time {
      time_modulo
    }
  }
}

impl Rotation {
  pub fn new(rotation: f32) -> Rotation {
    Rotation {
      rotation
    }
  }
}

impl VertexData {
  pub fn new(pos: [f32; 2], uv: [f32; 2]) -> VertexData {
    VertexData {
      pos,
      uv,
    }
  }
}

impl Iterator for VertexData {
  type Item = VertexData;

  fn next(&mut self) -> Option<Self::Item> {
    Some(VertexData {pos: self.pos, uv: self.uv})
  }
}

impl TileMapData {
  pub fn new_empty() -> TileMapData {
    TileMapData { data: [32.0, 32.0, 0.0, 0.0] }
  }

  pub fn new(data: [f32; 4]) -> TileMapData {
    TileMapData { data }
  }
}

impl Position {
  pub fn new<T: BaseFloat>(x: T, y: T) -> Position where f32: std::convert::From<T> {
    Position { position: [f32::from(x), f32::from(y)] }
  }

  pub fn new_from_array(pos: [f32; 2]) -> Position {
    Position { position: pos }
  }

  pub fn origin() -> Position {
    Position { position: [0.0, 0.0] }
  }

  pub fn x(self) -> f32 {
    self.position[0]
  }

  pub fn y(self) -> f32 {
    self.position[1]
  }

  pub fn offset(self, x: f32, y:f32) -> Position {
    Position::new(self.position[0] + x, self.position[1] + y)
  }
}

impl Add for Position {
  type Output = Position;

  fn add(self, other: Position) -> Position {
    Position::new(self.x() + other.x(), self.y() + other.y())
  }
}

impl Sub for Position {
  type Output = Position;

  fn sub(self, other: Position) -> Position {
    Position::new(self.x() - other.x(), self.y() - other.y())
  }
}

impl Display for Position {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}, {}", self.x(), self.y())
  }
}
<commit_msg>Fix offset utility function<commit_after>use std;
use std::{fmt::{Display, Formatter, Result}, ops::{Add, Sub}};

use cgmath::BaseFloat;
use gfx;

gfx_defines! {
  constant TileMapData {
    data: [f32; 4] = "data",
  }

  constant TilemapSettings {
    world_size: [f32; 2] = "u_WorldSize",
    tilesheet_size: [f32; 2] = "u_TilesheetSize",
  }

  vertex VertexData {
    pos: [f32; 2] = "a_Pos",
    uv: [f32; 2] = "a_BufPos",
  }

  constant CharacterSheet {
    x_div: f32 = "x_div",
    y_div: f32 = "y_div",
    row_idx: u32 = "a_row",
    index: f32 = "a_index",
  }

  constant Position {
    position: [f32; 2] = "a_position",
  }

  constant Rotation {
    rotation: f32 = "a_rotation",
  }

  constant Time {
    time_modulo: f32 = "a_time",
  }

  pipeline bullet_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    position_cb: gfx::ConstantBuffer<Position> = "b_BulletPosition",
    rotation_cb: gfx::ConstantBuffer<Rotation> = "b_BulletRotation",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline critter_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    position_cb: gfx::ConstantBuffer<Position> = "b_CharacterPosition",
    character_sprite_cb: gfx::ConstantBuffer<CharacterSheet> = "b_CharacterSprite",
    charactersheet: gfx::TextureSampler<[f32; 4]> = "t_CharacterSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline tilemap_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_TileMapPosition",
    time_passed_cb: gfx::ConstantBuffer<Time> = "b_TimeModulo",
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    tilemap: gfx::ConstantBuffer<TileMapData> = "b_TileMap",
    tilemap_cb: gfx::ConstantBuffer<TilemapSettings> = "b_PsLocals",
    tilesheet: gfx::TextureSampler<[f32; 4]> = "t_TileSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline static_element_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_StaticElementPosition",
    time_passed_cb: gfx::ConstantBuffer<Time> = "b_TimeModulo",
    projection_cb: gfx::ConstantBuffer<Projection> = "b_VsLocals",
    static_element_sheet: gfx::TextureSampler<[f32; 4]> = "t_StaticElementSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  pipeline text_pipeline {
    vbuf: gfx::VertexBuffer<VertexData> = (),
    position_cb: gfx::ConstantBuffer<Position> = "b_TextPosition",
    text_sheet: gfx::TextureSampler<[f32; 4]> = "t_TextSheet",
    out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
    out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
  }

  constant Projection {
    model: [[f32; 4]; 4] = "u_Model",
    view: [[f32; 4]; 4] = "u_View",
    proj: [[f32; 4]; 4] = "u_Proj",
  }
}

impl Time {
  pub fn new(time_passed: u64) -> Time {
    let time_modulo = (time_passed % 89) as f32;
    Time {
      time_modulo
    }
  }
}

impl Rotation {
  pub fn new(rotation: f32) -> Rotation {
    Rotation {
      rotation
    }
  }
}

impl VertexData {
  pub fn new(pos: [f32; 2], uv: [f32; 2]) -> VertexData {
    VertexData {
      pos,
      uv,
    }
  }
}

impl Iterator for VertexData {
  type Item = VertexData;

  fn next(&mut self) -> Option<Self::Item> {
    Some(VertexData {pos: self.pos, uv: self.uv})
  }
}

impl TileMapData {
  pub fn new_empty() -> TileMapData {
    TileMapData { data: [32.0, 32.0, 0.0, 0.0] }
  }

  pub fn new(data: [f32; 4]) -> TileMapData {
    TileMapData { data }
  }
}

impl Position {
  pub fn new<T: BaseFloat>(x: T, y: T) -> Position where f32: std::convert::From<T> {
    Position { position: [f32::from(x), f32::from(y)] }
  }

  pub fn new_from_array(pos: [f32; 2]) -> Position {
    Position { position: pos }
  }

  pub fn origin() -> Position {
    Position { position: [0.0, 0.0] }
  }

  pub fn x(self) -> f32 {
    self.position[0]
  }

  pub fn y(self) -> f32 {
    self.position[1]
  }

  pub fn offset(self, x: f32, y:f32) -> Position {
    let new_x = if self.position[0] < 0.0 { self.position[0] - x } else { self.position[0] + x };
    let new_y = if self.position[1] < 0.0 { self.position[1] - y } else { self.position[1] + y };
    Position::new(new_x, new_y)
  }
}

impl Add for Position {
  type Output = Position;

  fn add(self, other: Position) -> Position {
    Position::new(self.x() + other.x(), self.y() + other.y())
  }
}

impl Sub for Position {
  type Output = Position;

  fn sub(self, other: Position) -> Position {
    Position::new(self.x() - other.x(), self.y() - other.y())
  }
}

impl Display for Position {
  fn fmt(&self, f: &mut Formatter) -> Result {
    write!(f, "{}, {}", self.x(), self.y())
  }
}
<|endoftext|>


<commit_before>//! Macros to define CSS properties.

use crate::properties::ComputedValues;

/// Trait which all CSS property types should implement.
///
/// This is generic on `T` for testing purposes; in the actual code `T` needs to
/// be [`ComputedValues`][crate::properties::ComputedValues].
pub trait Property {
    /// Whether the property's computed value inherits from parent to child elements.
    ///
    /// For each property, the CSS or SVG specs say whether the property inherits
    /// automatically.  When a property is not specified in an element, the return value
    /// of this method determines whether the property's value is copied from the parent
    /// element (`true`), or whether it resets to the initial/default value (`false`).
    fn inherits_automatically() -> bool;

    /// Derive the CSS computed value from the parent element's
    /// [`ComputedValues`][crate::properties::ComputedValues] and the
    /// `self` value.
    ///
    /// The CSS or SVG specs say how to derive this for each property.
    fn compute(&self, _: &ComputedValues) -> Self;
}

/// Generates a type for a CSS property.
///
/// Writing a property by hand takes a bit of boilerplate:
///
/// * Define a type to represent the property's values.
///
/// * A [`Parse`] implementation to parse the property.
///
/// * A [`Default`] implementation to define the property's *initial* value.
///
/// * A [`Property`] implementation to define whether the property
/// inherits from the parent element, and how the property derives its
/// computed value.
///
/// When going from [`SpecifiedValues`] to [`ComputedValues`],
/// properties which inherit automatically from the parent element
/// will just have their values cloned.  Properties which do not
/// inherit will be reset back to their initial value (i.e. their
/// [`Default`]).
///
/// The default implementation of [`Property::compute()`] is to just
/// clone the property's value.  Properties which need more
/// sophisticated computation can override this.
///
/// This macro allows defining properties of different kinds; see the following
/// sections for examples.
///
/// # Simple identifiers
///
/// Many properties are just sets of identifiers and can be represented
/// by simple enums.  In this case, you can use the following:
///
/// ```text
/// make_property!(
///   /// Documentation here.
///   StrokeLinejoin,
///   default: Miter,
///   inherits_automatically: true,
///
///   identifiers:
///     "miter" => Miter,
///     "round" => Round,
///     "bevel" => Bevel,
/// );
/// ```
///
/// This generates a simple enum like the following, with implementations of [`Parse`],
/// [`Default`], and [`Property`].
///
/// ```
/// pub enum StrokeLinejoin { Miter, Round, Bevel }
/// ```
///
/// # Properties from an existing, general-purpose type
///
/// For example, both the `lightingColor` and `floodColor` properties can be represented
/// with a `cssparser::Color`, but their intial values are different.  In this case, the macro
/// can generate a newtype around `cssparser::Color` for each case:
///
/// ```text
/// make_property!(
///     /// Documentation here.
///     FloodColor,
///     default: cssparser::Color::RGBA(cssparser::RGBA::new(0, 0, 0, 0)),
///     inherits_automatically: false,
///     newtype_parse: cssparser::Color,
/// );
/// ```
///
/// # Properties from custom specific types
///
/// For example, font-related properties have custom, complex types that require an
/// implentation of `Property::compute` that is more than a simple `clone`.  In this case,
/// define the custom type separately, and use the macro to specify the default value and
/// the `Property` implementation.
///
/// [`Parse`]: crate::parsers::Parse
/// [`Property`]: crate::property_macros::Property
/// [`ComputedValues`]: crate::properties::ComputedValues
/// [`SpecifiedValues`]: crate::properties::SpecifiedValues
/// [`Property::compute()`]: crate::property_macros::Property::compute
///
#[macro_export]
macro_rules! make_property {
    ($(#[$attr:meta])*
     $name: ident,
     default: $default: ident,
     inherits_automatically: $inherits_automatically: expr,
     identifiers:
     $($str_prop: expr => $variant: ident,)+
    ) => {
        $(#[$attr])*
        #[derive(Debug, Copy, Clone, PartialEq)]
        #[repr(C)]
        pub enum $name {
            $($variant),+
        }

        impl_default!($name, $name::$default);
        impl_property!($name, $inherits_automatically);

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok(parse_identifiers!(
                    parser,
                    $($str_prop => $name::$variant,)+
                )?)
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: ident,
     identifiers: { $($str_prop: expr => $variant: ident,)+ },
     property_impl: { $prop: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Copy, Clone, PartialEq)]
        #[repr(C)]
        pub enum $name {
            $($variant),+
        }

        impl_default!($name, $name::$default);
        $prop

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok(parse_identifiers!(
                    parser,
                    $($str_prop => $name::$variant,)+
                )?)
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     newtype_parse: $type: ty,
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));
        impl_property!($name, $inherits_automatically);

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok($name(<$type as crate::parsers::Parse>::parse(parser)?))
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     property_impl: { $prop: item }
    ) => {
        impl_default!($name, $default);

        $prop
    };

    ($name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
    ) => {
        impl_default!($name, $default);
        impl_property!($name, $inherits_automatically);
    };

    ($name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     parse_impl: { $parse: item }
    ) => {
        impl_default!($name, $default);
        impl_property!($name, $inherits_automatically);

        $parse
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     newtype: $type: ty,
     property_impl: { $prop: item },
     parse_impl: { $parse: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));

        $prop

        $parse
    };

    // pending - only XmlLang
    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     newtype: $type: ty,
     parse_impl: { $parse: item },
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));
        impl_property!($name, $inherits_automatically);

        $parse
    };

    ($(#[$attr:meta])*
     $name: ident,
     inherits_automatically: $inherits_automatically: expr,
     fields: {
       $($field_name: ident : $field_type: ty, default: $field_default : expr,)+
     }
     parse_impl: { $parse: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name {
            $(pub $field_name: $field_type),+
        }

        impl_default!($name, $name { $($field_name: $field_default),+ });
        impl_property!($name, $inherits_automatically);

        $parse
    };
}

macro_rules! impl_default {
    ($name:ident, $default:expr) => {
        impl Default for $name {
            fn default() -> $name {
                $default
            }
        }
    };
}

macro_rules! impl_property {
    ($name:ident, $inherits_automatically:expr) => {
        impl crate::property_macros::Property for $name {
            fn inherits_automatically() -> bool {
                $inherits_automatically
            }

            fn compute(&self, _v: &crate::properties::ComputedValues) -> Self {
                self.clone()
            }
        }
    };
}
<commit_msg>Remove obsolete comment<commit_after>//! Macros to define CSS properties.

use crate::properties::ComputedValues;

/// Trait which all CSS property types should implement.
pub trait Property {
    /// Whether the property's computed value inherits from parent to child elements.
    ///
    /// For each property, the CSS or SVG specs say whether the property inherits
    /// automatically.  When a property is not specified in an element, the return value
    /// of this method determines whether the property's value is copied from the parent
    /// element (`true`), or whether it resets to the initial/default value (`false`).
    fn inherits_automatically() -> bool;

    /// Derive the CSS computed value from the parent element's
    /// [`ComputedValues`][crate::properties::ComputedValues] and the
    /// `self` value.
    ///
    /// The CSS or SVG specs say how to derive this for each property.
    fn compute(&self, _: &ComputedValues) -> Self;
}

/// Generates a type for a CSS property.
///
/// Writing a property by hand takes a bit of boilerplate:
///
/// * Define a type to represent the property's values.
///
/// * A [`Parse`] implementation to parse the property.
///
/// * A [`Default`] implementation to define the property's *initial* value.
///
/// * A [`Property`] implementation to define whether the property
/// inherits from the parent element, and how the property derives its
/// computed value.
///
/// When going from [`SpecifiedValues`] to [`ComputedValues`],
/// properties which inherit automatically from the parent element
/// will just have their values cloned.  Properties which do not
/// inherit will be reset back to their initial value (i.e. their
/// [`Default`]).
///
/// The default implementation of [`Property::compute()`] is to just
/// clone the property's value.  Properties which need more
/// sophisticated computation can override this.
///
/// This macro allows defining properties of different kinds; see the following
/// sections for examples.
///
/// # Simple identifiers
///
/// Many properties are just sets of identifiers and can be represented
/// by simple enums.  In this case, you can use the following:
///
/// ```text
/// make_property!(
///   /// Documentation here.
///   StrokeLinejoin,
///   default: Miter,
///   inherits_automatically: true,
///
///   identifiers:
///     "miter" => Miter,
///     "round" => Round,
///     "bevel" => Bevel,
/// );
/// ```
///
/// This generates a simple enum like the following, with implementations of [`Parse`],
/// [`Default`], and [`Property`].
///
/// ```
/// pub enum StrokeLinejoin { Miter, Round, Bevel }
/// ```
///
/// # Properties from an existing, general-purpose type
///
/// For example, both the `lightingColor` and `floodColor` properties can be represented
/// with a `cssparser::Color`, but their intial values are different.  In this case, the macro
/// can generate a newtype around `cssparser::Color` for each case:
///
/// ```text
/// make_property!(
///     /// Documentation here.
///     FloodColor,
///     default: cssparser::Color::RGBA(cssparser::RGBA::new(0, 0, 0, 0)),
///     inherits_automatically: false,
///     newtype_parse: cssparser::Color,
/// );
/// ```
///
/// # Properties from custom specific types
///
/// For example, font-related properties have custom, complex types that require an
/// implentation of `Property::compute` that is more than a simple `clone`.  In this case,
/// define the custom type separately, and use the macro to specify the default value and
/// the `Property` implementation.
///
/// [`Parse`]: crate::parsers::Parse
/// [`Property`]: crate::property_macros::Property
/// [`ComputedValues`]: crate::properties::ComputedValues
/// [`SpecifiedValues`]: crate::properties::SpecifiedValues
/// [`Property::compute()`]: crate::property_macros::Property::compute
///
#[macro_export]
macro_rules! make_property {
    ($(#[$attr:meta])*
     $name: ident,
     default: $default: ident,
     inherits_automatically: $inherits_automatically: expr,
     identifiers:
     $($str_prop: expr => $variant: ident,)+
    ) => {
        $(#[$attr])*
        #[derive(Debug, Copy, Clone, PartialEq)]
        #[repr(C)]
        pub enum $name {
            $($variant),+
        }

        impl_default!($name, $name::$default);
        impl_property!($name, $inherits_automatically);

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok(parse_identifiers!(
                    parser,
                    $($str_prop => $name::$variant,)+
                )?)
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: ident,
     identifiers: { $($str_prop: expr => $variant: ident,)+ },
     property_impl: { $prop: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Copy, Clone, PartialEq)]
        #[repr(C)]
        pub enum $name {
            $($variant),+
        }

        impl_default!($name, $name::$default);
        $prop

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok(parse_identifiers!(
                    parser,
                    $($str_prop => $name::$variant,)+
                )?)
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     newtype_parse: $type: ty,
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));
        impl_property!($name, $inherits_automatically);

        impl crate::parsers::Parse for $name {
            fn parse<'i>(parser: &mut ::cssparser::Parser<'i, '_>) -> Result<$name, crate::error::ParseError<'i>> {
                Ok($name(<$type as crate::parsers::Parse>::parse(parser)?))
            }
        }
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     property_impl: { $prop: item }
    ) => {
        impl_default!($name, $default);

        $prop
    };

    ($name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
    ) => {
        impl_default!($name, $default);
        impl_property!($name, $inherits_automatically);
    };

    ($name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     parse_impl: { $parse: item }
    ) => {
        impl_default!($name, $default);
        impl_property!($name, $inherits_automatically);

        $parse
    };

    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     newtype: $type: ty,
     property_impl: { $prop: item },
     parse_impl: { $parse: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));

        $prop

        $parse
    };

    // pending - only XmlLang
    ($(#[$attr:meta])*
     $name: ident,
     default: $default: expr,
     inherits_automatically: $inherits_automatically: expr,
     newtype: $type: ty,
     parse_impl: { $parse: item },
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name(pub $type);

        impl_default!($name, $name($default));
        impl_property!($name, $inherits_automatically);

        $parse
    };

    ($(#[$attr:meta])*
     $name: ident,
     inherits_automatically: $inherits_automatically: expr,
     fields: {
       $($field_name: ident : $field_type: ty, default: $field_default : expr,)+
     }
     parse_impl: { $parse: item }
    ) => {
        $(#[$attr])*
        #[derive(Debug, Clone, PartialEq)]
        pub struct $name {
            $(pub $field_name: $field_type),+
        }

        impl_default!($name, $name { $($field_name: $field_default),+ });
        impl_property!($name, $inherits_automatically);

        $parse
    };
}

macro_rules! impl_default {
    ($name:ident, $default:expr) => {
        impl Default for $name {
            fn default() -> $name {
                $default
            }
        }
    };
}

macro_rules! impl_property {
    ($name:ident, $inherits_automatically:expr) => {
        impl crate::property_macros::Property for $name {
            fn inherits_automatically() -> bool {
                $inherits_automatically
            }

            fn compute(&self, _v: &crate::properties::ComputedValues) -> Self {
                self.clone()
            }
        }
    };
}
<|endoftext|>


<commit_before>use super::{Color, Event, Point, Rect, Renderer, Widget};

use std::sync::Arc;

extern crate orbital;

pub struct WindowRenderer<'a> {
    inner: &'a mut Box<orbital::Window>,
}

impl<'a> WindowRenderer<'a> {
    pub fn new(inner: &'a mut Box<orbital::Window>) -> WindowRenderer {
        WindowRenderer { inner: inner }
    }
}

impl<'a> Renderer for WindowRenderer<'a> {
    fn clear(&mut self, color: Color) {
        self.inner.set(orbital::Color { data: color.data });
    }

    fn char(&mut self, pos: Point, c: char, color: Color) {
        self.inner.char(pos.x, pos.y, c, orbital::Color { data: color.data });
    }

    fn rect(&mut self, rect: Rect, color: Color) {
        self.inner.rect(rect.x,
                        rect.y,
                        rect.width,
                        rect.height,
                        orbital::Color { data: color.data });
    }
}

impl<'a> Drop for WindowRenderer<'a> {
    fn drop(&mut self) {
        self.inner.sync();
    }
}

pub struct Window {
    inner: Box<orbital::Window>,
    pub widgets: Vec<Arc<Widget>>,
    pub widget_focus: usize,
    pub bg: Color,
}

impl Window {
    pub fn new(rect: Rect, title: &str) -> Box<Self> {
        Box::new(Window {
            inner: orbital::Window::new(rect.x, rect.y, rect.width, rect.height, title).unwrap(),
            widgets: Vec::new(),
            widget_focus: 0,
            bg: Color::rgb(237, 233, 227),
        })
    }

    pub fn draw(&mut self) {
        let mut renderer = WindowRenderer::new(&mut self.inner);
        renderer.clear(self.bg);
        for widget in self.widgets.iter() {
            widget.draw(&mut renderer);
        }
    }

    pub fn exec(&mut self) {
        self.draw();
        'event: loop {
            let mut events = Vec::new();

            for orbital_event in self.inner.events() {
                match orbital_event.to_option() {
                    orbital::EventOption::Mouse(mouse_event) => {
                        events.push(Event::Mouse {
                            point: Point::new(mouse_event.x, mouse_event.y),
                            left_button: mouse_event.left_button,
                            middle_button: mouse_event.middle_button,
                            right_button: mouse_event.right_button,
                        })
                    }
                    orbital::EventOption::Key(key_event) => {
                        if key_event.pressed {
                            match key_event.scancode {
                                orbital::K_BKSP => events.push(Event::Backspace),
                                orbital::K_DEL => events.push(Event::Delete),
                                orbital::K_HOME => events.push(Event::Home),
                                orbital::K_END => events.push(Event::End),
                                orbital::K_UP => events.push(Event::UpArrow),
                                orbital::K_DOWN => events.push(Event::DownArrow),
                                orbital::K_LEFT => events.push(Event::LeftArrow),
                                orbital::K_RIGHT => events.push(Event::RightArrow),
                                _ => {
                                    match key_event.character {
                                        '\0' => (),
                                        '\x1B' => (),
                                        '\n' => events.push(Event::Enter),
                                        _ => events.push(Event::Text { c: key_event.character }),
                                    }
                                }
                            }
                        }
                    }
                    orbital::EventOption::Quit(_quit_event) => break 'event,
                    _ => (),
                };
            }

            for event in events.iter() {
                for i in 0..self.widgets.len() {
                    if let Some(widget) = self.widgets.get(i) {
                        if widget.event(*event, self.widget_focus == i) {
                            self.widget_focus = i;
                        }
                    }
                }
            }

            self.draw();
        }
    }
}
<commit_msg>Orbital -> Orbclient<commit_after>use super::{Color, Event, Point, Rect, Renderer, Widget};

use std::sync::Arc;

extern crate orbclient;

pub struct WindowRenderer<'a> {
    inner: &'a mut Box<orbclient::Window>,
}

impl<'a> WindowRenderer<'a> {
    pub fn new(inner: &'a mut Box<orbclient::Window>) -> WindowRenderer {
        WindowRenderer { inner: inner }
    }
}

impl<'a> Renderer for WindowRenderer<'a> {
    fn clear(&mut self, color: Color) {
        self.inner.set(orbclient::Color { data: color.data });
    }

    fn char(&mut self, pos: Point, c: char, color: Color) {
        self.inner.char(pos.x, pos.y, c, orbclient::Color { data: color.data });
    }

    fn rect(&mut self, rect: Rect, color: Color) {
        self.inner.rect(rect.x,
                        rect.y,
                        rect.width,
                        rect.height,
                        orbclient::Color { data: color.data });
    }
}

impl<'a> Drop for WindowRenderer<'a> {
    fn drop(&mut self) {
        self.inner.sync();
    }
}

pub struct Window {
    inner: Box<orbclient::Window>,
    pub widgets: Vec<Arc<Widget>>,
    pub widget_focus: usize,
    pub bg: Color,
}

impl Window {
    pub fn new(rect: Rect, title: &str) -> Box<Self> {
        Box::new(Window {
            inner: orbclient::Window::new(rect.x, rect.y, rect.width, rect.height, title).unwrap(),
            widgets: Vec::new(),
            widget_focus: 0,
            bg: Color::rgb(237, 233, 227),
        })
    }

    pub fn draw(&mut self) {
        let mut renderer = WindowRenderer::new(&mut self.inner);
        renderer.clear(self.bg);
        for widget in self.widgets.iter() {
            widget.draw(&mut renderer);
        }
    }

    pub fn exec(&mut self) {
        self.draw();
        'event: loop {
            let mut events = Vec::new();

            for orbital_event in self.inner.events() {
                match orbital_event.to_option() {
                    orbclient::EventOption::Mouse(mouse_event) => {
                        events.push(Event::Mouse {
                            point: Point::new(mouse_event.x, mouse_event.y),
                            left_button: mouse_event.left_button,
                            middle_button: mouse_event.middle_button,
                            right_button: mouse_event.right_button,
                        })
                    }
                    orbclient::EventOption::Key(key_event) => {
                        if key_event.pressed {
                            match key_event.scancode {
                                orbclient::K_BKSP => events.push(Event::Backspace),
                                orbclient::K_DEL => events.push(Event::Delete),
                                orbclient::K_HOME => events.push(Event::Home),
                                orbclient::K_END => events.push(Event::End),
                                orbclient::K_UP => events.push(Event::UpArrow),
                                orbclient::K_DOWN => events.push(Event::DownArrow),
                                orbclient::K_LEFT => events.push(Event::LeftArrow),
                                orbclient::K_RIGHT => events.push(Event::RightArrow),
                                _ => {
                                    match key_event.character {
                                        '\0' => (),
                                        '\x1B' => (),
                                        '\n' => events.push(Event::Enter),
                                        _ => events.push(Event::Text { c: key_event.character }),
                                    }
                                }
                            }
                        }
                    }
                    orbclient::EventOption::Quit(_quit_event) => break 'event,
                    _ => (),
                };
            }

            for event in events.iter() {
                for i in 0..self.widgets.len() {
                    if let Some(widget) = self.widgets.get(i) {
                        if widget.event(*event, self.widget_focus == i) {
                            self.widget_focus = i;
                        }
                    }
                }
            }

            self.draw();
        }
    }
}
<|endoftext|>


<commit_before>use runtime::Runtime;

use std::io;

pub fn repl(args: Vec<String>) {
    let mut runtime = Runtime::new();

    if args.len() > 1 {
        let path = Path::new(&args[1]);

        match runtime.eval_file(&path) {
            Ok(expr) => println!("{}", expr),
            Err(error) => println!("{}", error),
        }
    } else {
        enter_repl(&mut runtime);
    }
}

fn enter_repl(runtime: &mut Runtime) {
    let mut input = io::stdin();

    loop {
        print!("> ");

        match input.read_line() {
            Ok(line) => {
                match line.as_slice() {
                    "exit\n" => break,
                    "dump-heap\n" => {
                        runtime.dump_heap();
                    }
                    line => {
                        match runtime.eval_str(line) {
                            Ok(exprs) => {
                                for expr in exprs.iter() {
                                    println!("=> {}", expr);
                                }
                            },
                            Err(error) => println!("Error: {}", error),
                        }
                    }
                }
            },
            Err(error) => {
                match error.kind {
                    io::IoErrorKind::EndOfFile => break,
                    _ => panic!("{}", error),
                }
            },
        }
    }
}
<commit_msg>Do not print out the evaluation results when executing a file.<commit_after>use runtime::Runtime;

use std::io;

pub fn repl(args: Vec<String>) {
    let mut runtime = Runtime::new();

    if args.len() > 1 {
        let path = Path::new(&args[1]);

        match runtime.eval_file(&path) {
            Ok(_)      => (),
            Err(error) => println!("{}", error),
        }
    } else {
        enter_repl(&mut runtime);
    }
}

fn enter_repl(runtime: &mut Runtime) {
    let mut input = io::stdin();

    loop {
        print!("> ");

        match input.read_line() {
            Ok(line) => {
                match line.as_slice() {
                    "exit\n" => break,
                    "dump-heap\n" => {
                        runtime.dump_heap();
                    }
                    line => {
                        match runtime.eval_str(line) {
                            Ok(exprs) => {
                                for expr in exprs.iter() {
                                    println!("=> {}", expr);
                                }
                            },
                            Err(error) => println!("Error: {}", error),
                        }
                    }
                }
            },
            Err(error) => {
                match error.kind {
                    io::IoErrorKind::EndOfFile => break,
                    _ => panic!("{}", error),
                }
            },
        }
    }
}
<|endoftext|>


<commit_before>//! Utilities for tracking time.
//!
//! This module provides a number of types for executing code after a set period
//! of time.
//!
//! * [`Delay`][Delay] is a future that does no work and completes at a specific `Instant`
//!   in time.
//!
//! * [`Interval`][Interval] is a stream yielding a value at a fixed period. It
//!   is initialized with a `Duration` and repeatedly yields each time the
//!   duration elapses.
//!
//! * [`Timeout`][Timeout]: Wraps a future or stream, setting an upper bound to the
//!   amount of time it is allowed to execute. If the future or stream does not
//!   complete in time, then it is canceled and an error is returned.
//!
//! * [`DelayQueue`]: A queue where items are returned once the requested delay
//!   has expired.
//!
//! These types are sufficient for handling a large number of scenarios
//! involving time.
//!
//! These types must be used from within the context of the
//! [`Runtime`][runtime] or a timer context must be setup explicitly. See the
//! [`tokio-timer`][tokio-timer] crate for more details on how to setup a timer
//! context.
//!
//! # Examples
//!
//! Wait 100ms and print "Hello World!"
//!
//! ```
//! use tokio::timer::delay;
//!
//! use std::time::Duration;
//!
//!
//! #[tokio::main]
//! async fn main() {
//!     let when = tokio::clock::now() + Duration::from_millis(100);
//!     delay(when).await;
//!     println!("100 ms have elapsed");
//! }
//! ```
//!
//! Require that an operation takes no more than 300ms. Note that this uses the
//! [`timeout`][ext] function on the [`FutureExt`][ext] trait. This trait is
//! included in the prelude.
//!
//! ```
//! use tokio::prelude::*;
//! use std::time::Duration;
//!
//! async fn long_future() {
//!     // do work here
//! }
//!
//! # async fn dox() {
//! let res = long_future()
//!     .timeout(Duration::from_secs(1))
//!     .await;
//!
//! if res.is_err() {
//!     println!("operation timed out");
//! }
//! # }
//! ```
//!
//! [runtime]: ../runtime/struct.Runtime.html
//! [tokio-timer]: https://docs.rs/tokio-timer
//! [ext]: ../util/trait.FutureExt.html#method.timeout
//! [Timeout]: struct.Timeout.html
//! [Delay]: struct.Delay.html
//! [Interval]: struct.Interval.html
//! [`DelayQueue`]: struct.DelayQueue.html

pub mod clock;

pub mod delay_queue;
#[doc(inline)]
pub use self::delay_queue::DelayQueue;

pub mod throttle;

// TODO: clean this up
#[allow(clippy::module_inception)]
pub mod timer;
pub use timer::{set_default, Timer};

pub mod timeout;
#[doc(inline)]
pub use timeout::Timeout;

mod atomic;

mod delay;
pub use self::delay::Delay;

mod error;
pub use error::Error;

mod interval;
pub use interval::Interval;

mod wheel;

use std::time::{Duration, Instant};

/// Create a Future that completes at `deadline`.
pub fn delay(deadline: Instant) -> Delay {
    Delay::new(deadline)
}

/// Create a Future that completes in `duration` from now.
///
/// Equivalent to `delay(tokio::timer::clock::now() + duration)`. Analogous to `std::thread::sleep`.
pub fn delay_for(duration: Duration) -> Delay {
    delay(clock::now() + duration)
}

// ===== Internal utils =====

enum Round {
    Up,
    Down,
}

/// Convert a `Duration` to milliseconds, rounding up and saturating at
/// `u64::MAX`.
///
/// The saturating is fine because `u64::MAX` milliseconds are still many
/// million years.
#[inline]
fn ms(duration: Duration, round: Round) -> u64 {
    const NANOS_PER_MILLI: u32 = 1_000_000;
    const MILLIS_PER_SEC: u64 = 1_000;

    // Round up.
    let millis = match round {
        Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI,
        Round::Down => duration.subsec_millis(),
    };

    duration
        .as_secs()
        .saturating_mul(MILLIS_PER_SEC)
        .saturating_add(u64::from(millis))
}
<commit_msg>timer: have example use delay_for instead of delay (#1735)<commit_after>//! Utilities for tracking time.
//!
//! This module provides a number of types for executing code after a set period
//! of time.
//!
//! * [`Delay`][Delay] is a future that does no work and completes at a specific `Instant`
//!   in time.
//!
//! * [`Interval`][Interval] is a stream yielding a value at a fixed period. It
//!   is initialized with a `Duration` and repeatedly yields each time the
//!   duration elapses.
//!
//! * [`Timeout`][Timeout]: Wraps a future or stream, setting an upper bound to the
//!   amount of time it is allowed to execute. If the future or stream does not
//!   complete in time, then it is canceled and an error is returned.
//!
//! * [`DelayQueue`]: A queue where items are returned once the requested delay
//!   has expired.
//!
//! These types are sufficient for handling a large number of scenarios
//! involving time.
//!
//! These types must be used from within the context of the
//! [`Runtime`][runtime] or a timer context must be setup explicitly. See the
//! [`tokio-timer`][tokio-timer] crate for more details on how to setup a timer
//! context.
//!
//! # Examples
//!
//! Wait 100ms and print "Hello World!"
//!
//! ```
//! use tokio::timer::delay_for;
//!
//! use std::time::Duration;
//!
//!
//! #[tokio::main]
//! async fn main() {
//!     delay_for(Duration::from_millis(100)).await;
//!     println!("100 ms have elapsed");
//! }
//! ```
//!
//! Require that an operation takes no more than 300ms. Note that this uses the
//! [`timeout`][ext] function on the [`FutureExt`][ext] trait. This trait is
//! included in the prelude.
//!
//! ```
//! use tokio::prelude::*;
//! use std::time::Duration;
//!
//! async fn long_future() {
//!     // do work here
//! }
//!
//! # async fn dox() {
//! let res = long_future()
//!     .timeout(Duration::from_secs(1))
//!     .await;
//!
//! if res.is_err() {
//!     println!("operation timed out");
//! }
//! # }
//! ```
//!
//! [runtime]: ../runtime/struct.Runtime.html
//! [tokio-timer]: https://docs.rs/tokio-timer
//! [ext]: ../util/trait.FutureExt.html#method.timeout
//! [Timeout]: struct.Timeout.html
//! [Delay]: struct.Delay.html
//! [Interval]: struct.Interval.html
//! [`DelayQueue`]: struct.DelayQueue.html

pub mod clock;

pub mod delay_queue;
#[doc(inline)]
pub use self::delay_queue::DelayQueue;

pub mod throttle;

// TODO: clean this up
#[allow(clippy::module_inception)]
pub mod timer;
pub use timer::{set_default, Timer};

pub mod timeout;
#[doc(inline)]
pub use timeout::Timeout;

mod atomic;

mod delay;
pub use self::delay::Delay;

mod error;
pub use error::Error;

mod interval;
pub use interval::Interval;

mod wheel;

use std::time::{Duration, Instant};

/// Create a Future that completes at `deadline`.
pub fn delay(deadline: Instant) -> Delay {
    Delay::new(deadline)
}

/// Create a Future that completes in `duration` from now.
///
/// Equivalent to `delay(tokio::timer::clock::now() + duration)`. Analogous to `std::thread::sleep`.
pub fn delay_for(duration: Duration) -> Delay {
    delay(clock::now() + duration)
}

// ===== Internal utils =====

enum Round {
    Up,
    Down,
}

/// Convert a `Duration` to milliseconds, rounding up and saturating at
/// `u64::MAX`.
///
/// The saturating is fine because `u64::MAX` milliseconds are still many
/// million years.
#[inline]
fn ms(duration: Duration, round: Round) -> u64 {
    const NANOS_PER_MILLI: u32 = 1_000_000;
    const MILLIS_PER_SEC: u64 = 1_000;

    // Round up.
    let millis = match round {
        Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI,
        Round::Down => duration.subsec_millis(),
    };

    duration
        .as_secs()
        .saturating_mul(MILLIS_PER_SEC)
        .saturating_add(u64::from(millis))
}
<|endoftext|>


<commit_before>use std::fs;
use std::io::ErrorKind;
use std::path::Path;
use std::process::Command;

fn main() {
    let out_dir = Path::new(env!("OUT_DIR")).to_owned();
    let root = Path::new(env!("CARGO_MANIFEST_DIR")).to_owned();

    // Compile SCSS
    let scss_out = &out_dir.join("styles.css");
    let mut sass = Command::new("sass")
                       .arg("scss/main.scss")
                       .arg(scss_out.as_path().to_str().unwrap())
                       .spawn()
                       .unwrap_or_else(|e| {
                           match e.kind() {
                               ErrorKind::NotFound => panic!("sass not installed"),
                               _ => panic!(e),
                           }
                       });
    assert!(sass.wait().unwrap().success(),
            "there was a problem compiling scss");

    // Apply PostCSS
    let output = &root.join("static/css/");
    fs::create_dir_all(&output).unwrap();
    let mut postcss = Command::new("postcss")
                          .args(&["--use", "autoprefixer"])
                          .arg(scss_out.as_path().to_str().unwrap())
                          .args(&["-d", output.as_path().to_str().unwrap()])
                          .spawn()
                          .unwrap_or_else(|e| {
                              match e.kind() {
                                  ErrorKind::NotFound => panic!("postcss not installed"),
                                  _ => panic!(e),
                              }
                          });
    assert!(postcss.wait().unwrap().success(),
            "there was a problem postprocessing css");
}
<commit_msg>refactor(build): use `status()` over `spawn()`<commit_after>use std::fs;
use std::io::ErrorKind;
use std::path::Path;
use std::process::Command;

fn main() {
    let out_dir = Path::new(env!("OUT_DIR")).to_owned();
    let root = Path::new(env!("CARGO_MANIFEST_DIR")).to_owned();

    // Compile SCSS
    let scss_out = &out_dir.join("styles.css");
    let sass_status = Command::new("sass")
        .arg("scss/main.scss")
        .arg(scss_out.as_path().to_str().unwrap())
        .status()
        .unwrap_or_else(|e| {
            match e.kind() {
                ErrorKind::NotFound => panic!("sass not installed"),
                _ => panic!(e),
            }
        });
    assert!(sass_status.success(), "there was a problem compiling scss");

    // Apply PostCSS
    let output = &root.join("static/css/");
    fs::create_dir_all(&output).unwrap();
    let postcss_status = Command::new("postcss")
        .args(&["--use", "autoprefixer"])
        .arg(scss_out.as_path().to_str().unwrap())
        .args(&["-d", output.as_path().to_str().unwrap()])
        .status()
        .unwrap_or_else(|e| {
            match e.kind() {
                ErrorKind::NotFound => panic!("postcss not installed"),
                _ => panic!(e),
            }
        });
    assert!(postcss_status.success(),
            "there was a problem postprocessing css");
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017  Sebastian Wiesner <swiesner@lunaryorn.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

extern crate reqwest;
extern crate sha2;

use sha2::{Sha256, Digest};
use std::io::prelude::*;
use std::env;
use std::path::Path;
use std::fs::File;

static URL: &'static str = "https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt";
static WORDLIST_SHA256: &'static str = "addd35536511597a02fa0a9ff1e5284677b8883b83e986e43f15a3db996b903e";

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

    let client = reqwest::Client::new().unwrap();

    let mut response = client.get(URL).header(reqwest::header::Connection::close()).send().unwrap();
    let mut wordlist_buffer = Vec::with_capacity(40000);
    response.read_to_end(&mut wordlist_buffer).unwrap();

    let mut hasher = Sha256::new();
    hasher.input(&wordlist_buffer);
    let hash = hasher.result().map(|b| format!("{:02x}", b)).join("");
    if hash != WORDLIST_SHA256 {
        panic!("SHA256 mismatch for EFF wordlist! Report issue to https://github.com/lunaryorn/xkpwgen.rs");
    }

    File::create(&eff_wordlist).unwrap().write_all(&wordlist_buffer).unwrap();
    println!("Wrote EFF wordlist to {}", eff_wordlist.to_string_lossy());
}
<commit_msg>Reformat build.rs<commit_after>/*
 * Copyright (C) 2017  Sebastian Wiesner <swiesner@lunaryorn.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

extern crate reqwest;
extern crate sha2;

use sha2::{Sha256, Digest};
use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

static URL: &'static str = "https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt";
static WORDLIST_SHA256: &'static str = {
    "addd35536511597a02fa0a9ff1e5284677b8883b83e986e43f15a3db996b903e"
};

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

    let client = reqwest::Client::new().unwrap();

    let mut response = client.get(URL).header(reqwest::header::Connection::close()).send().unwrap();
    let mut wordlist_buffer = Vec::with_capacity(40000);
    response.read_to_end(&mut wordlist_buffer).unwrap();

    let mut hasher = Sha256::new();
    hasher.input(&wordlist_buffer);
    let hash = hasher.result().map(|b| format!("{:02x}", b)).join("");
    if hash != WORDLIST_SHA256 {
        panic!("SHA256 mismatch for EFF wordlist! Report issue to \
                https://github.com/lunaryorn/xkpwgen.rs");
    }

    File::create(&eff_wordlist).unwrap().write_all(&wordlist_buffer).unwrap();
    println!("Wrote EFF wordlist to {}", eff_wordlist.to_string_lossy());
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#![allow(clippy::print_literal)]
#![allow(clippy::unused_io_amount)]

use rustc_version::{version, Version};
#[allow(unused_imports)]
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::exit;

#[allow(dead_code)]
fn rerun_dir<P: AsRef<Path>>(dir: P) {
  for entry in fs::read_dir(dir).unwrap() {
    let entry = entry.unwrap();
    let path = entry.path();
    println!("cargo:rerun-if-changed={}", path.to_string_lossy());

    if path.is_dir() {
      rerun_dir(path);
    }
  }
}

#[allow(dead_code)]
fn hash_changed(
  files: &[&str], out_dir: &str, config: &Path,
) -> Option<([u8; 8], PathBuf)> {
  use std::collections::hash_map::DefaultHasher;
  use std::hash::Hasher;
  use std::io::Read;

  let mut hasher = DefaultHasher::new();

  let paths = files.iter().map(Path::new).chain(std::iter::once(config));

  for path in paths {
    if let Ok(mut f) = std::fs::File::open(path) {
      let mut buf = Vec::new();
      f.read_to_end(&mut buf).unwrap();

      hasher.write(&buf);
    } else {
      panic!("Cannot open {}", path.display());
    }
  }

  let hash = hasher.finish().to_be_bytes();

  let hash_path = Path::new(&out_dir).join("asm.hash");

  if let Ok(old_hash) = std::fs::read(&hash_path) {
    if old_hash == hash {
      return None;
    }
  }

  Some((hash, hash_path))
}

#[cfg(feature = "asm")]
fn build_nasm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();

  let dest_path = Path::new(&out_dir).join("config.asm");
  let mut config_file = File::create(&dest_path).unwrap();
  config_file.write(b"	%define private_prefix rav1e\n").unwrap();
  config_file.write(b"	%define ARCH_X86_32 0\n").unwrap();
  config_file.write(b" %define ARCH_X86_64 1\n").unwrap();
  config_file.write(b"	%define PIC 1\n").unwrap();
  config_file.write(b" %define STACK_ALIGNMENT 16\n").unwrap();
  if cfg!(target_os = "macos") {
    config_file.write(b" %define PREFIX 1\n").unwrap();
  }

  let asm_files = &[
    "src/x86/ipred.asm",
    "src/x86/ipred_ssse3.asm",
    "src/x86/itx.asm",
    "src/x86/itx_ssse3.asm",
    "src/x86/mc.asm",
    "src/x86/mc_ssse3.asm",
    "src/x86/me.asm",
    "src/x86/sad_sse2.asm",
    "src/x86/sad_avx.asm",
    "src/x86/satd.asm",
    "src/x86/cdef.asm",
    "src/x86/tables.asm",
  ];

  if let Some((hash, hash_path)) =
    hash_changed(asm_files, &out_dir, &dest_path)
  {
    let mut config_include_arg = String::from("-I");
    config_include_arg.push_str(&out_dir);
    config_include_arg.push('/');
    nasm_rs::compile_library_args(
      "rav1easm",
      asm_files,
      &[&config_include_arg, "-Isrc/"],
    );
    std::fs::write(hash_path, &hash[..]).unwrap();
  }
  println!("cargo:rustc-link-lib=static=rav1easm");
  rerun_dir("src/x86");
  rerun_dir("src/ext/x86");
}

#[cfg(feature = "asm")]
fn build_asm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();

  let dest_path = Path::new(&out_dir).join("config.h");
  let mut config_file = File::create(&dest_path).unwrap();
  config_file.write(b" #define PRIVATE_PREFIX rav1e_\n").unwrap();
  config_file.write(b" #define ARCH_AARCH64 1\n").unwrap();
  config_file.write(b" #define ARCH_ARM 0\n").unwrap();
  config_file.write(b" #define CONFIG_LOG 1 \n").unwrap();
  config_file.write(b" #define HAVE_ASM 1\n").unwrap();
  config_file.sync_all().unwrap();

  let asm_files = &[
    "src/arm/64/mc.S",
    "src/arm/64/itx.S",
    "src/arm/64/ipred.S",
    "src/arm/tables.S",
  ];

  if let Some((hash, hash_path)) =
    hash_changed(asm_files, &out_dir, &dest_path)
  {
    cc::Build::new()
      .files(asm_files)
      .include(".")
      .include(&out_dir)
      .compile("rav1e-aarch64");

    std::fs::write(hash_path, &hash[..]).unwrap();
  }
  rerun_dir("src/arm");
}

fn rustc_version_check() {
  // This should match the version in .travis.yml
  const REQUIRED_VERSION: &str = "1.36.0";
  if version().unwrap() < Version::parse(REQUIRED_VERSION).unwrap() {
    eprintln!("rav1e requires rustc >= {}.", REQUIRED_VERSION);
    exit(1);
  }
}

#[cfg(feature = "asm")]
fn is_nasm_new_enough(
  min_version: Option<(u8, u8, u8)>, nasm_path: &Path,
) -> Result<(), String> {
  match get_output(std::process::Command::new(nasm_path).arg("-v")) {
    Ok(version) => {
      if version.contains("NASM version 0.") {
        Err(version)
      } else if let Some((major, minor, micro)) = min_version {
        let ver = parse_nasm_version(&version)?;
        eprintln!("{:?} {:?} {:?}", min_version, version, ver);
        if major > ver.0
          || (major == ver.0 && minor > ver.1)
          || (major == ver.0 && minor == ver.1 && micro > ver.2)
        {
          Err(version)
        } else {
          Ok(())
        }
      } else {
        Ok(())
      }
    }
    Err(err) => Err(err),
  }
}

#[cfg(feature = "asm")]
fn parse_nasm_version(version_string: &str) -> Result<(u8, u8, u8), String> {
  // Rust regex lib doesn't support empty expressions in alterations,
  // so workaround the other way
  let regex1 =
    regex::Regex::new(r"(?:NASM version )?(\d+)\.(\d+)\.(\d+)").unwrap();
  if let Some(captures) = regex1.captures(version_string) {
    Ok((
      captures[1].parse().expect("Invalid version component"),
      captures[2].parse().expect("Invalid version component"),
      captures[3].parse().expect("Invalid version component"),
    ))
  } else {
    let regex2 = regex::Regex::new(r"(?:NASM version )?(\d+)\.(\d+)").unwrap();
    let captures = regex2
      .captures(version_string)
      .ok_or_else(|| "Unable to parse NASM version string".to_string())?;
    Ok((
      captures[1].parse().expect("Invalid version component"),
      captures[2].parse().expect("Invalid version component"),
      0,
    ))
  }
}

#[test]
fn test_parse_nasm_version() {
  let ver_str = "NASM version 2.14.02 compiled on Jan 22 2019";
  assert_eq!((2, 14, 2), parse_nasm_version(ver_str));
  let ver_str = "NASM version 2.14 compiled on Jan 22 2019";
  assert_eq!((2, 14, 0), parse_nasm_version(ver_str));
}

#[cfg(feature = "asm")]
fn nasm_version_check() -> std::path::PathBuf {
  let nasm_path = std::path::PathBuf::from("nasm");
  match is_nasm_new_enough(Some((2, 14, 0)), &nasm_path) {
    Ok(_) => nasm_path,
    Err(version) => {
      panic!("This version of NASM is too old: {}", version);
    }
  }
}

#[cfg(feature = "asm")]
fn get_output(cmd: &mut std::process::Command) -> Result<String, String> {
  let out = cmd.output().map_err(|e| e.to_string())?;
  if out.status.success() {
    Ok(String::from_utf8_lossy(&out.stdout).to_string())
  } else {
    Err(String::from_utf8_lossy(&out.stderr).to_string())
  }
}

#[allow(unused_variables)]
fn main() {
  rustc_version_check();

  let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
  let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
  // let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

  #[cfg(feature = "asm")]
  {
    if arch == "x86_64" {
      println!("cargo:rustc-cfg={}", "nasm_x86_64");
      nasm_version_check();
      build_nasm_files()
    }
    if arch == "aarch64" {
      println!("cargo:rustc-cfg={}", "asm_neon");
      build_asm_files()
    }
  }

  if os == "windows" && cfg!(feature = "decode_test") {
    panic!("Unsupported feature on this platform!");
  }

  vergen::generate_cargo_keys(vergen::ConstantsFlags::all())
    .expect("Unable to generate the cargo keys!");
}
<commit_msg>Fix rebuild with fresh assembly output<commit_after>// Copyright (c) 2017-2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#![allow(clippy::print_literal)]
#![allow(clippy::unused_io_amount)]

use rustc_version::{version, Version};
#[allow(unused_imports)]
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::exit;

#[allow(dead_code)]
fn rerun_dir<P: AsRef<Path>>(dir: P) {
  for entry in fs::read_dir(dir).unwrap() {
    let entry = entry.unwrap();
    let path = entry.path();
    println!("cargo:rerun-if-changed={}", path.to_string_lossy());

    if path.is_dir() {
      rerun_dir(path);
    }
  }
}

#[allow(dead_code)]
fn hash_changed(
  files: &[&str], out_dir: &str, config: &Path,
) -> Option<([u8; 8], PathBuf)> {
  use std::collections::hash_map::DefaultHasher;
  use std::hash::Hasher;
  use std::io::Read;

  let mut hasher = DefaultHasher::new();

  let paths = files.iter().map(Path::new).chain(std::iter::once(config));

  for path in paths {
    if let Ok(mut f) = std::fs::File::open(path) {
      let mut buf = Vec::new();
      f.read_to_end(&mut buf).unwrap();

      hasher.write(&buf);
    } else {
      panic!("Cannot open {}", path.display());
    }
  }

  let hash = hasher.finish().to_be_bytes();

  let hash_path = Path::new(&out_dir).join("asm.hash");

  if let Ok(old_hash) = std::fs::read(&hash_path) {
    if old_hash == hash {
      return None;
    }
  }

  Some((hash, hash_path))
}

#[cfg(feature = "asm")]
fn build_nasm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();

  let dest_path = Path::new(&out_dir).join("config.asm");
  let mut config_file = File::create(&dest_path).unwrap();
  config_file.write(b"	%define private_prefix rav1e\n").unwrap();
  config_file.write(b"	%define ARCH_X86_32 0\n").unwrap();
  config_file.write(b" %define ARCH_X86_64 1\n").unwrap();
  config_file.write(b"	%define PIC 1\n").unwrap();
  config_file.write(b" %define STACK_ALIGNMENT 16\n").unwrap();
  if cfg!(target_os = "macos") {
    config_file.write(b" %define PREFIX 1\n").unwrap();
  }

  let asm_files = &[
    "src/x86/ipred.asm",
    "src/x86/ipred_ssse3.asm",
    "src/x86/itx.asm",
    "src/x86/itx_ssse3.asm",
    "src/x86/mc.asm",
    "src/x86/mc_ssse3.asm",
    "src/x86/me.asm",
    "src/x86/sad_sse2.asm",
    "src/x86/sad_avx.asm",
    "src/x86/satd.asm",
    "src/x86/cdef.asm",
    "src/x86/tables.asm",
  ];

  if let Some((hash, hash_path)) =
    hash_changed(asm_files, &out_dir, &dest_path)
  {
    let mut config_include_arg = String::from("-I");
    config_include_arg.push_str(&out_dir);
    config_include_arg.push('/');
    nasm_rs::compile_library_args(
      "rav1easm",
      asm_files,
      &[&config_include_arg, "-Isrc/"],
    );
    std::fs::write(hash_path, &hash[..]).unwrap();
  } else {
    println!("cargo:rustc-link-search={}", out_dir);
  }
  println!("cargo:rustc-link-lib=static=rav1easm");
  rerun_dir("src/x86");
  rerun_dir("src/ext/x86");
}

#[cfg(feature = "asm")]
fn build_asm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();

  let dest_path = Path::new(&out_dir).join("config.h");
  let mut config_file = File::create(&dest_path).unwrap();
  config_file.write(b" #define PRIVATE_PREFIX rav1e_\n").unwrap();
  config_file.write(b" #define ARCH_AARCH64 1\n").unwrap();
  config_file.write(b" #define ARCH_ARM 0\n").unwrap();
  config_file.write(b" #define CONFIG_LOG 1 \n").unwrap();
  config_file.write(b" #define HAVE_ASM 1\n").unwrap();
  config_file.sync_all().unwrap();

  let asm_files = &[
    "src/arm/64/mc.S",
    "src/arm/64/itx.S",
    "src/arm/64/ipred.S",
    "src/arm/tables.S",
  ];

  if let Some((hash, hash_path)) =
    hash_changed(asm_files, &out_dir, &dest_path)
  {
    cc::Build::new()
      .files(asm_files)
      .include(".")
      .include(&out_dir)
      .compile("rav1e-aarch64");

    std::fs::write(hash_path, &hash[..]).unwrap();
  } else {
    println!("cargo:rustc-link-search={}", out_dir);
    println!("cargo:rustc-link-lib=static=rav1e-aarch64");
  }
  rerun_dir("src/arm");
}

fn rustc_version_check() {
  // This should match the version in .travis.yml
  const REQUIRED_VERSION: &str = "1.36.0";
  if version().unwrap() < Version::parse(REQUIRED_VERSION).unwrap() {
    eprintln!("rav1e requires rustc >= {}.", REQUIRED_VERSION);
    exit(1);
  }
}

#[cfg(feature = "asm")]
fn is_nasm_new_enough(
  min_version: Option<(u8, u8, u8)>, nasm_path: &Path,
) -> Result<(), String> {
  match get_output(std::process::Command::new(nasm_path).arg("-v")) {
    Ok(version) => {
      if version.contains("NASM version 0.") {
        Err(version)
      } else if let Some((major, minor, micro)) = min_version {
        let ver = parse_nasm_version(&version)?;
        eprintln!("{:?} {:?} {:?}", min_version, version, ver);
        if major > ver.0
          || (major == ver.0 && minor > ver.1)
          || (major == ver.0 && minor == ver.1 && micro > ver.2)
        {
          Err(version)
        } else {
          Ok(())
        }
      } else {
        Ok(())
      }
    }
    Err(err) => Err(err),
  }
}

#[cfg(feature = "asm")]
fn parse_nasm_version(version_string: &str) -> Result<(u8, u8, u8), String> {
  // Rust regex lib doesn't support empty expressions in alterations,
  // so workaround the other way
  let regex1 =
    regex::Regex::new(r"(?:NASM version )?(\d+)\.(\d+)\.(\d+)").unwrap();
  if let Some(captures) = regex1.captures(version_string) {
    Ok((
      captures[1].parse().expect("Invalid version component"),
      captures[2].parse().expect("Invalid version component"),
      captures[3].parse().expect("Invalid version component"),
    ))
  } else {
    let regex2 = regex::Regex::new(r"(?:NASM version )?(\d+)\.(\d+)").unwrap();
    let captures = regex2
      .captures(version_string)
      .ok_or_else(|| "Unable to parse NASM version string".to_string())?;
    Ok((
      captures[1].parse().expect("Invalid version component"),
      captures[2].parse().expect("Invalid version component"),
      0,
    ))
  }
}

#[test]
fn test_parse_nasm_version() {
  let ver_str = "NASM version 2.14.02 compiled on Jan 22 2019";
  assert_eq!((2, 14, 2), parse_nasm_version(ver_str));
  let ver_str = "NASM version 2.14 compiled on Jan 22 2019";
  assert_eq!((2, 14, 0), parse_nasm_version(ver_str));
}

#[cfg(feature = "asm")]
fn nasm_version_check() -> std::path::PathBuf {
  let nasm_path = std::path::PathBuf::from("nasm");
  match is_nasm_new_enough(Some((2, 14, 0)), &nasm_path) {
    Ok(_) => nasm_path,
    Err(version) => {
      panic!("This version of NASM is too old: {}", version);
    }
  }
}

#[cfg(feature = "asm")]
fn get_output(cmd: &mut std::process::Command) -> Result<String, String> {
  let out = cmd.output().map_err(|e| e.to_string())?;
  if out.status.success() {
    Ok(String::from_utf8_lossy(&out.stdout).to_string())
  } else {
    Err(String::from_utf8_lossy(&out.stderr).to_string())
  }
}

#[allow(unused_variables)]
fn main() {
  rustc_version_check();

  let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
  let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
  // let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

  #[cfg(feature = "asm")]
  {
    if arch == "x86_64" {
      println!("cargo:rustc-cfg={}", "nasm_x86_64");
      nasm_version_check();
      build_nasm_files()
    }
    if arch == "aarch64" {
      println!("cargo:rustc-cfg={}", "asm_neon");
      build_asm_files()
    }
  }

  if os == "windows" && cfg!(feature = "decode_test") {
    panic!("Unsupported feature on this platform!");
  }

  vergen::generate_cargo_keys(vergen::ConstantsFlags::all())
    .expect("Unable to generate the cargo keys!");
}
<|endoftext|>


<commit_before>extern crate gcc;

use std::fs::File;
use std::path::Path;
use std::io::Write;
use std::process::Command;
use std::env;

fn main() {
    if cfg!(target_os = "linux") || cfg!(target_os = "macos") || cfg!(target_os = "windows") {
        env::set_var("CC", "gcc");
        env::set_var("AS", "gcc -c");
        if cfg!(target_os = "linux") {
            env::set_var("AR", "ar");
        }
    } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
        env::set_var("CC", "cc");
        env::set_var("AS", "cc -c");
        env::set_var("AR", "ar");
    }

    let sse3 = if cfg!(target_os = "windows") {
        cfg!(feature = "sse")
    } else {
        let output = if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            // /usr/bin/grep -o SSSE3 /var/run/dmesg.boot | /usr/bin/head -1
            Command::new("/usr/bin/grep")
                .arg("-o")
                .arg("SSE3")
                .arg("/var/run/dmesg.boot")
                .arg("|")
                .arg("/usr/bin/head")
                .arg("-1")
                .output()
                .unwrap()
        } else if cfg!(target_os = "macos") {
            // /usr/sbin/sysctl machdep.cpu.features | grep -m 1 -ow SSSE3
            Command::new("/usr/sbin/sysctl")
                .arg("machdep.cpu.features")
                .arg("|")
                .arg("grep")
                .arg("-m")
                .arg("1")
                .arg("-ow")
                .arg("SSE3")
                .output()
                .unwrap()
        } else {
            // /bin/grep -m 1 -o ssse3 /proc/cpuinfo
            Command::new("/bin/grep")
                .arg("-m")
                .arg("1")
                .arg("-o")
                .arg("sse3")
                .arg("/proc/cpuinfo")
                .output()
                .unwrap()
        };
        let output = std::str::from_utf8(&output.stdout[..]).unwrap().trim();

        if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") || cfg!(target_os = "macos") {
            output == "SSE3"
        } else {
            output == "sse3"
        }
    };

    let mut cflags = "-g -Wall -Wextra -Wno-unused-parameter".to_owned();
    if !cfg!(feature = "no-sse") && sse3 {
        cflags = cflags + " -mssse3";
    }
    if cfg!(feature = "no-sse") && cfg!(target_os = "macos") {
        cflags = cflags + " -march=x86-64";
    }
    cflags = cflags + " -O2";

    env::set_var("CFLAGS", cflags);

    let mut config = gcc::Config::new();
    config.file("src/c/src/bitstring.c")
          .file("src/c/src/encparams.c")
          .file("src/c/src/hash.c")
          .file("src/c/src/idxgen.c")
          .file("src/c/src/key.c")
          .file("src/c/src/mgf.c")
          .file("src/c/src/ntru.c")
          .file("src/c/src/poly.c")
          .file("src/c/src/rand.c")
          .file("src/c/src/arith.c")
          .file("src/c/src/sha1.c")
          .file("src/c/src/sha2.c")
          .file("src/c/src/nist_ctr_drbg.c")
          .file("src/c/src/rijndael.c")
          .file("src/c/src/rijndael-alg-fst.c");

    if sse3 &&
       (cfg!(target_pointer_width = "64") || cfg!(target_os = "macos") ||
        cfg!(target_os = "windows")) {
        let out = if cfg!(target_os = "windows") {
            Command::new("c:\\mingw\\msys\\1.0\\bin\\perl")
                .arg("src/c/src/sha1-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        } else {
            Command::new("/usr/bin/perl")
                .arg("src/c/src/sha1-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        };
        let out = std::str::from_utf8(&out.stdout[..]).unwrap().trim();

        let p = Path::new("src/c/src/sha1-mb-x86_64.s");
        let mut f = File::create(&p).unwrap();
        f.write(out.as_bytes()).unwrap();

        println!("Out: {}", out);

        if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
            Command::new("gcc")
                .arg("-c")
                .arg("src/c/src/sha1-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha1-mb-x86_64.o")
                .output()
                .unwrap();
        } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            Command::new("cc")
                .arg("-c")
                .arg("src/c/src/sha1-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha1-mb-x86_64.o")
                .output()
                .unwrap();
        }

        println!("Exists: {}", Path::new("src/c/src/sha1-mb-x86_64.o").exists());

        if cfg!(target_os = "macos") {
        panic!();
    }

        let out = if cfg!(target_os = "windows") {
            Command::new("c:\\mingw\\msys\\1.0\\bin\\perl")
                .arg("src/c/src/sha256-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        } else {
            Command::new("/usr/bin/perl")
                .arg("src/c/src/sha256-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        };
        let out = std::str::from_utf8(&out.stdout[..]).unwrap().trim();

        let p = Path::new("src/c/src/sha256-mb-x86_64.s");
        let mut f = File::create(&p).unwrap();
        f.write(out.as_bytes()).unwrap();

        if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
            Command::new("gcc")
                .arg("-c")
                .arg("src/c/src/sha256-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha256-mb-x86_64.o")
                .output()
                .unwrap();
        } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            Command::new("cc")
                .arg("-c")
                .arg("src/c/src/sha256-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha256-mb-x86_64.o")
                .output()
                .unwrap();
        }

        config.object("src/c/src/sha1-mb-x86_64.o").object("src/c/src/sha256-mb-x86_64.o");
    }

    config.include("src/c/src").compile("libntru.a");

    if !cfg!(feature = "no-sse") && sse3 {
        println!("cargo:rustc-cfg=SSE3")
    }
}
<commit_msg>Panic for debugging again<commit_after>extern crate gcc;

use std::fs::File;
use std::path::Path;
use std::io::Write;
use std::process::Command;
use std::env;

fn main() {
    if cfg!(target_os = "linux") || cfg!(target_os = "macos") || cfg!(target_os = "windows") {
        env::set_var("CC", "gcc");
        env::set_var("AS", "gcc -c");
        if cfg!(target_os = "linux") {
            env::set_var("AR", "ar");
        }
    } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
        env::set_var("CC", "cc");
        env::set_var("AS", "cc -c");
        env::set_var("AR", "ar");
    }

    let sse3 = if cfg!(target_os = "windows") {
        cfg!(feature = "sse")
    } else {
        let output = if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            // /usr/bin/grep -o SSSE3 /var/run/dmesg.boot | /usr/bin/head -1
            Command::new("/usr/bin/grep")
                .arg("-o")
                .arg("SSE3")
                .arg("/var/run/dmesg.boot")
                .arg("|")
                .arg("/usr/bin/head")
                .arg("-1")
                .output()
                .unwrap()
        } else if cfg!(target_os = "macos") {
            // /usr/sbin/sysctl machdep.cpu.features | grep -m 1 -ow SSSE3
            Command::new("/usr/sbin/sysctl")
                .arg("machdep.cpu.features")
                .arg("|")
                .arg("grep")
                .arg("-m")
                .arg("1")
                .arg("-ow")
                .arg("SSE3")
                .output()
                .unwrap()
        } else {
            // /bin/grep -m 1 -o ssse3 /proc/cpuinfo
            Command::new("/bin/grep")
                .arg("-m")
                .arg("1")
                .arg("-o")
                .arg("sse3")
                .arg("/proc/cpuinfo")
                .output()
                .unwrap()
        };
        let output = std::str::from_utf8(&output.stdout[..]).unwrap().trim();

        if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") || cfg!(target_os = "macos") {
            output == "SSE3"
        } else {
            output == "sse3"
        }
    };

    let mut cflags = "-g -Wall -Wextra -Wno-unused-parameter".to_owned();
    if !cfg!(feature = "no-sse") && sse3 {
        cflags = cflags + " -mssse3";
    }
    if cfg!(feature = "no-sse") && cfg!(target_os = "macos") {
        cflags = cflags + " -march=x86-64";
    }
    cflags = cflags + " -O2";

    env::set_var("CFLAGS", cflags);

    let mut config = gcc::Config::new();
    config.file("src/c/src/bitstring.c")
          .file("src/c/src/encparams.c")
          .file("src/c/src/hash.c")
          .file("src/c/src/idxgen.c")
          .file("src/c/src/key.c")
          .file("src/c/src/mgf.c")
          .file("src/c/src/ntru.c")
          .file("src/c/src/poly.c")
          .file("src/c/src/rand.c")
          .file("src/c/src/arith.c")
          .file("src/c/src/sha1.c")
          .file("src/c/src/sha2.c")
          .file("src/c/src/nist_ctr_drbg.c")
          .file("src/c/src/rijndael.c")
          .file("src/c/src/rijndael-alg-fst.c");

    if sse3 &&
       (cfg!(target_pointer_width = "64") || cfg!(target_os = "macos") ||
        cfg!(target_os = "windows")) {
        let out = if cfg!(target_os = "windows") {
            Command::new("c:\\mingw\\msys\\1.0\\bin\\perl")
                .arg("src/c/src/sha1-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        } else {
            Command::new("/usr/bin/perl")
                .arg("src/c/src/sha1-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        };
        let out = std::str::from_utf8(&out.stdout[..]).unwrap().trim();

        let p = Path::new("src/c/src/sha1-mb-x86_64.s");
        let mut f = File::create(&p).unwrap();
        f.write(out.as_bytes()).unwrap();

        if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
            Command::new("gcc")
                .arg("-c")
                .arg("src/c/src/sha1-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha1-mb-x86_64.o")
                .output()
                .unwrap();
        } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            Command::new("cc")
                .arg("-c")
                .arg("src/c/src/sha1-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha1-mb-x86_64.o")
                .output()
                .unwrap();
        }

        println!("Exists: {}", Path::new("src/c/src/sha1-mb-x86_64.o").exists());

        let unix = cfg!(unix);
        println!("Unix: {}", unix);
        let linux = cfg!(target_os = "linux");
        println!("Linux: {}", linux);
        let mac = cfg!(target_os = "macos");
        println!("OSX: {}", mac);
        let freebsd = cfg!(target_os = "freebsd");
        println!("FreeBSD: {}", freebsd);
        let openbsd = cfg!(target_os = "openbsd");
        println!("OpenBSD: {}", openbsd);
        panic!("Panicing for debuging");

        let out = if cfg!(target_os = "windows") {
            Command::new("c:\\mingw\\msys\\1.0\\bin\\perl")
                .arg("src/c/src/sha256-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        } else {
            Command::new("/usr/bin/perl")
                .arg("src/c/src/sha256-mb-x86_64.pl")
                .arg("elf")
                .output()
                .unwrap()
        };
        let out = std::str::from_utf8(&out.stdout[..]).unwrap().trim();

        let p = Path::new("src/c/src/sha256-mb-x86_64.s");
        let mut f = File::create(&p).unwrap();
        f.write(out.as_bytes()).unwrap();

        if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
            Command::new("gcc")
                .arg("-c")
                .arg("src/c/src/sha256-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha256-mb-x86_64.o")
                .output()
                .unwrap();
        } else if cfg!(target_os = "freebsd") || cfg!(target_os = "openbsd") {
            Command::new("cc")
                .arg("-c")
                .arg("src/c/src/sha256-mb-x86_64.s")
                .arg("-o")
                .arg("src/c/src/sha256-mb-x86_64.o")
                .output()
                .unwrap();
        }

        config.object("src/c/src/sha1-mb-x86_64.o").object("src/c/src/sha256-mb-x86_64.o");
    }

    config.include("src/c/src").compile("libntru.a");

    if !cfg!(feature = "no-sse") && sse3 {
        println!("cargo:rustc-cfg=SSE3")
    }
}
<|endoftext|>


<commit_before>extern crate bindgen;
extern crate gcc;

use bindgen::RustTarget;
use gcc::Build;
use std::env;
use std::path::PathBuf;

fn main() {
	let mut c = Build::new();

	c.flag("-std=c99");
	c.file("src/c/YGEnums.c");
	c.file("src/c/YGNodeList.c");
	c.file("src/c/Yoga.c");
	c.compile("libyoga.a");

	let bindings = bindgen::Builder::default()
		.rust_target(RustTarget::Stable_1_21)
		.blacklist_type("max_align_t") // This fails `cargo test` so disable for now
		.rustfmt_bindings(false)
		.rustified_enum("YG.*")
		.header("src/c/wrapper.h")
		.generate()
		.expect("Unable to generate bindings");

	let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

	bindings
		.write_to_file(out_path.join("bindings.rs"))
		.expect("Unable to write bindings!");
}
<commit_msg>Fix `FP_` types binding errors<commit_after>extern crate bindgen;
extern crate gcc;

use bindgen::RustTarget;
use gcc::Build;
use std::env;
use std::path::PathBuf;

fn main() {
	let mut c = Build::new();

	c.flag("-std=c99");
	c.file("src/c/YGEnums.c");
	c.file("src/c/YGNodeList.c");
	c.file("src/c/Yoga.c");
	c.compile("libyoga.a");

	let bindings = bindgen::Builder::default()
		.rust_target(RustTarget::Stable_1_21)
		.blacklist_type("max_align_t") // This fails `cargo test` so disable for now
		.blacklist_type("FP_INFINITE")
		.blacklist_type("FP_NAN")
		.blacklist_type("FP_NORMAL")
		.blacklist_type("FP_SUBNORMAL")
		.blacklist_type("FP_ZERO")
		.rustfmt_bindings(false)
		.rustified_enum("YG.*")
		.header("src/c/wrapper.h")
		.generate()
		.expect("Unable to generate bindings");

	let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

	bindings
		.write_to_file(out_path.join("bindings.rs"))
		.expect("Unable to write bindings!");
}
<|endoftext|>


<commit_before>extern crate embed_resource;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
extern crate cc;

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::env;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::io::Write;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::path::Path;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::fs::{self, File};

/// The last line of this, after running it through a preprocessor, will expand to the value of `BLKGETSIZE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_CHECK_SOURCE: &str = r#"
#include <sys/mount.h>

BLKGETSIZE
"#;

/// Replace `{}` with the `BLKGETSIZE` expression from `IOCTL_CHECK_SOURCE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_INCLUDE_SKELETON: &str = r#"
/// Return `device size / 512` (`long *` arg)
static BLKGETSIZE: {type} = {expr} as {type};
"#;

#[cfg(all(not(any(target_os = "windows", target_os = "macos")), not(target_env = "musl")))]
static IOCTL_REQUEST_TYPE: &str = "libc::c_ulong";

#[cfg(all(not(any(target_os = "windows", target_os = "macos")), target_env = "musl"))]
static IOCTL_REQUEST_TYPE: &str = "libc::c_int";

fn main() {
    embed_resources();
    get_ioctl_data();
}

fn embed_resources() {
    embed_resource::compile("http-manifest.rc");
}

#[cfg(any(target_os = "windows", target_os = "macos"))]
fn get_ioctl_data() {}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn get_ioctl_data() {
    let ioctl_dir = Path::new(&env::var("OUT_DIR").unwrap()).join("ioctl-data");
    fs::create_dir_all(&ioctl_dir).unwrap();

    let ioctl_source = ioctl_dir.join("ioctl.c");
    File::create(&ioctl_source).unwrap().write_all(IOCTL_CHECK_SOURCE.as_bytes()).unwrap();

    let ioctl_preprocessed = String::from_utf8(cc::Build::new().file(ioctl_source).expand()).unwrap();
    let blkgetsize_expr = ioctl_preprocessed.lines().next_back().unwrap().replace("U", "");

    let ioctl_include = ioctl_dir.join("ioctl.rs");
    File::create(&ioctl_include)
        .unwrap()
        .write_all(IOCTL_INCLUDE_SKELETON.replace("{type}", IOCTL_REQUEST_TYPE).replace("{expr}", &blkgetsize_expr).as_bytes())
        .unwrap();
}
<commit_msg>Fix cross-compilation between glibc/musl<commit_after>extern crate embed_resource;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
extern crate cc;

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::env;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::io::Write;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::path::Path;
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
use std::fs::{self, File};

/// The last line of this, after running it through a preprocessor, will expand to the value of `BLKGETSIZE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_CHECK_SOURCE: &str = r#"
#include <sys/mount.h>

BLKGETSIZE
"#;

/// Replace `{}` with the `BLKGETSIZE` expression from `IOCTL_CHECK_SOURCE`
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
static IOCTL_INCLUDE_SKELETON: &str = r#"
/// Return `device size / 512` (`long *` arg)
static BLKGETSIZE: {type} = {expr} as {type};
"#;

fn main() {
    embed_resources();
    get_ioctl_data();
}

fn embed_resources() {
    embed_resource::compile("http-manifest.rc");
}

#[cfg(any(target_os = "windows", target_os = "macos"))]
fn get_ioctl_data() {}

#[cfg(not(any(target_os = "windows", target_os = "macos")))]
fn get_ioctl_data() {
    let ioctl_dir = Path::new(&env::var("OUT_DIR").unwrap()).join("ioctl-data");
    fs::create_dir_all(&ioctl_dir).unwrap();

    let ioctl_source = ioctl_dir.join("ioctl.c");
    File::create(&ioctl_source).unwrap().write_all(IOCTL_CHECK_SOURCE.as_bytes()).unwrap();

    let ioctl_preprocessed = String::from_utf8(cc::Build::new().file(ioctl_source).expand()).unwrap();
    let blkgetsize_expr = ioctl_preprocessed.lines().next_back().unwrap().replace("U", "");

    let ioctl_request_type = match &env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV")[..] {
        "musl" => "libc::c_int",
        _ => "libc::c_ulong",
    };

    let ioctl_include = ioctl_dir.join("ioctl.rs");
    File::create(&ioctl_include)
        .unwrap()
        .write_all(IOCTL_INCLUDE_SKELETON.replace("{type}", ioctl_request_type).replace("{expr}", &blkgetsize_expr).as_bytes())
        .unwrap();
}
<|endoftext|>


<commit_before>extern crate gcc;
extern crate semver;

use semver::{Version, VersionReq};
use semver::ParseError::IncorrectParse;
use std::process::Command;

/// Get the output from running `llvm-config` with the given argument.
fn llvm_config(arg: &str) -> String {
    let stdout = Command::new("llvm-config")
        .arg(arg)
        .output()
        .unwrap_or_else(|e| panic!("Couldn't execute llvm-config. Error: {}", e))
        .stdout;

    String::from_utf8(stdout).ok().expect("llvm-config output was not UTF-8.")
}

/// Get the LLVM version using llvm-config.
fn llvm_version() -> Version {
    match Version::parse(&llvm_config("--version")) {
        // Ignore partial error; particularly constructs like '3.8.0svn' should be accepted,
        // despite being invalid semver.
        Err(IncorrectParse(v, _)) | Ok(v) => v,
        _ => panic!("Could not determine LLVM version from llvm-config."),
    }
}

fn main() {
    // Check for LLVM 3.6 or greater.
    let minimum_llvm_version = VersionReq::parse(">=3.6").unwrap();
    let version = llvm_version();
    if minimum_llvm_version.matches(&version) {
        println!("Found LLVM version {}", version);
    } else {
        panic!("LLVM version 3.6 or higher is required. (Found {})", version);
    };

    // Parse library linking flags from llvm-config.
    for arg in llvm_config("--ldflags").split_whitespace() {
        if arg.starts_with("-L") {
            println!("cargo:rustc-link-search=native={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=static={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--system-libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=dylib={}", &arg[2..]);
        }
    }

    // This breaks the link step on Windows with MSVC.
    if !cfg!(windows) {
        // Determine which C++ standard library to use: LLVM's or GCC's.
        let cxxflags = llvm_config("--cxxflags");
        let libcpp = if cxxflags.contains("stdlib=libc++") { "c++" } else { "stdc++" };
        println!("cargo:rustc-link-lib={}", libcpp);
    }

    // Build the extra wrapper functions.
    std::env::set_var("CFLAGS", llvm_config("--cflags").trim());
    gcc::compile_library("libtargetwrappers.a", &["wrappers/target.c"]);
}
<commit_msg>Do not specify linkage type for LLVM libs.<commit_after>extern crate gcc;
extern crate semver;

use semver::{Version, VersionReq};
use semver::ParseError::IncorrectParse;
use std::process::Command;

/// Get the output from running `llvm-config` with the given argument.
fn llvm_config(arg: &str) -> String {
    let stdout = Command::new("llvm-config")
        .arg(arg)
        .output()
        .unwrap_or_else(|e| panic!("Couldn't execute llvm-config. Error: {}", e))
        .stdout;

    String::from_utf8(stdout).ok().expect("llvm-config output was not UTF-8.")
}

/// Get the LLVM version using llvm-config.
fn llvm_version() -> Version {
    match Version::parse(&llvm_config("--version")) {
        // Ignore partial error; particularly constructs like '3.8.0svn' should be accepted,
        // despite being invalid semver.
        Err(IncorrectParse(v, _)) | Ok(v) => v,
        _ => panic!("Could not determine LLVM version from llvm-config."),
    }
}

fn main() {
    // Check for LLVM 3.6 or greater.
    let minimum_llvm_version = VersionReq::parse(">=3.6").unwrap();
    let version = llvm_version();
    if minimum_llvm_version.matches(&version) {
        println!("Found LLVM version {}", version);
    } else {
        panic!("LLVM version 3.6 or higher is required. (Found {})", version);
    };

    // Parse library linking flags from llvm-config.
    for arg in llvm_config("--ldflags").split_whitespace() {
        if arg.starts_with("-L") {
            println!("cargo:rustc-link-search=native={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib={}", &arg[2..]);
        }
    }

    for arg in llvm_config("--system-libs").split_whitespace() {
        if arg.starts_with("-l") {
            println!("cargo:rustc-link-lib=dylib={}", &arg[2..]);
        }
    }

    // This breaks the link step on Windows with MSVC.
    if !cfg!(windows) {
        // Determine which C++ standard library to use: LLVM's or GCC's.
        let cxxflags = llvm_config("--cxxflags");
        let libcpp = if cxxflags.contains("stdlib=libc++") { "c++" } else { "stdc++" };
        println!("cargo:rustc-link-lib={}", libcpp);
    }

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