<commit_before>#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Integer {
    /// Every non-negative integer is treated as u64, even if it fits in i64.
    U64(u64),
    /// Every negative integer is treated as i64.
    I64(i64),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Float {
    F32(f32),
    F64(f64),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(String),
    /// Binary extending Raw type represents a byte array.
    Binary(Vec<u8>),
    /// Array represents a sequence of objects.
    Array(Vec<Value>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(Value, Value)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, Vec<u8>),
}

#[derive(Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
   /// Nil represents nil.
   Nil,
   /// Boolean represents true or false.
   Boolean(bool),
   /// Integer represents an integer.
   Integer(Integer),
   /// Float represents a floating point number.
   Float(Float),
   /// String extending Raw type represents a UTF-8 string.
   String(&'a str),
   /// Binary extending Raw type represents a byte array.
   Binary(&'a [u8]),
   /// Array represents a sequence of objects.
   Array(Vec<ValueRef<'a>>),
   /// Map represents key-value pairs of objects.
   Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
   /// Extended implements Extension interface: represents a tuple of type information and a byte
   /// array where type information is an integer whose meaning is defined by applications.
   Ext(i8, &'a [u8]),
}

impl<'a> ValueRef<'a> {
    /// Converts the current non-owning value to an owned Value.
    ///
    /// This is achieved by deep copying all underlying structures and borrowed buffers.
    ///
    /// # Panics
    ///
    /// Panics in unable to allocate memory to keep all internal structures and buffers.
    ///
    /// # Examples
    /// ```
    /// use rmp::{Value, ValueRef};
    /// use rmp::value::Integer;
    ///
    /// let val = ValueRef::Array(vec![
    ///    ValueRef::Nil,
    ///    ValueRef::Integer(Integer::U64(42)),
    ///    ValueRef::Array(vec![
    ///        ValueRef::String("le message"),
    ///    ])
    /// ]);
    ///
    /// let expected = Value::Array(vec![
    ///     Value::Nil,
    ///     Value::Integer(Integer::U64(42)),
    ///     Value::Array(vec![
    ///         Value::String("le message".to_string())
    ///     ])
    /// ]);
    ///
    /// assert_eq!(expected, val.to_owned());
    /// ```
    pub fn to_owned(&self) -> Value {
        match self {
            &ValueRef::Nil => Value::Nil,
            &ValueRef::Boolean(val) => Value::Boolean(val),
            &ValueRef::Integer(val) => Value::Integer(val),
            &ValueRef::Float(val) => Value::Float(val),
            &ValueRef::String(val) => Value::String(val.to_string()),
            &ValueRef::Binary(val) => Value::Binary(val.to_vec()),
            &ValueRef::Array(ref val) => {
                let mut vec = Vec::new();
                for item in val {
                    vec.push(item.to_owned());
                }

                Value::Array(vec)
            }
            &ValueRef::Map(ref val) => {
                let mut vec = Vec::new();
                for &(ref key, ref val) in val {
                    vec.push((key.to_owned(), val.to_owned()));
                }

                Value::Map(vec)
            }
            &ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
        }
    }
}

// For some weird reasons I can't implement it manually.
// It gives me: conflicting implementations for trait `collections::borrow::ToOwned`
// impl<'a> ToOwned for ValueRef<'a> {
//     type Owned = Value;
// }
<commit_msg>Misc: style.<commit_after>#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Integer {
    /// Every non-negative integer is treated as u64, even if it fits in i64.
    U64(u64),
    /// Every negative integer is treated as i64.
    I64(i64),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Float {
    F32(f32),
    F64(f64),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// Nil represents nil.
    Nil,
    /// Boolean represents true or false.
    Boolean(bool),
    /// Integer represents an integer.
    Integer(Integer),
    /// Float represents a floating point number.
    Float(Float),
    /// String extending Raw type represents a UTF-8 string.
    String(String),
    /// Binary extending Raw type represents a byte array.
    Binary(Vec<u8>),
    /// Array represents a sequence of objects.
    Array(Vec<Value>),
    /// Map represents key-value pairs of objects.
    Map(Vec<(Value, Value)>),
    /// Extended implements Extension interface: represents a tuple of type information and a byte
    /// array where type information is an integer whose meaning is defined by applications.
    Ext(i8, Vec<u8>),
}

#[derive(Clone, Debug, PartialEq)]
pub enum ValueRef<'a> {
   /// Nil represents nil.
   Nil,
   /// Boolean represents true or false.
   Boolean(bool),
   /// Integer represents an integer.
   Integer(Integer),
   /// Float represents a floating point number.
   Float(Float),
   /// String extending Raw type represents a UTF-8 string.
   String(&'a str),
   /// Binary extending Raw type represents a byte array.
   Binary(&'a [u8]),
   /// Array represents a sequence of objects.
   Array(Vec<ValueRef<'a>>),
   /// Map represents key-value pairs of objects.
   Map(Vec<(ValueRef<'a>, ValueRef<'a>)>),
   /// Extended implements Extension interface: represents a tuple of type information and a byte
   /// array where type information is an integer whose meaning is defined by applications.
   Ext(i8, &'a [u8]),
}

impl<'a> ValueRef<'a> {
    /// Converts the current non-owning value to an owned Value.
    ///
    /// This is achieved by deep copying all underlying structures and borrowed buffers.
    ///
    /// # Panics
    ///
    /// Panics in unable to allocate memory to keep all internal structures and buffers.
    ///
    /// # Examples
    /// ```
    /// use rmp::{Value, ValueRef};
    /// use rmp::value::Integer;
    ///
    /// let val = ValueRef::Array(vec![
    ///    ValueRef::Nil,
    ///    ValueRef::Integer(Integer::U64(42)),
    ///    ValueRef::Array(vec![
    ///        ValueRef::String("le message"),
    ///    ])
    /// ]);
    ///
    /// let expected = Value::Array(vec![
    ///     Value::Nil,
    ///     Value::Integer(Integer::U64(42)),
    ///     Value::Array(vec![
    ///         Value::String("le message".to_string())
    ///     ])
    /// ]);
    ///
    /// assert_eq!(expected, val.to_owned());
    /// ```
    pub fn to_owned(&self) -> Value {
        match self {
            &ValueRef::Nil => Value::Nil,
            &ValueRef::Boolean(val) => Value::Boolean(val),
            &ValueRef::Integer(val) => Value::Integer(val),
            &ValueRef::Float(val) => Value::Float(val),
            &ValueRef::String(val) => Value::String(val.to_string()),
            &ValueRef::Binary(val) => Value::Binary(val.to_vec()),
            &ValueRef::Array(ref val) => {
                let mut vec = Vec::new();
                for item in val {
                    vec.push(item.to_owned());
                }

                Value::Array(vec)
            }
            &ValueRef::Map(ref val) => {
                let mut vec = Vec::new();
                for &(ref key, ref val) in val {
                    vec.push((key.to_owned(), val.to_owned()));
                }

                Value::Map(vec)
            }
            &ValueRef::Ext(ty, buf) => Value::Ext(ty, buf.to_vec()),
        }
    }
}

// For some weird reasons I can't implement it manually.
// It gives: conflicting implementations for trait `collections::borrow::ToOwned`
// impl<'a> ToOwned for ValueRef<'a> {
//     type Owned = Value;
// }
<|endoftext|>


<commit_before>use raw::*;
use function::{Function, UncompiledFunction};
use std::kinds::marker::ContravariantLifetime;
use std::fmt::{Formatter, Result, Show};
use std::ops::*;
use types::Type;
use util::{mod, NativeRef};
/// Values form the backbone of the storage system in `libjit`.
/// Every value in the system, be it a constant, a local variable, or a
/// temporary result, is represented by an object of type `Value`. The JIT then
/// allocates registers or memory locations to the values as appropriate.
#[deriving(PartialEq)]
pub struct Value<'a> {
    _value: jit_value_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> NativeRef for Value<'a> {
    #[inline(always)]
    /// Convert to a native pointer
    unsafe fn as_ptr(&self) -> jit_value_t {
        self._value
    }
    #[inline(always)]
    /// Convert from a native pointer
    unsafe fn from_ptr(ptr:jit_value_t) -> Value<'a> {
        Value {
            _value: ptr,
            marker: ContravariantLifetime::<'a>
        }
    }
}
impl<'a> Show for Value<'a> {
    fn fmt(&self, fmt: &mut Formatter) -> Result {
        write!(fmt, "v({})", self.get_type())
    }
}
impl<'a> Clone for Value<'a> {
    fn clone(&self) -> Value<'a> {
        unsafe {
            let func = jit_value_get_function(self.as_ptr());
            NativeRef::from_ptr(jit_insn_dup(func, self.as_ptr()))
        }
    }
}
impl<'a> Value<'a> {
    #[inline(always)]
    /// Create a new value in the context of a function's current block.
    /// The value initially starts off as a block-specific temporary. It will be
    /// converted into a function-wide local variable if it is ever referenced
    /// from a different block.
    pub fn new(func:&UncompiledFunction<'a>, value_type:Type) -> Value<'a> {
        unsafe {
            let value = jit_value_create(func.as_ptr(), value_type.as_ptr());
            NativeRef::from_ptr(value)
        }
    }
    /// Get the type of the value
    pub fn get_type(&self) -> Type {
        unsafe {
            let ty = jit_value_get_type(self.as_ptr());
            NativeRef::from_ptr(ty)
        }
    }
    /// Get the function which made this value
    pub fn get_function(&self) -> UncompiledFunction<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_get_function(self.as_ptr()))
        }
    }
    /// Determine if a value is temporary.  i.e. its scope extends over a single
    /// block within its function.
    #[inline]
    pub fn is_temp(&self) -> bool {
        unsafe {
            jit_value_is_temporary(self.as_ptr()) != 0
        }
    }
    /// Determine if a value is addressable.
    #[inline]
    pub fn is_addressable(&self) -> bool {
        unsafe {
            jit_value_is_addressable(self.as_ptr()) != 0
        }
    }
    /// Set a flag on a value to indicate that it is addressable.
    /// This should be used when you want to take the address of a value (e.g.
    /// `&variable` in Rust/C).  The value is guaranteed to not be stored in a
    /// register across a function call.
    #[inline]
    pub fn set_addressable(&self) -> () {
        unsafe {
            jit_value_set_addressable(self.as_ptr())
        }
    }
}
macro_rules! bin_op {
    ($trait_ty:ident, $trait_func:ident, $func:ident) => (
        impl<'a> $trait_ty<Value<'a>, Value<'a>> for Value<'a> {
            fn $trait_func(self, other: Value<'a>) -> Value {
                self.get_function().$func(&self, &other)
            }
        }
    )
}
macro_rules! un_op {
    ($trait_ty:ident, $trait_func:ident, $func:ident) => (
        impl<'a> $trait_ty<Value<'a>> for Value<'a> {
            fn $trait_func(&self) -> Value<'a> {
                self.get_function().$func(self)
            }
        }
    )
}
bin_op!{Add, add, insn_add}
bin_op!{BitAnd, bitand, insn_and}
bin_op!{BitOr, bitor, insn_or}
bin_op!{BitXor, bitxor, insn_xor}
bin_op!{Div, div, insn_div}
bin_op!{Mul, mul, insn_mul}
bin_op!{Rem, rem, insn_rem}
bin_op!{Shl, shl, insn_shl}
bin_op!{Shr, shr, insn_shr}
bin_op!{Sub, sub, insn_sub}
un_op!{Neg, neg, insn_neg}
un_op!{Not, not, insn_not}<commit_msg>Suppress Warnings<commit_after>use raw::*;
use function::UncompiledFunction;
use std::kinds::marker::ContravariantLifetime;
use std::fmt::{Formatter, Result, Show};
use std::ops::*;
use types::Type;
use util::NativeRef;
/// Values form the backbone of the storage system in `libjit`.
/// Every value in the system, be it a constant, a local variable, or a
/// temporary result, is represented by an object of type `Value`. The JIT then
/// allocates registers or memory locations to the values as appropriate.
#[deriving(PartialEq)]
pub struct Value<'a> {
    _value: jit_value_t,
    marker: ContravariantLifetime<'a>
}
impl<'a> NativeRef for Value<'a> {
    #[inline(always)]
    /// Convert to a native pointer
    unsafe fn as_ptr(&self) -> jit_value_t {
        self._value
    }
    #[inline(always)]
    /// Convert from a native pointer
    unsafe fn from_ptr(ptr:jit_value_t) -> Value<'a> {
        Value {
            _value: ptr,
            marker: ContravariantLifetime::<'a>
        }
    }
}
impl<'a> Show for Value<'a> {
    fn fmt(&self, fmt: &mut Formatter) -> Result {
        write!(fmt, "v({})", self.get_type())
    }
}
impl<'a> Clone for Value<'a> {
    fn clone(&self) -> Value<'a> {
        unsafe {
            let func = jit_value_get_function(self.as_ptr());
            NativeRef::from_ptr(jit_insn_dup(func, self.as_ptr()))
        }
    }
}
impl<'a> Value<'a> {
    #[inline(always)]
    /// Create a new value in the context of a function's current block.
    /// The value initially starts off as a block-specific temporary. It will be
    /// converted into a function-wide local variable if it is ever referenced
    /// from a different block.
    pub fn new(func:&UncompiledFunction<'a>, value_type:Type) -> Value<'a> {
        unsafe {
            let value = jit_value_create(func.as_ptr(), value_type.as_ptr());
            NativeRef::from_ptr(value)
        }
    }
    /// Get the type of the value
    pub fn get_type(&self) -> Type {
        unsafe {
            let ty = jit_value_get_type(self.as_ptr());
            NativeRef::from_ptr(ty)
        }
    }
    /// Get the function which made this value
    pub fn get_function(&self) -> UncompiledFunction<'a> {
        unsafe {
            NativeRef::from_ptr(jit_value_get_function(self.as_ptr()))
        }
    }
    /// Determine if a value is temporary.  i.e. its scope extends over a single
    /// block within its function.
    #[inline]
    pub fn is_temp(&self) -> bool {
        unsafe {
            jit_value_is_temporary(self.as_ptr()) != 0
        }
    }
    /// Determine if a value is addressable.
    #[inline]
    pub fn is_addressable(&self) -> bool {
        unsafe {
            jit_value_is_addressable(self.as_ptr()) != 0
        }
    }
    /// Set a flag on a value to indicate that it is addressable.
    /// This should be used when you want to take the address of a value (e.g.
    /// `&variable` in Rust/C).  The value is guaranteed to not be stored in a
    /// register across a function call.
    #[inline]
    pub fn set_addressable(&self) -> () {
        unsafe {
            jit_value_set_addressable(self.as_ptr())
        }
    }
}
macro_rules! bin_op {
    ($trait_ty:ident, $trait_func:ident, $func:ident) => (
        impl<'a> $trait_ty<Value<'a>, Value<'a>> for Value<'a> {
            fn $trait_func(self, other: Value<'a>) -> Value {
                self.get_function().$func(&self, &other)
            }
        }
    )
}
macro_rules! un_op {
    ($trait_ty:ident, $trait_func:ident, $func:ident) => (
        impl<'a> $trait_ty<Value<'a>> for Value<'a> {
            fn $trait_func(&self) -> Value<'a> {
                self.get_function().$func(self)
            }
        }
    )
}
bin_op!{Add, add, insn_add}
bin_op!{BitAnd, bitand, insn_and}
bin_op!{BitOr, bitor, insn_or}
bin_op!{BitXor, bitxor, insn_xor}
bin_op!{Div, div, insn_div}
bin_op!{Mul, mul, insn_mul}
bin_op!{Rem, rem, insn_rem}
bin_op!{Shl, shl, insn_shl}
bin_op!{Shr, shr, insn_shr}
bin_op!{Sub, sub, insn_sub}
un_op!{Neg, neg, insn_neg}
un_op!{Not, not, insn_not}<|endoftext|>


<commit_before>#![feature(core,collections)]
/// Example file on how to compile a scss file.

extern crate "sass-rs" as sass_rs;
use sass_rs::sass_context::SassFileContext;
use sass_rs::sass_function::*;
use sass_rs::sass_value::*;

/// Function to be exported to libsass.
fn foo(value:& SassValue) -> SassValue {
    let out = format!("Called with {}", value);
    SassValue::sass_string(&out)
}

/// Setup the environment and compile a file.
fn compile(filename:&str) {
    let mut file_context = SassFileContext::new(filename);
    let fns = vec![SassFunctionCallback::from_sig_fn(String::from_str("foo($x)"),foo)];
    file_context.sass_context.sass_options.set_sass_functions(fns);
    let out = file_context.compile();
    match out {
        Ok(css) => println!("------- css  ------\n{}\n--------", css),
        Err(err) => println!("{}", err)
    };
}

pub fn main() {
    let mut args = std::env::args();
    let _ = args.next();
    let file = args.next().expect("Please pass in a file name");
    println!("Compiling sass file: `{}`.", file);
    compile(file.as_slice());
}
<commit_msg>Fix examples<commit_after>#![feature(core)]
/// Example file on how to compile a scss file.

extern crate "sass-rs" as sass_rs;
use sass_rs::sass_context::SassFileContext;
use sass_rs::sass_function::*;
use sass_rs::sass_value::*;

/// Function to be exported to libsass.
fn foo(value:& SassValue) -> SassValue {
    let out = format!("Called with {}", value);
    SassValue::sass_string(&out)
}

/// Setup the environment and compile a file.
fn compile(filename:&str) {
    let mut file_context = SassFileContext::new(filename);
    let fns = vec![("foo($x)",foo as SassFunction)];
    file_context.sass_context.sass_options.set_sass_functions(fns);
    let out = file_context.compile();
    match out {
        Ok(css) => println!("------- css  ------\n{}\n--------", css),
        Err(err) => println!("{}", err)
    };
}

pub fn main() {
    let mut args = std::env::args();
    let _ = args.next();
    let file = args.next().expect("Please pass in a file name");
    println!("Compiling sass file: `{}`.", file);
    compile(file.as_slice());
}
<|endoftext|>


<commit_before>use std::ffi;
use std::mem;
use std::ptr;
use std::slice;

use image::{RgbaImage, Pixel, Rgba};
use libc;
use x11::xlib;

pub const ALL_PLANES: libc::c_ulong = !0;

pub struct Display {
    handle: *mut xlib::Display,
}

pub struct Image {
    handle: *mut xlib::XImage,
}

impl Display {
    pub fn open(name: Option<ffi::CString>) -> Option<Display> {
        unsafe {
            let name = match name {
                None => ptr::null(),
                Some(cstr) => cstr.as_ptr(),
            };
            let d = xlib::XOpenDisplay(name);

            if d.is_null() {
                return None;
            }

            Some(Display {
                handle: d,
            })
        }
    }

    pub fn get_default_root(&self) -> xlib::Window {
        unsafe {
            xlib::XDefaultRootWindow(self.handle)
        }
    }

    pub fn get_window_attributes(&self, window: xlib::Window) -> xlib::XWindowAttributes {
        unsafe {
            let mut attrs = mem::uninitialized();
            xlib::XGetWindowAttributes(self.handle, window, &mut attrs);
            attrs
        }
    }

    pub fn get_image(&self, window: xlib::Window,
                     x: libc::c_int, y: libc::c_int,
                     w: libc::c_uint, h: libc::c_uint,
                     plane_mask: libc::c_ulong,
                     format: libc::c_int) -> Option<Image> {
        unsafe {
            let image = xlib::XGetImage(self.handle, window, x, y, w, h, plane_mask, format);

            if image.is_null() {
                return None;
            }

            Some(Image::from_raw_ximage(image))
        }
    }
}

impl Drop for Display {
    fn drop(&mut self) {
        unsafe {
            xlib::XCloseDisplay(self.handle);
        }
    }
}

impl Image {
    pub fn from_raw_ximage(ximage: *mut xlib::XImage) -> Image {
        Image {
            handle: ximage,
        }
    }

    pub fn into_image_buffer(&self) -> Option<RgbaImage> {
        unsafe {
            // Extract values from the XImage into our own scope
            macro_rules! get {
                ($($a:ident),+) => ($(let $a = (*self.handle).$a;)+);
            }
            get!(width, height,
                 byte_order, depth, bytes_per_line, bits_per_pixel,
                 red_mask, green_mask, blue_mask);

            // Pixel size
            let stride = match (depth, bits_per_pixel) {
                (24, 24) => 3,
                (24, 32) | (32, 32) => 4,
                _ => return None,
            };

            // Compute subpixel offsets into each pixel according the the bitmasks X gives us
            // Only 8 bit, byte-aligned values are supported
            // Truncate masks to the lower 32 bits as that is the maximum pixel size
            macro_rules! channel_offset {
                ($mask:expr) => (match (byte_order, $mask & 0xFFFFFFFF) {
                    (0, 0xFF) | (1, 0xFF000000) => 0,
                    (0, 0xFF00) | (1, 0xFF0000) => 1,
                    (0, 0xFF0000) | (1, 0xFF00) => 2,
                    (0, 0xFF000000) | (1, 0xFF) => 3,
                    _ => return None,
                })
            }
            let red_offset = channel_offset!(red_mask);
            let green_offset = channel_offset!(green_mask);
            let blue_offset = channel_offset!(blue_mask);
            let alpha_offset = channel_offset!(!(red_mask | green_mask | blue_mask));

            // Wrap the pixel buffer into a slice
            let size = (bytes_per_line * height) as usize;
            let data = slice::from_raw_parts((*self.handle).data as *const u8, size);

            // Finally, generate the image object
            Some(RgbaImage::from_fn(width as u32, height as u32, |x, y| {
                macro_rules! subpixel {
                    ($channel_offset:ident) => (data[(y * bytes_per_line as u32
                                                + x * stride as u32
                                                + $channel_offset) as usize]);
                }
                Rgba::from_channels(subpixel!(red_offset),
                                    subpixel!(green_offset),
                                    subpixel!(blue_offset),
                                    // Make the alpha channel fully opaque if none is provided
                                    if depth == 24 { 0xFF } else { subpixel!(alpha_offset) })
            }))
        }
    }
}

impl Drop for Image {
    fn drop(&mut self) {
        unsafe {
            xlib::XDestroyImage(self.handle);
        }
    }
}

pub fn parse_geometry(g: ffi::CString) -> (libc::c_uint, libc::c_uint, libc::c_int, libc::c_int) {
    unsafe {
        let mut w = mem::uninitialized();
        let mut h = mem::uninitialized();
        let mut x = mem::uninitialized();
        let mut y = mem::uninitialized();
        xlib::XParseGeometry(g.as_ptr() as *const i8, &mut x, &mut y, &mut w, &mut h);
        (w, h, x, y)
    }
}
<commit_msg>xwrap: Initialize geometry values to zero<commit_after>use std::ffi;
use std::mem;
use std::ptr;
use std::slice;

use image::{RgbaImage, Pixel, Rgba};
use libc;
use x11::xlib;

pub const ALL_PLANES: libc::c_ulong = !0;

pub struct Display {
    handle: *mut xlib::Display,
}

pub struct Image {
    handle: *mut xlib::XImage,
}

impl Display {
    pub fn open(name: Option<ffi::CString>) -> Option<Display> {
        unsafe {
            let name = match name {
                None => ptr::null(),
                Some(cstr) => cstr.as_ptr(),
            };
            let d = xlib::XOpenDisplay(name);

            if d.is_null() {
                return None;
            }

            Some(Display {
                handle: d,
            })
        }
    }

    pub fn get_default_root(&self) -> xlib::Window {
        unsafe {
            xlib::XDefaultRootWindow(self.handle)
        }
    }

    pub fn get_window_attributes(&self, window: xlib::Window) -> xlib::XWindowAttributes {
        unsafe {
            let mut attrs = mem::uninitialized();
            xlib::XGetWindowAttributes(self.handle, window, &mut attrs);
            attrs
        }
    }

    pub fn get_image(&self, window: xlib::Window,
                     x: libc::c_int, y: libc::c_int,
                     w: libc::c_uint, h: libc::c_uint,
                     plane_mask: libc::c_ulong,
                     format: libc::c_int) -> Option<Image> {
        unsafe {
            let image = xlib::XGetImage(self.handle, window, x, y, w, h, plane_mask, format);

            if image.is_null() {
                return None;
            }

            Some(Image::from_raw_ximage(image))
        }
    }
}

impl Drop for Display {
    fn drop(&mut self) {
        unsafe {
            xlib::XCloseDisplay(self.handle);
        }
    }
}

impl Image {
    pub fn from_raw_ximage(ximage: *mut xlib::XImage) -> Image {
        Image {
            handle: ximage,
        }
    }

    pub fn into_image_buffer(&self) -> Option<RgbaImage> {
        unsafe {
            // Extract values from the XImage into our own scope
            macro_rules! get {
                ($($a:ident),+) => ($(let $a = (*self.handle).$a;)+);
            }
            get!(width, height,
                 byte_order, depth, bytes_per_line, bits_per_pixel,
                 red_mask, green_mask, blue_mask);

            // Pixel size
            let stride = match (depth, bits_per_pixel) {
                (24, 24) => 3,
                (24, 32) | (32, 32) => 4,
                _ => return None,
            };

            // Compute subpixel offsets into each pixel according the the bitmasks X gives us
            // Only 8 bit, byte-aligned values are supported
            // Truncate masks to the lower 32 bits as that is the maximum pixel size
            macro_rules! channel_offset {
                ($mask:expr) => (match (byte_order, $mask & 0xFFFFFFFF) {
                    (0, 0xFF) | (1, 0xFF000000) => 0,
                    (0, 0xFF00) | (1, 0xFF0000) => 1,
                    (0, 0xFF0000) | (1, 0xFF00) => 2,
                    (0, 0xFF000000) | (1, 0xFF) => 3,
                    _ => return None,
                })
            }
            let red_offset = channel_offset!(red_mask);
            let green_offset = channel_offset!(green_mask);
            let blue_offset = channel_offset!(blue_mask);
            let alpha_offset = channel_offset!(!(red_mask | green_mask | blue_mask));

            // Wrap the pixel buffer into a slice
            let size = (bytes_per_line * height) as usize;
            let data = slice::from_raw_parts((*self.handle).data as *const u8, size);

            // Finally, generate the image object
            Some(RgbaImage::from_fn(width as u32, height as u32, |x, y| {
                macro_rules! subpixel {
                    ($channel_offset:ident) => (data[(y * bytes_per_line as u32
                                                + x * stride as u32
                                                + $channel_offset) as usize]);
                }
                Rgba::from_channels(subpixel!(red_offset),
                                    subpixel!(green_offset),
                                    subpixel!(blue_offset),
                                    // Make the alpha channel fully opaque if none is provided
                                    if depth == 24 { 0xFF } else { subpixel!(alpha_offset) })
            }))
        }
    }
}

impl Drop for Image {
    fn drop(&mut self) {
        unsafe {
            xlib::XDestroyImage(self.handle);
        }
    }
}

pub fn parse_geometry(g: ffi::CString) -> (libc::c_uint, libc::c_uint, libc::c_int, libc::c_int) {
    unsafe {
        let mut w = 0;
        let mut h = 0;
        let mut x = 0;
        let mut y = 0;
        xlib::XParseGeometry(g.as_ptr() as *const i8, &mut x, &mut y, &mut w, &mut h);
        (w, h, x, y)
    }
}
<|endoftext|>


<commit_before>extern crate mpi;

use mpi::traits::*;
use mpi::topology::Rank;

fn main() {
    let universe = mpi::initialize().unwrap();
    let world = universe.world();
    let size = world.size();
    let rank = world.rank();

    let next_rank = if rank + 1 < size { rank + 1 } else { 0 };
    let previous_rank = if rank - 1 >= 0 { rank - 1 } else { size - 1 };

    let (msg, status) = world.send_receive::<_, mpi::topology::Rank>(&rank, previous_rank, next_rank);
    assert!(msg.is_some());
    let msg = msg.unwrap();
    println!("Process {} got message {}.\nStatus is: {:?}", rank, msg, status);
    world.barrier();
    assert_eq!(msg, next_rank);

    if rank > 0 {
        let msg = vec![rank, rank + 1, rank - 1];
        world.process_at_rank(0).send(&msg[..]);
    } else {
        for _ in (1..size) {
            let (msg, status) = world.receive_vec::<Rank>();
            assert!(msg.is_some());
            let msg = msg.unwrap();
            println!("Process {} got long message {:?}.\nStatus is: {:?}", rank, msg, status);

            let x = status.source_rank();
            let v = vec![x, x + 1, x - 1];
            assert_eq!(v, msg);
        }
    }
    world.barrier();

    let mut x = rank;
    world.send_receive_replace_into(&mut x, next_rank, previous_rank);
    assert_eq!(x, previous_rank);
}
<commit_msg>Remove extra parantheses.<commit_after>extern crate mpi;

use mpi::traits::*;
use mpi::topology::Rank;

fn main() {
    let universe = mpi::initialize().unwrap();
    let world = universe.world();
    let size = world.size();
    let rank = world.rank();

    let next_rank = if rank + 1 < size { rank + 1 } else { 0 };
    let previous_rank = if rank - 1 >= 0 { rank - 1 } else { size - 1 };

    let (msg, status) = world.send_receive::<_, mpi::topology::Rank>(&rank, previous_rank, next_rank);
    assert!(msg.is_some());
    let msg = msg.unwrap();
    println!("Process {} got message {}.\nStatus is: {:?}", rank, msg, status);
    world.barrier();
    assert_eq!(msg, next_rank);

    if rank > 0 {
        let msg = vec![rank, rank + 1, rank - 1];
        world.process_at_rank(0).send(&msg[..]);
    } else {
        for _ in 1..size {
            let (msg, status) = world.receive_vec::<Rank>();
            assert!(msg.is_some());
            let msg = msg.unwrap();
            println!("Process {} got long message {:?}.\nStatus is: {:?}", rank, msg, status);

            let x = status.source_rank();
            let v = vec![x, x + 1, x - 1];
            assert_eq!(v, msg);
        }
    }
    world.barrier();

    let mut x = rank;
    world.send_receive_replace_into(&mut x, next_rank, previous_rank);
    assert_eq!(x, previous_rank);
}
<|endoftext|>


<commit_before>extern crate android_glue;

use libc;
use std::ffi::{CString};
use std::sync::mpsc::{Receiver, channel};
use {CreationError, Event, MouseCursor};
use CreationError::OsError;
use events::ElementState::{Pressed, Released};
use events::Event::{MouseInput, MouseMoved};
use events::MouseButton;

use std::collections::VecDeque;

use Api;
use BuilderAttribs;
use GlRequest;

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
    event_rx: Receiver<android_glue::Event>,
}

pub struct MonitorID;

mod ffi;

pub fn get_available_monitors() -> VecDeque <MonitorID> {
    let mut rb = VecDeque::new();
    rb.push_back(MonitorID);
    rb
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (u32, u32) {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
pub struct HeadlessContext(i32);

#[cfg(feature = "headless")]
impl HeadlessContext {
    /// See the docs in the crate root file.
    pub fn new(_builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub unsafe fn make_current(&self) {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub fn get_proc_address(&self, _addr: &str) -> *const () {
        unimplemented!()
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }
}

#[cfg(feature = "headless")]
unsafe impl Send for HeadlessContext {}
#[cfg(feature = "headless")]
unsafe impl Sync for HeadlessContext {}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        match self.window.event_rx.try_recv() {
            Ok(event) => {
                Some(match event {
                    android_glue::Event::EventDown => MouseInput(Pressed, MouseButton::Left),
                    android_glue::Event::EventUp => MouseInput(Released, MouseButton::Left),
                    android_glue::Event::EventMove(x, y) => MouseMoved((x as i32, y as i32)),
                })
            }
            Err(_) => {
                None
            }
        }
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        use std::time::Duration;
        use std::old_io::timer;

        loop {
            // calling poll_events()
            if let Some(ev) = self.window.poll_events().next() {
                return Some(ev);
            }

            // TODO: Implement a proper way of sleeping on the event queue
            timer::sleep(Duration::milliseconds(16));
        }
    }
}

impl Window {
    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        if builder.sharing.is_some() {
            unimplemented!()
        }

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let use_gles2 = match builder.gl_version {
            GlRequest::Specific(Api::OpenGlEs, (2, _)) => true,
            GlRequest::Specific(Api::OpenGlEs, _) => false,
            GlRequest::Specific(_, _) => panic!("Only OpenGL ES is supported"),     // FIXME: return a result
            GlRequest::GlThenGles { opengles_version: (2, _), .. } => true,
            _ => false,
        };

        let mut attribute_list = vec!();

        if use_gles2 {
            attribute_list.push_all(&[
                ffi::egl::RENDERABLE_TYPE as i32,
                ffi::egl::OPENGL_ES2_BIT as i32,
            ]);
        }

        {
            let (red, green, blue) = match builder.color_bits.unwrap_or(24) {
                24 => (8, 8, 8),
                16 => (6, 5, 6),
                _ => panic!("Bad color_bits"),
            };
            attribute_list.push_all(&[ffi::egl::RED_SIZE as i32, red]);
            attribute_list.push_all(&[ffi::egl::GREEN_SIZE as i32, green]);
            attribute_list.push_all(&[ffi::egl::BLUE_SIZE as i32, blue]);
        }

        attribute_list.push_all(&[
            ffi::egl::DEPTH_SIZE as i32,
            builder.depth_bits.unwrap_or(8) as i32,
        ]);

        attribute_list.push(ffi::egl::NONE as i32);

        let config = unsafe {
            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let mut context_attributes = vec!();
            if use_gles2 {
                context_attributes.push_all(&[ffi::egl::CONTEXT_CLIENT_VERSION as i32, 2]);
            }
            context_attributes.push(ffi::egl::NONE as i32);

            let context = ffi::egl::CreateContext(display, config, ptr::null(),
                                                  context_attributes.as_ptr());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        let (tx, rx) = channel();
        android_glue::add_sender(tx);

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
            event_rx: rx,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        None
    }

    pub fn set_position(&self, _x: i32, _y: i32) {
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as u32,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as u32
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: u32, _y: u32) {
    }

    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy
    }

    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self
        }
    }

    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self
        }
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        let addr = CString::from_slice(addr.as_bytes());
        let addr = addr.as_ptr();
        unsafe {
            ffi::egl::GetProcAddress(addr) as *const ()
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }

    pub fn platform_window(&self) -> *mut libc::c_void {
        unimplemented!()
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }

    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    pub fn set_cursor(&self, _: MouseCursor) {
    }

    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

#[cfg(feature = "window")]
#[derive(Clone)]
pub struct WindowProxy;

impl WindowProxy {
    pub fn wakeup_event_loop(&self) {
        unimplemented!()
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            // we don't call MakeCurrent(0, 0) because we are not sure that the context
            // is still the current one
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<commit_msg>android: Updated to latest android-rs-glue<commit_after>extern crate android_glue;

use libc;
use std::ffi::{CString};
use std::sync::mpsc::{Receiver, channel};
use {CreationError, Event, MouseCursor};
use CreationError::OsError;
use events::ElementState::{Pressed, Released};
use events::Event::{MouseInput, MouseMoved};
use events::MouseButton;

use std::collections::VecDeque;

use Api;
use BuilderAttribs;
use GlRequest;

pub struct Window {
    display: ffi::egl::types::EGLDisplay,
    context: ffi::egl::types::EGLContext,
    surface: ffi::egl::types::EGLSurface,
    event_rx: Receiver<android_glue::Event>,
}

pub struct MonitorID;

mod ffi;

pub fn get_available_monitors() -> VecDeque <MonitorID> {
    let mut rb = VecDeque::new();
    rb.push_back(MonitorID);
    rb
}

pub fn get_primary_monitor() -> MonitorID {
    MonitorID
}

impl MonitorID {
    pub fn get_name(&self) -> Option<String> {
        Some("Primary".to_string())
    }

    pub fn get_dimensions(&self) -> (u32, u32) {
        unimplemented!()
    }
}

#[cfg(feature = "headless")]
pub struct HeadlessContext(i32);

#[cfg(feature = "headless")]
impl HeadlessContext {
    /// See the docs in the crate root file.
    pub fn new(_builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub unsafe fn make_current(&self) {
        unimplemented!()
    }

    /// See the docs in the crate root file.
    pub fn get_proc_address(&self, _addr: &str) -> *const () {
        unimplemented!()
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }
}

#[cfg(feature = "headless")]
unsafe impl Send for HeadlessContext {}
#[cfg(feature = "headless")]
unsafe impl Sync for HeadlessContext {}

pub struct PollEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for PollEventsIterator<'a> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        match self.window.event_rx.try_recv() {
            Ok(event) => {
                match event {
                    android_glue::Event::EventDown => Some(MouseInput(Pressed, MouseButton::Left)),
                    android_glue::Event::EventUp => Some(MouseInput(Released, MouseButton::Left)),
                    android_glue::Event::EventMove(x, y) => Some(MouseMoved((x as i32, y as i32))),
                    _ => None,
                }
            }
            Err(_) => {
                None
            }
        }
    }
}

pub struct WaitEventsIterator<'a> {
    window: &'a Window,
}

impl<'a> Iterator for WaitEventsIterator<'a> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        use std::time::Duration;
        use std::old_io::timer;

        loop {
            // calling poll_events()
            if let Some(ev) = self.window.poll_events().next() {
                return Some(ev);
            }

            // TODO: Implement a proper way of sleeping on the event queue
            timer::sleep(Duration::milliseconds(16));
        }
    }
}

impl Window {
    pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
        use std::{mem, ptr};

        if builder.sharing.is_some() {
            unimplemented!()
        }

        let native_window = unsafe { android_glue::get_native_window() };
        if native_window.is_null() {
            return Err(OsError(format!("Android's native window is null")));
        }

        let display = unsafe {
            let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
            if display.is_null() {
                return Err(OsError("No EGL display connection available".to_string()));
            }
            display
        };

        android_glue::write_log("eglGetDisplay succeeded");

        let (_major, _minor) = unsafe {
            let mut major: ffi::egl::types::EGLint = mem::uninitialized();
            let mut minor: ffi::egl::types::EGLint = mem::uninitialized();

            if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
                return Err(OsError(format!("eglInitialize failed")))
            }

            (major, minor)
        };

        android_glue::write_log("eglInitialize succeeded");

        let use_gles2 = match builder.gl_version {
            GlRequest::Specific(Api::OpenGlEs, (2, _)) => true,
            GlRequest::Specific(Api::OpenGlEs, _) => false,
            GlRequest::Specific(_, _) => panic!("Only OpenGL ES is supported"),     // FIXME: return a result
            GlRequest::GlThenGles { opengles_version: (2, _), .. } => true,
            _ => false,
        };

        let mut attribute_list = vec!();

        if use_gles2 {
            attribute_list.push_all(&[
                ffi::egl::RENDERABLE_TYPE as i32,
                ffi::egl::OPENGL_ES2_BIT as i32,
            ]);
        }

        {
            let (red, green, blue) = match builder.color_bits.unwrap_or(24) {
                24 => (8, 8, 8),
                16 => (6, 5, 6),
                _ => panic!("Bad color_bits"),
            };
            attribute_list.push_all(&[ffi::egl::RED_SIZE as i32, red]);
            attribute_list.push_all(&[ffi::egl::GREEN_SIZE as i32, green]);
            attribute_list.push_all(&[ffi::egl::BLUE_SIZE as i32, blue]);
        }

        attribute_list.push_all(&[
            ffi::egl::DEPTH_SIZE as i32,
            builder.depth_bits.unwrap_or(8) as i32,
        ]);

        attribute_list.push(ffi::egl::NONE as i32);

        let config = unsafe {
            let mut num_config: ffi::egl::types::EGLint = mem::uninitialized();
            let mut config: ffi::egl::types::EGLConfig = mem::uninitialized();
            if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
                &mut num_config) == 0
            {
                return Err(OsError(format!("eglChooseConfig failed")))
            }

            if num_config <= 0 {
                return Err(OsError(format!("eglChooseConfig returned no available config")))
            }

            config
        };

        android_glue::write_log("eglChooseConfig succeeded");

        let context = unsafe {
            let mut context_attributes = vec!();
            if use_gles2 {
                context_attributes.push_all(&[ffi::egl::CONTEXT_CLIENT_VERSION as i32, 2]);
            }
            context_attributes.push(ffi::egl::NONE as i32);

            let context = ffi::egl::CreateContext(display, config, ptr::null(),
                                                  context_attributes.as_ptr());
            if context.is_null() {
                return Err(OsError(format!("eglCreateContext failed")))
            }
            context
        };

        android_glue::write_log("eglCreateContext succeeded");

        let surface = unsafe {
            let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
            if surface.is_null() {
                return Err(OsError(format!("eglCreateWindowSurface failed")))
            }
            surface
        };

        android_glue::write_log("eglCreateWindowSurface succeeded");

        let (tx, rx) = channel();
        android_glue::add_sender(tx);

        Ok(Window {
            display: display,
            context: context,
            surface: surface,
            event_rx: rx,
        })
    }

    pub fn is_closed(&self) -> bool {
        false
    }

    pub fn set_title(&self, _: &str) {
    }

    pub fn show(&self) {
    }

    pub fn hide(&self) {
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        None
    }

    pub fn set_position(&self, _x: i32, _y: i32) {
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        let native_window = unsafe { android_glue::get_native_window() };

        if native_window.is_null() {
            None
        } else {
            Some((
                unsafe { ffi::ANativeWindow_getWidth(native_window) } as u32,
                unsafe { ffi::ANativeWindow_getHeight(native_window) } as u32
            ))
        }
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.get_inner_size()
    }

    pub fn set_inner_size(&self, _x: u32, _y: u32) {
    }

    pub fn create_window_proxy(&self) -> WindowProxy {
        WindowProxy
    }

    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator {
            window: self
        }
    }

    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator {
            window: self
        }
    }

    pub fn make_current(&self) {
        unsafe {
            ffi::egl::MakeCurrent(self.display, self.surface, self.surface, self.context);
        }
    }

    pub fn get_proc_address(&self, addr: &str) -> *const () {
        let addr = CString::from_slice(addr.as_bytes());
        let addr = addr.as_ptr();
        unsafe {
            ffi::egl::GetProcAddress(addr) as *const ()
        }
    }

    pub fn swap_buffers(&self) {
        unsafe {
            ffi::egl::SwapBuffers(self.display, self.surface);
        }
    }

    pub fn platform_display(&self) -> *mut libc::c_void {
        self.display as *mut libc::c_void
    }

    pub fn platform_window(&self) -> *mut libc::c_void {
        unimplemented!()
    }

    pub fn get_api(&self) -> ::Api {
        ::Api::OpenGlEs
    }

    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }

    pub fn set_cursor(&self, _: MouseCursor) {
    }

    pub fn hidpi_factor(&self) -> f32 {
        1.0
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

#[cfg(feature = "window")]
#[derive(Clone)]
pub struct WindowProxy;

impl WindowProxy {
    pub fn wakeup_event_loop(&self) {
        unimplemented!()
    }
}

#[unsafe_destructor]
impl Drop for Window {
    fn drop(&mut self) {
        use std::ptr;

        unsafe {
            // we don't call MakeCurrent(0, 0) because we are not sure that the context
            // is still the current one
            android_glue::write_log("Destroying gl-init window");
            ffi::egl::DestroySurface(self.display, self.surface);
            ffi::egl::DestroyContext(self.display, self.context);
            ffi::egl::Terminate(self.display);
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Richard Diamond & contributors.
//
// This file is part of the Rust PPApi project.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::ptr;
use libc::{c_char, c_void};

mod consts {
    pub static INSTANCE: &'static str = "PPP_Instance;1.1";
    pub static MESSAGING: &'static str = "PPP_Messaging;1.0";
    pub static INPUTEVENT: &'static str = "PPP_InputEvent;0.1";
    pub static GRAPHICS: &'static str = "PPP_Graphics_3D;1.0";
}
mod globals {
    use super::super::entry;
    use super::super::ffi;
    pub const INSTANCE: ffi::Struct_PPP_Instance_1_1 = ffi::Struct_PPP_Instance_1_1 {
        DidCreate: Some(entry::did_create as extern "C" fn(i32, u32, *mut *const i8, *mut *const i8) -> u32),
        DidDestroy: Some(entry::did_destroy as extern "C" fn(i32)),
        DidChangeView: Some(entry::did_change_view as extern "C" fn(i32, i32)),
        DidChangeFocus: Some(entry::did_change_focus as extern "C" fn(i32, u32)),
        HandleDocumentLoad: Some(entry::handle_document_load as extern "C" fn(i32, i32) -> u32),
    };
    pub static MESSAGING: ffi::Struct_PPP_Messaging_1_0 = ffi::Struct_PPP_Messaging_1_0 {
        HandleMessage: Some(entry::handle_message as extern "C" fn(i32, ffi::Struct_PP_Var)),
    };
    pub static INPUTEVENT: ffi::Struct_PPP_InputEvent_0_1 = ffi::Struct_PPP_InputEvent_0_1 {
        HandleInputEvent: Some(entry::handle_input_event as extern "C" fn(i32, i32) -> u32),
    };
    pub static GRAPHICS: ffi::Struct_PPP_Graphics3D_1_0 = ffi::Struct_PPP_Graphics3D_1_0 {
        Graphics3DContextLost: Some(entry::graphics_context_lost as extern "C" fn(i32)),
    };
}

#[no_mangle]
#[allow(dead_code)]
#[doc(hidden)]
#[allow(non_snake_case)]
pub extern "C" fn PPP_GetInterface(interface_name: *const c_char) -> *const c_void {
    use std::mem::transmute;
    use std::ffi::CStr;
    use std::str::from_utf8_unchecked;

    let interface_name_buf = unsafe { CStr::from_ptr(interface_name) };
    let name = unsafe { from_utf8_unchecked(interface_name_buf.to_bytes()) };
    unsafe {
        if name == consts::INSTANCE {
            transmute(&globals::INSTANCE)
        } else if name == consts::MESSAGING {
            transmute(&globals::MESSAGING)
        } else if name == consts::INPUTEVENT {
            transmute(&globals::INPUTEVENT)
        } else if name == consts::GRAPHICS {
            transmute(&globals::GRAPHICS)
        } else {
            warn!("PPAPI requested an unknown interface: `{}`",
                  name);
            ptr::null()
        }
    }
}
<commit_msg>Fix PPP_GetInterface.<commit_after>// Copyright (c) 2014 Richard Diamond & contributors.
//
// This file is part of the Rust PPApi project.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::ptr;
use libc::{c_char, c_void};

mod consts {
    pub static INSTANCE: &'static [u8] = b"PPP_Instance;1.1\0";
    pub static MESSAGING: &'static [u8] = b"PPP_Messaging;1.0\0";
    pub static INPUTEVENT: &'static [u8] = b"PPP_InputEvent;0.1\0";
    pub static GRAPHICS: &'static [u8] = b"PPP_Graphics_3D;1.0\0";
}
mod globals {
    use entry;
    use ffi;
    pub const INSTANCE: ffi::Struct_PPP_Instance_1_1 = ffi::Struct_PPP_Instance_1_1 {
        DidCreate: Some(entry::did_create as extern "C" fn(i32, u32, *mut *const i8, *mut *const i8) -> u32),
        DidDestroy: Some(entry::did_destroy as extern "C" fn(i32)),
        DidChangeView: Some(entry::did_change_view as extern "C" fn(i32, i32)),
        DidChangeFocus: Some(entry::did_change_focus as extern "C" fn(i32, u32)),
        HandleDocumentLoad: Some(entry::handle_document_load as extern "C" fn(i32, i32) -> u32),
    };
    pub static MESSAGING: ffi::Struct_PPP_Messaging_1_0 = ffi::Struct_PPP_Messaging_1_0 {
        HandleMessage: Some(entry::handle_message as extern "C" fn(i32, ffi::Struct_PP_Var)),
    };
    pub static INPUTEVENT: ffi::Struct_PPP_InputEvent_0_1 = ffi::Struct_PPP_InputEvent_0_1 {
        HandleInputEvent: Some(entry::handle_input_event as extern "C" fn(i32, i32) -> u32),
    };
    pub static GRAPHICS: ffi::Struct_PPP_Graphics3D_1_0 = ffi::Struct_PPP_Graphics3D_1_0 {
        Graphics3DContextLost: Some(entry::graphics_context_lost as extern "C" fn(i32)),
    };
}

#[no_mangle]
#[allow(dead_code)]
#[doc(hidden)]
#[allow(non_snake_case)]
pub extern "C" fn PPP_GetInterface(name: *const c_char) -> *const c_void {
    use std::mem::transmute;
    use libc::strcmp;

    if name as usize == 0 { return ptr::null(); }

    unsafe {
        if strcmp(name, consts::INSTANCE.as_ptr() as *const _) == 0 {
            transmute(&globals::INSTANCE)
        } else if strcmp(name, consts::MESSAGING.as_ptr() as *const _) == 0 {
            transmute(&globals::MESSAGING)
        } else if strcmp(name, consts::INPUTEVENT.as_ptr() as *const _) == 0 {
            transmute(&globals::INPUTEVENT)
        } else if strcmp(name, consts::GRAPHICS.as_ptr() as *const _) == 0 {
            transmute(&globals::GRAPHICS)
        } else {
            ptr::null()
        }
    }
}
<|endoftext|>


<commit_before>//! Lua functionality

use hlua;
use hlua::{Lua, LuaError};
use hlua::any::AnyLuaValue;

use std::thread;

use std::fs::{File};
use std::path::Path;
use std::io::Write;

use std::sync::{Mutex, RwLock};
use std::sync::mpsc::{channel, Sender, Receiver};

#[macro_use]
mod funcs;

lazy_static! {
    /// Sends requests to the lua thread
    static ref SENDER: Mutex<Option<Sender<LuaQuery>>> = Mutex::new(None);

    /// Receives data back from the lua thread
    /// This should only be accessed by the lua thread itself.
    static ref RECEIVER: Mutex<Option<Receiver<LuaResponse>>> = Mutex::new(None);

    /// Whether the lua thread is currently running
    pub static ref RUNNING: RwLock<bool> = RwLock::new(false);
}

/// Messages sent to the lua thread
pub enum LuaQuery {
    /// Halt the lua thread
    Terminate,
    // Restart the lua thread
    Restart,
    /// Execute a string
    Execute(String),
    /// Execute a file
    ExecuteFile(String),
    /// Get a variable
    GetVariable(String),
    /// Set a value
    SetValue {
        name: Box<::std::borrow::Borrow<str> + Sized>,
        val: Box<hlua::Push<&'static mut Lua<'static>> + Sized>
    },
    /// Create a new array
    EmptyArray(String),
    /// Message to ping the lua thread
    Ping,
    /// Unused send type
    Unused,
}

/// Messages received from lua thread
pub enum LuaResponse {
    /// Lua variable obtained
    Variable(Option<AnyLuaValue>),
    /// Lua error
    Error(hlua::LuaError),
    /// A function is returned
    Function(hlua::functions_read::LuaFunction<String>),
    /// Pong response from lua ping
    Pong,
    /// Unused response type
    Unused,
}

unsafe impl Send for LuaQuery { }
unsafe impl Send for LuaResponse { }
unsafe impl Sync for LuaQuery { }
unsafe impl Sync for LuaResponse { }

/// Whether the lua thread is currently available
pub fn thread_running() -> bool {
    *RUNNING.read().unwrap()
}

/// Errors which may arise from attempting
/// to sending a message to the lua thread.
#[derive(Debug)]
pub enum LuaSendError {
    ThreadClosed,
    ThreadUninitialized,
    Sender
}

/// Attemps to send a LuaQuery to the lua thread.
pub fn try_send(query: LuaQuery) -> Result<(), LuaSendError> {
    if !thread_running() {
        Err(LuaSendError::ThreadClosed)
    }
    else if let Some(ref sender) = *SENDER.lock().unwrap() {
        match sender.send(query) {
            Ok(_) => Ok(()),
            Err(_) => Err(LuaSendError::Sender)
        }
    }
    else {
        Err(LuaSendError::ThreadUninitialized)
    }
}

/// Initialize the lua thread
pub fn init() {
    trace!("Initializing...");
    let (query_tx, query_rx) = channel::<LuaQuery>();
    let (answer_tx, answer_rx) = channel::<LuaResponse>();
    {
        let mut sender = SENDER.lock().unwrap();
        let mut receiver = RECEIVER.lock().unwrap();

        *sender = Some(query_tx);
        *receiver = Some(answer_rx);
    }

    thread::spawn(move || {
        trace!("thread: Inside thread!");
        let sender = answer_tx;
        let receiver = query_rx;
        let mut lua = Lua::new();
        trace!("thread: Loading core libraries...");
        lua.openlibs();
        trace!("thread: loading way-cooler library...");
        lua.execute_from_reader::<(), File>(
            File::open("lib/lua/init.lua").unwrap()
        );
        trace!("thread: loading Rust libraries...");
        funcs::register_libraries(&mut lua);
        trace!("Finished loading libraries!");
        // Only broadcast running after loading libs
        *RUNNING.write().unwrap() = true;
        trace!("thread: Testing hello world...");
        let mut file = File::create("/tmp/init.lua").unwrap();
        file.write(b"print('Hello world!')").unwrap();
        lua.execute_from_reader::<(), File>(File::open("/tmp/init.lua")
                                            .unwrap()).unwrap();
        trace!("thread: Done!");
        trace!("thread: Entering loop...");
        thread_main_loop(sender, receiver, &mut lua);
    });
    trace!("Created thread. Init finished.");
}

fn thread_main_loop(sender: Sender<LuaResponse>, receiver: Receiver<LuaQuery>,
                    lua: &mut Lua) {
    loop {
        let request = receiver.recv();
        match request {
            Err(e) => {
                error!("Lua thread: unable to receive message: {}", e);
                error!("Lua thread: now panicking!");
                *RUNNING.write().unwrap() = false;

                panic!("Lua thread: lost contact with host, exiting!");
            }
            Ok(message) => {
                trace!("Handling a request");
                thread_handle_message(&sender, message, lua);
            }
        }
    }
}

fn thread_handle_message(sender: &Sender<LuaResponse>,
                         request: LuaQuery, lua: &mut Lua) {
    match request {
        LuaQuery::Terminate => {
            trace!("thread: Received terminate signal");
            *RUNNING.write().unwrap() = false;

            info!("thread: Lua thread terminating!");
            return;
        },

        LuaQuery::Restart => {
            trace!("thread: Received restart signal!");
            error!("thread: Lua thread restart not supported!");

            *RUNNING.write().unwrap() = false;

            panic!("Lua thread: Restart not supported!");
        },

        LuaQuery::Execute(code) => {
            trace!("thread: Received request to execute code");
            trace!("thread: Executing {:?}", code);

            match lua.execute::<()>(&code) {
                Err(error) => {
                    warn!("thread: Error executing code: {:?}", error);
                    let response = LuaResponse::Error(error);

                    thread_send(&sender, response);
                }
                Ok(_) => {
                    // This is gonna be really spammy one day
                    trace!("thread: Code executed okay.");
                }
            }
        },

        LuaQuery::ExecuteFile(name) => {
            trace!("thread: Received request to execute file {}", name);
            info!("thread: Executing {}", name);

            let path = Path::new(&name);
            let try_file = File::open(path);

            if let Ok(file) = try_file {
                let result = lua.execute_from_reader::<(), File>(file);
                if let Err(err) = result {
                    warn!("thread: Error executing {}!", name);

                    thread_send(&sender, LuaResponse::Error(err));
                }
                else {
                    trace!("thread: Execution of {} successful.", name);
                }
            }
            else { // Could not open file
                // Unwrap_err is used because we're in the else of let
                let read_error =
                    LuaError::ReadError(try_file.unwrap_err());

                thread_send(&sender, LuaResponse::Error(read_error));
            }
        },

        LuaQuery::GetVariable(varname) => {
            trace!("thread: Received request to get variable {}", varname);
            let var_result = lua.get(varname.as_str());

            match var_result {
                Some(var) => {
                    thread_send(&sender, LuaResponse::Variable(Some(var)));
                }
                None => {
                    warn!("thread: Unable to get variable {}", varname);

                    thread_send(&sender, LuaResponse::Variable(None));
                }
            }
        },

        LuaQuery::SetValue { name: name, val: val } => {
        },

        LuaQuery::EmptyArray(name) => {

        },

        _ => {
            panic!("Unimplemented send type for lua thread!");
        }
    }
}

fn thread_send(sender: &Sender<LuaResponse>, response: LuaResponse) {
    trace!("Called thread_send");
    match sender.send(response) {
        Err(e) => {
            error!("thread: Unable to broadcast response!");
            error!("thread: Shutting down in response to inability \
                    to continue!");
            panic!("Lua thread unable to communicate with main thread, \
                    shutting down!");
        }
        Ok(_) => {}
    }
}
<commit_msg>Remove lua thread creating /tmp/hello_world.lua<commit_after>//! Lua functionality

use hlua;
use hlua::{Lua, LuaError};
use hlua::any::AnyLuaValue;

use std::thread;

use std::fs::{File};
use std::path::Path;
use std::io::Write;

use std::sync::{Mutex, RwLock};
use std::sync::mpsc::{channel, Sender, Receiver};

#[macro_use]
mod funcs;

lazy_static! {
    /// Sends requests to the lua thread
    static ref SENDER: Mutex<Option<Sender<LuaQuery>>> = Mutex::new(None);

    /// Receives data back from the lua thread
    /// This should only be accessed by the lua thread itself.
    static ref RECEIVER: Mutex<Option<Receiver<LuaResponse>>> = Mutex::new(None);

    /// Whether the lua thread is currently running
    pub static ref RUNNING: RwLock<bool> = RwLock::new(false);
}

/// Messages sent to the lua thread
pub enum LuaQuery {
    /// Halt the lua thread
    Terminate,
    // Restart the lua thread
    Restart,
    /// Execute a string
    Execute(String),
    /// Execute a file
    ExecuteFile(String),
    /// Get a variable
    GetVariable(String),
    /// Set a value
    SetValue {
        name: Box<::std::borrow::Borrow<str> + Sized>,
        val: Box<hlua::Push<&'static mut Lua<'static>> + Sized>
    },
    /// Create a new array
    EmptyArray(String),
    /// Message to ping the lua thread
    Ping,
    /// Unused send type
    Unused,
}

/// Messages received from lua thread
pub enum LuaResponse {
    /// Lua variable obtained
    Variable(Option<AnyLuaValue>),
    /// Lua error
    Error(hlua::LuaError),
    /// A function is returned
    Function(hlua::functions_read::LuaFunction<String>),
    /// Pong response from lua ping
    Pong,
    /// Unused response type
    Unused,
}

unsafe impl Send for LuaQuery { }
unsafe impl Send for LuaResponse { }
unsafe impl Sync for LuaQuery { }
unsafe impl Sync for LuaResponse { }

/// Whether the lua thread is currently available
pub fn thread_running() -> bool {
    *RUNNING.read().unwrap()
}

/// Errors which may arise from attempting
/// to sending a message to the lua thread.
#[derive(Debug)]
pub enum LuaSendError {
    ThreadClosed,
    ThreadUninitialized,
    Sender
}

/// Attemps to send a LuaQuery to the lua thread.
pub fn try_send(query: LuaQuery) -> Result<(), LuaSendError> {
    if !thread_running() {
        Err(LuaSendError::ThreadClosed)
    }
    else if let Some(ref sender) = *SENDER.lock().unwrap() {
        match sender.send(query) {
            Ok(_) => Ok(()),
            Err(_) => Err(LuaSendError::Sender)
        }
    }
    else {
        Err(LuaSendError::ThreadUninitialized)
    }
}

/// Initialize the lua thread
pub fn init() {
    trace!("Initializing...");
    let (query_tx, query_rx) = channel::<LuaQuery>();
    let (answer_tx, answer_rx) = channel::<LuaResponse>();
    {
        let mut sender = SENDER.lock().unwrap();
        let mut receiver = RECEIVER.lock().unwrap();

        *sender = Some(query_tx);
        *receiver = Some(answer_rx);
    }

    thread::spawn(move || {
        trace!("thread: Inside thread!");
        let sender = answer_tx;
        let receiver = query_rx;
        let mut lua = Lua::new();
        debug!("thread: Loading core libraries...");
        lua.openlibs();
        trace!("thread: loading way-cooler library...");
        lua.execute_from_reader::<(), File>(
            File::open("lib/lua/init.lua").unwrap()
        );
        trace!("thread: loading Rust libraries...");
        funcs::register_libraries(&mut lua);
        trace!("Finished loading libraries!");
        // Only broadcast running after loading libs
        *RUNNING.write().unwrap() = true;
        debug!("thread: Entering loop...");
        thread_main_loop(sender, receiver, &mut lua);
    });
    trace!("Created thread. Init finished.");
}

fn thread_main_loop(sender: Sender<LuaResponse>, receiver: Receiver<LuaQuery>,
                    lua: &mut Lua) {
    loop {
        let request = receiver.recv();
        match request {
            Err(e) => {
                error!("Lua thread: unable to receive message: {}", e);
                error!("Lua thread: now panicking!");
                *RUNNING.write().unwrap() = false;

                panic!("Lua thread: lost contact with host, exiting!");
            }
            Ok(message) => {
                trace!("Handling a request");
                thread_handle_message(&sender, message, lua);
            }
        }
    }
}

fn thread_handle_message(sender: &Sender<LuaResponse>,
                         request: LuaQuery, lua: &mut Lua) {
    match request {
        LuaQuery::Terminate => {
            trace!("thread: Received terminate signal");
            *RUNNING.write().unwrap() = false;

            info!("thread: Lua thread terminating!");
            return;
        },

        LuaQuery::Restart => {
            trace!("thread: Received restart signal!");
            error!("thread: Lua thread restart not supported!");

            *RUNNING.write().unwrap() = false;

            panic!("Lua thread: Restart not supported!");
        },

        LuaQuery::Execute(code) => {
            trace!("thread: Received request to execute code");
            trace!("thread: Executing {:?}", code);

            match lua.execute::<()>(&code) {
                Err(error) => {
                    warn!("thread: Error executing code: {:?}", error);
                    let response = LuaResponse::Error(error);

                    thread_send(&sender, response);
                }
                Ok(_) => {
                    // This is gonna be really spammy one day
                    trace!("thread: Code executed okay.");
                }
            }
        },

        LuaQuery::ExecuteFile(name) => {
            trace!("thread: Received request to execute file {}", name);
            info!("thread: Executing {}", name);

            let path = Path::new(&name);
            let try_file = File::open(path);

            if let Ok(file) = try_file {
                let result = lua.execute_from_reader::<(), File>(file);
                if let Err(err) = result {
                    warn!("thread: Error executing {}!", name);

                    thread_send(&sender, LuaResponse::Error(err));
                }
                else {
                    trace!("thread: Execution of {} successful.", name);
                }
            }
            else { // Could not open file
                // Unwrap_err is used because we're in the else of let
                let read_error =
                    LuaError::ReadError(try_file.unwrap_err());

                thread_send(&sender, LuaResponse::Error(read_error));
            }
        },

        LuaQuery::GetVariable(varname) => {
            trace!("thread: Received request to get variable {}", varname);
            let var_result = lua.get(varname.as_str());

            match var_result {
                Some(var) => {
                    thread_send(&sender, LuaResponse::Variable(Some(var)));
                }
                None => {
                    warn!("thread: Unable to get variable {}", varname);

                    thread_send(&sender, LuaResponse::Variable(None));
                }
            }
        },

        LuaQuery::SetValue { name: name, val: val } => {
        },

        LuaQuery::EmptyArray(name) => {

        },

        _ => {
            panic!("Unimplemented send type for lua thread!");
        }
    }
}

fn thread_send(sender: &Sender<LuaResponse>, response: LuaResponse) {
    trace!("Called thread_send");
    match sender.send(response) {
        Err(e) => {
            error!("thread: Unable to broadcast response!");
            error!("thread: Shutting down in response to inability \
                    to continue!");
            panic!("Lua thread unable to communicate with main thread, \
                    shutting down!");
        }
        Ok(_) => {}
    }
}
<|endoftext|>


<commit_before>use crate::utils::path_to_local_id;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, walk_expr, NestedVisitorMap, Visitor};
use rustc_hir::{Arm, Body, Expr, HirId, Stmt};
use rustc_lint::LateContext;
use rustc_middle::hir::map::Map;

/// returns `true` if expr contains match expr desugared from try
fn contains_try(expr: &hir::Expr<'_>) -> bool {
    struct TryFinder {
        found: bool,
    }

    impl<'hir> intravisit::Visitor<'hir> for TryFinder {
        type Map = Map<'hir>;

        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
            intravisit::NestedVisitorMap::None
        }

        fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
            if self.found {
                return;
            }
            match expr.kind {
                hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar) => self.found = true,
                _ => intravisit::walk_expr(self, expr),
            }
        }
    }

    let mut visitor = TryFinder { found: false };
    visitor.visit_expr(expr);
    visitor.found
}

pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool
where
    F: FnMut(&'hir hir::Expr<'hir>) -> bool,
{
    struct RetFinder<F> {
        in_stmt: bool,
        failed: bool,
        cb: F,
    }

    struct WithStmtGuarg<'a, F> {
        val: &'a mut RetFinder<F>,
        prev_in_stmt: bool,
    }

    impl<F> RetFinder<F> {
        fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuarg<'_, F> {
            let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt);
            WithStmtGuarg {
                val: self,
                prev_in_stmt,
            }
        }
    }

    impl<F> std::ops::Deref for WithStmtGuarg<'_, F> {
        type Target = RetFinder<F>;

        fn deref(&self) -> &Self::Target {
            self.val
        }
    }

    impl<F> std::ops::DerefMut for WithStmtGuarg<'_, F> {
        fn deref_mut(&mut self) -> &mut Self::Target {
            self.val
        }
    }

    impl<F> Drop for WithStmtGuarg<'_, F> {
        fn drop(&mut self) {
            self.val.in_stmt = self.prev_in_stmt;
        }
    }

    impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> {
        type Map = Map<'hir>;

        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
            intravisit::NestedVisitorMap::None
        }

        fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) {
            intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt)
        }

        fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) {
            if self.failed {
                return;
            }
            if self.in_stmt {
                match expr.kind {
                    hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
                    _ => intravisit::walk_expr(self, expr),
                }
            } else {
                match expr.kind {
                    hir::ExprKind::If(cond, then, else_opt) => {
                        self.inside_stmt(true).visit_expr(cond);
                        self.visit_expr(then);
                        if let Some(el) = else_opt {
                            self.visit_expr(el);
                        }
                    },
                    hir::ExprKind::Match(cond, arms, _) => {
                        self.inside_stmt(true).visit_expr(cond);
                        for arm in arms {
                            self.visit_expr(arm.body);
                        }
                    },
                    hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr),
                    hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
                    _ => self.failed |= !(self.cb)(expr),
                }
            }
        }
    }

    !contains_try(expr) && {
        let mut ret_finder = RetFinder {
            in_stmt: false,
            failed: false,
            cb: callback,
        };
        ret_finder.visit_expr(expr);
        !ret_finder.failed
    }
}

pub struct LocalUsedVisitor<'hir> {
    hir: Map<'hir>,
    pub local_hir_id: HirId,
    pub used: bool,
}

impl<'hir> LocalUsedVisitor<'hir> {
    pub fn new(cx: &LateContext<'hir>, local_hir_id: HirId) -> Self {
        Self {
            hir: cx.tcx.hir(),
            local_hir_id,
            used: false,
        }
    }

    fn check<T>(&mut self, t: T, visit: fn(&mut Self, T)) -> bool {
        visit(self, t);
        std::mem::replace(&mut self.used, false)
    }

    pub fn check_arm(&mut self, arm: &'hir Arm<'_>) -> bool {
        self.check(arm, Self::visit_arm)
    }

    pub fn check_body(&mut self, body: &'hir Body<'_>) -> bool {
        self.check(body, Self::visit_body)
    }

    pub fn check_expr(&mut self, expr: &'hir Expr<'_>) -> bool {
        self.check(expr, Self::visit_expr)
    }

    pub fn check_stmt(&mut self, stmt: &'hir Stmt<'_>) -> bool {
        self.check(stmt, Self::visit_stmt)
    }
}

impl<'v> Visitor<'v> for LocalUsedVisitor<'v> {
    type Map = Map<'v>;

    fn visit_expr(&mut self, expr: &'v Expr<'v>) {
        if self.used {
            return;
        }
        if path_to_local_id(expr, self.local_hir_id) {
            self.used = true;
        } else {
            walk_expr(self, expr);
        }
    }

    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
        NestedVisitorMap::OnlyBodies(self.hir)
    }
}
<commit_msg>Fix one import<commit_after>use crate::path_to_local_id;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, walk_expr, NestedVisitorMap, Visitor};
use rustc_hir::{Arm, Body, Expr, HirId, Stmt};
use rustc_lint::LateContext;
use rustc_middle::hir::map::Map;

/// returns `true` if expr contains match expr desugared from try
fn contains_try(expr: &hir::Expr<'_>) -> bool {
    struct TryFinder {
        found: bool,
    }

    impl<'hir> intravisit::Visitor<'hir> for TryFinder {
        type Map = Map<'hir>;

        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
            intravisit::NestedVisitorMap::None
        }

        fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
            if self.found {
                return;
            }
            match expr.kind {
                hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar) => self.found = true,
                _ => intravisit::walk_expr(self, expr),
            }
        }
    }

    let mut visitor = TryFinder { found: false };
    visitor.visit_expr(expr);
    visitor.found
}

pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool
where
    F: FnMut(&'hir hir::Expr<'hir>) -> bool,
{
    struct RetFinder<F> {
        in_stmt: bool,
        failed: bool,
        cb: F,
    }

    struct WithStmtGuarg<'a, F> {
        val: &'a mut RetFinder<F>,
        prev_in_stmt: bool,
    }

    impl<F> RetFinder<F> {
        fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuarg<'_, F> {
            let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt);
            WithStmtGuarg {
                val: self,
                prev_in_stmt,
            }
        }
    }

    impl<F> std::ops::Deref for WithStmtGuarg<'_, F> {
        type Target = RetFinder<F>;

        fn deref(&self) -> &Self::Target {
            self.val
        }
    }

    impl<F> std::ops::DerefMut for WithStmtGuarg<'_, F> {
        fn deref_mut(&mut self) -> &mut Self::Target {
            self.val
        }
    }

    impl<F> Drop for WithStmtGuarg<'_, F> {
        fn drop(&mut self) {
            self.val.in_stmt = self.prev_in_stmt;
        }
    }

    impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> {
        type Map = Map<'hir>;

        fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
            intravisit::NestedVisitorMap::None
        }

        fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) {
            intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt)
        }

        fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) {
            if self.failed {
                return;
            }
            if self.in_stmt {
                match expr.kind {
                    hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
                    _ => intravisit::walk_expr(self, expr),
                }
            } else {
                match expr.kind {
                    hir::ExprKind::If(cond, then, else_opt) => {
                        self.inside_stmt(true).visit_expr(cond);
                        self.visit_expr(then);
                        if let Some(el) = else_opt {
                            self.visit_expr(el);
                        }
                    },
                    hir::ExprKind::Match(cond, arms, _) => {
                        self.inside_stmt(true).visit_expr(cond);
                        for arm in arms {
                            self.visit_expr(arm.body);
                        }
                    },
                    hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr),
                    hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
                    _ => self.failed |= !(self.cb)(expr),
                }
            }
        }
    }

    !contains_try(expr) && {
        let mut ret_finder = RetFinder {
            in_stmt: false,
            failed: false,
            cb: callback,
        };
        ret_finder.visit_expr(expr);
        !ret_finder.failed
    }
}

pub struct LocalUsedVisitor<'hir> {
    hir: Map<'hir>,
    pub local_hir_id: HirId,
    pub used: bool,
}

impl<'hir> LocalUsedVisitor<'hir> {
    pub fn new(cx: &LateContext<'hir>, local_hir_id: HirId) -> Self {
        Self {
            hir: cx.tcx.hir(),
            local_hir_id,
            used: false,
        }
    }

    fn check<T>(&mut self, t: T, visit: fn(&mut Self, T)) -> bool {
        visit(self, t);
        std::mem::replace(&mut self.used, false)
    }

    pub fn check_arm(&mut self, arm: &'hir Arm<'_>) -> bool {
        self.check(arm, Self::visit_arm)
    }

    pub fn check_body(&mut self, body: &'hir Body<'_>) -> bool {
        self.check(body, Self::visit_body)
    }

    pub fn check_expr(&mut self, expr: &'hir Expr<'_>) -> bool {
        self.check(expr, Self::visit_expr)
    }

    pub fn check_stmt(&mut self, stmt: &'hir Stmt<'_>) -> bool {
        self.check(stmt, Self::visit_stmt)
    }
}

impl<'v> Visitor<'v> for LocalUsedVisitor<'v> {
    type Map = Map<'v>;

    fn visit_expr(&mut self, expr: &'v Expr<'v>) {
        if self.used {
            return;
        }
        if path_to_local_id(expr, self.local_hir_id) {
            self.used = true;
        } else {
            walk_expr(self, expr);
        }
    }

    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
        NestedVisitorMap::OnlyBodies(self.hir)
    }
}
<|endoftext|>