<commit_before>// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
// Copyright (C) 2018 LEE Dongjun <redongjun@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
// Boston, MA 02110-1335, USA.

use futures::future::BoxFuture;

use gst::prelude::*;
use gst::{gst_debug, gst_error, gst_log};

use once_cell::sync::Lazy;

use std::io;

use gio::prelude::*;

use std::error;
use std::fmt;

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};

#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};

static SOCKET_CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
    gst::DebugCategory::new(
        "ts-socket",
        gst::DebugColorFlags::empty(),
        Some("Thread-sharing Socket"),
    )
});

pub trait SocketRead: Send + Unpin {
    const DO_TIMESTAMP: bool;

    fn read<'buf>(
        &'buf mut self,
        buffer: &'buf mut [u8],
    ) -> BoxFuture<'buf, io::Result<(usize, Option<std::net::SocketAddr>)>>;
}

pub struct Socket<T: SocketRead> {
    element: gst::Element,
    buffer_pool: gst::BufferPool,
    reader: T,
    mapped_buffer: Option<gst::MappedBuffer<gst::buffer::Writable>>,
    clock: Option<gst::Clock>,
    base_time: Option<gst::ClockTime>,
}

impl<T: SocketRead> Socket<T> {
    pub fn try_new(
        element: gst::Element,
        buffer_pool: gst::BufferPool,
        reader: T,
    ) -> Result<Self, ()> {
        // FIXME couldn't we just delegate this to caller?
        buffer_pool.set_active(true).map_err(|err| {
            gst_error!(
                SOCKET_CAT,
                obj: &element,
                "Failed to prepare socket: {}",
                err
            );
        })?;

        Ok(Socket::<T> {
            buffer_pool,
            element,
            reader,
            mapped_buffer: None,
            clock: None,
            base_time: None,
        })
    }

    pub fn set_clock(&mut self, clock: Option<gst::Clock>, base_time: Option<gst::ClockTime>) {
        self.clock = clock;
        self.base_time = base_time;
    }
}

#[derive(Debug)]
pub enum SocketError {
    Gst(gst::FlowError),
    Io(io::Error),
}

impl error::Error for SocketError {}

impl fmt::Display for SocketError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            SocketError::Gst(err) => write!(f, "flow error: {}", err),
            SocketError::Io(err) => write!(f, "IO error: {}", err),
        }
    }
}

pub type SocketStreamItem = Result<(gst::Buffer, Option<std::net::SocketAddr>), SocketError>;

impl<T: SocketRead> Socket<T> {
    // Can't implement this as a Stream trait because we end up using things like
    // tokio::net::UdpSocket which don't implement pollable functions.
    #[allow(clippy::should_implement_trait)]
    pub async fn next(&mut self) -> Option<SocketStreamItem> {
        gst_log!(SOCKET_CAT, obj: &self.element, "Trying to read data");

        if self.mapped_buffer.is_none() {
            match self.buffer_pool.acquire_buffer(None) {
                Ok(buffer) => {
                    self.mapped_buffer = Some(buffer.into_mapped_buffer_writable().unwrap());
                }
                Err(err) => {
                    gst_debug!(SOCKET_CAT, obj: &self.element, "Failed to acquire buffer {:?}", err);
                    return Some(Err(SocketError::Gst(err)));
                }
            }
        }

        match self
            .reader
            .read(self.mapped_buffer.as_mut().unwrap().as_mut_slice())
            .await
        {
            Ok((len, saddr)) => {
                let dts = if T::DO_TIMESTAMP {
                    let time = self.clock.as_ref().unwrap().get_time();
                    let running_time = time - self.base_time.unwrap();
                    gst_debug!(
                        SOCKET_CAT,
                        obj: &self.element,
                        "Read {} bytes at {} (clock {})",
                        len,
                        running_time,
                        time
                    );
                    running_time
                } else {
                    gst_debug!(SOCKET_CAT, obj: &self.element, "Read {} bytes", len);
                    gst::CLOCK_TIME_NONE
                };

                let mut buffer = self.mapped_buffer.take().unwrap().into_buffer();
                {
                    let buffer = buffer.get_mut().unwrap();
                    if len < buffer.get_size() {
                        buffer.set_size(len);
                    }
                    buffer.set_dts(dts);
                }

                Some(Ok((buffer, saddr)))
            }
            Err(err) => {
                gst_debug!(SOCKET_CAT, obj: &self.element, "Read error {:?}", err);

                Some(Err(SocketError::Io(err)))
            }
        }
    }
}

impl<T: SocketRead> Drop for Socket<T> {
    fn drop(&mut self) {
        if let Err(err) = self.buffer_pool.set_active(false) {
            gst_error!(SOCKET_CAT, obj: &self.element, "Failed to unprepare socket: {}", err);
        }
    }
}

// Send/Sync struct for passing around a gio::Socket
// and getting the raw fd from it
//
// gio::Socket is not Send/Sync as it's generally unsafe
// to access it from multiple threads. Getting the underlying raw
// fd is safe though, as is receiving/sending from two different threads
#[derive(Debug)]
pub struct GioSocketWrapper {
    socket: *mut gio::ffi::GSocket,
}

unsafe impl Send for GioSocketWrapper {}
unsafe impl Sync for GioSocketWrapper {}

impl GioSocketWrapper {
    pub fn new(socket: &gio::Socket) -> Self {
        use glib::translate::*;

        Self {
            socket: socket.to_glib_full(),
        }
    }

    pub fn as_socket(&self) -> gio::Socket {
        unsafe {
            use glib::translate::*;

            from_glib_none(self.socket)
        }
    }

    #[cfg(unix)]
    pub fn set_tos(&self, qos_dscp: i32) -> Result<(), glib::Error> {
        use libc::{IPPROTO_IP, IPPROTO_IPV6, IPV6_TCLASS, IP_TOS};

        let tos = (qos_dscp & 0x3f) << 2;

        let socket = self.as_socket();

        socket.set_option(IPPROTO_IP, IP_TOS, tos)?;

        if socket.get_family() == gio::SocketFamily::Ipv6 {
            socket.set_option(IPPROTO_IPV6, IPV6_TCLASS, tos)?;
        }

        Ok(())
    }

    #[cfg(not(unix))]
    pub fn set_tos(&self, qos_dscp: i32) -> Result<(), glib::Error> {
        Ok(())
    }

    #[cfg(unix)]
    pub fn get<T: FromRawFd>(&self) -> T {
        unsafe { FromRawFd::from_raw_fd(libc::dup(gio::ffi::g_socket_get_fd(self.socket))) }
    }

    #[cfg(windows)]
    pub fn get<T: FromRawSocket>(&self) -> T {
        unsafe {
            FromRawSocket::from_raw_socket(
                dup_socket(gio::ffi::g_socket_get_fd(self.socket) as _) as _
            )
        }
    }
}

impl Clone for GioSocketWrapper {
    fn clone(&self) -> Self {
        Self {
            socket: unsafe { glib::gobject_ffi::g_object_ref(self.socket as *mut _) as *mut _ },
        }
    }
}

impl Drop for GioSocketWrapper {
    fn drop(&mut self) {
        unsafe {
            glib::gobject_ffi::g_object_unref(self.socket as *mut _);
        }
    }
}

#[cfg(windows)]
unsafe fn dup_socket(socket: usize) -> usize {
    use std::mem;
    use winapi::shared::ws2def;
    use winapi::um::processthreadsapi;
    use winapi::um::winsock2;

    let mut proto_info = mem::MaybeUninit::uninit();
    let ret = winsock2::WSADuplicateSocketA(
        socket,
        processthreadsapi::GetCurrentProcessId(),
        proto_info.as_mut_ptr(),
    );
    assert_eq!(ret, 0);
    let mut proto_info = proto_info.assume_init();

    let socket = winsock2::WSASocketA(
        ws2def::AF_INET,
        ws2def::SOCK_DGRAM,
        ws2def::IPPROTO_UDP as i32,
        &mut proto_info,
        0,
        0,
    );

    assert_ne!(socket, winsock2::INVALID_SOCKET);

    socket
}

pub fn wrap_socket(socket: &tokio::net::UdpSocket) -> Result<GioSocketWrapper, gst::ErrorMessage> {
    #[cfg(unix)]
    unsafe {
        let fd = libc::dup(socket.as_raw_fd());

        // This is unsafe because it allows us to share the fd between the socket and the
        // GIO socket below, but safety of this is the job of the application
        struct FdConverter(RawFd);
        impl IntoRawFd for FdConverter {
            fn into_raw_fd(self) -> RawFd {
                self.0
            }
        }

        let fd = FdConverter(fd);

        let gio_socket = gio::Socket::from_fd(fd).map_err(|err| {
            gst::error_msg!(
                gst::ResourceError::OpenWrite,
                ["Failed to create wrapped GIO socket: {}", err]
            )
        })?;
        Ok(GioSocketWrapper::new(&gio_socket))
    }
    #[cfg(windows)]
    unsafe {
        // FIXME: Needs https://github.com/tokio-rs/tokio/pull/806
        // and https://github.com/carllerche/mio/pull/859
        let fd = unreachable!(); //dup_socket(socket.as_raw_socket() as _) as _;

        // This is unsafe because it allows us to share the fd between the socket and the
        // GIO socket below, but safety of this is the job of the application
        struct SocketConverter(RawSocket);
        impl IntoRawSocket for SocketConverter {
            fn into_raw_socket(self) -> RawSocket {
                self.0
            }
        }

        let fd = SocketConverter(fd);

        let gio_socket = gio::Socket::from_socket(fd).map_err(|err| {
            gst::error_msg!(
                gst::ResourceError::OpenWrite,
                ["Failed to create wrapped GIO socket: {}", err]
            )
        })?;

        Ok(GioSocketWrapper::new(&gio_socket))
    }
}
<commit_msg>threadshare: Return a proper error type instead of ()<commit_after>// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
// Copyright (C) 2018 LEE Dongjun <redongjun@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Suite 500,
// Boston, MA 02110-1335, USA.

use futures::future::BoxFuture;

use gst::prelude::*;
use gst::{gst_debug, gst_error, gst_log};

use once_cell::sync::Lazy;

use std::io;

use gio::prelude::*;

use std::error;
use std::fmt;

#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};

#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};

static SOCKET_CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
    gst::DebugCategory::new(
        "ts-socket",
        gst::DebugColorFlags::empty(),
        Some("Thread-sharing Socket"),
    )
});

pub trait SocketRead: Send + Unpin {
    const DO_TIMESTAMP: bool;

    fn read<'buf>(
        &'buf mut self,
        buffer: &'buf mut [u8],
    ) -> BoxFuture<'buf, io::Result<(usize, Option<std::net::SocketAddr>)>>;
}

pub struct Socket<T: SocketRead> {
    element: gst::Element,
    buffer_pool: gst::BufferPool,
    reader: T,
    mapped_buffer: Option<gst::MappedBuffer<gst::buffer::Writable>>,
    clock: Option<gst::Clock>,
    base_time: Option<gst::ClockTime>,
}

impl<T: SocketRead> Socket<T> {
    pub fn try_new(
        element: gst::Element,
        buffer_pool: gst::BufferPool,
        reader: T,
    ) -> Result<Self, glib::BoolError> {
        // FIXME couldn't we just delegate this to caller?
        buffer_pool.set_active(true).map_err(|err| {
            gst_error!(
                SOCKET_CAT,
                obj: &element,
                "Failed to prepare socket: {}",
                err
            );

            err
        })?;

        Ok(Socket::<T> {
            buffer_pool,
            element,
            reader,
            mapped_buffer: None,
            clock: None,
            base_time: None,
        })
    }

    pub fn set_clock(&mut self, clock: Option<gst::Clock>, base_time: Option<gst::ClockTime>) {
        self.clock = clock;
        self.base_time = base_time;
    }
}

#[derive(Debug)]
pub enum SocketError {
    Gst(gst::FlowError),
    Io(io::Error),
}

impl error::Error for SocketError {}

impl fmt::Display for SocketError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            SocketError::Gst(err) => write!(f, "flow error: {}", err),
            SocketError::Io(err) => write!(f, "IO error: {}", err),
        }
    }
}

pub type SocketStreamItem = Result<(gst::Buffer, Option<std::net::SocketAddr>), SocketError>;

impl<T: SocketRead> Socket<T> {
    // Can't implement this as a Stream trait because we end up using things like
    // tokio::net::UdpSocket which don't implement pollable functions.
    #[allow(clippy::should_implement_trait)]
    pub async fn next(&mut self) -> Option<SocketStreamItem> {
        gst_log!(SOCKET_CAT, obj: &self.element, "Trying to read data");

        if self.mapped_buffer.is_none() {
            match self.buffer_pool.acquire_buffer(None) {
                Ok(buffer) => {
                    self.mapped_buffer = Some(buffer.into_mapped_buffer_writable().unwrap());
                }
                Err(err) => {
                    gst_debug!(SOCKET_CAT, obj: &self.element, "Failed to acquire buffer {:?}", err);
                    return Some(Err(SocketError::Gst(err)));
                }
            }
        }

        match self
            .reader
            .read(self.mapped_buffer.as_mut().unwrap().as_mut_slice())
            .await
        {
            Ok((len, saddr)) => {
                let dts = if T::DO_TIMESTAMP {
                    let time = self.clock.as_ref().unwrap().get_time();
                    let running_time = time - self.base_time.unwrap();
                    gst_debug!(
                        SOCKET_CAT,
                        obj: &self.element,
                        "Read {} bytes at {} (clock {})",
                        len,
                        running_time,
                        time
                    );
                    running_time
                } else {
                    gst_debug!(SOCKET_CAT, obj: &self.element, "Read {} bytes", len);
                    gst::CLOCK_TIME_NONE
                };

                let mut buffer = self.mapped_buffer.take().unwrap().into_buffer();
                {
                    let buffer = buffer.get_mut().unwrap();
                    if len < buffer.get_size() {
                        buffer.set_size(len);
                    }
                    buffer.set_dts(dts);
                }

                Some(Ok((buffer, saddr)))
            }
            Err(err) => {
                gst_debug!(SOCKET_CAT, obj: &self.element, "Read error {:?}", err);

                Some(Err(SocketError::Io(err)))
            }
        }
    }
}

impl<T: SocketRead> Drop for Socket<T> {
    fn drop(&mut self) {
        if let Err(err) = self.buffer_pool.set_active(false) {
            gst_error!(SOCKET_CAT, obj: &self.element, "Failed to unprepare socket: {}", err);
        }
    }
}

// Send/Sync struct for passing around a gio::Socket
// and getting the raw fd from it
//
// gio::Socket is not Send/Sync as it's generally unsafe
// to access it from multiple threads. Getting the underlying raw
// fd is safe though, as is receiving/sending from two different threads
#[derive(Debug)]
pub struct GioSocketWrapper {
    socket: *mut gio::ffi::GSocket,
}

unsafe impl Send for GioSocketWrapper {}
unsafe impl Sync for GioSocketWrapper {}

impl GioSocketWrapper {
    pub fn new(socket: &gio::Socket) -> Self {
        use glib::translate::*;

        Self {
            socket: socket.to_glib_full(),
        }
    }

    pub fn as_socket(&self) -> gio::Socket {
        unsafe {
            use glib::translate::*;

            from_glib_none(self.socket)
        }
    }

    #[cfg(unix)]
    pub fn set_tos(&self, qos_dscp: i32) -> Result<(), glib::Error> {
        use libc::{IPPROTO_IP, IPPROTO_IPV6, IPV6_TCLASS, IP_TOS};

        let tos = (qos_dscp & 0x3f) << 2;

        let socket = self.as_socket();

        socket.set_option(IPPROTO_IP, IP_TOS, tos)?;

        if socket.get_family() == gio::SocketFamily::Ipv6 {
            socket.set_option(IPPROTO_IPV6, IPV6_TCLASS, tos)?;
        }

        Ok(())
    }

    #[cfg(not(unix))]
    pub fn set_tos(&self, qos_dscp: i32) -> Result<(), glib::Error> {
        Ok(())
    }

    #[cfg(unix)]
    pub fn get<T: FromRawFd>(&self) -> T {
        unsafe { FromRawFd::from_raw_fd(libc::dup(gio::ffi::g_socket_get_fd(self.socket))) }
    }

    #[cfg(windows)]
    pub fn get<T: FromRawSocket>(&self) -> T {
        unsafe {
            FromRawSocket::from_raw_socket(
                dup_socket(gio::ffi::g_socket_get_fd(self.socket) as _) as _
            )
        }
    }
}

impl Clone for GioSocketWrapper {
    fn clone(&self) -> Self {
        Self {
            socket: unsafe { glib::gobject_ffi::g_object_ref(self.socket as *mut _) as *mut _ },
        }
    }
}

impl Drop for GioSocketWrapper {
    fn drop(&mut self) {
        unsafe {
            glib::gobject_ffi::g_object_unref(self.socket as *mut _);
        }
    }
}

#[cfg(windows)]
unsafe fn dup_socket(socket: usize) -> usize {
    use std::mem;
    use winapi::shared::ws2def;
    use winapi::um::processthreadsapi;
    use winapi::um::winsock2;

    let mut proto_info = mem::MaybeUninit::uninit();
    let ret = winsock2::WSADuplicateSocketA(
        socket,
        processthreadsapi::GetCurrentProcessId(),
        proto_info.as_mut_ptr(),
    );
    assert_eq!(ret, 0);
    let mut proto_info = proto_info.assume_init();

    let socket = winsock2::WSASocketA(
        ws2def::AF_INET,
        ws2def::SOCK_DGRAM,
        ws2def::IPPROTO_UDP as i32,
        &mut proto_info,
        0,
        0,
    );

    assert_ne!(socket, winsock2::INVALID_SOCKET);

    socket
}

pub fn wrap_socket(socket: &tokio::net::UdpSocket) -> Result<GioSocketWrapper, gst::ErrorMessage> {
    #[cfg(unix)]
    unsafe {
        let fd = libc::dup(socket.as_raw_fd());

        // This is unsafe because it allows us to share the fd between the socket and the
        // GIO socket below, but safety of this is the job of the application
        struct FdConverter(RawFd);
        impl IntoRawFd for FdConverter {
            fn into_raw_fd(self) -> RawFd {
                self.0
            }
        }

        let fd = FdConverter(fd);

        let gio_socket = gio::Socket::from_fd(fd).map_err(|err| {
            gst::error_msg!(
                gst::ResourceError::OpenWrite,
                ["Failed to create wrapped GIO socket: {}", err]
            )
        })?;
        Ok(GioSocketWrapper::new(&gio_socket))
    }
    #[cfg(windows)]
    unsafe {
        // FIXME: Needs https://github.com/tokio-rs/tokio/pull/806
        // and https://github.com/carllerche/mio/pull/859
        let fd = unreachable!(); //dup_socket(socket.as_raw_socket() as _) as _;

        // This is unsafe because it allows us to share the fd between the socket and the
        // GIO socket below, but safety of this is the job of the application
        struct SocketConverter(RawSocket);
        impl IntoRawSocket for SocketConverter {
            fn into_raw_socket(self) -> RawSocket {
                self.0
            }
        }

        let fd = SocketConverter(fd);

        let gio_socket = gio::Socket::from_socket(fd).map_err(|err| {
            gst::error_msg!(
                gst::ResourceError::OpenWrite,
                ["Failed to create wrapped GIO socket: {}", err]
            )
        })?;

        Ok(GioSocketWrapper::new(&gio_socket))
    }
}
<|endoftext|>


<commit_before>//! The ORC JIT.

use super::prelude::*;
use super::object::LLVMObjectFileRef;
use super::target_machine::LLVMTargetMachineRef;

pub enum LLVMOrcOpaqueJITStack {}
pub type LLVMOrcJITStackRef = *mut LLVMOrcOpaqueJITStack;
pub type LLVMOrcModuleHandle = u32;
pub type LLVMOrcTargetAddress = u64;

pub type LLVMOrcSymbolResolverFn = extern "C" fn(*const ::libc::c_char, *mut ::libc::c_void) -> u64;
pub type LLVMOrcLazyCompileCallbackFn = extern "C" fn(LLVMOrcJITStackRef, *mut ::libc::c_void);
#[repr(C)]
pub enum LLVMOrcErrorCode {
    LLVMOrcErrSuccess = 0,
    LLVMOrcErrGeneric,
}

extern "C" {
    /// Create an ORC JIT stack.
    ///
    /// The client owns the returned stack and must call OrcDisposeInstance
    /// when done with it. The JIT stack takes ownership of the provided
    /// TargetMachine.
    pub fn LLVMOrcCreateInstance(TM: LLVMTargetMachineRef) -> LLVMOrcJITStackRef;

    /// Get the error message for the most recent error (if any).
    ///
    /// The returned message is owned by the ORC JIT stack.
    pub fn LLVMOrcGetErrorMsg(JITStack: LLVMOrcJITStackRef) -> *const ::libc::c_char;

    /// Mangle the given symbol.
    ///
    /// Memory is allocated for the mangled symbol, which will be owned by
    /// the client.
    pub fn LLVMOrcGetMangledSymbol(JITStack: LLVMOrcJITStackRef,
                                   MangledSymbol: *mut *mut ::libc::c_char,
                                   Symbol: *const ::libc::c_char);

    /// Dispose of a mangled symbol.
    pub fn LLVMOrcDisposeMangledSymbol(MangledSymbol: *mut ::libc::c_char);

    /// Create a lazy compile callback.
    pub fn LLVMOrcCreateLazyCompileCallback(JITStack: LLVMOrcJITStackRef,
                                            Callback: LLVMOrcLazyCompileCallbackFn,
                                            CallbackCtx: *mut ::libc::c_void)
                                            -> LLVMOrcTargetAddress;

    /// Create a named indirect call stub.
    pub fn LLVMOrcCreateIndirectStub(JITStack: LLVMOrcJITStackRef,
                                     StubName: *const ::libc::c_char,
                                     InitAddr: LLVMOrcTargetAddress)
                                     -> LLVMOrcErrorCode;

    /// Set the pointer for the given indirect stub.
    pub fn LLVMOrcSetIndirectStubPointer(JITStack: LLVMOrcJITStackRef,
                                         StubName: *const ::libc::c_char,
                                         NewAddr: LLVMOrcTargetAddress)
                                         -> LLVMOrcErrorCode;

    /// Add a module to be eagerly compiled.
    pub fn LLVMOrcAddEagerlyCompiledIR(JITStack: LLVMOrcJITStackRef,
                                       Mod: LLVMModuleRef,
                                       SymbolResolver: LLVMOrcSymbolResolverFn,
                                       SymbolResolverCtx: *mut ::libc::c_void)
                                       -> LLVMOrcModuleHandle;

    /// Add a module to be lazily compiled one function at a time.
    pub fn LLVMOrcAddLazilyCompiledIR(JITStack: LLVMOrcJITStackRef,
                                      Mod: LLVMModuleRef,
                                      SymbolResolver: LLVMOrcSymbolResolverFn,
                                      SymbolResolverCtx: *mut ::libc::c_void)
                                      -> LLVMOrcModuleHandle;

    /// Add an object file.
    pub fn LLVMOrcAddObjectFile(JITStack: LLVMOrcJITStackRef,
                                Obj: LLVMObjectFileRef,
                                SymbolResolver: LLVMOrcSymbolResolverFn,
                                SymbolResolverCtx: *mut ::libc::c_void)
                                -> LLVMOrcModuleHandle;

    /// Remove a module set from the JIT.
    pub fn LLVMRemoveModule(JITStack: LLVMOrcJITStackRef, H: LLVMOrcModuleHandle);

    /// Get symbol address from JIT instance.
    pub fn LLVMOrcGetSymbolAddress(JITStack: LLVMOrcJITStackRef,
                                   SymbolName: ::libc::c_char)
                                   -> LLVMOrcTargetAddress;

    /// Dispose of an ORC JIT stack.
    pub fn LLVMOrcDisposeInstance(JITStack: LLVMOrcJITStackRef);
}
<commit_msg>Correct type of SymbolName parameter to LLVMOrcGetSymbolAddress<commit_after>//! The ORC JIT.

use super::prelude::*;
use super::object::LLVMObjectFileRef;
use super::target_machine::LLVMTargetMachineRef;

pub enum LLVMOrcOpaqueJITStack {}
pub type LLVMOrcJITStackRef = *mut LLVMOrcOpaqueJITStack;
pub type LLVMOrcModuleHandle = u32;
pub type LLVMOrcTargetAddress = u64;

pub type LLVMOrcSymbolResolverFn = extern "C" fn(*const ::libc::c_char, *mut ::libc::c_void) -> u64;
pub type LLVMOrcLazyCompileCallbackFn = extern "C" fn(LLVMOrcJITStackRef, *mut ::libc::c_void);
#[repr(C)]
pub enum LLVMOrcErrorCode {
    LLVMOrcErrSuccess = 0,
    LLVMOrcErrGeneric,
}

extern "C" {
    /// Create an ORC JIT stack.
    ///
    /// The client owns the returned stack and must call OrcDisposeInstance
    /// when done with it. The JIT stack takes ownership of the provided
    /// TargetMachine.
    pub fn LLVMOrcCreateInstance(TM: LLVMTargetMachineRef) -> LLVMOrcJITStackRef;

    /// Get the error message for the most recent error (if any).
    ///
    /// The returned message is owned by the ORC JIT stack.
    pub fn LLVMOrcGetErrorMsg(JITStack: LLVMOrcJITStackRef) -> *const ::libc::c_char;

    /// Mangle the given symbol.
    ///
    /// Memory is allocated for the mangled symbol, which will be owned by
    /// the client.
    pub fn LLVMOrcGetMangledSymbol(JITStack: LLVMOrcJITStackRef,
                                   MangledSymbol: *mut *mut ::libc::c_char,
                                   Symbol: *const ::libc::c_char);

    /// Dispose of a mangled symbol.
    pub fn LLVMOrcDisposeMangledSymbol(MangledSymbol: *mut ::libc::c_char);

    /// Create a lazy compile callback.
    pub fn LLVMOrcCreateLazyCompileCallback(JITStack: LLVMOrcJITStackRef,
                                            Callback: LLVMOrcLazyCompileCallbackFn,
                                            CallbackCtx: *mut ::libc::c_void)
                                            -> LLVMOrcTargetAddress;

    /// Create a named indirect call stub.
    pub fn LLVMOrcCreateIndirectStub(JITStack: LLVMOrcJITStackRef,
                                     StubName: *const ::libc::c_char,
                                     InitAddr: LLVMOrcTargetAddress)
                                     -> LLVMOrcErrorCode;

    /// Set the pointer for the given indirect stub.
    pub fn LLVMOrcSetIndirectStubPointer(JITStack: LLVMOrcJITStackRef,
                                         StubName: *const ::libc::c_char,
                                         NewAddr: LLVMOrcTargetAddress)
                                         -> LLVMOrcErrorCode;

    /// Add a module to be eagerly compiled.
    pub fn LLVMOrcAddEagerlyCompiledIR(JITStack: LLVMOrcJITStackRef,
                                       Mod: LLVMModuleRef,
                                       SymbolResolver: LLVMOrcSymbolResolverFn,
                                       SymbolResolverCtx: *mut ::libc::c_void)
                                       -> LLVMOrcModuleHandle;

    /// Add a module to be lazily compiled one function at a time.
    pub fn LLVMOrcAddLazilyCompiledIR(JITStack: LLVMOrcJITStackRef,
                                      Mod: LLVMModuleRef,
                                      SymbolResolver: LLVMOrcSymbolResolverFn,
                                      SymbolResolverCtx: *mut ::libc::c_void)
                                      -> LLVMOrcModuleHandle;

    /// Add an object file.
    pub fn LLVMOrcAddObjectFile(JITStack: LLVMOrcJITStackRef,
                                Obj: LLVMObjectFileRef,
                                SymbolResolver: LLVMOrcSymbolResolverFn,
                                SymbolResolverCtx: *mut ::libc::c_void)
                                -> LLVMOrcModuleHandle;

    /// Remove a module set from the JIT.
    pub fn LLVMRemoveModule(JITStack: LLVMOrcJITStackRef, H: LLVMOrcModuleHandle);

    /// Get symbol address from JIT instance.
    pub fn LLVMOrcGetSymbolAddress(JITStack: LLVMOrcJITStackRef,
                                   SymbolName: *const ::libc::c_char)
                                   -> LLVMOrcTargetAddress;

    /// Dispose of an ORC JIT stack.
    pub fn LLVMOrcDisposeInstance(JITStack: LLVMOrcJITStackRef);
}
<|endoftext|>


<commit_before>//!Extract a slice from a list. (medium)
//!
//!Given two indices, i and k, the slice is the list containing the elements
//!    between the i'th and k'th element of the original list (both limits
//!                                                            included). Start
//!    counting the elements with 0 (this is the way the List module numbers
//!                                  elements).
///```
///use p99::p18::Slice;
///let a: Vec<usize> = (0..100).collect();
///assert_eq!(a.slice(10,20),(10..30).collect::<Vec<usize>>());
///```

pub trait Slice<T: Copy>{
    fn slice(&self, start: usize, length: usize) -> Vec<T>;
}

impl <T: Copy> Slice<T> for Vec<T>{
    fn slice(&self, start: usize, length: usize) -> Vec<T>{
        let mut result = Vec::with_capacity(length);
        for i in &self[start..start+length] {
            result.push(*i);
        }
        result
    }
}
<commit_msg>fix error<commit_after>//!Extract a slice from a list. (medium)
//!
//!Given two indices, i and k, the slice is the list containing the elements
//!    between the i'th and k'th element of the original list (both limits
//!                                                            included). Start
//!    counting the elements with 0 (this is the way the List module numbers
//!                                  elements).
///```
///use p99::p18::Slice;
///let a: Vec<usize> = (0..100).collect();
///assert_eq!(a.slice(10,20),(10..21).collect::<Vec<usize>>());
///```

pub trait Slice<T: Copy>{
    fn slice(&self, start: usize, end: usize) -> Vec<T>;
}

impl <T: Copy> Slice<T> for Vec<T>{
    fn slice(&self, start: usize, end: usize) -> Vec<T>{
        let mut result = Vec::with_capacity(end - start + 1);
        for i in &self[start..(end+1)] {
            result.push(*i);
        }
        result
    }
}
<|endoftext|>


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

/// An element of the Table of content
#[derive(Debug, Clone)]
pub struct TocElement {
    /// The level. 0: part, 1: chapter, 2: section, ...
    pub level: i32,
    /// The link
    pub url: String,
    /// Title of this entry
    pub title: String,
    /// Inner elements
    pub children: Vec<TocElement>,
}

impl TocElement {
    /// Creates a new element of the toc
    pub fn new<S1: Into<String>, S2: Into<String>>(url: S1,
                                                   title: S2) -> TocElement {
        TocElement {
            level: 1,
            url: url.into(),
            title: title.into(),
            children: vec!(),
        }
    }

    /// Sets the level of a TocElement
    pub fn level(mut self, level: i32) -> Self {
        self.level = level;
        self
    }

    /// Change level, recursively, so the structure keeps having some sense
    pub fn level_up(&mut self, level: i32) {
        self.level = level;
        for mut child in self.children.iter_mut() {
            if child.level <= self.level {
                child.level_up(level + 1);
            }
        }
    }

    /// Add a child to this element. Adjust the level of the child to be the level
    /// of its parents, plus 1.
    pub fn child(mut self, mut child: TocElement) -> Self {
        if child.level <= self.level {
            child.level_up(self.level + 1);
        }
        self.children.push(child);
        self
    }

    /// Add element to self or to children, according to level
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.children.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.children.push(element);
        }
    }

    /// Render element for Epub's toc.ncx format
    pub fn render_epub(&self, mut offset: u32) -> (u32, String) {
        offset += 1;
        let id = offset;
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                let (n, s) = child.render_epub(offset);
                offset = n;
                output.push_str(&s);
            }
            output
        };
        (offset,
         format!("
<navPoint id = \"navPoint-{id}\">
  <navLabel>
   <text>{title}</text>
  </navLabel>
  <content src = \"{url}\" />
{children}
</navPoint>",
                id = id,
                title = self.title,
                url = self.url,
                children = children))

    }

    /// Render element as a list element
    pub fn render(&self, numbered: bool) -> String {
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                output.push_str(&child.render(numbered));
            }
            format!("\n<{oul}>{children}\n</{oul}>\n",
                    oul = if numbered { "ol" } else { "ul" },
                    children = output)
        };
        format!("
{title}{children}
\n",
                link = self.url,
                title = self.title,
                children = children)

    }
}

/// A structure for manipulating Table Of Contents
#[derive(Debug)]
pub struct Toc {
    /// The elements composing the TOC
    pub elements: Vec<TocElement>,
}

impl Toc {
    /// Create a new, empty, Toc
    pub fn new() -> Toc {
        Toc {
            elements: vec![],
        }
    }

    /// Returns `true` if the toc is empty, `false` else.
    ///
    /// Note that `empty` here means that the the toc has zero *or one*
    /// element, since it's still useless in this case.
    pub fn is_empty(&self) -> bool {
        self.elements.len() <= 1
    }

    /// Adds an element
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.elements.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.elements.push(element);
        }
    }

    /// Render the Toc in a toc.ncx compatible way, for EPUB.
    pub fn render_epub(&mut self) -> String {
        let mut output = String::new();
        let mut offset = 0;
        for elem in &self.elements {
            let (n, s) = elem.render_epub(offset);
            offset = n;
            output.push_str(&s);
        }
        output
    }

    /// Render the Toc in either
 or
 form (according to numbered)
    pub fn render(&mut self, numbered: bool) -> String {
        let mut output = String::new();
        for elem in &self.elements {
            output.push_str(&elem.render(numbered));
        }
        format!("<{oul}>\n{output}\n</{oul}>\n",
                output = output,
                oul = if numbered { "ol" } else { "ul" })
    }
}

/////////////////////////////////////////////////////////////////////////////////
//                                   TESTS                                     //
/////////////////////////////////////////////////////////////////////////////////

#[test]
fn toc_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "0.0.1").level(3));
    toc.add(TocElement::new("#2", "1").level(1));
    toc.add(TocElement::new("#3", "1.0.1").level(3));
    toc.add(TocElement::new("#4", "1.1").level(2));
    toc.add(TocElement::new("#5", "2"));
    let actual = toc.render(false);
    let expected = "

0.0.1

1

1.0.1

1.1

2

";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#2", "2"));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src = \"#1\" />

</navPoint>
<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#1.1","1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1","2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src = \"#1\" />

<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src = \"#1.1\" />

</navPoint>
</navPoint>
<navPoint id = \"navPoint-3\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

<navPoint id = \"navPoint-4\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src = \"#2.1\" />

</navPoint>
</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_broken_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src = \"#1.1\" />

</navPoint>\n<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

<navPoint id = \"navPoint-3\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src = \"#2.1\" />

</navPoint>\n</navPoint>";
    assert_eq!(&actual, expected);
}
<commit_msg>Fix typo<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at https://mozilla.org/MPL/2.0/.

/// An element of the Table of contents
#[derive(Debug, Clone)]
pub struct TocElement {
    /// The level. 0: part, 1: chapter, 2: section, ...
    pub level: i32,
    /// The link
    pub url: String,
    /// Title of this entry
    pub title: String,
    /// Inner elements
    pub children: Vec<TocElement>,
}

impl TocElement {
    /// Creates a new element of the toc
    pub fn new<S1: Into<String>, S2: Into<String>>(url: S1,
                                                   title: S2) -> TocElement {
        TocElement {
            level: 1,
            url: url.into(),
            title: title.into(),
            children: vec!(),
        }
    }

    /// Sets the level of a TocElement
    pub fn level(mut self, level: i32) -> Self {
        self.level = level;
        self
    }

    /// Change level, recursively, so the structure keeps having some sense
    pub fn level_up(&mut self, level: i32) {
        self.level = level;
        for mut child in self.children.iter_mut() {
            if child.level <= self.level {
                child.level_up(level + 1);
            }
        }
    }

    /// Add a child to this element. Adjust the level of the child to be the level
    /// of its parents, plus 1.
    pub fn child(mut self, mut child: TocElement) -> Self {
        if child.level <= self.level {
            child.level_up(self.level + 1);
        }
        self.children.push(child);
        self
    }

    /// Add element to self or to children, according to level
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.children.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.children.push(element);
        }
    }

    /// Render element for Epub's toc.ncx format
    pub fn render_epub(&self, mut offset: u32) -> (u32, String) {
        offset += 1;
        let id = offset;
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                let (n, s) = child.render_epub(offset);
                offset = n;
                output.push_str(&s);
            }
            output
        };
        (offset,
         format!("
<navPoint id = \"navPoint-{id}\">
  <navLabel>
   <text>{title}</text>
  </navLabel>
  <content src = \"{url}\" />
{children}
</navPoint>",
                id = id,
                title = self.title,
                url = self.url,
                children = children))

    }

    /// Render element as a list element
    pub fn render(&self, numbered: bool) -> String {
        let children = if self.children.is_empty() {
            String::new()
        } else {
            let mut output = String::new();
            for child in &self.children {
                output.push_str(&child.render(numbered));
            }
            format!("\n<{oul}>{children}\n</{oul}>\n",
                    oul = if numbered { "ol" } else { "ul" },
                    children = output)
        };
        format!("
{title}{children}
\n",
                link = self.url,
                title = self.title,
                children = children)

    }
}

/// A structure for manipulating Table Of Contents
#[derive(Debug)]
pub struct Toc {
    /// The elements composing the TOC
    pub elements: Vec<TocElement>,
}

impl Toc {
    /// Create a new, empty, Toc
    pub fn new() -> Toc {
        Toc {
            elements: vec![],
        }
    }

    /// Returns `true` if the toc is empty, `false` else.
    ///
    /// Note that `empty` here means that the the toc has zero *or one*
    /// element, since it's still useless in this case.
    pub fn is_empty(&self) -> bool {
        self.elements.len() <= 1
    }

    /// Adds an element
    pub fn add(&mut self, element: TocElement) {
        let mut inserted = false;
        if let Some(ref mut last_elem) = self.elements.last_mut() {
            if element.level > last_elem.level {
                last_elem.add(element.clone());
                inserted = true;
            }
        }
        if !inserted {
            self.elements.push(element);
        }
    }

    /// Render the Toc in a toc.ncx compatible way, for EPUB.
    pub fn render_epub(&mut self) -> String {
        let mut output = String::new();
        let mut offset = 0;
        for elem in &self.elements {
            let (n, s) = elem.render_epub(offset);
            offset = n;
            output.push_str(&s);
        }
        output
    }

    /// Render the Toc in either
 or
 form (according to numbered)
    pub fn render(&mut self, numbered: bool) -> String {
        let mut output = String::new();
        for elem in &self.elements {
            output.push_str(&elem.render(numbered));
        }
        format!("<{oul}>\n{output}\n</{oul}>\n",
                output = output,
                oul = if numbered { "ol" } else { "ul" })
    }
}

/////////////////////////////////////////////////////////////////////////////////
//                                   TESTS                                     //
/////////////////////////////////////////////////////////////////////////////////

#[test]
fn toc_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "0.0.1").level(3));
    toc.add(TocElement::new("#2", "1").level(1));
    toc.add(TocElement::new("#3", "1.0.1").level(3));
    toc.add(TocElement::new("#4", "1.1").level(2));
    toc.add(TocElement::new("#5", "2"));
    let actual = toc.render(false);
    let expected = "

0.0.1

1

1.0.1

1.1

2

";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#2", "2"));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src = \"#1\" />

</navPoint>
<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_simple_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1", "1"));
    toc.add(TocElement::new("#1.1","1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1","2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1</text>
  </navLabel>
  <content src = \"#1\" />

<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src = \"#1.1\" />

</navPoint>
</navPoint>
<navPoint id = \"navPoint-3\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

<navPoint id = \"navPoint-4\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src = \"#2.1\" />

</navPoint>
</navPoint>";
    assert_eq!(&actual, expected);
}

#[test]
fn toc_epub_broken_sublevels() {
    let mut toc = Toc::new();
    toc.add(TocElement::new("#1.1", "1.1").level(2));
    toc.add(TocElement::new("#2", "2"));
    toc.add(TocElement::new("#2.1", "2.1").level(2));
    let actual = toc.render_epub();
    let expected = "
<navPoint id = \"navPoint-1\">
  <navLabel>
   <text>1.1</text>
  </navLabel>
  <content src = \"#1.1\" />

</navPoint>\n<navPoint id = \"navPoint-2\">
  <navLabel>
   <text>2</text>
  </navLabel>
  <content src = \"#2\" />

<navPoint id = \"navPoint-3\">
  <navLabel>
   <text>2.1</text>
  </navLabel>
  <content src = \"#2.1\" />

</navPoint>\n</navPoint>";
    assert_eq!(&actual, expected);
}
<|endoftext|>


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

use std::vec;

#[deriving(Eq)]
pub struct NumericValue {
    representation: ~str,
    value: f64,
    int_value: Option<i64>,
}

#[deriving(Eq)]
pub struct SourceLocation {
    line: uint,  // First line is 1
    column: uint,  // First character of a line is at column 1
}

pub type Node = (ComponentValue, SourceLocation);  // TODO this is not a good name

#[deriving(Eq)]
pub enum ComponentValue {
    // Preserved tokens.
    Ident(~str),
    AtKeyword(~str),
    Hash(~str),
    IDHash(~str),  // Hash that is a valid ID selector.
    String(~str),
    URL(~str),
    Delim(char),
    Number(NumericValue),
    Percentage(NumericValue),
    Dimension(NumericValue, ~str),
    UnicodeRange { start: u32, end: u32 },
    WhiteSpace,
    Colon,  // :
    Semicolon,  // ;
    Comma,  // ,
    IncludeMatch, // ~=
    DashMatch, // |=
    PrefixMatch, // ^=
    SuffixMatch, // $=
    SubstringMatch, // *=
    Column, // ||
    CDO,  // <!--
    CDC,  // -->

    // Function
    Function(~str, ~[ComponentValue]),  // name, arguments

    // Simple block
    ParenthesisBlock(~[ComponentValue]),  // (…)
    SquareBracketBlock(~[ComponentValue]),  // […]
    CurlyBracketBlock(~[Node]),  // {…}

    // These are always invalid
    BadURL,
    BadString,
    CloseParenthesis, // )
    CloseSquareBracket, // ]
    CloseCurlyBracket, // }
}

#[deriving(Eq)]
pub struct Declaration {
    location: SourceLocation,
    name: ~str,
    value: ~[ComponentValue],
    important: bool,
}

#[deriving(Eq)]
pub struct QualifiedRule {
    location: SourceLocation,
    prelude: ~[ComponentValue],
    block: ~[Node],
}

#[deriving(Eq)]
pub struct AtRule {
    location: SourceLocation,
    name: ~str,
    prelude: ~[ComponentValue],
    block: Option<~[Node]>,
}

#[deriving(Eq)]
pub enum DeclarationListItem {
    Declaration(Declaration),
    // A better idea for a name that means "at-rule" but is not "AtRule"?
    Decl_AtRule(AtRule),
}

#[deriving(Eq)]
pub enum Rule {
    QualifiedRule(QualifiedRule),
    AtRule(AtRule),
}

#[deriving(Eq)]
pub struct SyntaxError {
    location: SourceLocation,
    reason: ErrorReason,
}

#[deriving(Eq)]
pub enum ErrorReason {
    ErrEmptyInput,  // Parsing a single "thing", found only whitespace.
    ErrExtraInput,  // Found more non-whitespace after parsing a single "thing".
    ErrMissingQualifiedRuleBlock,  // EOF in a qualified rule prelude, before '{'
    ErrInvalidDeclarationSyntax,
    ErrInvalidBangImportantSyntax,
    // This is meant to be extended
}

impl ToStr for SyntaxError {
    fn to_str(&self) -> ~str {
        fmt!("%u:%u %?", self.location.line, self.location.column, self.reason)
    }
}

pub trait SkipWhitespaceIterable<'self> {
    fn skip_whitespace(self) -> SkipWhitespaceIterator<'self>;
}

impl<'self> SkipWhitespaceIterable<'self> for &'self [ComponentValue] {
    fn skip_whitespace(self) -> SkipWhitespaceIterator<'self> {
        SkipWhitespaceIterator{ iter_with_whitespace: self.iter() }
    }
}

#[deriving(Clone)]
pub struct SkipWhitespaceIterator<'self> {
    iter_with_whitespace: vec::VecIterator<'self, ComponentValue>,
}

impl<'self> Iterator<&'self ComponentValue> for SkipWhitespaceIterator<'self> {
    fn next(&mut self) -> Option<&'self ComponentValue> {
        for component_value in self.iter_with_whitespace {
            if component_value != &WhiteSpace { return Some(component_value) }
        }
        None
    }
}

pub trait MoveSkipWhitespaceIterable {
    fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator;
}

impl MoveSkipWhitespaceIterable for ~[ComponentValue] {
    fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator {
        MoveSkipWhitespaceIterator{ iter_with_whitespace: self.move_iter() }
    }
}

pub struct MoveSkipWhitespaceIterator {
    iter_with_whitespace: vec::MoveIterator<ComponentValue>,
}

impl Iterator<ComponentValue> for MoveSkipWhitespaceIterator {
    fn next(&mut self) -> Option<ComponentValue> {
        for component_value in self.iter_with_whitespace {
            if component_value != WhiteSpace { return Some(component_value) }
        }
        None
    }
}
<commit_msg>Upgrade to rustc 0.9-pre (7075eb3 2013-10-24 05:11:06 -0700)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::vec;

#[deriving(Eq)]
pub struct NumericValue {
    representation: ~str,
    value: f64,
    int_value: Option<i64>,
}

#[deriving(Eq)]
pub struct SourceLocation {
    line: uint,  // First line is 1
    column: uint,  // First character of a line is at column 1
}

pub type Node = (ComponentValue, SourceLocation);  // TODO this is not a good name

#[deriving(Eq)]
pub enum ComponentValue {
    // Preserved tokens.
    Ident(~str),
    AtKeyword(~str),
    Hash(~str),
    IDHash(~str),  // Hash that is a valid ID selector.
    String(~str),
    URL(~str),
    Delim(char),
    Number(NumericValue),
    Percentage(NumericValue),
    Dimension(NumericValue, ~str),
    UnicodeRange { start: u32, end: u32 },
    WhiteSpace,
    Colon,  // :
    Semicolon,  // ;
    Comma,  // ,
    IncludeMatch, // ~=
    DashMatch, // |=
    PrefixMatch, // ^=
    SuffixMatch, // $=
    SubstringMatch, // *=
    Column, // ||
    CDO,  // <!--
    CDC,  // -->

    // Function
    Function(~str, ~[ComponentValue]),  // name, arguments

    // Simple block
    ParenthesisBlock(~[ComponentValue]),  // (…)
    SquareBracketBlock(~[ComponentValue]),  // […]
    CurlyBracketBlock(~[Node]),  // {…}

    // These are always invalid
    BadURL,
    BadString,
    CloseParenthesis, // )
    CloseSquareBracket, // ]
    CloseCurlyBracket, // }
}

#[deriving(Eq)]
pub struct Declaration {
    location: SourceLocation,
    name: ~str,
    value: ~[ComponentValue],
    important: bool,
}

#[deriving(Eq)]
pub struct QualifiedRule {
    location: SourceLocation,
    prelude: ~[ComponentValue],
    block: ~[Node],
}

#[deriving(Eq)]
pub struct AtRule {
    location: SourceLocation,
    name: ~str,
    prelude: ~[ComponentValue],
    block: Option<~[Node]>,
}

#[deriving(Eq)]
pub enum DeclarationListItem {
    Declaration(Declaration),
    // A better idea for a name that means "at-rule" but is not "AtRule"?
    Decl_AtRule(AtRule),
}

#[deriving(Eq)]
pub enum Rule {
    QualifiedRule(QualifiedRule),
    AtRule(AtRule),
}

#[deriving(Eq)]
pub struct SyntaxError {
    location: SourceLocation,
    reason: ErrorReason,
}

#[deriving(Eq)]
pub enum ErrorReason {
    ErrEmptyInput,  // Parsing a single "thing", found only whitespace.
    ErrExtraInput,  // Found more non-whitespace after parsing a single "thing".
    ErrMissingQualifiedRuleBlock,  // EOF in a qualified rule prelude, before '{'
    ErrInvalidDeclarationSyntax,
    ErrInvalidBangImportantSyntax,
    // This is meant to be extended
}

impl ToStr for SyntaxError {
    fn to_str(&self) -> ~str {
        format!("{}:{} {:?}", self.location.line, self.location.column, self.reason)
    }
}

pub trait SkipWhitespaceIterable<'self> {
    fn skip_whitespace(self) -> SkipWhitespaceIterator<'self>;
}

impl<'self> SkipWhitespaceIterable<'self> for &'self [ComponentValue] {
    fn skip_whitespace(self) -> SkipWhitespaceIterator<'self> {
        SkipWhitespaceIterator{ iter_with_whitespace: self.iter() }
    }
}

#[deriving(Clone)]
pub struct SkipWhitespaceIterator<'self> {
    iter_with_whitespace: vec::VecIterator<'self, ComponentValue>,
}

impl<'self> Iterator<&'self ComponentValue> for SkipWhitespaceIterator<'self> {
    fn next(&mut self) -> Option<&'self ComponentValue> {
        for component_value in self.iter_with_whitespace {
            if component_value != &WhiteSpace { return Some(component_value) }
        }
        None
    }
}

pub trait MoveSkipWhitespaceIterable {
    fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator;
}

impl MoveSkipWhitespaceIterable for ~[ComponentValue] {
    fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator {
        MoveSkipWhitespaceIterator{ iter_with_whitespace: self.move_iter() }
    }
}

pub struct MoveSkipWhitespaceIterator {
    iter_with_whitespace: vec::MoveIterator<ComponentValue>,
}

impl Iterator<ComponentValue> for MoveSkipWhitespaceIterator {
    fn next(&mut self) -> Option<ComponentValue> {
        for component_value in self.iter_with_whitespace {
            if component_value != WhiteSpace { return Some(component_value) }
        }
        None
    }
}
<|endoftext|>


<commit_before>use redox::{Box, String, Url};
use redox::{cmp, mem, ptr};
use redox::fs::File;
use redox::get_slice::GetSlice;
use redox::io::*;
use redox::ops::DerefMut;
use redox::to_num::ToNum;
use redox::syscall::sys_clone;

use orbital::event::Event;
use orbital::Point;
use orbital::Size;

use self::display::Display;
use self::session::Session;
use self::window::Window;

pub mod display;
pub mod package;
pub mod scheduler;
pub mod session;
pub mod window;

pub static mut session_ptr: *mut Session = 0 as *mut Session;

/// A window resource
pub struct Resource {
    /// The window
    pub window: Box<Window>,
    /// Seek point
    pub seek: usize,
}

impl Resource {
    pub fn dup(&self) -> Option<Box<Resource>> {
        Some(box Resource {
            window: Window::new(self.window.point, self.window.size, self.window.title.clone()),
            seek: self.seek,
        })
    }

    /// Return the url of this resource
    pub fn path(&self) -> Option<String> {
        Some(format!("orbital:///{}/{}/{}/{}/{}",
                         self.window.point.x,
                         self.window.point.y,
                         self.window.size.width,
                         self.window.size.height,
                         self.window.title))
    }

    /// Read data to buffer
    pub fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        //Read events from window
        let mut i = 0;
        while buf.len() - i >= mem::size_of::<Event>() {
            match self.window.poll() {
                Some(event) => {
                    unsafe { ptr::write(buf.as_ptr().offset(i as isize) as *mut Event, event) };
                    i += mem::size_of::<Event>();
                }
                None => break,
            }
        }

        Some(i)
    }

    /// Write to resource
    pub fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let content = &mut self.window.content;

        let size = cmp::min(content.size - self.seek, buf.len());
        unsafe {
            Display::copy_run(buf.as_ptr() as usize,
                              content.offscreen + self.seek,
                              size);
        }
        self.seek += size;

        return Some(size);
    }

    /// Seek
    pub fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let end = self.window.content.size;

        self.seek = match pos {
            SeekFrom::Start(offset) => cmp::min(end, cmp::max(0, offset)),
            SeekFrom::Current(offset) => cmp::min(end, cmp::max(0, self.seek as isize + offset) as usize),
            SeekFrom::End(offset) => cmp::min(end, cmp::max(0, end as isize + offset) as usize),
        };

        return Some(self.seek);
    }

    /// Sync the resource, should flip
    pub fn sync(&mut self) -> bool {
        self.window.redraw();
        true
    }
}

/// A window scheme
pub struct Scheme {
    pub session: Box<Session>,
    pub next_x: isize,
    pub next_y: isize,
}

impl Scheme {
    pub fn new() -> Box<Scheme> {
        debugln!("- Starting Orbital");
        debugln!("    Console: Press F1");
        debugln!("    Desktop: Press F2");
        let mut ret = box Scheme {
            session: Session::new(),
            next_x: 0,
            next_y: 0,
        };
        unsafe { session_ptr = ret.session.deref_mut() };
        ret
    }

    pub fn open(&mut self, url_str: &str, _: usize) -> Option<Box<Resource>> {
        //window://host/path/path/path is the path type we're working with.
        let url = Url::from_str(url_str);

        let host = url.host();
        if host.is_empty() {
            let path = url.path_parts();
            let mut pointx = match path.get(0) {
                Some(x) => x.to_num_signed(),
                None => 0,
            };
            let mut pointy = match path.get(1) {
                Some(y) => y.to_num_signed(),
                None => 0,
            };
            let size_width = match path.get(2) {
                Some(w) => w.to_num(),
                None => 100,
            };
            let size_height = match path.get(3) {
                Some(h) => h.to_num(),
                None => 100,
            };

            let mut title = match path.get(4) {
                Some(t) => t.clone(),
                None => String::new(),
            };
            for i in 5..path.len() {
                if let Some(t) = path.get(i) {
                    title = title + "/" + t;
                }
            }

            if pointx <= 0 || pointy <= 0 {
                if self.next_x > self.session.display.width as isize - size_width as isize {
                    self.next_x = 0;
                }
                self.next_x += 32;
                pointx = self.next_x;

                if self.next_y > self.session.display.height as isize - size_height as isize {
                    self.next_y = 0;
                }
                self.next_y += 32;
                pointy = self.next_y;
            }

            Some(box Resource {
                window: Window::new(Point::new(pointx, pointy), Size::new(size_width, size_height), title),
                seek: 0,
            })
        } else if host == "launch" {
            let path = url.path();

            unsafe {
                let reenable = scheduler::start_no_ints();

                for package in self.session.packages.iter() {
                    let mut accepted = false;
                    for accept in package.accepts.iter() {
                        if (accept.starts_with('*') && path.ends_with(&accept.get_slice(Some(1), None)))
                        || (accept.ends_with('*') && path.starts_with(&accept.get_slice(None, Some(accept.len() - 1))))
                        {
                            accepted = true;
                            break;
                        }
                    }
                    if accepted {
                        let binary = package.binary.clone();
                        println!("Exec {} {}", binary, path);
                        //File::exec(&binary, &[&path]);
                        break;
                    }
                }

                scheduler::end_no_ints(reenable);
            }

            None
        } else {
            None
        }
    }

    pub fn event(&mut self, event: &Event) {
        unsafe {
            let reenable = scheduler::start_no_ints();

            self.session.event(event);

            scheduler::end_no_ints(reenable);

            self.session.redraw();
        }
    }
}

//TODO: This is a hack and it will go away
#[cold]
#[inline(never)]
#[no_mangle]
pub unsafe extern "C" fn _event(scheme: *mut Scheme, event: *const Event) {
    (*scheme).event(&*event);
}
<commit_msg>Do not clone inside of orbital<commit_after>use redox::{Box, String, Url};
use redox::{cmp, mem, ptr};
use redox::fs::File;
use redox::get_slice::GetSlice;
use redox::io::*;
use redox::ops::DerefMut;
use redox::to_num::ToNum;

use orbital::event::Event;
use orbital::Point;
use orbital::Size;

use self::display::Display;
use self::session::Session;
use self::window::Window;

pub mod display;
pub mod package;
pub mod scheduler;
pub mod session;
pub mod window;

pub static mut session_ptr: *mut Session = 0 as *mut Session;

/// A window resource
pub struct Resource {
    /// The window
    pub window: Box<Window>,
    /// Seek point
    pub seek: usize,
}

impl Resource {
    pub fn dup(&self) -> Option<Box<Resource>> {
        Some(box Resource {
            window: Window::new(self.window.point, self.window.size, self.window.title.clone()),
            seek: self.seek,
        })
    }

    /// Return the url of this resource
    pub fn path(&self) -> Option<String> {
        Some(format!("orbital:///{}/{}/{}/{}/{}",
                         self.window.point.x,
                         self.window.point.y,
                         self.window.size.width,
                         self.window.size.height,
                         self.window.title))
    }

    /// Read data to buffer
    pub fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        //Read events from window
        let mut i = 0;
        while buf.len() - i >= mem::size_of::<Event>() {
            match self.window.poll() {
                Some(event) => {
                    unsafe { ptr::write(buf.as_ptr().offset(i as isize) as *mut Event, event) };
                    i += mem::size_of::<Event>();
                }
                None => break,
            }
        }

        Some(i)
    }

    /// Write to resource
    pub fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let content = &mut self.window.content;

        let size = cmp::min(content.size - self.seek, buf.len());
        unsafe {
            Display::copy_run(buf.as_ptr() as usize,
                              content.offscreen + self.seek,
                              size);
        }
        self.seek += size;

        return Some(size);
    }

    /// Seek
    pub fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let end = self.window.content.size;

        self.seek = match pos {
            SeekFrom::Start(offset) => cmp::min(end, cmp::max(0, offset)),
            SeekFrom::Current(offset) => cmp::min(end, cmp::max(0, self.seek as isize + offset) as usize),
            SeekFrom::End(offset) => cmp::min(end, cmp::max(0, end as isize + offset) as usize),
        };

        return Some(self.seek);
    }

    /// Sync the resource, should flip
    pub fn sync(&mut self) -> bool {
        self.window.redraw();
        true
    }
}

/// A window scheme
pub struct Scheme {
    pub session: Box<Session>,
    pub next_x: isize,
    pub next_y: isize,
}

impl Scheme {
    pub fn new() -> Box<Scheme> {
        debugln!("- Starting Orbital");
        debugln!("    Console: Press F1");
        debugln!("    Desktop: Press F2");
        let mut ret = box Scheme {
            session: Session::new(),
            next_x: 0,
            next_y: 0,
        };
        unsafe { session_ptr = ret.session.deref_mut() };
        ret
    }

    pub fn open(&mut self, url_str: &str, _: usize) -> Option<Box<Resource>> {
        //window://host/path/path/path is the path type we're working with.
        let url = Url::from_str(url_str);

        let host = url.host();
        if host.is_empty() {
            let path = url.path_parts();
            let mut pointx = match path.get(0) {
                Some(x) => x.to_num_signed(),
                None => 0,
            };
            let mut pointy = match path.get(1) {
                Some(y) => y.to_num_signed(),
                None => 0,
            };
            let size_width = match path.get(2) {
                Some(w) => w.to_num(),
                None => 100,
            };
            let size_height = match path.get(3) {
                Some(h) => h.to_num(),
                None => 100,
            };

            let mut title = match path.get(4) {
                Some(t) => t.clone(),
                None => String::new(),
            };
            for i in 5..path.len() {
                if let Some(t) = path.get(i) {
                    title = title + "/" + t;
                }
            }

            if pointx <= 0 || pointy <= 0 {
                if self.next_x > self.session.display.width as isize - size_width as isize {
                    self.next_x = 0;
                }
                self.next_x += 32;
                pointx = self.next_x;

                if self.next_y > self.session.display.height as isize - size_height as isize {
                    self.next_y = 0;
                }
                self.next_y += 32;
                pointy = self.next_y;
            }

            Some(box Resource {
                window: Window::new(Point::new(pointx, pointy), Size::new(size_width, size_height), title),
                seek: 0,
            })
        } else if host == "launch" {
            let path = url.path();

            unsafe {
                let reenable = scheduler::start_no_ints();

                for package in self.session.packages.iter() {
                    let mut accepted = false;
                    for accept in package.accepts.iter() {
                        if (accept.starts_with('*') && path.ends_with(&accept.get_slice(Some(1), None)))
                        || (accept.ends_with('*') && path.starts_with(&accept.get_slice(None, Some(accept.len() - 1))))
                        {
                            accepted = true;
                            break;
                        }
                    }
                    if accepted {
                        let binary = package.binary.clone();
                        println!("Exec {} {}", binary, path);
                        //File::exec(&binary, &[&path]);
                        break;
                    }
                }

                scheduler::end_no_ints(reenable);
            }

            None
        } else {
            None
        }
    }

    pub fn event(&mut self, event: &Event) {
        unsafe {
            let reenable = scheduler::start_no_ints();

            self.session.event(event);

            scheduler::end_no_ints(reenable);

            self.session.redraw();
        }
    }
}

//TODO: This is a hack and it will go away
#[cold]
#[inline(never)]
#[no_mangle]
pub unsafe extern "C" fn _event(scheme: *mut Scheme, event: *const Event) {
    (*scheme).event(&*event);
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Flipping_bits_game

// For random generation
extern crate rand;

// For fmt::Display
use std::fmt;
// For I/O (stdin, stdout, etc)
use std::io::prelude::*;

// A simple struct for our board
struct Board {
    cells: Vec<bool>,
    size: usize,
}

// Functions for the Board struct
impl Board {
    // Generate a new, empty board
    fn new(size: usize) -> Board {
        // Ensure we make a board with a non-zero size
        if size == 0 {
            // Don't make a board of size 0
            Board {
                cells: vec![false; 1],
                size: 1,
            }
        } else {
            Board {
                cells: vec![false; size*size],
                size: size,
            }
        }
    }

    // Flip the specified row
    fn fliprow(&mut self, row: usize) -> bool {
        // Check constraints
        if row > self.size {
            return false;
        }
        // Starting position in the vector
        let start = row * self.size;
        // Loop through the vector row
        for i in start..start + self.size {
            self.cells[i] = !self.cells[i];
        }
        true
    }

    // Flip the specified column
    fn flipcol(&mut self, col: usize) -> bool {
        // Check constraints
        if col > self.size {
            return false;
        }
        // Loop through the vector column
        for i in 0..self.size {
            self.cells[col + i * self.size] = !self.cells[col + i * self.size];
        }
        true
    }

    // Generate a random board
    fn random(size: usize) -> Board {
        // Make a vector of the board size
        let mut r: Vec<bool> = vec![false; size*size];
        // Loop through all the cells
        for i in 0..size * size {
            // Give it a random state
            r[i] = rand::random::<bool>();
        }
        // Return the random board
        Board {
            cells: r.clone(),
            size: size,
        }
    }

    // Check if a board is equal to another
    fn eq(&self, rhs: &Board) -> bool {
        // Has to be a board of the same size
        if self.size != rhs.size {
            return false;
        }
        // Loop through the board
        for i in 0..self.size * self.size {
            // If cells do not match, not equal
            if self.cells[i] != rhs.cells[i] {
                return false;
            }
        }
        // If we get here, boards are equal
        true
    }
}

// Implement the Display format, used with `print!("{}", &board);`
impl fmt::Display for Board {
    // Example output:
    //   0 1 2
    // 0 0 1 0
    // 1 1 0 0
    // 2 0 1 1
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Get the string width of the size of the board
        let width = (self.size - 1).to_string().len();
        // Write the initial spaces (upper left)
        try!(write!(f, "{space: >0$}", width, space = " "));
        // Write the column numbers
        for i in 0..self.size {
            try!(write!(f, " {offset:>0$}", width, offset = i));
        }
        // Newline for rows
        try!(write!(f, "\n"));
        // Loop through the rows
        for row in 0..self.size {
            // Write the row number
            try!(write!(f, "{row:>0$}", width, row = row));
            // Loop through the columns
            for col in 0..self.size {
                // Get the value of the cell as 1 or 0
                let p = if self.cells[row * self.size + col] {
                    1
                } else {
                    0
                };
                // Write the column value
                try!(write!(f, " {col:>0$}", width, col = p));
            }
            // Newline for next row
            try!(write!(f, "\n"));
        }
        // Return Formatter result
        write!(f, "")
    }
}

fn main() {
    // The board size
    let size: usize = 3;
    // The target board
    let target: Board = Board::random(size);
    // The user board
    let mut board: Board = Board::new(size);
    // How many moves taken
    let mut moves: u32 = 0;
    // Loop until win or quit
    'mainloop: loop {
        // User input
        let mut input: String = String::new();
        // Write the boards
        println!("Target:\n{}\nBoard:\n{}", &target, &board);
        // User input loop
        'userinput: loop {
            // Prompt
            print!("\nFlip? [q|[r|c]#] ");
            // Flush stdout to write the previous print, if we can't then exit
            match std::io::stdout().flush() {
                Ok(_) => {}
                Err(e) => {
                    println!("Error: cannot flush stdout: {}", e);
                    break 'mainloop;
                }
            };
            // Read user input
            match std::io::stdin().read_line(&mut input) {
                Ok(_) => {
                    // Get the first character
                    let rc: char = match input.chars().nth(0) {
                        Some(c) => c,
                        None => {
                            println!("Error: No input");
                            continue 'userinput;
                        }
                    };
                    // Make sure input is r, c, or q
                    if rc != 'r' && rc != 'c' && rc != 'q' {
                        println!("Error: '{}': Must use 'r'ow or 'c'olumn or 'q'uit", rc);
                        continue 'userinput;
                    }
                    // If input is q, exit game
                    if rc == 'q' {
                        println!("Thanks for playing!");
                        break 'mainloop;
                    }
                    // If input is r or c, get the number after
                    let n: usize = match input[1..].to_string().trim().parse() {
                        Ok(x) => {
                            // If we're within bounds, return the parsed number
                            if x < size {
                                x
                            } else {
                                println!("Error: Must specify a row or column within size({})",
                                         size);
                                continue 'userinput;
                            }
                        }
                        Err(_) => {
                            println!("Error: '{}': Unable to parse row or column number",
                                     input[1..].to_string());
                            continue 'userinput;
                        }
                    };
                    // Flip the row or column specified
                    match rc {
                        'r' => board.fliprow(n),
                        'c' => board.flipcol(n),
                        _ => {
                            // We want to panic here because should NEVER
                            // have anything other than 'r' or 'c' here
                            panic!("How did you end up here?");
                        }
                    };
                    // Increment moves
                    moves += 1;
                    println!("Moves taken: {}", moves);
                    break 'userinput;
                }
                Err(e) => {
                    println!("Error reading input: {}", e);
                    break 'mainloop;
                }
            }
        } // 'userinput
        if board.eq(&target) {
            println!("You win!");
            break;
        }
    } // 'mainloop
}
<commit_msg>Fix input string not clearing after erroroneous input<commit_after>// http://rosettacode.org/wiki/Flipping_bits_game

// For random generation
extern crate rand;

// For fmt::Display
use std::fmt;
// For I/O (stdin, stdout, etc)
use std::io::prelude::*;

// A simple struct for our board
struct Board {
    cells: Vec<bool>,
    size: usize,
}

// Functions for the Board struct
impl Board {
    // Generate a new, empty board
    fn new(size: usize) -> Board {
        // Ensure we make a board with a non-zero size
        if size == 0 {
            // Don't make a board of size 0
            Board {
                cells: vec![false; 1],
                size: 1,
            }
        } else {
            Board {
                cells: vec![false; size*size],
                size: size,
            }
        }
    }

    // Flip the specified row
    fn fliprow(&mut self, row: usize) -> bool {
        // Check constraints
        if row > self.size {
            return false;
        }
        // Starting position in the vector
        let start = row * self.size;
        // Loop through the vector row
        for i in start..start + self.size {
            self.cells[i] = !self.cells[i];
        }
        true
    }

    // Flip the specified column
    fn flipcol(&mut self, col: usize) -> bool {
        // Check constraints
        if col > self.size {
            return false;
        }
        // Loop through the vector column
        for i in 0..self.size {
            self.cells[col + i * self.size] = !self.cells[col + i * self.size];
        }
        true
    }

    // Generate a random board
    fn random(size: usize) -> Board {
        // Make a vector of the board size
        let mut r: Vec<bool> = vec![false; size*size];
        // Loop through all the cells
        for i in 0..size * size {
            // Give it a random state
            r[i] = rand::random::<bool>();
        }
        // Return the random board
        Board {
            cells: r.clone(),
            size: size,
        }
    }

    // Check if a board is equal to another
    fn eq(&self, rhs: &Board) -> bool {
        // Has to be a board of the same size
        if self.size != rhs.size {
            return false;
        }
        // Loop through the board
        for i in 0..self.size * self.size {
            // If cells do not match, not equal
            if self.cells[i] != rhs.cells[i] {
                return false;
            }
        }
        // If we get here, boards are equal
        true
    }
}

// Implement the Display format, used with `print!("{}", &board);`
impl fmt::Display for Board {
    // Example output:
    //   0 1 2
    // 0 0 1 0
    // 1 1 0 0
    // 2 0 1 1
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Get the string width of the size of the board
        let width = (self.size - 1).to_string().len();
        // Write the initial spaces (upper left)
        try!(write!(f, "{space: >0$}", width, space = " "));
        // Write the column numbers
        for i in 0..self.size {
            try!(write!(f, " {offset:>0$}", width, offset = i));
        }
        // Newline for rows
        try!(write!(f, "\n"));
        // Loop through the rows
        for row in 0..self.size {
            // Write the row number
            try!(write!(f, "{row:>0$}", width, row = row));
            // Loop through the columns
            for col in 0..self.size {
                // Get the value of the cell as 1 or 0
                let p = if self.cells[row * self.size + col] {
                    1
                } else {
                    0
                };
                // Write the column value
                try!(write!(f, " {col:>0$}", width, col = p));
            }
            // Newline for next row
            try!(write!(f, "\n"));
        }
        // Return Formatter result
        write!(f, "")
    }
}

fn main() {
    // The board size
    let size: usize = 3;
    // The target board
    let target: Board = Board::random(size);
    // The user board
    let mut board: Board = Board::new(size);
    // How many moves taken
    let mut moves: u32 = 0;
    // Loop until win or quit
    'mainloop: loop {
        // User input
        let mut input: String;
        // Write the boards
        println!("Target:\n{}\nBoard:\n{}", &target, &board);
        // User input loop
        'userinput: loop {
            // Prompt
            print!("\nFlip? [q|[r|c]#] ");
            // Flush stdout to write the previous print, if we can't then exit
            match std::io::stdout().flush() {
                Ok(_) => {}
                Err(e) => {
                    println!("Error: cannot flush stdout: {}", e);
                    break 'mainloop;
                }
            };
            // Reset input for each loop
            input = String::new();
            // Read user input
            match std::io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input = input.trim().to_string();
                    // Get the first character
                    let rc: char = match input.chars().nth(0) {
                        Some(c) => c,
                        None => {
                            println!("Error: No input");
                            continue 'userinput;
                        }
                    };
                    // Make sure input is r, c, or q
                    if rc != 'r' && rc != 'c' && rc != 'q' {
                        println!("Error: '{}': Must use 'r'ow or 'c'olumn or 'q'uit", rc);
                        continue 'userinput;
                    }
                    // If input is q, exit game
                    if rc == 'q' {
                        println!("Thanks for playing!");
                        break 'mainloop;
                    }
                    // If input is r or c, get the number after
                    let n: usize = match input[1..].to_string().parse() {
                        Ok(x) => {
                            // If we're within bounds, return the parsed number
                            if x < size {
                                x
                            } else {
                                println!("Error: Must specify a row or column within size({})",
                                         size);
                                continue 'userinput;
                            }
                        }
                        Err(_) => {
                            println!("Error: '{}': Unable to parse row or column number",
                                     input[1..].to_string());
                            continue 'userinput;
                        }
                    };
                    // Flip the row or column specified
                    match rc {
                        'r' => board.fliprow(n),
                        'c' => board.flipcol(n),
                        _ => {
                            // We want to panic here because should NEVER
                            // have anything other than 'r' or 'c' here
                            panic!("How did you end up here?");
                        }
                    };
                    // Increment moves
                    moves += 1;
                    println!("Moves taken: {}", moves);
                    break 'userinput;
                }
                Err(e) => {
                    println!("Error reading input: {}", e);
                    break 'mainloop;
                }
            }
        } // 'userinput
        if board.eq(&target) {
            println!("You win!");
            break;
        }
    } // 'mainloop
}
<|endoftext|>


<commit_before>pub struct Brackets(String);

impl<'a> From<&'a str> for Brackets {
    fn from(string: &str) -> Self {
        Brackets(string.into())
    }
}

impl Brackets {
    pub fn are_balanced(&self) -> bool {
        let mut stack = Vec::new();

        for c in self.0.chars() {
            match c {
                '[' | '{' | '(' => {
                    stack.push(c);
                },
                ']' | '}' | ')' => {
                    match stack.pop() {
                        Some(x) => {
                            if c == ']' && x != '[' ||
                               c == '}' && x != '{' ||
                               c == ')' && x != '(' {
                                return false
                            }
                        },
                        None => return false
                    }
                },
                _ => ()
            }
        }

        stack.len() == 0
    }
}
<commit_msg>Convert Bracket Push solution to store &str instead of String<commit_after>pub struct Brackets<'a>(&'a str);

impl<'a> From<&'a str> for Brackets<'a> {
    fn from(brackets: &'a str) -> Self {
        Brackets(brackets)
    }
}

impl<'a> Brackets<'a> {
    pub fn are_balanced(&self) -> bool {
        let mut stack = Vec::new();

        for c in self.0.chars() {
            match c {
                '[' | '{' | '(' => {
                    stack.push(c);
                },
                ']' | '}' | ')' => {
                    match stack.pop() {
                        Some(x) => {
                            if c == ']' && x != '[' ||
                               c == '}' && x != '{' ||
                               c == ')' && x != '(' {
                                return false
                            }
                        },
                        None => return false
                    }
                },
                _ => ()
            }
        }

        stack.len() == 0
    }
}
<|endoftext|>


<commit_before>#![deny(clippy::all, clippy::pedantic)]

use std::fmt::Display;
use thiserror::Error;

fn assert<T: Display>(expected: &str, value: T) {
    assert_eq!(expected, value.to_string());
}

#[test]
fn test_braced() {
    #[derive(Error, Debug)]
    #[error("braced error: {msg}")]
    struct Error {
        msg: String,
    }

    let msg = "T".to_owned();
    assert("braced error: T", Error { msg });
}

#[test]
fn test_braced_unused() {
    #[derive(Error, Debug)]
    #[error("braced error")]
    struct Error {
        extra: usize,
    }

    assert("braced error", Error { extra: 0 });
}

#[test]
fn test_tuple() {
    #[derive(Error, Debug)]
    #[error("tuple error: {0}")]
    struct Error(usize);

    assert("tuple error: 0", Error(0));
}

#[test]
fn test_unit() {
    #[derive(Error, Debug)]
    #[error("unit error")]
    struct Error;

    assert("unit error", Error);
}

#[test]
fn test_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced error: {id}")]
        Braced { id: usize },
        #[error("tuple error: {0}")]
        Tuple(usize),
        #[error("unit error")]
        Unit,
    }

    assert("braced error: 0", Error::Braced { id: 0 });
    assert("tuple error: 0", Error::Tuple(0));
    assert("unit error", Error::Unit);
}

#[test]
fn test_constants() {
    #[derive(Error, Debug)]
    #[error("{MSG}: {id:?} (code {CODE:?})")]
    struct Error {
        id: &'static str,
    }

    const MSG: &str = "failed to do";
    const CODE: usize = 9;

    assert("failed to do: \"\" (code 9)", Error { id: "" });
}

#[test]
fn test_inherit() {
    #[derive(Error, Debug)]
    #[error("{0}")]
    enum Error {
        Some(&'static str),
        #[error("other error")]
        Other(&'static str),
    }

    assert("some error", Error::Some("some error"));
    assert("other error", Error::Other("..."));
}

#[test]
fn test_brace_escape() {
    #[derive(Error, Debug)]
    #[error("fn main() {{}}")]
    struct Error;

    assert("fn main() {}", Error);
}

#[test]
fn test_expr() {
    #[derive(Error, Debug)]
    #[error("1 + 1 = {}", 1 + 1)]
    struct Error;
    assert("1 + 1 = 2", Error);
}

#[test]
fn test_nested() {
    #[derive(Error, Debug)]
    #[error("!bool = {}", not(.0))]
    struct Error(bool);

    #[allow(clippy::trivially_copy_pass_by_ref)]
    fn not(bool: &bool) -> bool {
        !*bool
    }

    assert("!bool = false", Error(true));
}

#[test]
fn test_match() {
    #[derive(Error, Debug)]
    #[error("{}: {0}", match .1 {
        Some(n) => format!("error occurred with {}", n),
        None => "there was an empty error".to_owned(),
    })]
    struct Error(String, Option<usize>);

    assert(
        "error occurred with 1: ...",
        Error("...".to_owned(), Some(1)),
    );
    assert(
        "there was an empty error: ...",
        Error("...".to_owned(), None),
    );
}

#[test]
fn test_void() {
    #[allow(clippy::empty_enum)]
    #[derive(Error, Debug)]
    #[error("...")]
    pub enum Error {}

    let _: Error;
}

#[test]
fn test_mixed() {
    #[derive(Error, Debug)]
    #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)]
    struct Error {
        a: usize,
        d: usize,
    }

    assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 });
}

#[test]
fn test_ints() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("error {0}")]
        Tuple(usize, usize),
        #[error("error {0}", '?')]
        Struct { v: usize },
    }

    assert("error 9", Error::Tuple(9, 0));
    assert("error ?", Error::Struct { v: 0 });
}

#[test]
fn test_trailing_comma() {
    #[derive(Error, Debug)]
    #[error(
        "error {0}",
    )]
    #[rustfmt::skip]
    struct Error(char);

    assert("error ?", Error('?'));
}

#[test]
fn test_field() {
    #[derive(Debug)]
    struct Inner {
        data: usize,
    }

    #[derive(Error, Debug)]
    #[error("{}", .0.data)]
    struct Error(Inner);

    assert("0", Error(Inner { data: 0 }));
}

#[test]
fn test_macro_rules() {
    // Regression test for https://github.com/dtolnay/thiserror/issues/86

    macro_rules! decl_error {
        ($variant:ident($value:ident)) => {
            #[derive(Debug, Error)]
            pub enum Error0 {
                #[error("{0:?}")]
                $variant($value),
            }

            #[derive(Debug, Error)]
            #[error("{0:?}")]
            pub enum Error1 {
                $variant($value),
            }
        };
    }

    decl_error!(Repro(u8));

    assert("0", Error0::Repro(0));
    assert("0", Error1::Repro(0));
}

#[test]
fn test_raw() {
    #[derive(Error, Debug)]
    #[error("braced raw error: {r#fn}")]
    struct Error {
        r#fn: String,
    }

    assert(
        "braced raw error: T",
        Error {
            r#fn: "T".to_owned(),
        },
    );
}

#[test]
fn test_raw_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced raw error: {r#fn}")]
        Braced { r#fn: String },
    }

    assert(
        "braced raw error: T",
        Error::Braced {
            r#fn: "T".to_owned(),
        },
    );
}
<commit_msg>Test collision with user-defined named params<commit_after>#![deny(clippy::all, clippy::pedantic)]

use std::fmt::Display;
use thiserror::Error;

fn assert<T: Display>(expected: &str, value: T) {
    assert_eq!(expected, value.to_string());
}

#[test]
fn test_braced() {
    #[derive(Error, Debug)]
    #[error("braced error: {msg}")]
    struct Error {
        msg: String,
    }

    let msg = "T".to_owned();
    assert("braced error: T", Error { msg });
}

#[test]
fn test_braced_unused() {
    #[derive(Error, Debug)]
    #[error("braced error")]
    struct Error {
        extra: usize,
    }

    assert("braced error", Error { extra: 0 });
}

#[test]
fn test_tuple() {
    #[derive(Error, Debug)]
    #[error("tuple error: {0}")]
    struct Error(usize);

    assert("tuple error: 0", Error(0));
}

#[test]
fn test_unit() {
    #[derive(Error, Debug)]
    #[error("unit error")]
    struct Error;

    assert("unit error", Error);
}

#[test]
fn test_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced error: {id}")]
        Braced { id: usize },
        #[error("tuple error: {0}")]
        Tuple(usize),
        #[error("unit error")]
        Unit,
    }

    assert("braced error: 0", Error::Braced { id: 0 });
    assert("tuple error: 0", Error::Tuple(0));
    assert("unit error", Error::Unit);
}

#[test]
fn test_constants() {
    #[derive(Error, Debug)]
    #[error("{MSG}: {id:?} (code {CODE:?})")]
    struct Error {
        id: &'static str,
    }

    const MSG: &str = "failed to do";
    const CODE: usize = 9;

    assert("failed to do: \"\" (code 9)", Error { id: "" });
}

#[test]
fn test_inherit() {
    #[derive(Error, Debug)]
    #[error("{0}")]
    enum Error {
        Some(&'static str),
        #[error("other error")]
        Other(&'static str),
    }

    assert("some error", Error::Some("some error"));
    assert("other error", Error::Other("..."));
}

#[test]
fn test_brace_escape() {
    #[derive(Error, Debug)]
    #[error("fn main() {{}}")]
    struct Error;

    assert("fn main() {}", Error);
}

#[test]
fn test_expr() {
    #[derive(Error, Debug)]
    #[error("1 + 1 = {}", 1 + 1)]
    struct Error;
    assert("1 + 1 = 2", Error);
}

#[test]
fn test_nested() {
    #[derive(Error, Debug)]
    #[error("!bool = {}", not(.0))]
    struct Error(bool);

    #[allow(clippy::trivially_copy_pass_by_ref)]
    fn not(bool: &bool) -> bool {
        !*bool
    }

    assert("!bool = false", Error(true));
}

#[test]
fn test_match() {
    #[derive(Error, Debug)]
    #[error("{}: {0}", match .1 {
        Some(n) => format!("error occurred with {}", n),
        None => "there was an empty error".to_owned(),
    })]
    struct Error(String, Option<usize>);

    assert(
        "error occurred with 1: ...",
        Error("...".to_owned(), Some(1)),
    );
    assert(
        "there was an empty error: ...",
        Error("...".to_owned(), None),
    );
}

#[test]
fn test_void() {
    #[allow(clippy::empty_enum)]
    #[derive(Error, Debug)]
    #[error("...")]
    pub enum Error {}

    let _: Error;
}

#[test]
fn test_mixed() {
    #[derive(Error, Debug)]
    #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)]
    struct Error {
        a: usize,
        d: usize,
    }

    assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 });
}

#[test]
fn test_ints() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("error {0}")]
        Tuple(usize, usize),
        #[error("error {0}", '?')]
        Struct { v: usize },
    }

    assert("error 9", Error::Tuple(9, 0));
    assert("error ?", Error::Struct { v: 0 });
}

#[test]
fn test_trailing_comma() {
    #[derive(Error, Debug)]
    #[error(
        "error {0}",
    )]
    #[rustfmt::skip]
    struct Error(char);

    assert("error ?", Error('?'));
}

#[test]
fn test_field() {
    #[derive(Debug)]
    struct Inner {
        data: usize,
    }

    #[derive(Error, Debug)]
    #[error("{}", .0.data)]
    struct Error(Inner);

    assert("0", Error(Inner { data: 0 }));
}

#[test]
fn test_macro_rules() {
    // Regression test for https://github.com/dtolnay/thiserror/issues/86

    macro_rules! decl_error {
        ($variant:ident($value:ident)) => {
            #[derive(Debug, Error)]
            pub enum Error0 {
                #[error("{0:?}")]
                $variant($value),
            }

            #[derive(Debug, Error)]
            #[error("{0:?}")]
            pub enum Error1 {
                $variant($value),
            }
        };
    }

    decl_error!(Repro(u8));

    assert("0", Error0::Repro(0));
    assert("0", Error1::Repro(0));
}

#[test]
fn test_raw() {
    #[derive(Error, Debug)]
    #[error("braced raw error: {r#fn}")]
    struct Error {
        r#fn: String,
    }

    assert(
        "braced raw error: T",
        Error {
            r#fn: "T".to_owned(),
        },
    );
}

#[test]
fn test_raw_enum() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced raw error: {r#fn}")]
        Braced { r#fn: String },
    }

    assert(
        "braced raw error: T",
        Error::Braced {
            r#fn: "T".to_owned(),
        },
    );
}

#[test]
fn test_raw_conflict() {
    #[derive(Error, Debug)]
    enum Error {
        #[error("braced raw error: {r#func}, {func}", func = "U")]
        Braced { r#func: String },
    }

    assert(
        "braced raw error: T, U",
        Error::Braced {
            r#func: "T".to_owned(),
        },
    );
}
<|endoftext|>