<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! How to retreive data from an image within a shader.
//!
//! This module contains a struct named `Sampler` which describes how to get pixel data from
//! a texture.
//!
use std::mem;
use std::ptr;
use std::sync::Arc;

use device::Device;
use OomError;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// Describes how to retreive data from an image within a shader.
pub struct Sampler {
    device: Arc<Device>,
    sampler: vk::Sampler,
}

impl Sampler {
    /// Creates a new `Sampler` with the given behavior.
    ///
    /// # Panic
    ///
    /// - Panicks if `max_anisotropy < 1.0`.
    /// - Panicks if `min_lod > max_lod`.
    ///
    pub fn new(device: &Arc<Device>, mag_filter: Filter, min_filter: Filter,
               mipmap_mode: MipmapMode, address_u: SamplerAddressMode,
               address_v: SamplerAddressMode, address_w: SamplerAddressMode, mip_lod_bias: f32,
               max_anisotropy: f32, min_lod: f32, max_lod: f32) -> Result<Arc<Sampler>, OomError>
    {
        assert!(max_anisotropy >= 1.0);
        assert!(min_lod <= max_lod);

        let vk = device.pointers();

        let sampler = unsafe {
            let infos = vk::SamplerCreateInfo {
                sType: vk::STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                magFilter: mag_filter as u32,
                minFilter: min_filter as u32,
                mipmapMode: mipmap_mode as u32,
                addressModeU: address_u as u32,
                addressModeV: address_v as u32,
                addressModeW: address_w as u32,
                mipLodBias: mip_lod_bias,
                anisotropyEnable: if max_anisotropy > 1.0 { vk::TRUE } else { vk::FALSE },
                maxAnisotropy: max_anisotropy,
                compareEnable: 0,       // FIXME:
                compareOp: 0,       // FIXME:
                minLod: min_lod,
                maxLod: max_lod,
                borderColor: 0,     // FIXME:
                unnormalizedCoordinates: 0,     // FIXME:
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateSampler(device.internal_object(), &infos,
                                               ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(Sampler {
            device: device.clone(),
            sampler: sampler,
        }))
    }
}

unsafe impl VulkanObject for Sampler {
    type Object = vk::Sampler;

    #[inline]
    fn internal_object(&self) -> vk::Sampler {
        self.sampler
    }
}

impl Drop for Sampler {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroySampler(self.device.internal_object(), self.sampler, ptr::null());
        }
    }
}

/// Describes how the color of each pixel should be determined.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum Filter {
    /// The four pixels whose center surround the requested coordinates are taken, then their
    /// values are interpolated.
    Linear = vk::FILTER_LINEAR,

    /// The pixel whose center is nearest to the requested coordinates is taken from the source
    /// and its value is returned as-is.
    Nearest = vk::FILTER_NEAREST,
}

/// Describes which mipmap from the source to use.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum MipmapMode {
    /// Use the mipmap whose dimensions are the nearest to the dimensions of the destination.
    Nearest = vk::SAMPLER_MIPMAP_MODE_NEAREST,

    /// Take the two mipmaps whose dimensions are immediately inferior and superior to the
    /// dimensions of the destination, calculate the value for both, and interpolate them.
    Linear = vk::SAMPLER_MIPMAP_MODE_LINEAR,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum SamplerAddressMode {
    Repeat = vk::SAMPLER_ADDRESS_MODE_REPEAT,
    MirroredRepeat = vk::SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
    ClampToEdge = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
    ClampToBorder = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
    MirrorClampToEdge = vk::SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,
}

#[cfg(test)]
mod tests {
    use sampler;

    #[test]
    fn create() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 1.0,
                                      0.0, 2.0).unwrap();
    }

    #[test]
    #[should_panic]
    fn min_lod_inferior() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 1.0, 5.0, 2.0);
    }

    #[test]
    #[should_panic]
    fn max_anisotropy() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 0.5, 0.0, 2.0);
    }
}
<commit_msg>Add a unnormalized constructor for shaders<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! How to retreive data from an image within a shader.
//!
//! This module contains a struct named `Sampler` which describes how to get pixel data from
//! a texture.
//!
use std::mem;
use std::ptr;
use std::sync::Arc;

use device::Device;
use OomError;
use VulkanObject;
use VulkanPointers;
use check_errors;
use vk;

/// Describes how to retreive data from an image within a shader.
pub struct Sampler {
    sampler: vk::Sampler,
    device: Arc<Device>,
}

// TODO: what's the story with VK_KHR_mirror_clamp_to_edge? Is it an extension or is it core?

impl Sampler {
    /// Creates a new `Sampler` with the given behavior.
    ///
    /// # Panic
    ///
    /// - Panicks if `max_anisotropy < 1.0`.
    /// - Panicks if `min_lod > max_lod`.
    ///
    // TODO: wrong error type returned
    pub fn new(device: &Arc<Device>, mag_filter: Filter, min_filter: Filter,
               mipmap_mode: MipmapMode, address_u: SamplerAddressMode,
               address_v: SamplerAddressMode, address_w: SamplerAddressMode, mip_lod_bias: f32,
               max_anisotropy: f32, min_lod: f32, max_lod: f32) -> Result<Arc<Sampler>, OomError>
    {
        assert!(max_anisotropy >= 1.0);
        // TODO: check limits
        assert!(min_lod <= max_lod);

        let vk = device.pointers();

        let sampler = unsafe {
            let infos = vk::SamplerCreateInfo {
                sType: vk::STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                magFilter: mag_filter as u32,
                minFilter: min_filter as u32,
                mipmapMode: mipmap_mode as u32,
                addressModeU: address_u as u32,
                addressModeV: address_v as u32,
                addressModeW: address_w as u32,
                mipLodBias: mip_lod_bias,
                anisotropyEnable: if max_anisotropy > 1.0 { vk::TRUE } else { vk::FALSE },
                maxAnisotropy: max_anisotropy,
                compareEnable: 0,       // FIXME:
                compareOp: 0,       // FIXME:
                minLod: min_lod,
                maxLod: max_lod,
                borderColor: 0,     // FIXME:
                unnormalizedCoordinates: vk::FALSE,
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateSampler(device.internal_object(), &infos,
                                               ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(Sampler {
            sampler: sampler,
            device: device.clone(),
        }))
    }

    /// Creates a sampler with unnormalized coordinates. This means that texture coordinates won't
    /// range between `0.0` and `1.0` but use plain pixel offsets.
    ///
    /// Using an unnormalized sampler adds a few restrictions:
    ///
    /// - It can only be used with non-array 1D or 2D images.
    /// - It can only be used with images with a single mipmap.
    /// - Projection and offsets can't be used by shaders. Only the first mipmap can be accessed.
    ///
    // TODO: wrong error type returned
    pub fn unnormalized(device: &Arc<Device>, filter: Filter,
                        address_u: UnnormalizedSamplerAddressMode,
                        address_v: UnnormalizedSamplerAddressMode) -> Result<Arc<Sampler>, OomError>
    {
        let vk = device.pointers();

        let sampler = unsafe {
            let infos = vk::SamplerCreateInfo {
                sType: vk::STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
                pNext: ptr::null(),
                flags: 0,   // reserved
                magFilter: filter as u32,
                minFilter: filter as u32,
                mipmapMode: vk::SAMPLER_MIPMAP_MODE_NEAREST,
                addressModeU: address_u as u32,
                addressModeV: address_v as u32,
                addressModeW: vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,       // unused by the impl
                mipLodBias: 0.0,
                anisotropyEnable: vk::FALSE,
                maxAnisotropy: 0.0,
                compareEnable: vk::FALSE,
                compareOp: vk::COMPARE_OP_NEVER,
                minLod: 0.0,
                maxLod: 0.0,
                borderColor: 0,     // FIXME:
                unnormalizedCoordinates: vk::TRUE,
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateSampler(device.internal_object(), &infos,
                                               ptr::null(), &mut output)));
            output
        };

        Ok(Arc::new(Sampler {
            sampler: sampler,
            device: device.clone(),
        }))
    }
}

unsafe impl VulkanObject for Sampler {
    type Object = vk::Sampler;

    #[inline]
    fn internal_object(&self) -> vk::Sampler {
        self.sampler
    }
}

impl Drop for Sampler {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroySampler(self.device.internal_object(), self.sampler, ptr::null());
        }
    }
}

/// Describes how the color of each pixel should be determined.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum Filter {
    /// The four pixels whose center surround the requested coordinates are taken, then their
    /// values are interpolated.
    Linear = vk::FILTER_LINEAR,

    /// The pixel whose center is nearest to the requested coordinates is taken from the source
    /// and its value is returned as-is.
    Nearest = vk::FILTER_NEAREST,
}

/// Describes which mipmap from the source to use.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum MipmapMode {
    /// Use the mipmap whose dimensions are the nearest to the dimensions of the destination.
    Nearest = vk::SAMPLER_MIPMAP_MODE_NEAREST,

    /// Take the two mipmaps whose dimensions are immediately inferior and superior to the
    /// dimensions of the destination, calculate the value for both, and interpolate them.
    Linear = vk::SAMPLER_MIPMAP_MODE_LINEAR,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum SamplerAddressMode {
    Repeat = vk::SAMPLER_ADDRESS_MODE_REPEAT,
    MirroredRepeat = vk::SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT,
    ClampToEdge = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
    ClampToBorder = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
    MirrorClampToEdge = vk::SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum UnnormalizedSamplerAddressMode {
    ClampToEdge = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
    ClampToBorder = vk::SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
}

#[cfg(test)]
mod tests {
    use sampler;

    #[test]
    fn create() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 1.0,
                                      0.0, 2.0).unwrap();
    }

    #[test]
    #[should_panic]
    fn min_lod_inferior() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 1.0, 5.0, 2.0);
    }

    #[test]
    #[should_panic]
    fn max_anisotropy() {
        let (device, queue) = gfx_dev_and_queue!();

        let _ = sampler::Sampler::new(&device, sampler::Filter::Linear, sampler::Filter::Linear,
                                      sampler::MipmapMode::Nearest,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat,
                                      sampler::SamplerAddressMode::Repeat, 1.0, 0.5, 0.0, 2.0);
    }
}
<|endoftext|>


<commit_before>use std::ptr::null;
use libc::{c_char, c_int, c_double};
use std::ffi::CString;
use utils::_string;
use vector::{ogr, geom};
use GdalError;

pub struct Geometry {
    c_geometry: *const (),
}

impl Geometry {
    pub fn empty(wkb_type: c_int) -> Geometry {
        let c_geom = unsafe { ogr::OGR_G_CreateGeometry(wkb_type) };
        assert!(c_geom != null());
        return Geometry{c_geometry: c_geom};
    }

    pub fn from_wkt(wkt: &str) -> Geometry {
        let c_wkt = CString::from_slice(wkt.as_bytes());
        let mut c_wkt_ptr: *const c_char = c_wkt.as_ptr();
        let mut c_geom: *const () = null();
        let rv = unsafe { ogr::OGR_G_CreateFromWkt(&mut c_wkt_ptr, null(), &mut c_geom) };
        assert_eq!(rv, ogr::OGRERR_NONE);
        return Geometry{c_geometry: c_geom};
    }

    pub fn bbox(w: f64, s: f64, e: f64, n: f64) -> Geometry {
        Geometry::from_wkt(format!(
            "POLYGON (({} {}, {} {}, {} {}, {} {}, {} {}))",
            w, n,
            e, n,
            e, s,
            w, s,
            w, n,
        ).as_slice())
    }

    pub fn json(&self) -> String {
        let c_json = unsafe { ogr::OGR_G_ExportToJson(self.c_geometry) };
        let rv = _string(c_json);
        unsafe { ogr::VSIFree(c_json as *mut ()) };
        return rv;
    }

    pub unsafe fn c_geometry(&self) -> *const () {
        return self.c_geometry;
    }

    pub fn set_point_2d(&mut self, i: isize, p: (f64, f64)) {
        let (x, y) = p;
        unsafe { ogr::OGR_G_SetPoint_2D(
            self.c_geometry,
            i as c_int,
            x as c_double,
            y as c_double,
        ) };
    }

    pub fn get_point(&self, i: isize) -> (f64, f64, f64) {
        let mut x: c_double = 0.;
        let mut y: c_double = 0.;
        let mut z: c_double = 0.;
        unsafe { ogr::OGR_G_GetPoint(self.c_geometry, 0, &mut x, &mut y, &mut z) };
        return (x as f64, y as f64, z as f64);
    }

    pub fn to_geom(&self) -> Result<geom::Geom, GdalError> {
        let geometry_type = unsafe { ogr::OGR_G_GetGeometryType(self.c_geometry) };
        match geometry_type {
            1 => {
                let (x, y, _) = self.get_point(0);
                Ok(geom::Geom::Point(geom::Point{x: x, y: y}))
            },
            _ => Err(GdalError{desc: "Unknown geometry type"})
        }
    }
}

impl Drop for Geometry {
    fn drop(&mut self) {
        unsafe { ogr::OGR_G_DestroyGeometry(self.c_geometry as *mut ()) };
    }
}

pub trait ToGdal {
    fn to_gdal(&self) -> Geometry;
}

impl ToGdal for geom::Point {
    fn to_gdal(&self) -> Geometry {
        let mut geom = Geometry::empty(ogr::wkbPoint);
        geom.set_point_2d(0, (self.x, self.y));
        return geom;
    }
}

#[cfg(test)]
mod tests {
    use vector::{Geometry, ToGdal};
    use vector::geom::{Geom, Point};

    #[test]
    fn test_ogr_to_point() {
        let g = Geometry::from_wkt("POINT (10 20)".as_slice());
        assert_eq!(g.to_geom(), Ok(Geom::Point(Point{x: 10., y: 20.})));
    }

    #[test]
    fn test_point_to_ogr() {
        let g = Point{x: 10., y: 20.}.to_gdal();
        assert_eq!(g.json(), "{ \"type\": \"Point\", \"coordinates\": [ 10.0, 20.0 ] }");
    }
}
<commit_msg>Geometry.wkt()<commit_after>use std::ptr::null;
use libc::{c_char, c_int, c_double};
use std::ffi::CString;
use utils::_string;
use vector::{ogr, geom};
use GdalError;

pub struct Geometry {
    c_geometry: *const (),
}

impl Geometry {
    pub fn empty(wkb_type: c_int) -> Geometry {
        let c_geom = unsafe { ogr::OGR_G_CreateGeometry(wkb_type) };
        assert!(c_geom != null());
        return Geometry{c_geometry: c_geom};
    }

    pub fn from_wkt(wkt: &str) -> Geometry {
        let c_wkt = CString::from_slice(wkt.as_bytes());
        let mut c_wkt_ptr: *const c_char = c_wkt.as_ptr();
        let mut c_geom: *const () = null();
        let rv = unsafe { ogr::OGR_G_CreateFromWkt(&mut c_wkt_ptr, null(), &mut c_geom) };
        assert_eq!(rv, ogr::OGRERR_NONE);
        return Geometry{c_geometry: c_geom};
    }

    pub fn bbox(w: f64, s: f64, e: f64, n: f64) -> Geometry {
        Geometry::from_wkt(format!(
            "POLYGON (({} {}, {} {}, {} {}, {} {}, {} {}))",
            w, n,
            e, n,
            e, s,
            w, s,
            w, n,
        ).as_slice())
    }

    pub fn json(&self) -> String {
        let c_json = unsafe { ogr::OGR_G_ExportToJson(self.c_geometry) };
        let rv = _string(c_json);
        unsafe { ogr::VSIFree(c_json as *mut ()) };
        return rv;
    }

    pub fn wkt(&self) -> String {
        let mut c_wkt: *const c_char = null();
        let _err = unsafe { ogr::OGR_G_ExportToWkt(self.c_geometry, &mut c_wkt) };
        assert_eq!(_err, ogr::OGRERR_NONE);
        let wkt = _string(c_wkt);
        unsafe { ogr::OGRFree(c_wkt as *mut ()) };
        return wkt;
    }

    pub unsafe fn c_geometry(&self) -> *const () {
        return self.c_geometry;
    }

    pub fn set_point_2d(&mut self, i: isize, p: (f64, f64)) {
        let (x, y) = p;
        unsafe { ogr::OGR_G_SetPoint_2D(
            self.c_geometry,
            i as c_int,
            x as c_double,
            y as c_double,
        ) };
    }

    pub fn get_point(&self, i: isize) -> (f64, f64, f64) {
        let mut x: c_double = 0.;
        let mut y: c_double = 0.;
        let mut z: c_double = 0.;
        unsafe { ogr::OGR_G_GetPoint(self.c_geometry, 0, &mut x, &mut y, &mut z) };
        return (x as f64, y as f64, z as f64);
    }

    pub fn to_geom(&self) -> Result<geom::Geom, GdalError> {
        let geometry_type = unsafe { ogr::OGR_G_GetGeometryType(self.c_geometry) };
        match geometry_type {
            1 => {
                let (x, y, _) = self.get_point(0);
                Ok(geom::Geom::Point(geom::Point{x: x, y: y}))
            },
            _ => Err(GdalError{desc: "Unknown geometry type"})
        }
    }
}

impl Drop for Geometry {
    fn drop(&mut self) {
        unsafe { ogr::OGR_G_DestroyGeometry(self.c_geometry as *mut ()) };
    }
}

pub trait ToGdal {
    fn to_gdal(&self) -> Geometry;
}

impl ToGdal for geom::Point {
    fn to_gdal(&self) -> Geometry {
        let mut geom = Geometry::empty(ogr::wkbPoint);
        geom.set_point_2d(0, (self.x, self.y));
        return geom;
    }
}

#[cfg(test)]
mod tests {
    use vector::{Geometry, ToGdal};
    use vector::geom::{Geom, Point};

    #[test]
    fn test_ogr_to_point() {
        let g = Geometry::from_wkt("POINT (10 20)".as_slice());
        assert_eq!(g.to_geom(), Ok(Geom::Point(Point{x: 10., y: 20.})));
    }

    #[test]
    fn test_point_to_ogr() {
        let g = Point{x: 10., y: 20.}.to_gdal();
        assert_eq!(g.wkt(), "POINT (10 20)");
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use adapton_syntax::*;
use adapton_sigs::*;
use std::rc::Rc;
use std::hash::{Hash,Hasher};
use std::fmt::{Formatter,Result};
use std::mem::transmute;
use std::marker::PhantomData;

pub type Loc = usize;

#[derive(Debug,Clone,Hash,Eq,PartialEq)]
pub struct Name;

trait Void { }

pub struct AdaptonFromScratch {
    /// need a store; the Adapton trait provides a store semantics (viz., see `set` and `force`).
    store : Vec<Box<Void>>
}

impl Adapton for AdaptonFromScratch {
    type Name = Name;
    type Loc  = Loc;

    fn new () -> AdaptonFromScratch {
        AdaptonFromScratch {
            store : Vec::new (),
        }
    }

    fn name_of_string (self:&mut AdaptonFromScratch, sym:String) -> Name { Name }
    fn name_of_u64 (self:&mut AdaptonFromScratch, sym:u64) -> Name { Name }
    fn name_pair (self: &mut AdaptonFromScratch, fst:Name, snd:Name) -> Name { Name }
    fn name_fork (self:&mut AdaptonFromScratch, nm:Name) -> (Name, Name) { (Name,Name) }
    fn ns<T,F> (self: &mut AdaptonFromScratch, nm:Name, body:F) -> T where F:FnOnce(&mut AdaptonFromScratch) -> T { body(self) }
    fn put<T:Eq> (self:&mut AdaptonFromScratch, x:T) -> Art<T,Loc> { Art::Rc(Rc::new(x)) }

    fn cell<T:Eq+Debug+Clone
        +'static // TODO-Later: Needed on T because of lifetime issues.
        >
        (self:&mut AdaptonFromScratch, nm:Name, val:T) -> MutArt<T,Loc> {
            panic!("")
        }

    fn set<T:Eq+Debug> (self:&mut AdaptonFromScratch, cell:MutArt<T,Loc>, val:T) {
        panic!("")
    }

    fn thunk<Arg:Eq+Hash+Debug+Clone+'static,Spurious:'static+Clone,Res:Eq+Debug+Clone+'static>
        (self:&mut AdaptonFromScratch,
         id:ArtIdChoice<Name>,
         prog_pt:ProgPt,
         fn_box:Rc<Box<Fn(&mut AdaptonFromScratch, Arg, Spurious) -> Res>>,
         arg:Arg, spurious:Spurious)
         -> Art<Res,Loc>
    {
        let producer : Box<Producer<Res>> =
            Box::new(App{prog_pt:prog_pt,
                         fn_box:fn_box,
                         arg:arg.clone(),
                         spurious:spurious.clone()});
        let producer : Box<Void> =
            unsafe {
                // This transmute is always safe: `Void`s have no information.
                // `force`'s transmute from `Void` to a `Producer<Res>` does require justification.
                // The justification is the phantom type `Res` in the `Art<Res,Loc>` type.
                transmute::<_,_>(producer)
            };
        self.store.push( producer );
        Art::Loc( Rc::new( self.store.len() ) )
    }

    fn force<Res:'static+Eq+Debug+Clone> (self:&mut AdaptonFromScratch,
                                          art:&Art<Res,Loc>) -> Res
    {
        match *art {
            Art::Loc(ref index) => {
                let producer = {
                    let producer : &Box<Void> = & self.store[ **index ] ;
                    let producer : &Box<Producer<Res>> =
                        unsafe {
                            // This transmute is always safe:
                            // The justification is the phantom type `Res` in the `Art<Res,Loc>` type.
                            transmute::<_,_>(producer)
                        };
                    producer.copy()
                };
                producer.produce(self)
            },
            Art::Rc(ref rc) => (**rc).clone(),
        }
    }
}

// Produce a value of type Res.
trait Producer<Res> {
    fn produce(self:&Self, st:&mut AdaptonFromScratch) -> Res;
    fn copy(self:&Self) -> Box<Producer<Res>>;
}

#[derive(Clone)]
struct App<Arg,Spurious,Res> {
    prog_pt:  ProgPt,
    fn_box:   Rc<Box<Fn(&mut AdaptonFromScratch, Arg, Spurious) -> Res>>,
    arg:      Arg,
    spurious: Spurious,
}

impl<Arg,Spurious,Res> Debug for App<Arg,Spurious,Res> {
    fn fmt(&self, f: &mut Formatter) -> Result { self.prog_pt.fmt(f) }
}

impl<Arg:Hash,Spurious,Res> Hash for App<Arg,Spurious,Res> {
    fn hash<H>(&self, state: &mut H) where H: Hasher { (&self.prog_pt,&self.arg).hash(state) }
}

impl<Arg:'static+PartialEq+Eq+Clone,Spurious:'static+Clone,Res:'static> Producer<Res>
    for App<Arg,Spurious,Res>
{
    fn produce(self:&Self, st:&mut AdaptonFromScratch) -> Res {
        let f = self.fn_box.clone() ;
        f (st,self.arg.clone(),self.spurious.clone())
    }
    fn copy(self:&Self) -> Box<Producer<Res>> {
        Box::new(App{
            prog_pt:self.prog_pt.clone(),
            fn_box:self.fn_box.clone(),
            arg:self.arg.clone(),
            spurious:self.spurious.clone(),
        })
    }
}
<commit_msg>implemented the rest of the Adapton trait for FromScratch struct<commit_after>use std::fmt::Debug;
use adapton_syntax::*;
use adapton_sigs::*;
use std::rc::Rc;
use std::hash::{Hash,Hasher};
use std::fmt::{Formatter,Result};
use std::mem::transmute;
use std::marker::PhantomData;

pub type Loc = usize;

#[derive(Debug,Clone,Hash,Eq,PartialEq)]
pub struct Name;

trait Void { }

pub struct AdaptonFromScratch {
    /// need a store; the Adapton trait provides a store semantics (viz., see `set` and `force`).
    store : Vec<Box<Void>>
}

impl Adapton for AdaptonFromScratch {
    type Name = Name;
    type Loc  = Loc;

    fn new () -> AdaptonFromScratch {
        AdaptonFromScratch {
            store : Vec::new (),
        }
    }

    fn name_of_string (self:&mut AdaptonFromScratch, sym:String) -> Name { Name }
    fn name_of_u64 (self:&mut AdaptonFromScratch, sym:u64) -> Name { Name }
    fn name_pair (self: &mut AdaptonFromScratch, fst:Name, snd:Name) -> Name { Name }
    fn name_fork (self:&mut AdaptonFromScratch, nm:Name) -> (Name, Name) { (Name,Name) }
    fn ns<T,F> (self: &mut AdaptonFromScratch, nm:Name, body:F) -> T where F:FnOnce(&mut AdaptonFromScratch) -> T { body(self) }
    fn put<T:Eq> (self:&mut AdaptonFromScratch, x:T) -> Art<T,Loc> { Art::Rc(Rc::new(x)) }

    fn cell<T:Eq+Debug+Clone
        +'static // TODO-Later: Needed on T because of lifetime issues.
        >
        (self:&mut AdaptonFromScratch, nm:Name, val:T) -> MutArt<T,Loc>
    {
        let val : Box<Producer<T>> = Box::new( Val{val:Rc::new(val)} ) ;
        let val : Box<Void> = unsafe { transmute::<_,_>( val ) } ;
        MutArt{loc:{ self.store.push( val );
                     Rc::new(self.store.len())},
               phantom:PhantomData
        }
    }

    fn set<T:'static+Eq+Debug+Clone>
        (self:&mut AdaptonFromScratch, cell:MutArt<T,Loc>, val:T)
    {
        let val : Box<Producer<T>> = Box::new( Val{val:Rc::new( val )} ) ;
        let val : Box<Void>  = unsafe { transmute::<_,_>( val ) } ;
        self.store.insert( *cell.loc, val );
    }

    fn thunk<Arg:Eq+Hash+Debug+Clone+'static,Spurious:'static+Clone,Res:Eq+Debug+Clone+'static>
        (self:&mut AdaptonFromScratch,
         id:ArtIdChoice<Name>,
         prog_pt:ProgPt,
         fn_box:Rc<Box<Fn(&mut AdaptonFromScratch, Arg, Spurious) -> Res>>,
         arg:Arg, spurious:Spurious)
         -> Art<Res,Loc>
    {
        let producer : Box<Producer<Res>> =
            Box::new(App{prog_pt:prog_pt,
                         fn_box:fn_box,
                         arg:arg.clone(),
                         spurious:spurious.clone()});
        let producer : Box<Void> =
            unsafe {
                // This transmute is always safe: `Void`s have no information.
                // However, transmute in `force` from `Void` to a `Producer<Res>` does require justification.
                // The justification is the phantom type `Res` in the `Art<Res,Loc>` type.
                transmute::<_,_>(producer)
            };
        self.store.push( producer );
        Art::Loc( Rc::new( self.store.len() ) )
    }

    fn force<Res:'static+Eq+Debug+Clone> (self:&mut AdaptonFromScratch,
                                          art:&Art<Res,Loc>) -> Res
    {
        match *art {
            Art::Loc(ref index) => {
                let producer = {
                    let producer : &Box<Void> = & self.store[ **index ] ;
                    let producer : &Box<Producer<Res>> =
                        unsafe {
                            // This transmute is always safe:
                            // The justification is the phantom type `Res` in the `Art<Res,Loc>` type.
                            transmute::<_,_>(producer)
                        };
                    producer.copy()
                };
                producer.produce(self)
            },
            Art::Rc(ref rc) => (**rc).clone(),
        }
    }
}

// Produce a value of type Res.
trait Producer<Res> {
    fn produce(self:&Self, st:&mut AdaptonFromScratch) -> Res;
    fn copy(self:&Self) -> Box<Producer<Res>>;
}

#[derive(Clone,Hash,Eq,PartialEq,Debug)]
struct Val<Res> {
    val:Rc<Res>
}

impl<Res:Clone+'static>
    Producer<Res> for Val<Res>
{
    fn produce(self:&Self, st:&mut AdaptonFromScratch) -> Res {
        (*self.val).clone()
    }
    fn copy(self:&Self) -> Box<Producer<Res>> {
        Box::new(Val{val:self.val.clone()})
    }
}

#[derive(Clone)]
struct App<Arg,Spurious,Res> {
    prog_pt:  ProgPt,
    fn_box:   Rc<Box<Fn(&mut AdaptonFromScratch, Arg, Spurious) -> Res>>,
    arg:      Arg,
    spurious: Spurious,
}

impl<Arg,Spurious,Res>
    Debug for App<Arg,Spurious,Res>
{
    fn fmt(&self, f: &mut Formatter) -> Result { self.prog_pt.fmt(f) }
}

impl<Arg:Hash,Spurious,Res>
    Hash for App<Arg,Spurious,Res>
{
    fn hash<H>(&self, state: &mut H) where H: Hasher { (&self.prog_pt,&self.arg).hash(state) }
}

impl<Arg:'static+PartialEq+Eq+Clone,Spurious:'static+Clone,Res:'static>
    Producer<Res>
    for App<Arg,Spurious,Res>
{
    fn produce(self:&Self, st:&mut AdaptonFromScratch) -> Res {
        let f = self.fn_box.clone() ;
        f (st,self.arg.clone(),self.spurious.clone())
    }
    fn copy(self:&Self) -> Box<Producer<Res>> {
        Box::new(App{
            prog_pt:self.prog_pt.clone(),
            fn_box:self.fn_box.clone(),
            arg:self.arg.clone(),
            spurious:self.spurious.clone(),
        })
    }
}
<|endoftext|>


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

//! A helper class for dealing with static archives

use back::link::{get_ar_prog};
use driver::session::Session;
use metadata::filesearch;
use lib::llvm::{ArchiveRef, llvm};

use std::cast;
use std::io;
use std::io::{fs, TempDir};
use libc;
use std::os;
use std::io::process::{ProcessConfig, Process, ProcessOutput};
use std::str;
use std::raw;
use syntax::abi;

pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";

pub struct Archive<'a> {
    sess: &'a Session,
    dst: Path,
}

pub struct ArchiveRO {
    ptr: ArchiveRef,
}

fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>,
          paths: &[&Path]) -> ProcessOutput {
    let ar = get_ar_prog(sess);

    let mut args = vec!(args.to_owned());
    let paths = paths.iter().map(|p| p.as_str().unwrap().to_owned());
    args.extend(paths);
    debug!("{} {}", ar, args.connect(" "));
    match cwd {
        Some(p) => { debug!("inside {}", p.display()); }
        None => {}
    }
    match Process::configure(ProcessConfig {
        program: ar.as_slice(),
        args: args.as_slice(),
        cwd: cwd.map(|a| &*a),
        .. ProcessConfig::new()
    }) {
        Ok(mut prog) => {
            let o = prog.wait_with_output();
            if !o.status.success() {
                sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
                                 o.status));
                sess.note(format!("stdout ---\n{}",
                                  str::from_utf8(o.output.as_slice()).unwrap()));
                sess.note(format!("stderr ---\n{}",
                                  str::from_utf8(o.error.as_slice()).unwrap()));
                sess.abort_if_errors();
            }
            o
        },
        Err(e) => {
            sess.err(format!("could not exec `{}`: {}", ar, e));
            sess.abort_if_errors();
            fail!("rustc::back::archive::run_ar() should not reach this point");
        }
    }
}

impl<'a> Archive<'a> {
    /// Initializes a new static archive with the given object file
    pub fn create<'b>(sess: &'a Session, dst: &'b Path,
                      initial_object: &'b Path) -> Archive<'a> {
        run_ar(sess, "crus", None, [dst, initial_object]);
        Archive { sess: sess, dst: dst.clone() }
    }

    /// Opens an existing static archive
    pub fn open(sess: &'a Session, dst: Path) -> Archive<'a> {
        assert!(dst.exists());
        Archive { sess: sess, dst: dst }
    }

    /// Adds all of the contents of a native library to this archive. This will
    /// search in the relevant locations for a library named `name`.
    pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
        let location = self.find_library(name);
        self.add_archive(&location, name, [])
    }

    /// Adds all of the contents of the rlib at the specified path to this
    /// archive.
    ///
    /// This ignores adding the bytecode from the rlib, and if LTO is enabled
    /// then the object file also isn't added.
    pub fn add_rlib(&mut self, rlib: &Path, name: &str,
                    lto: bool) -> io::IoResult<()> {
        let object = format!("{}.o", name);
        let bytecode = format!("{}.bc", name);
        let mut ignore = vec!(METADATA_FILENAME, bytecode.as_slice());
        if lto {
            ignore.push(object.as_slice());
        }
        self.add_archive(rlib, name, ignore.as_slice())
    }

    /// Adds an arbitrary file to this archive
    pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
        let cmd = if has_symbols {"r"} else {"rS"};
        run_ar(self.sess, cmd, None, [&self.dst, file]);
    }

    /// Removes a file from this archive
    pub fn remove_file(&mut self, file: &str) {
        run_ar(self.sess, "d", None, [&self.dst, &Path::new(file)]);
    }

    /// Updates all symbols in the archive (runs 'ar s' over it)
    pub fn update_symbols(&mut self) {
        run_ar(self.sess, "s", None, [&self.dst]);
    }

    /// Lists all files in an archive
    pub fn files(&self) -> Vec<~str> {
        let output = run_ar(self.sess, "t", None, [&self.dst]);
        let output = str::from_utf8(output.output.as_slice()).unwrap();
        // use lines_any because windows delimits output with `\r\n` instead of
        // just `\n`
        output.lines_any().map(|s| s.to_owned()).collect()
    }

    fn add_archive(&mut self, archive: &Path, name: &str,
                   skip: &[&str]) -> io::IoResult<()> {
        let loc = TempDir::new("rsar").unwrap();

        // First, extract the contents of the archive to a temporary directory
        let archive = os::make_absolute(archive);
        run_ar(self.sess, "x", Some(loc.path()), [&archive]);

        // Next, we must rename all of the inputs to "guaranteed unique names".
        // The reason for this is that archives are keyed off the name of the
        // files, so if two files have the same name they will override one
        // another in the archive (bad).
        //
        // We skip any files explicitly desired for skipping, and we also skip
        // all SYMDEF files as these are just magical placeholders which get
        // re-created when we make a new archive anyway.
        let files = try!(fs::readdir(loc.path()));
        let mut inputs = Vec::new();
        for file in files.iter() {
            let filename = file.filename_str().unwrap();
            if skip.iter().any(|s| *s == filename) { continue }
            if filename.contains(".SYMDEF") { continue }

            let filename = format!("r-{}-{}", name, filename);
            let new_filename = file.with_filename(filename);
            try!(fs::rename(file, &new_filename));
            inputs.push(new_filename);
        }
        if inputs.len() == 0 { return Ok(()) }

        // Finally, add all the renamed files to this archive
        let mut args = vec!(&self.dst);
        args.extend(inputs.iter());
        run_ar(self.sess, "r", None, args.as_slice());
        Ok(())
    }

    fn find_library(&self, name: &str) -> Path {
        let (osprefix, osext) = match self.sess.targ_cfg.os {
            abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
        };
        // On Windows, static libraries sometimes show up as libfoo.a and other
        // times show up as foo.lib
        let oslibname = format!("{}{}.{}", osprefix, name, osext);
        let unixlibname = format!("lib{}.a", name);

        let mut rustpath = filesearch::rust_path();
        rustpath.push(self.sess.filesearch().get_target_lib_path());
        let search = self.sess.opts.addl_lib_search_paths.borrow();
        for path in search.iter().chain(rustpath.iter()) {
            debug!("looking for {} inside {}", name, path.display());
            let test = path.join(oslibname.as_slice());
            if test.exists() { return test }
            if oslibname != unixlibname {
                let test = path.join(unixlibname.as_slice());
                if test.exists() { return test }
            }
        }
        self.sess.fatal(format!("could not find native static library `{}`, \
                                 perhaps an -L flag is missing?", name));
    }
}

impl ArchiveRO {
    /// Opens a static archive for read-only purposes. This is more optimized
    /// than the `open` method because it uses LLVM's internal `Archive` class
    /// rather than shelling out to `ar` for everything.
    ///
    /// If this archive is used with a mutable method, then an error will be
    /// raised.
    pub fn open(dst: &Path) -> Option<ArchiveRO> {
        unsafe {
            let ar = dst.with_c_str(|dst| {
                llvm::LLVMRustOpenArchive(dst)
            });
            if ar.is_null() {
                None
            } else {
                Some(ArchiveRO { ptr: ar })
            }
        }
    }

    /// Reads a file in the archive
    pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
        unsafe {
            let mut size = 0 as libc::size_t;
            let ptr = file.with_c_str(|file| {
                llvm::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
            });
            if ptr.is_null() {
                None
            } else {
                Some(cast::transmute(raw::Slice {
                    data: ptr,
                    len: size as uint,
                }))
            }
        }
    }
}

impl Drop for ArchiveRO {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMRustDestroyArchive(self.ptr);
        }
    }
}
<commit_msg>rustc: Fix omission of bytecode in staticlibs<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A helper class for dealing with static archives

use back::link::{get_ar_prog};
use driver::session::Session;
use metadata::filesearch;
use lib::llvm::{ArchiveRef, llvm};

use std::cast;
use std::io;
use std::io::{fs, TempDir};
use libc;
use std::os;
use std::io::process::{ProcessConfig, Process, ProcessOutput};
use std::str;
use std::raw;
use syntax::abi;

pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";

pub struct Archive<'a> {
    sess: &'a Session,
    dst: Path,
}

pub struct ArchiveRO {
    ptr: ArchiveRef,
}

fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>,
          paths: &[&Path]) -> ProcessOutput {
    let ar = get_ar_prog(sess);

    let mut args = vec!(args.to_owned());
    let paths = paths.iter().map(|p| p.as_str().unwrap().to_owned());
    args.extend(paths);
    debug!("{} {}", ar, args.connect(" "));
    match cwd {
        Some(p) => { debug!("inside {}", p.display()); }
        None => {}
    }
    match Process::configure(ProcessConfig {
        program: ar.as_slice(),
        args: args.as_slice(),
        cwd: cwd.map(|a| &*a),
        .. ProcessConfig::new()
    }) {
        Ok(mut prog) => {
            let o = prog.wait_with_output();
            if !o.status.success() {
                sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
                                 o.status));
                sess.note(format!("stdout ---\n{}",
                                  str::from_utf8(o.output.as_slice()).unwrap()));
                sess.note(format!("stderr ---\n{}",
                                  str::from_utf8(o.error.as_slice()).unwrap()));
                sess.abort_if_errors();
            }
            o
        },
        Err(e) => {
            sess.err(format!("could not exec `{}`: {}", ar, e));
            sess.abort_if_errors();
            fail!("rustc::back::archive::run_ar() should not reach this point");
        }
    }
}

impl<'a> Archive<'a> {
    /// Initializes a new static archive with the given object file
    pub fn create<'b>(sess: &'a Session, dst: &'b Path,
                      initial_object: &'b Path) -> Archive<'a> {
        run_ar(sess, "crus", None, [dst, initial_object]);
        Archive { sess: sess, dst: dst.clone() }
    }

    /// Opens an existing static archive
    pub fn open(sess: &'a Session, dst: Path) -> Archive<'a> {
        assert!(dst.exists());
        Archive { sess: sess, dst: dst }
    }

    /// Adds all of the contents of a native library to this archive. This will
    /// search in the relevant locations for a library named `name`.
    pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
        let location = self.find_library(name);
        self.add_archive(&location, name, [])
    }

    /// Adds all of the contents of the rlib at the specified path to this
    /// archive.
    ///
    /// This ignores adding the bytecode from the rlib, and if LTO is enabled
    /// then the object file also isn't added.
    pub fn add_rlib(&mut self, rlib: &Path, name: &str,
                    lto: bool) -> io::IoResult<()> {
        let object = format!("{}.o", name);
        let bytecode = format!("{}.bc.deflate", name);
        let mut ignore = vec!(METADATA_FILENAME, bytecode.as_slice());
        if lto {
            ignore.push(object.as_slice());
        }
        self.add_archive(rlib, name, ignore.as_slice())
    }

    /// Adds an arbitrary file to this archive
    pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
        let cmd = if has_symbols {"r"} else {"rS"};
        run_ar(self.sess, cmd, None, [&self.dst, file]);
    }

    /// Removes a file from this archive
    pub fn remove_file(&mut self, file: &str) {
        run_ar(self.sess, "d", None, [&self.dst, &Path::new(file)]);
    }

    /// Updates all symbols in the archive (runs 'ar s' over it)
    pub fn update_symbols(&mut self) {
        run_ar(self.sess, "s", None, [&self.dst]);
    }

    /// Lists all files in an archive
    pub fn files(&self) -> Vec<~str> {
        let output = run_ar(self.sess, "t", None, [&self.dst]);
        let output = str::from_utf8(output.output.as_slice()).unwrap();
        // use lines_any because windows delimits output with `\r\n` instead of
        // just `\n`
        output.lines_any().map(|s| s.to_owned()).collect()
    }

    fn add_archive(&mut self, archive: &Path, name: &str,
                   skip: &[&str]) -> io::IoResult<()> {
        let loc = TempDir::new("rsar").unwrap();

        // First, extract the contents of the archive to a temporary directory
        let archive = os::make_absolute(archive);
        run_ar(self.sess, "x", Some(loc.path()), [&archive]);

        // Next, we must rename all of the inputs to "guaranteed unique names".
        // The reason for this is that archives are keyed off the name of the
        // files, so if two files have the same name they will override one
        // another in the archive (bad).
        //
        // We skip any files explicitly desired for skipping, and we also skip
        // all SYMDEF files as these are just magical placeholders which get
        // re-created when we make a new archive anyway.
        let files = try!(fs::readdir(loc.path()));
        let mut inputs = Vec::new();
        for file in files.iter() {
            let filename = file.filename_str().unwrap();
            if skip.iter().any(|s| *s == filename) { continue }
            if filename.contains(".SYMDEF") { continue }

            let filename = format!("r-{}-{}", name, filename);
            let new_filename = file.with_filename(filename);
            try!(fs::rename(file, &new_filename));
            inputs.push(new_filename);
        }
        if inputs.len() == 0 { return Ok(()) }

        // Finally, add all the renamed files to this archive
        let mut args = vec!(&self.dst);
        args.extend(inputs.iter());
        run_ar(self.sess, "r", None, args.as_slice());
        Ok(())
    }

    fn find_library(&self, name: &str) -> Path {
        let (osprefix, osext) = match self.sess.targ_cfg.os {
            abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
        };
        // On Windows, static libraries sometimes show up as libfoo.a and other
        // times show up as foo.lib
        let oslibname = format!("{}{}.{}", osprefix, name, osext);
        let unixlibname = format!("lib{}.a", name);

        let mut rustpath = filesearch::rust_path();
        rustpath.push(self.sess.filesearch().get_target_lib_path());
        let search = self.sess.opts.addl_lib_search_paths.borrow();
        for path in search.iter().chain(rustpath.iter()) {
            debug!("looking for {} inside {}", name, path.display());
            let test = path.join(oslibname.as_slice());
            if test.exists() { return test }
            if oslibname != unixlibname {
                let test = path.join(unixlibname.as_slice());
                if test.exists() { return test }
            }
        }
        self.sess.fatal(format!("could not find native static library `{}`, \
                                 perhaps an -L flag is missing?", name));
    }
}

impl ArchiveRO {
    /// Opens a static archive for read-only purposes. This is more optimized
    /// than the `open` method because it uses LLVM's internal `Archive` class
    /// rather than shelling out to `ar` for everything.
    ///
    /// If this archive is used with a mutable method, then an error will be
    /// raised.
    pub fn open(dst: &Path) -> Option<ArchiveRO> {
        unsafe {
            let ar = dst.with_c_str(|dst| {
                llvm::LLVMRustOpenArchive(dst)
            });
            if ar.is_null() {
                None
            } else {
                Some(ArchiveRO { ptr: ar })
            }
        }
    }

    /// Reads a file in the archive
    pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
        unsafe {
            let mut size = 0 as libc::size_t;
            let ptr = file.with_c_str(|file| {
                llvm::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
            });
            if ptr.is_null() {
                None
            } else {
                Some(cast::transmute(raw::Slice {
                    data: ptr,
                    len: size as uint,
                }))
            }
        }
    }
}

impl Drop for ArchiveRO {
    fn drop(&mut self) {
        unsafe {
            llvm::LLVMRustDestroyArchive(self.ptr);
        }
    }
}
<|endoftext|>


<commit_before>extern crate libbindgen;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate clap;
extern crate rustc_serialize;

use libbindgen::clang_version;
use std::env;

mod options;
use options::builder_from_flags;

pub fn main() {
    log::set_logger(|max_log_level| {
            use env_logger::Logger;
            let env_logger = Logger::new();
            max_log_level.set(env_logger.filter());
            Box::new(env_logger)
        })
        .expect("Failed to set logger.");

    let mut bind_args: Vec<_> = env::args().collect();

    let version = clang_version();
    let expected_version = if cfg!(feature = "llvm_stable") {
        (3, 8)
    } else {
        (3, 9)
    };

    info!("Clang Version: {}", version.full);

    match version.parsed {
        None => warn!("Couldn't parse libclang version"),
        Some(version) if version != expected_version => {
            error!("Using clang {:?}, expected {:?}",
                   version,
                   expected_version);
        }
        _ => {}
    }

    match builder_from_flags(bind_args.into_iter()) {
        Ok((builder, output)) => {
            let mut bindings = builder.generate()
                .expect("Unable to generate bindings");
            bindings.write(output)
                .expect("Unable to write output");
            bindings.write_dummy_uses()
                .expect("Unable to write dummy uses to file.");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}
<commit_msg>Fix an unused_mut warning<commit_after>extern crate libbindgen;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate clap;
extern crate rustc_serialize;

use libbindgen::clang_version;
use std::env;

mod options;
use options::builder_from_flags;

pub fn main() {
    log::set_logger(|max_log_level| {
            use env_logger::Logger;
            let env_logger = Logger::new();
            max_log_level.set(env_logger.filter());
            Box::new(env_logger)
        })
        .expect("Failed to set logger.");

    let bind_args: Vec<_> = env::args().collect();

    let version = clang_version();
    let expected_version = if cfg!(feature = "llvm_stable") {
        (3, 8)
    } else {
        (3, 9)
    };

    info!("Clang Version: {}", version.full);

    match version.parsed {
        None => warn!("Couldn't parse libclang version"),
        Some(version) if version != expected_version => {
            error!("Using clang {:?}, expected {:?}",
                   version,
                   expected_version);
        }
        _ => {}
    }

    match builder_from_flags(bind_args.into_iter()) {
        Ok((builder, output)) => {
            let mut bindings = builder.generate()
                .expect("Unable to generate bindings");
            bindings.write(output)
                .expect("Unable to write output");
            bindings.write_dummy_uses()
                .expect("Unable to write dummy uses to file.");
        }
        Err(error) => {
            println!("{}", error);
            std::process::exit(1);
        }
    };
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Arithmetic/Integer

use std::io::stdio::stdin;
use std::from_str::from_str;
use std::io::BufferedReader;

fn main() {
    let input = BufferedReader::new(stdin()).read_line().unwrap();
    let mut words = input.words();
    let a = match words.next().and_then(from_str::<int>) {
            Some(_a) => _a,
            _        => fail!("Please enter 2 integers")
    };
    let b = match words.next().and_then(from_str::<int>) {
            Some(_b) => _b,
            _        => fail!("Please enter 2 integers")
    };

    println!("a + b = {}", a + b);
    println!("a - b = {}", a - b);
    println!("a * b = {}", a * b);
    println!("a / b = {}", a / b);
    println!("a % b = {}", a % b);
}
<commit_msg>Improved arithmetic integers<commit_after>// Implements http://rosettacode.org/wiki/Arithmetic/Integer

use std::io::stdio::stdin;
use std::from_str::from_str;
use std::io::BufferedReader;

fn main() {
    let input = BufferedReader::new(stdin()).read_line().unwrap();
    let mut words = input.words();

    let (a, b) = match (words.next().and_then(from_str::<int>), words.next().and_then(from_str::<int>)) {
            (Some(x), Some(y)) => (x, y),
            _                  => fail!("Please enter 2 integers")
    };

    println!("a + b = {}", a + b);
    println!("a - b = {}", a - b);
    println!("a * b = {}", a * b);
    println!("a / b = {}", a / b);
    println!("a % b = {}", a % b);
}
<|endoftext|>


<commit_before>use core::mem;
use core::num::Wrapping;

use float::Float;

macro_rules! add {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a + b`
        #[allow(unused_parens)]
        #[cfg_attr(not(test), no_mangle)]
        pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let one = Wrapping(1 as <$ty as Float>::Int);
            let zero = Wrapping(0 as <$ty as Float>::Int);

            let bits =             Wrapping(<$ty>::bits() as <$ty as Float>::Int);
            let significand_bits = Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int);
            let exponent_bits =    Wrapping(<$ty>::exponent_bits() as <$ty as Float>::Int);
            let max_exponent =     (one << exponent_bits.0 as usize) - one;

            let implicit_bit =     one << significand_bits.0 as usize;
            let significand_mask = implicit_bit - one;
            let sign_bit =         one << (significand_bits + exponent_bits).0 as usize;
            let abs_mask =         sign_bit - one;
            let exponent_mask =    abs_mask ^ significand_mask;
            let inf_rep =          exponent_mask;
            let quiet_bit =        implicit_bit >> 1;
            let qnan_rep =         exponent_mask | quiet_bit;

            let mut a_rep = Wrapping(a.repr());
            let mut b_rep = Wrapping(b.repr());
            let a_abs = a_rep & abs_mask;
            let b_abs = b_rep & abs_mask;

            // Detect if a or b is zero, infinity, or NaN.
            if a_abs - one >= inf_rep - one ||
                b_abs - one >= inf_rep - one {
                // NaN + anything = qNaN
                if a_abs > inf_rep {
                    return (<$ty as Float>::from_repr((a_abs | quiet_bit).0));
                }
                // anything + NaN = qNaN
                if b_abs > inf_rep {
                    return (<$ty as Float>::from_repr((b_abs | quiet_bit).0));
                }

                if a_abs == inf_rep {
                    // +/-infinity + -/+infinity = qNaN
                    if (a.repr() ^ b.repr()) == sign_bit.0 {
                        return (<$ty as Float>::from_repr(qnan_rep.0));
                    } else {
                        // +/-infinity + anything remaining = +/- infinity
                        return a;
                    }
                }

                // anything remaining + +/-infinity = +/-infinity
                if b_abs == inf_rep {
                    return b;
                }

                // zero + anything = anything
                if a_abs.0 == 0 {
                    // but we need to get the sign right for zero + zero
                    if b_abs.0 == 0 {
                        return (<$ty as Float>::from_repr(a.repr() & b.repr()));
                    } else {
                        return b;
                    }
                }

                // anything + zero = anything
                if b_abs.0 == 0 {
                     return a;
                }
            }

            // Swap a and b if necessary so that a has the larger absolute value.
            if b_abs > a_abs {
                mem::swap(&mut a_rep, &mut b_rep);
            }

            // Extract the exponent and significand from the (possibly swapped) a and b.
            let mut a_exponent = Wrapping((a_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut b_exponent = Wrapping((b_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut a_significand = a_rep & significand_mask;
            let mut b_significand = b_rep & significand_mask;

            // normalize any denormals, and adjust the exponent accordingly.
            if a_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(a_significand.0);
                a_exponent = Wrapping(exponent);
                a_significand = Wrapping(significand);
            }
            if b_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(b_significand.0);
                b_exponent = Wrapping(exponent);
                b_significand = Wrapping(significand);
            }

            // The sign of the result is the sign of the larger operand, a.  If they
            // have opposite signs, we are performing a subtraction; otherwise addition.
            let result_sign = a_rep & sign_bit;
            let subtraction = ((a_rep ^ b_rep) & sign_bit) != zero;

            // Shift the significands to give us round, guard and sticky, and or in the
            // implicit significand bit.  (If we fell through from the denormal path it
            // was already set by normalize(), but setting it twice won't hurt
            // anything.)
            a_significand = (a_significand | implicit_bit) << 3;
            b_significand = (b_significand | implicit_bit) << 3;

            // Shift the significand of b by the difference in exponents, with a sticky
            // bottom bit to get rounding correct.
            let align = Wrapping((a_exponent - b_exponent).0 as <$ty as Float>::Int);
            if align.0 != 0 {
                if align < bits {
                    let sticky = ((b_significand << (bits - align).0 as usize).0 != 0) as <$ty as Float>::Int;
                    b_significand = (b_significand >> align.0 as usize) | Wrapping(sticky);
                } else {
                    b_significand = one; // sticky; b is known to be non-zero.
                }
            }
            if subtraction {
                a_significand -= b_significand;
                // If a == -b, return +zero.
                if a_significand.0 == 0 {
                    return (<$ty as Float>::from_repr(0));
                }

                // If partial cancellation occured, we need to left-shift the result
                // and adjust the exponent:
                if a_significand < implicit_bit << 3 {
                    let shift = a_significand.0.leading_zeros() as i32
                        - (implicit_bit << 3).0.leading_zeros() as i32;
                    a_significand <<= shift as usize;
                    a_exponent -= Wrapping(shift);
                }
            } else /* addition */ {
                a_significand += b_significand;

                // If the addition carried up, we need to right-shift the result and
                // adjust the exponent:
                if (a_significand & implicit_bit << 4).0 != 0 {
                    let sticky = ((a_significand & one).0 != 0) as <$ty as Float>::Int;
                    a_significand = a_significand >> 1 | Wrapping(sticky);
                    a_exponent += Wrapping(1);
                }
            }

            // If we have overflowed the type, return +/- infinity:
            if a_exponent >= Wrapping(max_exponent.0 as i32) {
                return (<$ty>::from_repr((inf_rep | result_sign).0));
            }

            if a_exponent.0 <= 0 {
                // Result is denormal before rounding; the exponent is zero and we
                // need to shift the significand.
                let shift = Wrapping((Wrapping(1) - a_exponent).0 as <$ty as Float>::Int);
                let sticky = ((a_significand << (bits - shift).0 as usize).0 != 0) as <$ty as Float>::Int;
                a_significand = a_significand >> shift.0 as usize | Wrapping(sticky);
                a_exponent = Wrapping(0);
            }

            // Low three bits are round, guard, and sticky.
            let round_guard_sticky: i32 = (a_significand.0 & 0x7) as i32;

            // Shift the significand into place, and mask off the implicit bit.
            let mut result = a_significand >> 3 & significand_mask;

            // Insert the exponent and sign.
            result |= Wrapping(a_exponent.0 as <$ty as Float>::Int) << significand_bits.0 as usize;
            result |= result_sign;

            // Final rounding.  The result may overflow to infinity, but that is the
            // correct result in that case.
            if round_guard_sticky > 0x4 { result += one; }
            if round_guard_sticky == 0x4 { result += result & one; }
            return (<$ty>::from_repr(result.0));
        }
    }
}

add!(__addsf3: f32);
add!(__adddf3: f64);

#[cfg(test)]
mod tests {
    use core::{f32, f64};

    use float::Float;
    use qc::{U32, U64};

    // NOTE The tests below have special handing for NaN values.
    // Because NaN != NaN, the floating-point representations must be used
    // Because there are many diffferent values of NaN, and the implementation
    // doesn't care about calculating the 'correct' one, if both values are NaN
    // the values are considered equivalent.

    struct FRepr<F>(F);

    impl<F: Float> PartialEq for FRepr<F> {
        fn eq(&self, other: &FRepr<F>) -> bool {
            // NOTE(cfg) for some reason, on hard float targets, our implementation doesn't
            // match the output of its gcc_s counterpart. Until we investigate further, we'll
            // just avoid testing against gcc_s on those targets. Do note that our
            // implementation matches the output of the FPU instruction on *hard* float targets
            // and matches its gcc_s counterpart on *soft* float targets.
            if cfg!(gnueabihf) {
                return true
            }
            self.0.eq_repr(other.0)
        }
    }

    // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
    check! {
        fn __addsf3(f: extern fn(f32, f32) -> f32,
                    a: U32,
                    b: U32)
                    -> Option<FRepr<f32> > {
            let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
            Some(FRepr(f(a, b)))
        }

        fn __adddf3(f: extern fn(f64, f64) -> f64,
                    a: U64,
                    b: U64) -> Option<FRepr<f64> > {
            let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
            Some(FRepr(f(a, b)))
        }
    }

    // More tests for special float values

    #[test]
    fn test_float_tiny_plus_tiny() {
        let tiny = f32::from_repr(1);
        let r = super::__addsf3(tiny, tiny);
        assert!(r.eq_repr(tiny + tiny));
    }

    #[test]
    fn test_double_tiny_plus_tiny() {
        let tiny = f64::from_repr(1);
        let r = super::__adddf3(tiny, tiny);
        assert!(r.eq_repr(tiny + tiny));
    }

    #[test]
    fn test_float_small_plus_small() {
        let a = f32::from_repr(327);
        let b = f32::from_repr(256);
        let r = super::__addsf3(a, b);
        assert!(r.eq_repr(a + b));
    }

    #[test]
    fn test_double_small_plus_small() {
        let a = f64::from_repr(327);
        let b = f64::from_repr(256);
        let r = super::__adddf3(a, b);
        assert!(r.eq_repr(a + b));
    }

    #[test]
    fn test_float_one_plus_one() {
        let r = super::__addsf3(1f32, 1f32);
        assert!(r.eq_repr(1f32 + 1f32));
    }

    #[test]
    fn test_double_one_plus_one() {
        let r = super::__adddf3(1f64, 1f64);
        assert!(r.eq_repr(1f64 + 1f64));
    }

    #[test]
    fn test_float_different_nan() {
        let a = f32::from_repr(1);
        let b = f32::from_repr(0b11111111100100010001001010101010);
        let x = super::__addsf3(a, b);
        let y = a + b;
        assert!(x.eq_repr(y));
    }

    #[test]
    fn test_double_different_nan() {
        let a = f64::from_repr(1);
        let b = f64::from_repr(0b1111111111110010001000100101010101001000101010000110100011101011);
        let x = super::__adddf3(a, b);
        let y = a + b;
        assert!(x.eq_repr(y));
    }

    #[test]
    fn test_float_nan() {
        let r = super::__addsf3(f32::NAN, 1.23);
        assert_eq!(r.repr(), f32::NAN.repr());
    }

    #[test]
    fn test_double_nan() {
        let r = super::__adddf3(f64::NAN, 1.23);
        assert_eq!(r.repr(), f64::NAN.repr());
    }

    #[test]
    fn test_float_inf() {
        let r = super::__addsf3(f32::INFINITY, -123.4);
        assert_eq!(r, f32::INFINITY);
    }

    #[test]
    fn test_double_inf() {
        let r = super::__adddf3(f64::INFINITY, -123.4);
        assert_eq!(r, f64::INFINITY);
    }
}
<commit_msg>Cleanup add builtin assignments<commit_after>use core::mem;
use core::num::Wrapping;

use float::Float;

macro_rules! add {
    ($intrinsic:ident: $ty:ty) => {
        /// Returns `a + b`
        #[allow(unused_parens)]
        #[cfg_attr(not(test), no_mangle)]
        pub extern fn $intrinsic(a: $ty, b: $ty) -> $ty {
            let one =               Wrapping(1 as <$ty as Float>::Int);
            let zero =              Wrapping(0 as <$ty as Float>::Int);

            let bits =              Wrapping(<$ty>::bits() as <$ty as Float>::Int);
            let significand_bits =  Wrapping(<$ty>::significand_bits() as <$ty as Float>::Int);
            let exponent_bits =     Wrapping(<$ty>::exponent_bits() as <$ty as Float>::Int);
            let max_exponent =      (one << exponent_bits.0 as usize) - one;

            let implicit_bit =      one << significand_bits.0 as usize;
            let significand_mask =  implicit_bit - one;
            let sign_bit =          one << (significand_bits + exponent_bits).0 as usize;
            let abs_mask =          sign_bit - one;
            let exponent_mask =     abs_mask ^ significand_mask;
            let inf_rep =           exponent_mask;
            let quiet_bit =         implicit_bit >> 1;
            let qnan_rep =          exponent_mask | quiet_bit;

            let mut a_rep =         Wrapping(a.repr());
            let mut b_rep =         Wrapping(b.repr());
            let a_abs =             a_rep & abs_mask;
            let b_abs =             b_rep & abs_mask;

            // Detect if a or b is zero, infinity, or NaN.
            if a_abs - one >= inf_rep - one ||
                b_abs - one >= inf_rep - one {
                // NaN + anything = qNaN
                if a_abs > inf_rep {
                    return (<$ty as Float>::from_repr((a_abs | quiet_bit).0));
                }
                // anything + NaN = qNaN
                if b_abs > inf_rep {
                    return (<$ty as Float>::from_repr((b_abs | quiet_bit).0));
                }

                if a_abs == inf_rep {
                    // +/-infinity + -/+infinity = qNaN
                    if (a.repr() ^ b.repr()) == sign_bit.0 {
                        return (<$ty as Float>::from_repr(qnan_rep.0));
                    } else {
                        // +/-infinity + anything remaining = +/- infinity
                        return a;
                    }
                }

                // anything remaining + +/-infinity = +/-infinity
                if b_abs == inf_rep {
                    return b;
                }

                // zero + anything = anything
                if a_abs.0 == 0 {
                    // but we need to get the sign right for zero + zero
                    if b_abs.0 == 0 {
                        return (<$ty as Float>::from_repr(a.repr() & b.repr()));
                    } else {
                        return b;
                    }
                }

                // anything + zero = anything
                if b_abs.0 == 0 {
                     return a;
                }
            }

            // Swap a and b if necessary so that a has the larger absolute value.
            if b_abs > a_abs {
                mem::swap(&mut a_rep, &mut b_rep);
            }

            // Extract the exponent and significand from the (possibly swapped) a and b.
            let mut a_exponent = Wrapping((a_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut b_exponent = Wrapping((b_rep >> significand_bits.0 as usize & max_exponent).0 as i32);
            let mut a_significand = a_rep & significand_mask;
            let mut b_significand = b_rep & significand_mask;

            // normalize any denormals, and adjust the exponent accordingly.
            if a_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(a_significand.0);
                a_exponent = Wrapping(exponent);
                a_significand = Wrapping(significand);
            }
            if b_exponent.0 == 0 {
                let (exponent, significand) = <$ty>::normalize(b_significand.0);
                b_exponent = Wrapping(exponent);
                b_significand = Wrapping(significand);
            }

            // The sign of the result is the sign of the larger operand, a.  If they
            // have opposite signs, we are performing a subtraction; otherwise addition.
            let result_sign = a_rep & sign_bit;
            let subtraction = ((a_rep ^ b_rep) & sign_bit) != zero;

            // Shift the significands to give us round, guard and sticky, and or in the
            // implicit significand bit.  (If we fell through from the denormal path it
            // was already set by normalize(), but setting it twice won't hurt
            // anything.)
            a_significand = (a_significand | implicit_bit) << 3;
            b_significand = (b_significand | implicit_bit) << 3;

            // Shift the significand of b by the difference in exponents, with a sticky
            // bottom bit to get rounding correct.
            let align = Wrapping((a_exponent - b_exponent).0 as <$ty as Float>::Int);
            if align.0 != 0 {
                if align < bits {
                    let sticky = ((b_significand << (bits - align).0 as usize).0 != 0) as <$ty as Float>::Int;
                    b_significand = (b_significand >> align.0 as usize) | Wrapping(sticky);
                } else {
                    b_significand = one; // sticky; b is known to be non-zero.
                }
            }
            if subtraction {
                a_significand -= b_significand;
                // If a == -b, return +zero.
                if a_significand.0 == 0 {
                    return (<$ty as Float>::from_repr(0));
                }

                // If partial cancellation occured, we need to left-shift the result
                // and adjust the exponent:
                if a_significand < implicit_bit << 3 {
                    let shift = a_significand.0.leading_zeros() as i32
                        - (implicit_bit << 3).0.leading_zeros() as i32;
                    a_significand <<= shift as usize;
                    a_exponent -= Wrapping(shift);
                }
            } else /* addition */ {
                a_significand += b_significand;

                // If the addition carried up, we need to right-shift the result and
                // adjust the exponent:
                if (a_significand & implicit_bit << 4).0 != 0 {
                    let sticky = ((a_significand & one).0 != 0) as <$ty as Float>::Int;
                    a_significand = a_significand >> 1 | Wrapping(sticky);
                    a_exponent += Wrapping(1);
                }
            }

            // If we have overflowed the type, return +/- infinity:
            if a_exponent >= Wrapping(max_exponent.0 as i32) {
                return (<$ty>::from_repr((inf_rep | result_sign).0));
            }

            if a_exponent.0 <= 0 {
                // Result is denormal before rounding; the exponent is zero and we
                // need to shift the significand.
                let shift = Wrapping((Wrapping(1) - a_exponent).0 as <$ty as Float>::Int);
                let sticky = ((a_significand << (bits - shift).0 as usize).0 != 0) as <$ty as Float>::Int;
                a_significand = a_significand >> shift.0 as usize | Wrapping(sticky);
                a_exponent = Wrapping(0);
            }

            // Low three bits are round, guard, and sticky.
            let round_guard_sticky: i32 = (a_significand.0 & 0x7) as i32;

            // Shift the significand into place, and mask off the implicit bit.
            let mut result = a_significand >> 3 & significand_mask;

            // Insert the exponent and sign.
            result |= Wrapping(a_exponent.0 as <$ty as Float>::Int) << significand_bits.0 as usize;
            result |= result_sign;

            // Final rounding.  The result may overflow to infinity, but that is the
            // correct result in that case.
            if round_guard_sticky > 0x4 { result += one; }
            if round_guard_sticky == 0x4 { result += result & one; }
            return (<$ty>::from_repr(result.0));
        }
    }
}

add!(__addsf3: f32);
add!(__adddf3: f64);

#[cfg(test)]
mod tests {
    use core::{f32, f64};

    use float::Float;
    use qc::{U32, U64};

    // NOTE The tests below have special handing for NaN values.
    // Because NaN != NaN, the floating-point representations must be used
    // Because there are many diffferent values of NaN, and the implementation
    // doesn't care about calculating the 'correct' one, if both values are NaN
    // the values are considered equivalent.

    struct FRepr<F>(F);

    impl<F: Float> PartialEq for FRepr<F> {
        fn eq(&self, other: &FRepr<F>) -> bool {
            // NOTE(cfg) for some reason, on hard float targets, our implementation doesn't
            // match the output of its gcc_s counterpart. Until we investigate further, we'll
            // just avoid testing against gcc_s on those targets. Do note that our
            // implementation matches the output of the FPU instruction on *hard* float targets
            // and matches its gcc_s counterpart on *soft* float targets.
            if cfg!(gnueabihf) {
                return true
            }
            self.0.eq_repr(other.0)
        }
    }

    // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
    check! {
        fn __addsf3(f: extern fn(f32, f32) -> f32,
                    a: U32,
                    b: U32)
                    -> Option<FRepr<f32> > {
            let (a, b) = (f32::from_repr(a.0), f32::from_repr(b.0));
            Some(FRepr(f(a, b)))
        }

        fn __adddf3(f: extern fn(f64, f64) -> f64,
                    a: U64,
                    b: U64) -> Option<FRepr<f64> > {
            let (a, b) = (f64::from_repr(a.0), f64::from_repr(b.0));
            Some(FRepr(f(a, b)))
        }
    }

    // More tests for special float values

    #[test]
    fn test_float_tiny_plus_tiny() {
        let tiny = f32::from_repr(1);
        let r = super::__addsf3(tiny, tiny);
        assert!(r.eq_repr(tiny + tiny));
    }

    #[test]
    fn test_double_tiny_plus_tiny() {
        let tiny = f64::from_repr(1);
        let r = super::__adddf3(tiny, tiny);
        assert!(r.eq_repr(tiny + tiny));
    }

    #[test]
    fn test_float_small_plus_small() {
        let a = f32::from_repr(327);
        let b = f32::from_repr(256);
        let r = super::__addsf3(a, b);
        assert!(r.eq_repr(a + b));
    }

    #[test]
    fn test_double_small_plus_small() {
        let a = f64::from_repr(327);
        let b = f64::from_repr(256);
        let r = super::__adddf3(a, b);
        assert!(r.eq_repr(a + b));
    }

    #[test]
    fn test_float_one_plus_one() {
        let r = super::__addsf3(1f32, 1f32);
        assert!(r.eq_repr(1f32 + 1f32));
    }

    #[test]
    fn test_double_one_plus_one() {
        let r = super::__adddf3(1f64, 1f64);
        assert!(r.eq_repr(1f64 + 1f64));
    }

    #[test]
    fn test_float_different_nan() {
        let a = f32::from_repr(1);
        let b = f32::from_repr(0b11111111100100010001001010101010);
        let x = super::__addsf3(a, b);
        let y = a + b;
        assert!(x.eq_repr(y));
    }

    #[test]
    fn test_double_different_nan() {
        let a = f64::from_repr(1);
        let b = f64::from_repr(0b1111111111110010001000100101010101001000101010000110100011101011);
        let x = super::__adddf3(a, b);
        let y = a + b;
        assert!(x.eq_repr(y));
    }

    #[test]
    fn test_float_nan() {
        let r = super::__addsf3(f32::NAN, 1.23);
        assert_eq!(r.repr(), f32::NAN.repr());
    }

    #[test]
    fn test_double_nan() {
        let r = super::__adddf3(f64::NAN, 1.23);
        assert_eq!(r.repr(), f64::NAN.repr());
    }

    #[test]
    fn test_float_inf() {
        let r = super::__addsf3(f32::INFINITY, -123.4);
        assert_eq!(r, f32::INFINITY);
    }

    #[test]
    fn test_double_inf() {
        let r = super::__adddf3(f64::INFINITY, -123.4);
        assert_eq!(r, f64::INFINITY);
    }
}
<|endoftext|>


<commit_before>#![feature(re_rebalance_coherence)]

// compile-flags:--crate-name=test
// aux-build:coherence_lib.rs

extern crate coherence_lib as lib;
use lib::*;
use std::rc::Rc;

struct Local;

impl Remote1<u32> for f64 {
    //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types [E0117]
}

fn main() {}
<commit_msg>Split line to fix tidy<commit_after>#![feature(re_rebalance_coherence)]

// compile-flags:--crate-name=test
// aux-build:coherence_lib.rs

extern crate coherence_lib as lib;
use lib::*;
use std::rc::Rc;

struct Local;

impl Remote1<u32> for f64 {
    //~^ ERROR only traits defined in the current crate
    // | can be implemented for arbitrary types [E0117]
}

fn main() {}
<|endoftext|>


<commit_before>use value::{Array, DateTime, InlineTable, Value};
use table::{Item, KeyValuePairs, TableKeyValue};
use decor::{Decor, Formatted, InternalString, Repr};
use key::Key;
use std::iter::FromIterator;
use parser::strings;
use parser::TomlError;
use combine::{self, Parser};

pub(crate) fn decorate_array(array: &mut Array) {
    for (i, val) in array
        .values
        .iter_mut()
        .filter_map(|i| i.as_value_mut())
        .enumerate()
    {
        // [value1, value2, value3]
        if i > 0 {
            decorate(val, " ", "");
        } else {
            decorate(val, "", "");
        }
    }
}

pub(crate) fn decorate_inline_table(table: &mut InlineTable) {
    let n = table.len();
    for (i, (key, value)) in table
        .items
        .iter_mut()
        .filter(|&(_, ref kv)| kv.value.is_value())
        .map(|(_, kv)| (&mut kv.key, kv.value.as_value_mut().unwrap()))
        .enumerate()
    {
        // { key1 = value1, key2 = value2 }
        key.decor.prefix = InternalString::from(" ");
        key.decor.suffix = InternalString::from(" ");
        if i == n - 1 {
            decorate(value, " ", " ");
        } else {
            decorate(value, " ", "");
        }
    }
}

pub(crate) fn decorate(value: &mut Value, prefix: &str, suffix: &str) {
    let decor = match *value {
        Value::Integer(ref mut f) => &mut f.repr.decor,
        Value::String(ref mut f) => &mut f.repr.decor,
        Value::Float(ref mut f) => &mut f.repr.decor,
        Value::DateTime(ref mut f) => &mut f.repr.decor,
        Value::Boolean(ref mut f) => &mut f.repr.decor,
        Value::Array(ref mut a) => &mut a.decor,
        Value::InlineTable(ref mut t) => &mut t.decor,
    };
    decor.prefix = InternalString::from(prefix);
    decor.suffix = InternalString::from(suffix);
}

pub fn decorated(mut value: Value, prefix: &str, suffix: &str) -> Value {
    {
        decorate(&mut value, prefix, suffix);
    }
    value
}

pub(crate) fn value(mut val: Value, raw: &str) -> Value {
    match val {
        Value::Integer(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::String(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::Float(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::DateTime(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::Boolean(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        _ => {}
    };
    decorate(&mut val, "", "");
    val
}

pub(crate) fn to_key_value(key: &str, mut value: Value) -> TableKeyValue {
    decorate(&mut value, " ", "");
    to_table_key_value(key, Item::Value(value))
}

pub(crate) fn to_table_key_value(key: &str, value: Item) -> TableKeyValue {
    TableKeyValue {
        key: key_repr(key),
        value: value,
    }
}

pub(crate) fn key_repr(raw: &str) -> Repr {
    Repr {
        decor: Decor {
            prefix: InternalString::from(""),
            suffix: InternalString::from(" "),
        },
        raw_value: raw.into(),
    }
}

impl From<i64> for Value {
    fn from(i: i64) -> Self {
        Value::Integer(Formatted::new(
            i,
            Repr::new("".to_string(), i.to_string(), "".to_string()),
        ))
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Self {
        Value::Float(Formatted::new(
            f,
            Repr::new("".to_string(), f.to_string(), "".to_string()),
        ))
    }
}

macro_rules! try_parse {
    ($s:expr, $p:expr) => (
        {
            let result = $p.parse(combine::State::new($s));
            match result {
                Ok((_, ref rest)) if !rest.input.is_empty() => {
                    Err(TomlError::from_unparsed(rest.positioner, $s))
                }
                Ok((s, _)) => Ok(s),
                Err(e) => Err(TomlError::new(e, $s)),
            }
        }
    );
}

// TODO: clean this mess
fn parse_string_guess_delimiters(s: &str) -> (InternalString, InternalString) {
    let basic = format!("\"{}\"", s);
    let literal = format!("'{}'", s);
    let ml_basic = format!("\"\"\"{}\"\"\"", s);
    let ml_literal = format!("'''{}'''", s);
    if let Ok(r) = try_parse!(s, strings::string()) {
        return (r, s.into());
    } else if let Ok(r) = try_parse!(&basic[..], strings::basic_string()) {
        return (r, basic);
    } else if let Ok(r) = try_parse!(&literal[..], strings::literal_string()) {
        return (r.into(), literal.clone());
    } else if let Ok(r) = try_parse!(&ml_basic[..], strings::ml_basic_string()) {
        return (r, ml_literal);
    } else {
        try_parse!(&ml_literal[..], strings::ml_literal_string())
            .map(|r| (r, ml_literal))
            .unwrap_or_else(|e| panic!("toml string parse error: {}, {}", e, s))
    }
}

impl<'b> From<&'b str> for Value {
    fn from(s: &'b str) -> Self {
        let (value, raw) = parse_string_guess_delimiters(s);
        Value::String(Formatted::new(
            value,
            Repr::new("".to_string(), raw, "".to_string()),
        ))
    }
}

impl From<InternalString> for Value {
    fn from(s: InternalString) -> Self {
        Value::from(s.as_ref())
    }
}

impl From<bool> for Value {
    fn from(b: bool) -> Self {
        Value::Boolean(Formatted::new(
            b,
            Repr::new("", if b { "true" } else { "false" }, ""),
        ))
    }
}

impl From<DateTime> for Value {
    fn from(d: DateTime) -> Self {
        let s = d.to_string();
        Value::DateTime(Formatted::new(
            d,
            Repr::new("".to_string(), s, "".to_string()),
        ))
    }
}

impl<V: Into<Value>> FromIterator<V> for Value {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = V>,
    {
        let v = iter.into_iter().map(|a| Item::Value(a.into()));
        let mut array = Array {
            values: v.collect(),
            ..Default::default()
        };
        decorate_array(&mut array);
        Value::Array(array)
    }
}

pub(crate) fn to_key_value_pairs<'k, K, V, I>(iter: I) -> KeyValuePairs
where
    K: Into<&'k Key>,
    V: Into<Value>,
    I: IntoIterator<Item = (K, V)>,
{
    let v = iter.into_iter().map(|(a, b)| {
        let s: &Key = a.into();
        (s.get().into(), to_key_value(s.raw(), b.into()))
    });
    KeyValuePairs::from_iter(v)
}

impl<'k, K: Into<&'k Key>, V: Into<Value>> FromIterator<(K, V)> for Value {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = (K, V)>,
    {
        let mut table = InlineTable {
            items: to_key_value_pairs(iter),
            ..Default::default()
        };
        decorate_inline_table(&mut table);
        Value::InlineTable(table)
    }
}
<commit_msg>Add `From<Array>` and `From<InlineTable>` for `Value`<commit_after>use value::{Array, DateTime, InlineTable, Value};
use table::{Item, KeyValuePairs, TableKeyValue};
use decor::{Decor, Formatted, InternalString, Repr};
use key::Key;
use std::iter::FromIterator;
use parser::strings;
use parser::TomlError;
use combine::{self, Parser};

pub(crate) fn decorate_array(array: &mut Array) {
    for (i, val) in array
        .values
        .iter_mut()
        .filter_map(|i| i.as_value_mut())
        .enumerate()
    {
        // [value1, value2, value3]
        if i > 0 {
            decorate(val, " ", "");
        } else {
            decorate(val, "", "");
        }
    }
}

pub(crate) fn decorate_inline_table(table: &mut InlineTable) {
    let n = table.len();
    for (i, (key, value)) in table
        .items
        .iter_mut()
        .filter(|&(_, ref kv)| kv.value.is_value())
        .map(|(_, kv)| (&mut kv.key, kv.value.as_value_mut().unwrap()))
        .enumerate()
    {
        // { key1 = value1, key2 = value2 }
        key.decor.prefix = InternalString::from(" ");
        key.decor.suffix = InternalString::from(" ");
        if i == n - 1 {
            decorate(value, " ", " ");
        } else {
            decorate(value, " ", "");
        }
    }
}

pub(crate) fn decorate(value: &mut Value, prefix: &str, suffix: &str) {
    let decor = match *value {
        Value::Integer(ref mut f) => &mut f.repr.decor,
        Value::String(ref mut f) => &mut f.repr.decor,
        Value::Float(ref mut f) => &mut f.repr.decor,
        Value::DateTime(ref mut f) => &mut f.repr.decor,
        Value::Boolean(ref mut f) => &mut f.repr.decor,
        Value::Array(ref mut a) => &mut a.decor,
        Value::InlineTable(ref mut t) => &mut t.decor,
    };
    decor.prefix = InternalString::from(prefix);
    decor.suffix = InternalString::from(suffix);
}

pub fn decorated(mut value: Value, prefix: &str, suffix: &str) -> Value {
    {
        decorate(&mut value, prefix, suffix);
    }
    value
}

pub(crate) fn value(mut val: Value, raw: &str) -> Value {
    match val {
        Value::Integer(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::String(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::Float(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::DateTime(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        Value::Boolean(ref mut f) => {
            f.repr.raw_value = InternalString::from(raw);
        }
        _ => {}
    };
    decorate(&mut val, "", "");
    val
}

pub(crate) fn to_key_value(key: &str, mut value: Value) -> TableKeyValue {
    decorate(&mut value, " ", "");
    to_table_key_value(key, Item::Value(value))
}

pub(crate) fn to_table_key_value(key: &str, value: Item) -> TableKeyValue {
    TableKeyValue {
        key: key_repr(key),
        value: value,
    }
}

pub(crate) fn key_repr(raw: &str) -> Repr {
    Repr {
        decor: Decor {
            prefix: InternalString::from(""),
            suffix: InternalString::from(" "),
        },
        raw_value: raw.into(),
    }
}

impl From<i64> for Value {
    fn from(i: i64) -> Self {
        Value::Integer(Formatted::new(
            i,
            Repr::new("".to_string(), i.to_string(), "".to_string()),
        ))
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Self {
        Value::Float(Formatted::new(
            f,
            Repr::new("".to_string(), f.to_string(), "".to_string()),
        ))
    }
}

macro_rules! try_parse {
    ($s:expr, $p:expr) => (
        {
            let result = $p.parse(combine::State::new($s));
            match result {
                Ok((_, ref rest)) if !rest.input.is_empty() => {
                    Err(TomlError::from_unparsed(rest.positioner, $s))
                }
                Ok((s, _)) => Ok(s),
                Err(e) => Err(TomlError::new(e, $s)),
            }
        }
    );
}

// TODO: clean this mess
fn parse_string_guess_delimiters(s: &str) -> (InternalString, InternalString) {
    let basic = format!("\"{}\"", s);
    let literal = format!("'{}'", s);
    let ml_basic = format!("\"\"\"{}\"\"\"", s);
    let ml_literal = format!("'''{}'''", s);
    if let Ok(r) = try_parse!(s, strings::string()) {
        return (r, s.into());
    } else if let Ok(r) = try_parse!(&basic[..], strings::basic_string()) {
        return (r, basic);
    } else if let Ok(r) = try_parse!(&literal[..], strings::literal_string()) {
        return (r.into(), literal.clone());
    } else if let Ok(r) = try_parse!(&ml_basic[..], strings::ml_basic_string()) {
        return (r, ml_literal);
    } else {
        try_parse!(&ml_literal[..], strings::ml_literal_string())
            .map(|r| (r, ml_literal))
            .unwrap_or_else(|e| panic!("toml string parse error: {}, {}", e, s))
    }
}

impl<'b> From<&'b str> for Value {
    fn from(s: &'b str) -> Self {
        let (value, raw) = parse_string_guess_delimiters(s);
        Value::String(Formatted::new(
            value,
            Repr::new("".to_string(), raw, "".to_string()),
        ))
    }
}

impl From<InternalString> for Value {
    fn from(s: InternalString) -> Self {
        Value::from(s.as_ref())
    }
}

impl From<bool> for Value {
    fn from(b: bool) -> Self {
        Value::Boolean(Formatted::new(
            b,
            Repr::new("", if b { "true" } else { "false" }, ""),
        ))
    }
}

impl From<DateTime> for Value {
    fn from(d: DateTime) -> Self {
        let s = d.to_string();
        Value::DateTime(Formatted::new(
            d,
            Repr::new("".to_string(), s, "".to_string()),
        ))
    }
}

impl From<Array> for Value {
    fn from(array: Array) -> Self {
        Value::Array(array)
    }
}

impl From<InlineTable> for Value {
    fn from(table: InlineTable) -> Self {
        Value::InlineTable(table)
    }
}

impl<V: Into<Value>> FromIterator<V> for Value {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = V>,
    {
        let v = iter.into_iter().map(|a| Item::Value(a.into()));
        let mut array = Array {
            values: v.collect(),
            ..Default::default()
        };
        decorate_array(&mut array);
        Value::Array(array)
    }
}

pub(crate) fn to_key_value_pairs<'k, K, V, I>(iter: I) -> KeyValuePairs
where
    K: Into<&'k Key>,
    V: Into<Value>,
    I: IntoIterator<Item = (K, V)>,
{
    let v = iter.into_iter().map(|(a, b)| {
        let s: &Key = a.into();
        (s.get().into(), to_key_value(s.raw(), b.into()))
    });
    KeyValuePairs::from_iter(v)
}

impl<'k, K: Into<&'k Key>, V: Into<Value>> FromIterator<(K, V)> for Value {
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = (K, V)>,
    {
        let mut table = InlineTable {
            items: to_key_value_pairs(iter),
            ..Default::default()
        };
        decorate_inline_table(&mut table);
        Value::InlineTable(table)
    }
}
<|endoftext|>