<commit_before>/// The `libc_bitflags!` macro helps with a common use case of defining bitflags with values from
/// the libc crate. It is used the same way as the `bitflags!` macro, except that only the name of
/// the flag value has to be given.
///
/// The `libc` crate must be in scope with the name `libc`.
///
/// # Example
/// ```
/// libc_bitflags!{
///     pub struct ProtFlags: libc::c_int {
///         PROT_NONE;
///         PROT_READ;
///         PROT_WRITE;
///         PROT_EXEC;
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSDOWN;
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSUP;
///     }
/// }
/// ```
///
/// Example with casting, due to a mistake in libc. In this example, the
/// various flags have different types, so we cast the broken ones to the right
/// type.
///
/// ```
/// libc_bitflags!{
///     pub struct SaFlags: libc::c_ulong {
///         SA_NOCLDSTOP as libc::c_ulong;
///         SA_NOCLDWAIT;
///         SA_NODEFER as libc::c_ulong;
///         SA_ONSTACK;
///         SA_RESETHAND as libc::c_ulong;
///         SA_RESTART as libc::c_ulong;
///         SA_SIGINFO;
///     }
/// }
/// ```
macro_rules! libc_bitflags {
    // (non-pub) Exit rule.
    (@call_bitflags
        {
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: [$($attrs:tt)*],
            flags: [$($flags:tt)*],
        }
    ) => {
        bitflags! {
            $($attrs)*
            struct $BitFlags: $T {
                $($flags)*
            }
        }
    };

    // (pub) Exit rule.
    (@call_bitflags
        {
            pub,
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: [$($attrs:tt)*],
            flags: [$($flags:tt)*],
        }
    ) => {
        bitflags! {
            $($attrs)*
            pub struct $BitFlags: $T {
                $($flags)*
            }
        }
    };

    // (non-pub) Done accumulating.
    (@accumulate_flags
        {
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: $attrs:tt,
        },
        $flags:tt;
    ) => {
        libc_bitflags! {
            @call_bitflags
            {
                name: $BitFlags,
                type: $T,
                attrs: $attrs,
                flags: $flags,
            }
        }
    };

    // (pub) Done accumulating.
    (@accumulate_flags
        {
            pub,
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: $attrs:tt,
        },
        $flags:tt;
    ) => {
        libc_bitflags! {
            @call_bitflags
            {
                pub,
                name: $BitFlags,
                type: $T,
                attrs: $attrs,
                flags: $flags,
            }
        }
    };

    // Munch an attr.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        #[$attr:meta] $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                #[$attr]
            ];
            $($tail)*
        }
    };

    // Munch last ident if not followed by a semicolon.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag;
            ];
        }
    };

    // Munch last ident and cast it to the given type.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident as $ty:ty
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag as $ty;
            ];
        }
    };

    // Munch an ident; covers terminating semicolon case.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident; $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag;
            ];
            $($tail)*
        }
    };

    // Munch an ident and cast it to the given type; covers terminating semicolon
    // case.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident as $ty:ty; $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag as $ty;
            ];
            $($tail)*
        }
    };

    // (non-pub) Entry rule.
    (
        $(#[$attr:meta])*
        struct $BitFlags:ident: $T:ty {
            $($vals:tt)*
        }
    ) => {
        libc_bitflags! {
            @accumulate_flags
            {
                name: $BitFlags,
                type: $T,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };

    // (pub) Entry rule.
    (
        $(#[$attr:meta])*
        pub struct $BitFlags:ident: $T:ty {
            $($vals:tt)*
        }
    ) => {
        libc_bitflags! {
            @accumulate_flags
            {
                pub,
                name: $BitFlags,
                type: $T,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };
}

/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using
/// values from the `libc` crate. This macro supports both `pub` and private `enum`s.
///
/// The `libc` crate must be in scope with the name `libc`.
///
/// # Example
/// ```
/// libc_enum!{
///     pub enum ProtFlags {
///         PROT_NONE,
///         PROT_READ,
///         PROT_WRITE,
///         PROT_EXEC,
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSDOWN,
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSUP,
///     }
/// }
/// ```
macro_rules! libc_enum {
    // (non-pub) Exit rule.
    (@make_enum
        {
            name: $BitFlags:ident,
            attrs: [$($attrs:tt)*],
            entries: [$($entries:tt)*],
        }
    ) => {
        $($attrs)*
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        enum $BitFlags {
            $($entries)*
        }
    };

    // (pub) Exit rule.
    (@make_enum
        {
            pub,
            name: $BitFlags:ident,
            attrs: [$($attrs:tt)*],
            entries: [$($entries:tt)*],
        }
    ) => {
        $($attrs)*
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        pub enum $BitFlags {
            $($entries)*
        }
    };

    // (non-pub) Done accumulating.
    (@accumulate_entries
        {
            name: $BitFlags:ident,
            attrs: $attrs:tt,
        },
        $entries:tt;
    ) => {
        libc_enum! {
            @make_enum
            {
                name: $BitFlags,
                attrs: $attrs,
                entries: $entries,
            }
        }
    };

    // (pub) Done accumulating.
    (@accumulate_entries
        {
            pub,
            name: $BitFlags:ident,
            attrs: $attrs:tt,
        },
        $entries:tt;
    ) => {
        libc_enum! {
            @make_enum
            {
                pub,
                name: $BitFlags,
                attrs: $attrs,
                entries: $entries,
            }
        }
    };

    // Munch an attr.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        #[$attr:meta] $($tail:tt)*
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                #[$attr]
            ];
            $($tail)*
        }
    };

    // Munch last ident if not followed by a comma.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        $entry:ident
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                $entry = libc::$entry,
            ];
        }
    };

    // Munch an ident; covers terminating comma case.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        $entry:ident, $($tail:tt)*
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                $entry = libc::$entry,
            ];
            $($tail)*
        }
    };

    // (non-pub) Entry rule.
    (
        $(#[$attr:meta])*
        enum $BitFlags:ident {
            $($vals:tt)*
        }
    ) => {
        libc_enum! {
            @accumulate_entries
            {
                name: $BitFlags,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };

    // (pub) Entry rule.
    (
        $(#[$attr:meta])*
        pub enum $BitFlags:ident {
            $($vals:tt)*
        }
    ) => {
        libc_enum! {
            @accumulate_entries
            {
                pub,
                name: $BitFlags,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };
}

/// A Rust version of the familiar C `offset_of` macro.  It returns the byte
/// offset of `field` within struct `ty`
macro_rules! offset_of {
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
}
<commit_msg>Support casting values in libc_enum!<commit_after>/// The `libc_bitflags!` macro helps with a common use case of defining bitflags with values from
/// the libc crate. It is used the same way as the `bitflags!` macro, except that only the name of
/// the flag value has to be given.
///
/// The `libc` crate must be in scope with the name `libc`.
///
/// # Example
/// ```
/// libc_bitflags!{
///     pub struct ProtFlags: libc::c_int {
///         PROT_NONE;
///         PROT_READ;
///         PROT_WRITE;
///         PROT_EXEC;
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSDOWN;
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSUP;
///     }
/// }
/// ```
///
/// Example with casting, due to a mistake in libc. In this example, the
/// various flags have different types, so we cast the broken ones to the right
/// type.
///
/// ```
/// libc_bitflags!{
///     pub struct SaFlags: libc::c_ulong {
///         SA_NOCLDSTOP as libc::c_ulong;
///         SA_NOCLDWAIT;
///         SA_NODEFER as libc::c_ulong;
///         SA_ONSTACK;
///         SA_RESETHAND as libc::c_ulong;
///         SA_RESTART as libc::c_ulong;
///         SA_SIGINFO;
///     }
/// }
/// ```
macro_rules! libc_bitflags {
    // (non-pub) Exit rule.
    (@call_bitflags
        {
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: [$($attrs:tt)*],
            flags: [$($flags:tt)*],
        }
    ) => {
        bitflags! {
            $($attrs)*
            struct $BitFlags: $T {
                $($flags)*
            }
        }
    };

    // (pub) Exit rule.
    (@call_bitflags
        {
            pub,
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: [$($attrs:tt)*],
            flags: [$($flags:tt)*],
        }
    ) => {
        bitflags! {
            $($attrs)*
            pub struct $BitFlags: $T {
                $($flags)*
            }
        }
    };

    // (non-pub) Done accumulating.
    (@accumulate_flags
        {
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: $attrs:tt,
        },
        $flags:tt;
    ) => {
        libc_bitflags! {
            @call_bitflags
            {
                name: $BitFlags,
                type: $T,
                attrs: $attrs,
                flags: $flags,
            }
        }
    };

    // (pub) Done accumulating.
    (@accumulate_flags
        {
            pub,
            name: $BitFlags:ident,
            type: $T:ty,
            attrs: $attrs:tt,
        },
        $flags:tt;
    ) => {
        libc_bitflags! {
            @call_bitflags
            {
                pub,
                name: $BitFlags,
                type: $T,
                attrs: $attrs,
                flags: $flags,
            }
        }
    };

    // Munch an attr.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        #[$attr:meta] $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                #[$attr]
            ];
            $($tail)*
        }
    };

    // Munch last ident if not followed by a semicolon.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag;
            ];
        }
    };

    // Munch last ident and cast it to the given type.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident as $ty:ty
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag as $ty;
            ];
        }
    };

    // Munch an ident; covers terminating semicolon case.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident; $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag;
            ];
            $($tail)*
        }
    };

    // Munch an ident and cast it to the given type; covers terminating semicolon
    // case.
    (@accumulate_flags
        $prefix:tt,
        [$($flags:tt)*];
        $flag:ident as $ty:ty; $($tail:tt)*
    ) => {
        libc_bitflags! {
            @accumulate_flags
            $prefix,
            [
                $($flags)*
                const $flag = libc::$flag as $ty;
            ];
            $($tail)*
        }
    };

    // (non-pub) Entry rule.
    (
        $(#[$attr:meta])*
        struct $BitFlags:ident: $T:ty {
            $($vals:tt)*
        }
    ) => {
        libc_bitflags! {
            @accumulate_flags
            {
                name: $BitFlags,
                type: $T,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };

    // (pub) Entry rule.
    (
        $(#[$attr:meta])*
        pub struct $BitFlags:ident: $T:ty {
            $($vals:tt)*
        }
    ) => {
        libc_bitflags! {
            @accumulate_flags
            {
                pub,
                name: $BitFlags,
                type: $T,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };
}

/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using
/// values from the `libc` crate. This macro supports both `pub` and private `enum`s.
///
/// The `libc` crate must be in scope with the name `libc`.
///
/// # Example
/// ```
/// libc_enum!{
///     pub enum ProtFlags {
///         PROT_NONE,
///         PROT_READ,
///         PROT_WRITE,
///         PROT_EXEC,
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSDOWN,
///         #[cfg(any(target_os = "linux", target_os = "android"))]
///         PROT_GROWSUP,
///     }
/// }
/// ```
macro_rules! libc_enum {
    // (non-pub) Exit rule.
    (@make_enum
        {
            name: $BitFlags:ident,
            attrs: [$($attrs:tt)*],
            entries: [$($entries:tt)*],
        }
    ) => {
        $($attrs)*
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        enum $BitFlags {
            $($entries)*
        }
    };

    // (pub) Exit rule.
    (@make_enum
        {
            pub,
            name: $BitFlags:ident,
            attrs: [$($attrs:tt)*],
            entries: [$($entries:tt)*],
        }
    ) => {
        $($attrs)*
        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
        pub enum $BitFlags {
            $($entries)*
        }
    };

    // (non-pub) Done accumulating.
    (@accumulate_entries
        {
            name: $BitFlags:ident,
            attrs: $attrs:tt,
        },
        $entries:tt;
    ) => {
        libc_enum! {
            @make_enum
            {
                name: $BitFlags,
                attrs: $attrs,
                entries: $entries,
            }
        }
    };

    // (pub) Done accumulating.
    (@accumulate_entries
        {
            pub,
            name: $BitFlags:ident,
            attrs: $attrs:tt,
        },
        $entries:tt;
    ) => {
        libc_enum! {
            @make_enum
            {
                pub,
                name: $BitFlags,
                attrs: $attrs,
                entries: $entries,
            }
        }
    };

    // Munch an attr.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        #[$attr:meta] $($tail:tt)*
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                #[$attr]
            ];
            $($tail)*
        }
    };

    // Munch last ident if not followed by a comma.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        $entry:ident
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                $entry = libc::$entry,
            ];
        }
    };

    // Munch an ident; covers terminating comma case.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        $entry:ident, $($tail:tt)*
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                $entry = libc::$entry,
            ];
            $($tail)*
        }
    };

    // Munch an ident and cast it to the given type; covers terminating comma.
    (@accumulate_entries
        $prefix:tt,
        [$($entries:tt)*];
        $entry:ident as $ty:ty, $($tail:tt)*
    ) => {
        libc_enum! {
            @accumulate_entries
            $prefix,
            [
                $($entries)*
                $entry = libc::$entry as $ty,
            ];
            $($tail)*
        }
    };

    // (non-pub) Entry rule.
    (
        $(#[$attr:meta])*
        enum $BitFlags:ident {
            $($vals:tt)*
        }
    ) => {
        libc_enum! {
            @accumulate_entries
            {
                name: $BitFlags,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };

    // (pub) Entry rule.
    (
        $(#[$attr:meta])*
        pub enum $BitFlags:ident {
            $($vals:tt)*
        }
    ) => {
        libc_enum! {
            @accumulate_entries
            {
                pub,
                name: $BitFlags,
                attrs: [$(#[$attr])*],
            },
            [];
            $($vals)*
        }
    };
}

/// A Rust version of the familiar C `offset_of` macro.  It returns the byte
/// offset of `field` within struct `ty`
macro_rules! offset_of {
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

include!("../relm-state/src/macros.rs");
<commit_msg>Temporary fix to publish the crate<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/// Connect events to sending a message.
///
/// ## Rules
/// 1. Send `$msg` to `$other_component` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Optionally send `$msg.0` when the GTK+ `$event` is emitted on `$widget`.
/// Return `$msg.1` in the GTK+ callback.
/// This variant gives more control to the caller since it expects a `$msg` returning `(Option<MSG>,
/// ReturnValue)` where the `ReturnValue` is the value to return in the GTK+ callback.
/// Option<MSG> can be None if no message needs to be emitted.
///
/// 3. Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
///
/// 4. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect {
    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_component:expr, $msg:expr) => {
        connect_stream!($widget, $event($($args),*), $other_component.stream(), $msg);
    };

    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), return $msg:expr) => {{
        connect_stream!(return $relm.stream(), $widget, $event($($args),*), $msg);
    }};

    // Connect to a GTK+ widget event.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $relm.stream().clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    }};

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_component:ident @ $message:pat, $dst_component:expr, $msg:expr) => {
        let stream = $src_component.stream().clone();
        connect_stream!(stream@$message, $dst_component.stream(), $msg);
    };
}

/// Connect events to sending a message.
/// Similar to `connect!` but wants a stream instead of a component.
///
/// ## Rules
/// 1. Send `$msg` to `$other_stream` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect_stream {
    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    (return $stream:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let (msg, return_value) = $crate::IntoPair::into_pair($msg);
            let msg: Option<_> = $crate::IntoOption::into_option(msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
            return_value
        });
    }};

    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_stream:expr, $msg:expr) => {
        let stream = $other_stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    };

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_stream:ident @ $message:pat, $dst_stream:expr, $msg:expr) => {
        let stream = $dst_stream.clone();
        $src_stream.observe(move |msg| {
            #[allow(unreachable_patterns)]
            match msg {
                &$message =>  {
                    let msg: Option<_> = $crate::IntoOption::into_option($msg);
                    if let Some(msg) = msg {
                        stream.emit(msg);
                    }
                },
                _ => (),
            }
        });
    };
}

/// Connect an asynchronous method call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });
    }};
}

/// Connect an asynchronous function call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async_func {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

    }};
}

/// Like `connect_async!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_full {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}

/// Like `connect_async_func!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_func_full {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async!($async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}
<|endoftext|>


<commit_before>use rand::rngs::StdRng;

use rustc_mir::interpret::{Pointer, Allocation, AllocationExtra, InterpResult};
use rustc_target::abi::Size;

use crate::{stacked_borrows, intptrcast};
use crate::stacked_borrows::Tag;

#[derive(Default, Clone, Debug)]
pub struct MemoryExtra {
    pub stacked_borrows: stacked_borrows::MemoryExtra,
    pub intptrcast: intptrcast::MemoryExtra,
    /// The random number generator to use if Miri is running in non-deterministic mode and to
    /// enable intptrcast
    pub(crate) rng: Option<StdRng>
}

impl MemoryExtra {
    pub fn with_rng(rng: Option<StdRng>) -> Self {
        MemoryExtra {
            stacked_borrows: Default::default(),
            intptrcast: Default::default(),
            rng,
        }
    }
}

#[derive(Debug, Clone)]
pub struct AllocExtra {
    pub stacked_borrows: stacked_borrows::AllocExtra,
    pub intptrcast: intptrcast::AllocExtra,
}

impl AllocationExtra<Tag> for AllocExtra {
    #[inline(always)]
    fn memory_read<'tcx>(
        alloc: &Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_read(ptr, size)
    }

    #[inline(always)]
    fn memory_written<'tcx>(
        alloc: &mut Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_written(ptr, size)
    }

    #[inline(always)]
    fn memory_deallocated<'tcx>(
        alloc: &mut Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_deallocated(ptr, size)
    }
}
<commit_msg>Remove default derive for MemoryExtra<commit_after>use rand::rngs::StdRng;

use rustc_mir::interpret::{Pointer, Allocation, AllocationExtra, InterpResult};
use rustc_target::abi::Size;

use crate::{stacked_borrows, intptrcast};
use crate::stacked_borrows::Tag;

#[derive(Clone, Debug)]
pub struct MemoryExtra {
    pub stacked_borrows: stacked_borrows::MemoryExtra,
    pub intptrcast: intptrcast::MemoryExtra,
    /// The random number generator to use if Miri is running in non-deterministic mode and to
    /// enable intptrcast
    pub(crate) rng: Option<StdRng>
}

impl MemoryExtra {
    pub fn with_rng(rng: Option<StdRng>) -> Self {
        MemoryExtra {
            stacked_borrows: Default::default(),
            intptrcast: Default::default(),
            rng,
        }
    }
}

#[derive(Debug, Clone)]
pub struct AllocExtra {
    pub stacked_borrows: stacked_borrows::AllocExtra,
    pub intptrcast: intptrcast::AllocExtra,
}

impl AllocationExtra<Tag> for AllocExtra {
    #[inline(always)]
    fn memory_read<'tcx>(
        alloc: &Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_read(ptr, size)
    }

    #[inline(always)]
    fn memory_written<'tcx>(
        alloc: &mut Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_written(ptr, size)
    }

    #[inline(always)]
    fn memory_deallocated<'tcx>(
        alloc: &mut Allocation<Tag, AllocExtra>,
        ptr: Pointer<Tag>,
        size: Size,
    ) -> InterpResult<'tcx> {
        alloc.extra.stacked_borrows.memory_deallocated(ptr, size)
    }
}
<|endoftext|>


<commit_before>//! Metrics for indexing `Rope`s.
//!
//! A [`Metric`] represents a measurement with which indices into a [`Rope`]
//! may be calculated.
//!
//! All [`Rope`] methods are optionally parameterised with [`Metric`]s. This
//! means that you can [`split`], [`insert`], or [`delete`] Ropes on character,
//! line, or grapheme indices, without necessitating the addition of a whole
//! bunch of new, wordy method names like `split_on_grapheme_index` and so on.
//!
//! # Examples
//!
//! If I wanted to delete characters 10 to 15 from rope _r_, I could say:
//!
//! ```
//! # use an_rope::Rope;
//! let mut r = Rope::from("this is a long rope");
//! r.delete(10..15);
//! assert_eq!(&r, "this is a rope");
//! ```
//!
//! Suppose my `Rope` contained some strange Unicode characters, and I realised
//! that I actually wanted to delete _graphemes_ 10 to 13. In that case, I
//! could say:
//!
//! ```
//! # use an_rope::Rope;
//! use an_rope::metric::Grapheme;
//! let mut r = Rope::from("this is a 🆒🆕 rope, 🆗!");
//! r.delete(Grapheme(10)..Grapheme(13));
//! assert_eq!(&r, "this is a rope, 🆗!");
//! ```
//!
//! Or, suppose my `Rope` spanned multiple lines:
//!
//! ```
//! # use an_rope::Rope;
//! use an_rope::metric::Line;
//! let mut r = Rope::from("this is\n\
//!                         a\n\
//!                         multi\n\
//!                         line\n\
//!                         rope");
//! r.delete(Line(2)..Line(3));
//! assert_eq!(&r, "this is\na\nrope");
//! ```
//!
//! [`Metric`]: trait.Metric.html
//! [`Rope`]: ../struct.Rope.html
//! [`split`]: ../struct.Rope.html#method.split
//! [`insert`]: ../struct.Rope.html#method.insert
//! [`delete`]: ../struct.Rope.html#method.delete

use std::convert;
use std::ops::{Add, Sub};
use std::default::Default;
use std::fmt;

/// The class of monoids
///
/// [Monoid]s are types with an accumulative binary operation that has
/// an identity.
///
/// Technically, `Add<Self, Output=Self>` is standing in for "semigroup" here,
/// while [`Default`] is standing in for "identity"[^id].
///
/// An instance _M_ should satisfy the following laws:
///
///  + _x_`.add(`_M_`::default())` = _x_
///  + _M_`::default().add(`_x_`)` = _x_
///  + _x_`.add(`_y_`.add(`_z_`))` = _z_`.add(`_x_`.add(`_y_`))`
///  + _M_`::accumulate(`_a_`)` = _a_`.fold(`_M_`::default,`_M_`::sum)`
///
/// [^id]: A mathematician might point out that it might be more correct to
///        represent the "identity" operation using the [`Zero`] trait rather
///        than [`Default`], as the documentation for `Zero` notes that "[t]his
///        trait is intended for use in conjunction with `Add`, as an identity".
///        However, the `Zero` trait is marked as unstable, so it would only be
///        useable on nightly Rust, and its use is deprecated. Thus, `Default`.
/// [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html)
/// [`Zero`]: https://doc.rust-lang.org/std/num/trait.Zero.html
/// [Monoid]: http://mathworld.wolfram.com/Monoid.html
pub trait Monoid: Add<Self, Output=Self> + Default + Sized {
    #[inline]
    fn accumulate<F>(xs: F) -> Self
    where F: Iterator<Item=Self>
        , Self: Sized {
        xs.fold(Self::default(), Self::add)
    }
}

/// Trait indicating that a type may be measured with [`Metric`] _M_.
///
/// [`Metric`]: trait.Metric.html
pub trait Measured<M: Metric> {
    /// Apply `Metric` to `Self`
    ///
    /// Although we aren't currently enforcing this, `measure`ing a `Node` with
    /// two children should produce the same result as `measure`ing both
    /// children and `Monoid::sum`ming the result. That is to say, `measure`
    /// should be a [_monoid homomorphism_].
    ///
    /// [_monoid homomorphism_]:
    /// https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms
    fn measure(&self) -> M;

    /// Measure the `weight` of `Node` by this `metric`.
    fn measure_weight(&self) -> M;

    /// Convert the `Metric` into a byte index into the given `Node`
    ///
    /// # Returns
    /// - `Some` with the byte index of the beginning of the `n`th  element
    ///    in `node` measured by this `Metric`, if there is an `n`th element
    /// - `None` if there is no `n`th element in `node`
    fn to_byte_index(&self, index: M) -> Option<usize>;
}

/// A [monoid] that can be applied to a type as a measurement.
///
/// [monoid]: trait.Monoid.html
pub trait Metric: Monoid + Eq + Add<usize, Output=Self>
                         + Sub<usize, Output=Self>
                         + Sub<Self, Output=Self>
                         + Eq + Ord
                         + Sized
                         + convert::Into<usize>
                         + Copy
                         + fmt::Debug {

    /// Returns whether text may be split into new leaf nodes using this metric.
    fn is_splittable() -> bool;

    /// Returns the byte index of the next element of this metric in `Node`
    #[inline]
    fn next<M: Measured<Self> >(self, node: &M)-> Option<usize> {
        node.to_byte_index(self + 1)
    }

    /// Returns the byte index of the previous element of this metric in `Node`
    #[inline]
    fn back<M: Measured<Self>>(self, node: &M) -> Option<usize> {
        node.to_byte_index(self - 1)
    }

    /// Returns true if index `i` in `node` is a boundary along this `Metric`
    fn is_boundary<M: Measured<Self>>(node: &M, i: usize) -> bool;
}

macro_attr! {
    /// A metric for calculating indices in `Rope`s based on Unicode graphemes.
    #[derive( Clone, Copy, PartialOrd, Ord, PartialEq, Eq
            , NewtypeFrom!
            , NewtypeAdd!(*), NewtypeAdd!(&self, usize), NewtypeAdd!(usize)
            , NewtypeSub!(*), NewtypeSub!(&self, usize), NewtypeSub!(usize)
            , NewtypeMul!(*), NewtypeMul!(&self, usize), NewtypeMul!(usize) )]
    pub struct Grapheme(pub usize);
}

impl Default for Grapheme {
    #[inline] fn default() -> Self { Grapheme(0) }
}

impl Monoid for Grapheme { }

impl fmt::Debug for Grapheme {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "grapheme {}", self.0)
   }
}

macro_attr! {
    /// A metric for calculating indices in `Rope`s based on line numbering.
    #[derive( Clone, Copy, PartialOrd, Ord, PartialEq, Eq
            , NewtypeFrom!
            , NewtypeAdd!(*), NewtypeAdd!(&self, usize), NewtypeAdd!(usize)
            , NewtypeSub!(*), NewtypeSub!(&self, usize), NewtypeSub!(usize)
            , NewtypeMul!(*), NewtypeMul!(&self, usize), NewtypeMul!(usize) )]
    pub struct Line(pub usize);
}
impl Default for Line {
    #[inline] fn default() -> Self { Line(0) }
}

impl Monoid for Line { }

impl Monoid for usize { }

impl fmt::Debug for Line {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "line {}", self.0)
   }
}
<commit_msg>test(rope metrics): disable line indexing doctests as well<commit_after>//! Metrics for indexing `Rope`s.
//!
//! A [`Metric`] represents a measurement with which indices into a [`Rope`]
//! may be calculated.
//!
//! All [`Rope`] methods are optionally parameterised with [`Metric`]s. This
//! means that you can [`split`], [`insert`], or [`delete`] Ropes on character,
//! line, or grapheme indices, without necessitating the addition of a whole
//! bunch of new, wordy method names like `split_on_grapheme_index` and so on.
//!
//! # Examples
//!
//! If I wanted to delete characters 10 to 15 from rope _r_, I could say:
//!
//! ```
//! # use an_rope::Rope;
//! let mut r = Rope::from("this is a long rope");
//! r.delete(10..15);
//! assert_eq!(&r, "this is a rope");
//! ```
//!
//! Suppose my `Rope` contained some strange Unicode characters, and I realised
//! that I actually wanted to delete _graphemes_ 10 to 13. In that case, I
//! could say:
//!
//! ```
//! # use an_rope::Rope;
//! use an_rope::metric::Grapheme;
//! let mut r = Rope::from("this is a 🆒🆕 rope, 🆗!");
//! r.delete(Grapheme(10)..Grapheme(13));
//! assert_eq!(&r, "this is a rope, 🆗!");
//! ```
//!
//! Or, suppose my `Rope` spanned multiple lines:
//!
//  FIXME: this test is ignored until
//         https://github.com/an-cabal/an-rope/issues/66
//         is fixed. i feel bad about this but it's not my fault.
//          – eliza, 1/9/2017
//! ```ignore
//! # use an_rope::Rope;
//! use an_rope::metric::Line;
//! let mut r = Rope::from("this is\n\
//!                         a\n\
//!                         multi\n\
//!                         line\n\
//!                         rope");
//! r.delete(Line(2)..Line(3));
//! assert_eq!(&r, "this is\na\nrope");
//! ```
//!
//! [`Metric`]: trait.Metric.html
//! [`Rope`]: ../struct.Rope.html
//! [`split`]: ../struct.Rope.html#method.split
//! [`insert`]: ../struct.Rope.html#method.insert
//! [`delete`]: ../struct.Rope.html#method.delete

use std::convert;
use std::ops::{Add, Sub};
use std::default::Default;
use std::fmt;

/// The class of monoids
///
/// [Monoid]s are types with an accumulative binary operation that has
/// an identity.
///
/// Technically, `Add<Self, Output=Self>` is standing in for "semigroup" here,
/// while [`Default`] is standing in for "identity"[^id].
///
/// An instance _M_ should satisfy the following laws:
///
///  + _x_`.add(`_M_`::default())` = _x_
///  + _M_`::default().add(`_x_`)` = _x_
///  + _x_`.add(`_y_`.add(`_z_`))` = _z_`.add(`_x_`.add(`_y_`))`
///  + _M_`::accumulate(`_a_`)` = _a_`.fold(`_M_`::default,`_M_`::sum)`
///
/// [^id]: A mathematician might point out that it might be more correct to
///        represent the "identity" operation using the [`Zero`] trait rather
///        than [`Default`], as the documentation for `Zero` notes that "[t]his
///        trait is intended for use in conjunction with `Add`, as an identity".
///        However, the `Zero` trait is marked as unstable, so it would only be
///        useable on nightly Rust, and its use is deprecated. Thus, `Default`.
/// [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html)
/// [`Zero`]: https://doc.rust-lang.org/std/num/trait.Zero.html
/// [Monoid]: http://mathworld.wolfram.com/Monoid.html
pub trait Monoid: Add<Self, Output=Self> + Default + Sized {
    #[inline]
    fn accumulate<F>(xs: F) -> Self
    where F: Iterator<Item=Self>
        , Self: Sized {
        xs.fold(Self::default(), Self::add)
    }
}

/// Trait indicating that a type may be measured with [`Metric`] _M_.
///
/// [`Metric`]: trait.Metric.html
pub trait Measured<M: Metric> {
    /// Apply `Metric` to `Self`
    ///
    /// Although we aren't currently enforcing this, `measure`ing a `Node` with
    /// two children should produce the same result as `measure`ing both
    /// children and `Monoid::sum`ming the result. That is to say, `measure`
    /// should be a [_monoid homomorphism_].
    ///
    /// [_monoid homomorphism_]:
    /// https://en.wikipedia.org/wiki/Monoid#Monoid_homomorphisms
    fn measure(&self) -> M;

    /// Measure the `weight` of `Node` by this `metric`.
    fn measure_weight(&self) -> M;

    /// Convert the `Metric` into a byte index into the given `Node`
    ///
    /// # Returns
    /// - `Some` with the byte index of the beginning of the `n`th  element
    ///    in `node` measured by this `Metric`, if there is an `n`th element
    /// - `None` if there is no `n`th element in `node`
    fn to_byte_index(&self, index: M) -> Option<usize>;
}

/// A [monoid] that can be applied to a type as a measurement.
///
/// [monoid]: trait.Monoid.html
pub trait Metric: Monoid + Eq + Add<usize, Output=Self>
                         + Sub<usize, Output=Self>
                         + Sub<Self, Output=Self>
                         + Eq + Ord
                         + Sized
                         + convert::Into<usize>
                         + Copy
                         + fmt::Debug {

    /// Returns whether text may be split into new leaf nodes using this metric.
    fn is_splittable() -> bool;

    /// Returns the byte index of the next element of this metric in `Node`
    #[inline]
    fn next<M: Measured<Self> >(self, node: &M)-> Option<usize> {
        node.to_byte_index(self + 1)
    }

    /// Returns the byte index of the previous element of this metric in `Node`
    #[inline]
    fn back<M: Measured<Self>>(self, node: &M) -> Option<usize> {
        node.to_byte_index(self - 1)
    }

    /// Returns true if index `i` in `node` is a boundary along this `Metric`
    fn is_boundary<M: Measured<Self>>(node: &M, i: usize) -> bool;
}

macro_attr! {
    /// A metric for calculating indices in `Rope`s based on Unicode graphemes.
    #[derive( Clone, Copy, PartialOrd, Ord, PartialEq, Eq
            , NewtypeFrom!
            , NewtypeAdd!(*), NewtypeAdd!(&self, usize), NewtypeAdd!(usize)
            , NewtypeSub!(*), NewtypeSub!(&self, usize), NewtypeSub!(usize)
            , NewtypeMul!(*), NewtypeMul!(&self, usize), NewtypeMul!(usize) )]
    pub struct Grapheme(pub usize);
}

impl Default for Grapheme {
    #[inline] fn default() -> Self { Grapheme(0) }
}

impl Monoid for Grapheme { }

impl fmt::Debug for Grapheme {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "grapheme {}", self.0)
   }
}

macro_attr! {
    /// A metric for calculating indices in `Rope`s based on line numbering.
    #[derive( Clone, Copy, PartialOrd, Ord, PartialEq, Eq
            , NewtypeFrom!
            , NewtypeAdd!(*), NewtypeAdd!(&self, usize), NewtypeAdd!(usize)
            , NewtypeSub!(*), NewtypeSub!(&self, usize), NewtypeSub!(usize)
            , NewtypeMul!(*), NewtypeMul!(&self, usize), NewtypeMul!(usize) )]
    pub struct Line(pub usize);
}
impl Default for Line {
    #[inline] fn default() -> Self { Line(0) }
}

impl Monoid for Line { }

impl Monoid for usize { }

impl fmt::Debug for Line {
   fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "line {}", self.0)
   }
}
<|endoftext|>


<commit_before>/// Internal metric representation
///
use std::fmt;
use std::str::FromStr;

/// Enum of metric types
pub enum MetricKind {
    Counter(f64), // sample rate
    Gauge,
    Timer,
}

impl fmt::Debug for MetricKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            MetricKind::Gauge      => write!(f, "Gauge"),
            MetricKind::Timer      => write!(f, "Timer"),
            MetricKind::Counter(s) => write!(f, "Counter(s={})", s)
        }
    }
}

/// Error types for parsing Metrics from strings.
///
#[derive(Debug)]
pub enum ParseError {
    // Error message, column
    SyntaxError(&'static str, usize)
}

/// Metric value objects.
///
#[derive(Debug)]
pub struct Metric {
    pub kind: MetricKind,
    pub name: String,
    pub value: f64
}

impl Metric {
    pub fn new(name: &str, value: f64, kind: MetricKind) -> Metric {
        Metric{name: name.to_string(), value: value, kind: kind}
    }
}

impl FromStr for Metric {
    type Err = ParseError;

    /// Valid message formats are:
    ///
    /// - `<str:metric_name>:<f64:value>|<str:type>`
    /// - `<str:metric_name>:<f64:value>|c|@<f64:sample_rate>`
    fn from_str(line: &str) -> Result<Metric, ParseError> {
        // Get the metric name
        let name_parts: Vec<&str> = line.trim_right_matches('\n')
            .split(':')
            .collect();
        if name_parts.len() < 2 || name_parts[0].is_empty() {
            return Err(ParseError::SyntaxError(
                    "Metrics require a name.",
                    0))
        }
        let name = name_parts[0].to_string();

        // Get the float val
        let val_parts: Vec<&str> = name_parts[1].split('|').collect();
        if val_parts.len() < 2 || val_parts[0].is_empty() {
            return Err(ParseError::SyntaxError(
                    "Metrics require a value.",
                    name.len()))
        }
        let value = val_parts[0].parse::<f64>().ok().unwrap();

        // Get kind parts
        let kind = match val_parts[1] {
            "ms" => MetricKind::Timer,
            "g" => MetricKind::Gauge,
            "c" => {
                let mut rate:f64 = 1.0;
                if val_parts.len() == 3 {
                    rate = val_parts[2].trim_left_matches('@')
                        .parse::<f64>().ok().unwrap();
                }
                MetricKind::Counter(rate)
            }
            _ => return Err(ParseError::SyntaxError(
                    "Unknown metric type.",
                    2))
        };

        Ok(Metric{name: name, value: value, kind: kind})
    }
}

//
// Tests
//
#[cfg(test)]
mod test {
    use metric::{Metric,MetricKind};
    use std::str::FromStr;
    use std::collections::HashMap;

    #[test]
    fn test_metric_kind_debug_fmt() {
        assert_eq!(
            "Gauge",
            format!("{:?}", MetricKind::Gauge)
        );
        assert_eq!(
            "Timer",
            format!("{:?}", MetricKind::Timer)
        );
        assert_eq!(
            "Counter(s=6)",
            format!("{:?}", MetricKind::Counter(6.0))
        );
    }

    #[test]
    fn test_metric_from_str_invalid_no_name() {
        let res = Metric::from_str("");
        assert!(res.is_err(), "Should have an error");
        assert!(!res.is_ok(), "Should have an error");
    }

    #[test]
    fn test_metric_from_str_invalid_no_value() {
        let res = Metric::from_str("foo:");
        assert!(res.is_err(), "Should have an error");
        assert!(!res.is_ok(), "Should have an error");
    }

    #[test]
    fn test_metric_valid() {
        let mut valid = HashMap::new();
        valid.insert(
            "foo.test:12.3|ms\n",
            Metric::new("foo.test", 12.3, MetricKind::Timer)
        );
        valid.insert(
            "foo.test:12.3|ms",
            Metric::new("foo.test", 12.3, MetricKind::Timer)
        );
        valid.insert(
            "test:18.123|g",
            Metric::new("test", 18.123, MetricKind::Gauge)
        );
        valid.insert(
            "test:18.123|g",
            Metric::new("test", 18.123, MetricKind::Gauge)
        );
        valid.insert(
            "thing.total:12|c",
            Metric::new("thing.total", 12.0, MetricKind::Counter(1.0))
        );
        valid.insert(
            "thing.total:5.6|c|@123",
            Metric::new("thing.total", 5.6, MetricKind::Counter(123.0))
        );

        for (input, expected) in valid.iter() {
            let result = Metric::from_str(*input);
            assert!(result.is_ok());

            let actual = result.ok().unwrap();
            assert_eq!(expected.name, actual.name);
            assert_eq!(expected.value, actual.value);

            // TODO this is stupid, there must be a better way.
            assert_eq!(
                format!("{:?}", expected.kind),
                format!("{:?}", actual.kind)
            );
        }
    }

    #[test]
    fn test_metric_invalid() {
        let invalid = vec![
            "",
            "metric",
            "metric|12",
            "metric:13|",
            "metric:14|c@1",
            ":|@",
            ":1.0|c"
        ];
        for input in invalid.iter() {
            let result = Metric::from_str(*input);
            assert!(result.is_err());
        }
    }
}
<commit_msg>Add notes on limitation.<commit_after>/// Internal metric representation
///
use std::fmt;
use std::str::FromStr;

/// Enum of metric types
pub enum MetricKind {
    Counter(f64), // sample rate
    Gauge,
    Timer,
}

impl fmt::Debug for MetricKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            MetricKind::Gauge      => write!(f, "Gauge"),
            MetricKind::Timer      => write!(f, "Timer"),
            MetricKind::Counter(s) => write!(f, "Counter(s={})", s)
        }
    }
}

/// Error types for parsing Metrics from strings.
///
#[derive(Debug)]
pub enum ParseError {
    // Error message, column
    SyntaxError(&'static str, usize)
}

/// Metric value objects.
///
#[derive(Debug)]
pub struct Metric {
    pub kind: MetricKind,
    pub name: String,
    pub value: f64
}

impl Metric {
    pub fn new(name: &str, value: f64, kind: MetricKind) -> Metric {
        Metric{name: name.to_string(), value: value, kind: kind}
    }
}

impl FromStr for Metric {
    type Err = ParseError;

    /// Valid message formats are:
    ///
    /// - `<str:metric_name>:<f64:value>|<str:type>`
    /// - `<str:metric_name>:<f64:value>|c|@<f64:sample_rate>`
    ///
    /// This does not yet support batch metrics. Right now each UDP packet
    /// can only contain a single metric.
    fn from_str(line: &str) -> Result<Metric, ParseError> {
        // Get the metric name
        let name_parts: Vec<&str> = line.trim_right_matches('\n')
            .split(':')
            .collect();
        if name_parts.len() < 2 || name_parts[0].is_empty() {
            return Err(ParseError::SyntaxError(
                    "Metrics require a name.",
                    0))
        }
        let name = name_parts[0].to_string();

        // Get the float val
        let val_parts: Vec<&str> = name_parts[1].split('|').collect();
        if val_parts.len() < 2 || val_parts[0].is_empty() {
            return Err(ParseError::SyntaxError(
                    "Metrics require a value.",
                    name.len()))
        }
        let value = val_parts[0].parse::<f64>().ok().unwrap();

        // Get kind parts
        let kind = match val_parts[1] {
            "ms" => MetricKind::Timer,
            "g" => MetricKind::Gauge,
            "c" => {
                let mut rate:f64 = 1.0;
                if val_parts.len() == 3 {
                    rate = val_parts[2].trim_left_matches('@')
                        .parse::<f64>().ok().unwrap();
                }
                MetricKind::Counter(rate)
            }
            _ => return Err(ParseError::SyntaxError(
                    "Unknown metric type.",
                    2))
        };

        Ok(Metric{name: name, value: value, kind: kind})
    }
}

//
// Tests
//
#[cfg(test)]
mod test {
    use metric::{Metric,MetricKind};
    use std::str::FromStr;
    use std::collections::HashMap;

    #[test]
    fn test_metric_kind_debug_fmt() {
        assert_eq!(
            "Gauge",
            format!("{:?}", MetricKind::Gauge)
        );
        assert_eq!(
            "Timer",
            format!("{:?}", MetricKind::Timer)
        );
        assert_eq!(
            "Counter(s=6)",
            format!("{:?}", MetricKind::Counter(6.0))
        );
    }

    #[test]
    fn test_metric_from_str_invalid_no_name() {
        let res = Metric::from_str("");
        assert!(res.is_err(), "Should have an error");
        assert!(!res.is_ok(), "Should have an error");
    }

    #[test]
    fn test_metric_from_str_invalid_no_value() {
        let res = Metric::from_str("foo:");
        assert!(res.is_err(), "Should have an error");
        assert!(!res.is_ok(), "Should have an error");
    }

    #[test]
    fn test_metric_valid() {
        let mut valid = HashMap::new();
        valid.insert(
            "foo.test:12.3|ms\n",
            Metric::new("foo.test", 12.3, MetricKind::Timer)
        );
        valid.insert(
            "foo.test:12.3|ms",
            Metric::new("foo.test", 12.3, MetricKind::Timer)
        );
        valid.insert(
            "test:18.123|g",
            Metric::new("test", 18.123, MetricKind::Gauge)
        );
        valid.insert(
            "test:18.123|g",
            Metric::new("test", 18.123, MetricKind::Gauge)
        );
        valid.insert(
            "thing.total:12|c",
            Metric::new("thing.total", 12.0, MetricKind::Counter(1.0))
        );
        valid.insert(
            "thing.total:5.6|c|@123",
            Metric::new("thing.total", 5.6, MetricKind::Counter(123.0))
        );

        for (input, expected) in valid.iter() {
            let result = Metric::from_str(*input);
            assert!(result.is_ok());

            let actual = result.ok().unwrap();
            assert_eq!(expected.name, actual.name);
            assert_eq!(expected.value, actual.value);

            // TODO this is stupid, there must be a better way.
            assert_eq!(
                format!("{:?}", expected.kind),
                format!("{:?}", actual.kind)
            );
        }
    }

    #[test]
    fn test_metric_invalid() {
        let invalid = vec![
            "",
            "metric",
            "metric|12",
            "metric:13|",
            "metric:14|c@1",
            ":|@",
            ":1.0|c"
        ];
        for input in invalid.iter() {
            let result = Metric::from_str(*input);
            assert!(result.is_err());
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::CString;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::io::{Error, ErrorKind};
use std::io::Result as IoResult;
use std::iter::{Iterator, IntoIterator};
use std::path::Path;
use std::process::Command;

use cbox::{CBox, CSemiBox};
use ffi::analysis::LLVMVerifierFailureAction;
use ffi::{analysis, core, linker, LLVMModule};
use ffi::bit_writer as writer;
use ffi::bit_reader as reader;
use ffi::ir_reader as ir_reader;
use ffi::prelude::{LLVMValueRef, LLVMModuleRef};
use ffi::transforms::pass_manager_builder as builder;
use libc::{c_char, c_uint};

use buffer::MemoryBuffer;
use context::{Context, GetContext};
use util;
use ty::Type;
use value::{Function, GlobalValue, Value};

/// Represents a single compilation unit of code.
///
/// This is attached to the lifetime of the context that constructs it, but is owned by the `CSemiBox`.
pub struct Module;
native_ref!(&Module = LLVMModuleRef);
impl Module
{
  /// Create a new module in the context given with the name given.
  ///
  /// The lifetime of the module will match the lifetime of the context
  /// you instance it in because the context contains it.
  ///
  /// ```rust
  /// use llvm::*;
  /// let context = Context::new();
  /// let context = context.as_semi();
  /// let module = Module::new("name", &context);
  /// println!("{:?}", module)
  /// ```
  pub fn new<'a>(name: &str, context: &'a Context) -> CSemiBox<'a, Module>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
    	CSemiBox::new(core::LLVMModuleCreateWithNameInContext(c_name.as_ptr(), context.into()))
    }
  }

  /// Add an external global to the module with the given type and name.
  pub fn add_global<'a>(&'a self, name: &str, ty: &'a Type) -> &'a GlobalValue {
    util::with_cstr(name, |ptr| unsafe {
        core::LLVMAddGlobal(self.into(), ty.into(), ptr).into()
    })
  }

  /// Add a global in the given address space to the module with the given type and name.
  pub fn add_global_in_addr_space<'a>(&'a self,
  	                                  name: &str,
  	                                  ty: &'a Type,
  	                                  sp: AddressSpace) -> &'a GlobalValue
  {
    util::with_cstr(name, |ptr| unsafe {
      core::LLVMAddGlobalInAddressSpace(self.into(), ty.into(), ptr, sp as c_uint).into()
    })
  }

  /// Add a constant global to the module with the given type, name and value.
  pub fn add_global_constant<'a>(&'a self, name: &str, val: &'a Value) -> &'a GlobalValue
  {
    util::with_cstr(name, |ptr| unsafe {
      let global = core::LLVMAddGlobal(self.into(), val.get_type().into(), ptr);
      core::LLVMSetInitializer (global.into(), val.into());
      global.into()
    })
  }
  /// Get the global with the name given, or `None` if no global with that name exists.
  pub fn get_global<'a>(&'a self, name: &str) -> Option<&'a GlobalValue>
  {
    util::with_cstr(name, |ptr| unsafe {
        let ptr = core::LLVMGetNamedGlobal(self.into(), ptr);
        util::ptr_to_null(ptr)
    })
  }

  pub fn parse_ir<'a>(context: &'a Context, path: &str) -> Result<CSemiBox<'a, Module>, CBox<str>>
  {
  	unsafe {
      let mut out = mem::uninitialized();
      let mut err = mem::uninitialized();
      let buf = try!(MemoryBuffer::new_from_file(path));

      let ret = ir_reader::LLVMParseIRInContext(context.into(), buf.as_ptr(), &mut out, &mut err);
      if ret == 1 {
      	Err(CBox::new(err))
      } else {
        Ok(CSemiBox::new(out))
      }
    }
  }

  /// Parse this bitcode file into a module, or return an error string.
  pub fn parse_bitcode<'a>(context: &'a Context, path: &str) -> Result<CSemiBox<'a, Module>, CBox<str>> {
    unsafe {
      let mut out = mem::uninitialized();
      let mut err = mem::uninitialized();
      let buf = try!(MemoryBuffer::new_from_file(path));

      let ret = reader::LLVMParseBitcodeInContext(context.into(),
      																					  buf.as_ptr(),
      	                                          &mut out,
      	                                          &mut err);
      if ret == 1 {
          Err(CBox::new(err))
      } else {
          Ok(CSemiBox::new(out))
      }
    }
  }
  /// Write this module's bitcode to the path given.
  pub fn write_bitcode(&self, path: &str) -> IoResult<()>
  {
     util::with_cstr(path, |cpath| unsafe {
       if writer::LLVMWriteBitcodeToFile(self.into(), cpath) != 0 {
           Err(Error::new(ErrorKind::Other, &format!("could not write to {}", path) as &str))
       } else {
           Ok(())
       }
     })
  }
  /// Add a function to the module with the name given.
  pub fn add_function<'a>(&'a self, name: &str, sig: &'a Type) -> &'a Function
  {
    let c_name = CString::new(name).unwrap();
    unsafe { core::LLVMAddFunction(self.into(), c_name.as_ptr(), sig.into()) }.into()
  }

  /// Returns the function with the name given, or `None` if no function with that name exists.
  pub fn get_function<'a>(&'a self, name: &str) -> Option<&'a Function>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
      let ty = core::LLVMGetNamedFunction(self.into(), c_name.as_ptr());
      util::ptr_to_null(ty)
    }
  }

  /// Returns the type with the name given, or `None`` if no type with that name exists.
  pub fn get_type<'a>(&'a self, name: &str) -> Option<&'a Type>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
      let ty = core::LLVMGetTypeByName(self.into(), c_name.as_ptr());
      util::ptr_to_null(ty)
    }
  }

  /// Clone this module.
  pub fn clone<'a>(&'a self) -> CSemiBox<'a, Module>
  {
    CSemiBox::new(unsafe { core::LLVMCloneModule(self.into()) })
  }

  /// Optimize this module with the given optimization level and size level.
  ///
  /// This runs passes depending on the levels given.
  pub fn optimize(&self, opt_level: usize, size_level: usize) {
    unsafe {
      let builder = builder::LLVMPassManagerBuilderCreate();
      builder::LLVMPassManagerBuilderSetOptLevel(builder, opt_level as c_uint);
      builder::LLVMPassManagerBuilderSetSizeLevel(builder, size_level as c_uint);
      let pass_manager = core::LLVMCreatePassManager();
      builder::LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);
      builder::LLVMPassManagerBuilderDispose(builder);
      core::LLVMRunPassManager(pass_manager, self.into());
    }
  }

  /// Returns the target data of this module represented as a string
  pub fn get_target(&self) -> &str
  {
    unsafe {
      let target = core::LLVMGetTarget(self.into());
      util::to_str(target as *mut c_char)
    }
  }

  pub fn get_data_layout(&self) -> &str
  {
  	unsafe {
  		let layout = core::LLVMGetDataLayout(self.into());
  		util::to_str(layout as *mut c_char)
  	}
  }

  /// Set the target data of this module to the target data string given.
  pub fn set_target(&self, target: &str)
  {
      let c_target = CString::new(target).unwrap();
      unsafe { core::LLVMSetTarget(self.into(), c_target.as_ptr()) }
  }

  /// Verify that the module is safe to run, returning a string detailing the error
  /// when an error occurs.
  pub fn verify(&self) -> Result<(), CBox<str>>
  {
    unsafe {
      let mut error = mem::uninitialized();
      let action = LLVMVerifierFailureAction::LLVMReturnStatusAction;
      if analysis::LLVMVerifyModule(self.into(), action, &mut error) == 1 {
          Err(CBox::new(error))
      } else {
          Ok(())
      }
    }
  }

  /// Compile the module into an object file at the given location.
  ///
  /// Note that this uses the LLVM tool `llc` to do this, which may or may not be
  /// installed on the user's machine.
  pub fn compile(&self, path: &Path, opt_level: usize) -> IoResult<()>
  {
    let dir = env::temp_dir();
    let path = path.to_str().unwrap();
    let mod_path = dir.join("module.bc");
    let mod_path = mod_path.to_str().unwrap();
    try!(self.write_bitcode(mod_path));
    Command::new("llc")
      .arg(&format!("-O={}", opt_level))
      .arg("-filetype=obj")
      .arg("-o").arg(path)
      .arg(mod_path)
      .spawn()
      .map(|_| ())
  }

  /// Link a module into this module, returning an error string if an error occurs.
  ///
  /// This *does not* destroy the source module.
  pub fn link(&self, src: &Module) -> Result<(), CBox<str>>
  {
    unsafe {
      let dest = self.into();
      let src = src.into();
      let mut message = mem::uninitialized();

      let ret = linker::LLVMLinkModules(dest, src,
      	                                linker::LLVMLinkerMode::LLVMLinkerPreserveSource,
      	                                &mut message);
      if ret == 1 {
        Err(CBox::new(message))
      } else {
        Ok(())
      }
    }
  }

  /// Link a module into this module, returning an error string if an error occurs.
  ///
  /// This *does* destroy the source module.
  pub fn link_destroy(&self, src: CSemiBox<Module>) -> Result<(), CBox<str>>
  {
    unsafe {
      let dest = self.into();
      let src = src.as_ptr();
      let mut message = mem::uninitialized();

      let ret = linker::LLVMLinkModules(dest, src,
      	                                linker::LLVMLinkerMode::LLVMLinkerDestroySource,
      	                                &mut message);
      if ret == 1 {
        Err(CBox::new(message))
      } else {
        Ok(())
      }
    }
  }
}

get_context!(Module, LLVMGetModuleContext);
impl_display!(Module, LLVMPrintModuleToString);
dispose!(Module, LLVMModule, core::LLVMDisposeModule);

impl<'a> IntoIterator for &'a Module
{
  type Item = &'a Function;
  type IntoIter = Functions<'a>;
  /// Iterate through the functions in the module
  fn into_iter(self) -> Functions<'a>
  {
    Functions {
      value: unsafe { core::LLVMGetFirstFunction(self.into()) },
      marker: PhantomData
    }
  }
}

#[derive(Copy, Clone)]
/// An iterator through the functions contained in a module.
pub struct Functions<'a>
{
  value: LLVMValueRef,
  marker: PhantomData<&'a ()>
}

impl<'a> Iterator for Functions<'a>
{
  type Item = &'a Function;

  fn next(&mut self) -> Option<&'a Function>
  {
    if self.value.is_null() {
      None
    } else {
      let c_next = unsafe { core::LLVMGetNextFunction(self.value) };
      self.value = c_next;
      Some(self.value.into())
    }
  }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub enum AddressSpace
{
  Generic = 0,
  Global = 1,
  Shared = 3,
  Const = 4,
  Local = 5,
}<commit_msg>Add Module::dump API.<commit_after>use std::env;
use std::ffi::CString;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::io::{Error, ErrorKind};
use std::io::Result as IoResult;
use std::iter::{Iterator, IntoIterator};
use std::path::Path;
use std::process::Command;

use cbox::{CBox, CSemiBox};
use ffi::analysis::LLVMVerifierFailureAction;
use ffi::{analysis, core, linker, LLVMModule};
use ffi::bit_writer as writer;
use ffi::bit_reader as reader;
use ffi::ir_reader as ir_reader;
use ffi::prelude::{LLVMValueRef, LLVMModuleRef};
use ffi::transforms::pass_manager_builder as builder;
use libc::{c_char, c_uint};

use buffer::MemoryBuffer;
use context::{Context, GetContext};
use util;
use ty::Type;
use value::{Function, GlobalValue, Value};

/// Represents a single compilation unit of code.
///
/// This is attached to the lifetime of the context that constructs it, but is owned by the `CSemiBox`.
pub struct Module;
native_ref!(&Module = LLVMModuleRef);
impl Module
{
  /// Create a new module in the context given with the name given.
  ///
  /// The lifetime of the module will match the lifetime of the context
  /// you instance it in because the context contains it.
  ///
  /// ```rust
  /// use llvm::*;
  /// let context = Context::new();
  /// let context = context.as_semi();
  /// let module = Module::new("name", &context);
  /// println!("{:?}", module)
  /// ```
  pub fn new<'a>(name: &str, context: &'a Context) -> CSemiBox<'a, Module>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
    	CSemiBox::new(core::LLVMModuleCreateWithNameInContext(c_name.as_ptr(), context.into()))
    }
  }

  /// Add an external global to the module with the given type and name.
  pub fn add_global<'a>(&'a self, name: &str, ty: &'a Type) -> &'a GlobalValue {
    util::with_cstr(name, |ptr| unsafe {
        core::LLVMAddGlobal(self.into(), ty.into(), ptr).into()
    })
  }

  /// Add a global in the given address space to the module with the given type and name.
  pub fn add_global_in_addr_space<'a>(&'a self,
  	                                  name: &str,
  	                                  ty: &'a Type,
  	                                  sp: AddressSpace) -> &'a GlobalValue
  {
    util::with_cstr(name, |ptr| unsafe {
      core::LLVMAddGlobalInAddressSpace(self.into(), ty.into(), ptr, sp as c_uint).into()
    })
  }

  /// Add a constant global to the module with the given type, name and value.
  pub fn add_global_constant<'a>(&'a self, name: &str, val: &'a Value) -> &'a GlobalValue
  {
    util::with_cstr(name, |ptr| unsafe {
      let global = core::LLVMAddGlobal(self.into(), val.get_type().into(), ptr);
      core::LLVMSetInitializer (global.into(), val.into());
      global.into()
    })
  }
  /// Get the global with the name given, or `None` if no global with that name exists.
  pub fn get_global<'a>(&'a self, name: &str) -> Option<&'a GlobalValue>
  {
    util::with_cstr(name, |ptr| unsafe {
        let ptr = core::LLVMGetNamedGlobal(self.into(), ptr);
        util::ptr_to_null(ptr)
    })
  }

  pub fn parse_ir<'a>(context: &'a Context, path: &str) -> Result<CSemiBox<'a, Module>, CBox<str>>
  {
  	unsafe {
      let mut out = mem::uninitialized();
      let mut err = mem::uninitialized();
      let buf = try!(MemoryBuffer::new_from_file(path));

      let ret = ir_reader::LLVMParseIRInContext(context.into(), buf.as_ptr(), &mut out, &mut err);
      if ret == 1 {
      	Err(CBox::new(err))
      } else {
        Ok(CSemiBox::new(out))
      }
    }
  }

  /// Parse this bitcode file into a module, or return an error string.
  pub fn parse_bitcode<'a>(context: &'a Context, path: &str) -> Result<CSemiBox<'a, Module>, CBox<str>> {
    unsafe {
      let mut out = mem::uninitialized();
      let mut err = mem::uninitialized();
      let buf = try!(MemoryBuffer::new_from_file(path));

      let ret = reader::LLVMParseBitcodeInContext(context.into(),
      																					  buf.as_ptr(),
      	                                          &mut out,
      	                                          &mut err);
      if ret == 1 {
          Err(CBox::new(err))
      } else {
          Ok(CSemiBox::new(out))
      }
    }
  }
  /// Write this module's bitcode to the path given.
  pub fn write_bitcode(&self, path: &str) -> IoResult<()>
  {
     util::with_cstr(path, |cpath| unsafe {
       if writer::LLVMWriteBitcodeToFile(self.into(), cpath) != 0 {
           Err(Error::new(ErrorKind::Other, &format!("could not write to {}", path) as &str))
       } else {
           Ok(())
       }
     })
  }
  /// Add a function to the module with the name given.
  pub fn add_function<'a>(&'a self, name: &str, sig: &'a Type) -> &'a Function
  {
    let c_name = CString::new(name).unwrap();
    unsafe { core::LLVMAddFunction(self.into(), c_name.as_ptr(), sig.into()) }.into()
  }

  /// Returns the function with the name given, or `None` if no function with that name exists.
  pub fn get_function<'a>(&'a self, name: &str) -> Option<&'a Function>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
      let ty = core::LLVMGetNamedFunction(self.into(), c_name.as_ptr());
      util::ptr_to_null(ty)
    }
  }

  /// Returns the type with the name given, or `None`` if no type with that name exists.
  pub fn get_type<'a>(&'a self, name: &str) -> Option<&'a Type>
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
      let ty = core::LLVMGetTypeByName(self.into(), c_name.as_ptr());
      util::ptr_to_null(ty)
    }
  }

  /// Clone this module.
  pub fn clone<'a>(&'a self) -> CSemiBox<'a, Module>
  {
    CSemiBox::new(unsafe { core::LLVMCloneModule(self.into()) })
  }

  /// Optimize this module with the given optimization level and size level.
  ///
  /// This runs passes depending on the levels given.
  pub fn optimize(&self, opt_level: usize, size_level: usize) {
    unsafe {
      let builder = builder::LLVMPassManagerBuilderCreate();
      builder::LLVMPassManagerBuilderSetOptLevel(builder, opt_level as c_uint);
      builder::LLVMPassManagerBuilderSetSizeLevel(builder, size_level as c_uint);
      let pass_manager = core::LLVMCreatePassManager();
      builder::LLVMPassManagerBuilderPopulateModulePassManager(builder, pass_manager);
      builder::LLVMPassManagerBuilderDispose(builder);
      core::LLVMRunPassManager(pass_manager, self.into());
    }
  }

  /// Returns the target data of this module represented as a string
  pub fn get_target(&self) -> &str
  {
    unsafe {
      let target = core::LLVMGetTarget(self.into());
      util::to_str(target as *mut c_char)
    }
  }

  pub fn get_data_layout(&self) -> &str
  {
  	unsafe {
  		let layout = core::LLVMGetDataLayout(self.into());
  		util::to_str(layout as *mut c_char)
  	}
  }

  /// Set the target data of this module to the target data string given.
  pub fn set_target(&self, target: &str)
  {
      let c_target = CString::new(target).unwrap();
      unsafe { core::LLVMSetTarget(self.into(), c_target.as_ptr()) }
  }

  /// Verify that the module is safe to run, returning a string detailing the error
  /// when an error occurs.
  pub fn verify(&self) -> Result<(), CBox<str>>
  {
    unsafe {
      let mut error = mem::uninitialized();
      let action = LLVMVerifierFailureAction::LLVMReturnStatusAction;
      if analysis::LLVMVerifyModule(self.into(), action, &mut error) == 1 {
          Err(CBox::new(error))
      } else {
          Ok(())
      }
    }
  }

  /// Compile the module into an object file at the given location.
  ///
  /// Note that this uses the LLVM tool `llc` to do this, which may or may not be
  /// installed on the user's machine.
  pub fn compile(&self, path: &Path, opt_level: usize) -> IoResult<()>
  {
    let dir = env::temp_dir();
    let path = path.to_str().unwrap();
    let mod_path = dir.join("module.bc");
    let mod_path = mod_path.to_str().unwrap();
    try!(self.write_bitcode(mod_path));
    Command::new("llc")
      .arg(&format!("-O={}", opt_level))
      .arg("-filetype=obj")
      .arg("-o").arg(path)
      .arg(mod_path)
      .spawn()
      .map(|_| ())
  }

  /// Link a module into this module, returning an error string if an error occurs.
  ///
  /// This *does not* destroy the source module.
  pub fn link(&self, src: &Module) -> Result<(), CBox<str>>
  {
    unsafe {
      let dest = self.into();
      let src = src.into();
      let mut message = mem::uninitialized();

      let ret = linker::LLVMLinkModules(dest, src,
      	                                linker::LLVMLinkerMode::LLVMLinkerPreserveSource,
      	                                &mut message);
      if ret == 1 {
        Err(CBox::new(message))
      } else {
        Ok(())
      }
    }
  }

  /// Link a module into this module, returning an error string if an error occurs.
  ///
  /// This *does* destroy the source module.
  pub fn link_destroy(&self, src: CSemiBox<Module>) -> Result<(), CBox<str>>
  {
    unsafe {
      let dest = self.into();
      let src = src.as_ptr();
      let mut message = mem::uninitialized();

      let ret = linker::LLVMLinkModules(dest, src,
      	                                linker::LLVMLinkerMode::LLVMLinkerDestroySource,
      	                                &mut message);
      if ret == 1 {
        Err(CBox::new(message))
      } else {
        Ok(())
      }
    }
  }

  /// Dump the module to stderr (for debugging).
  pub fn dump(&self)
  {
  	unsafe { core::LLVMDumpModule(self.into()); }
  }
}

get_context!(Module, LLVMGetModuleContext);
impl_display!(Module, LLVMPrintModuleToString);
dispose!(Module, LLVMModule, core::LLVMDisposeModule);

impl<'a> IntoIterator for &'a Module
{
  type Item = &'a Function;
  type IntoIter = Functions<'a>;
  /// Iterate through the functions in the module
  fn into_iter(self) -> Functions<'a>
  {
    Functions {
      value: unsafe { core::LLVMGetFirstFunction(self.into()) },
      marker: PhantomData
    }
  }
}

#[derive(Copy, Clone)]
/// An iterator through the functions contained in a module.
pub struct Functions<'a>
{
  value: LLVMValueRef,
  marker: PhantomData<&'a ()>
}

impl<'a> Iterator for Functions<'a>
{
  type Item = &'a Function;

  fn next(&mut self) -> Option<&'a Function>
  {
    if self.value.is_null() {
      None
    } else {
      let c_next = unsafe { core::LLVMGetNextFunction(self.value) };
      self.value = c_next;
      Some(self.value.into())
    }
  }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub enum AddressSpace
{
  Generic = 0,
  Global = 1,
  Shared = 3,
  Const = 4,
  Local = 5,
}<|endoftext|>


<commit_before>use std::slice;

use std::marker;

pub trait ModuleStruct<'a> {
	fn init_module(&mut self);
}

struct TorchBackend {}
struct Parameter {}

pub struct Module<'a> {
	pub _name: &'a str,
	_backend : TorchBackend,
//	_buffers: HashTable<&str, Tensor>
//	_backward_hooks:
//	_forward_hooks:
	_params: Vec<&'a str>,
    _modulesp: Vec<*mut Module<'a>>,
	training: bool,
}
pub struct ModuleIterMut<'a, T: 'a> {
	mod_iter: slice::IterMut<'a, *mut T>,
//	 _marker: marker::PhantomData<&'module Module<'module>>,
}

impl <'a>Iterator for ModuleIterMut<'a, Module<'a>> {
	type Item = &'a mut Module<'a>;
	fn next(&mut self) -> Option<Self::Item> {
		if let Some(t) = self.mod_iter.next() {
			Some(unsafe { &mut **t as Self::Item })
		} else {
			None
		}
	}
}

impl <'a>Module<'a> {
	pub fn new() -> Module<'a> {
		Module {_name: "", _backend: TorchBackend {}, _params: Vec::new(),
		_modulesp: Vec::new(), training: true }
	}
	#[inline]
    fn as_mut_ptr(&mut self) -> *mut Module<'a> {
        self as *mut Module<'a>
    }
    pub fn add_module(&mut self, module: &mut ModIntf<'a>) {
    	self._modulesp.push(module.delegate().as_mut_ptr())

    }
	pub fn modules_iter_mut(&mut self) -> ModuleIterMut<Module<'a> > {
		ModuleIterMut {mod_iter: self._modulesp.iter_mut()}  //_marker: marker::PhantomData } }
	}
}

pub trait ModIntf<'a> {
	fn delegate(&mut self) -> &mut Module<'a>;
	fn forward(&mut self /* Tensor */ ) /* -> Tensor */;
}

#[derive(ModParse)]
pub struct Linear<'a> {
	delegate: Module<'a> ,
	in_features: u32,
}

impl <'a>Linear<'a> {
	pub fn new(/* args: LinearArgs */) -> Linear<'a> {
		let mut t = Linear {delegate: Module::new(), in_features: 0 };
		t.init_module();
		t
	}
}

impl <'a> ModIntf<'a> for Linear<'a>  {
	fn delegate(&mut self) -> &mut Module<'a> {
		&mut self.delegate
	}
	fn forward(&mut self/* Tensor */) /* -> Tensor */ {

	}
}

<commit_msg>rename ModulesIterMut to PtrIterMut<commit_after>use std::slice;

use std::marker;

pub trait ModuleStruct<'a> {
	fn init_module(&mut self);
}

struct TorchBackend {}
struct Parameter {}

pub struct Module<'a> {
	pub _name: &'a str,
	_backend : TorchBackend,
//	_buffers: HashTable<&str, Tensor>
//	_backward_hooks:
//	_forward_hooks:
	_params: Vec<&'a str>,
    _modulesp: Vec<*mut Module<'a>>,
	training: bool,
}
pub struct PtrIterMut<'a, T: 'a> {
	mod_iter: slice::IterMut<'a, *mut T>,
}

impl <'a>Iterator for PtrIterMut<'a, Module<'a>> {
	type Item = &'a mut Module<'a>;
	fn next(&mut self) -> Option<Self::Item> {
		if let Some(t) = self.mod_iter.next() {
			Some(unsafe { &mut **t as Self::Item })
		} else {
			None
		}
	}
}

impl <'a>Module<'a> {
	pub fn new() -> Module<'a> {
		Module {_name: "", _backend: TorchBackend {}, _params: Vec::new(),
		_modulesp: Vec::new(), training: true }
	}
	#[inline]
    fn as_mut_ptr(&mut self) -> *mut Module<'a> {
        self as *mut Module<'a>
    }
    pub fn add_module(&mut self, module: &mut ModIntf<'a>) {
    	self._modulesp.push(module.delegate().as_mut_ptr())

    }
	pub fn modules_iter_mut(&mut self) -> PtrIterMut<Module<'a> > {
		PtrIterMut {mod_iter: self._modulesp.iter_mut()}  //_marker: marker::PhantomData } }
	}
}

pub trait ModIntf<'a> {
	fn delegate(&mut self) -> &mut Module<'a>;
	fn forward(&mut self /* Tensor */ ) /* -> Tensor */;
}

#[derive(ModParse)]
pub struct Linear<'a> {
	delegate: Module<'a> ,
	in_features: u32,
}

impl <'a>Linear<'a> {
	pub fn new(/* args: LinearArgs */) -> Linear<'a> {
		let mut t = Linear {delegate: Module::new(), in_features: 0 };
		t.init_module();
		t
	}
}

impl <'a> ModIntf<'a> for Linear<'a>  {
	fn delegate(&mut self) -> &mut Module<'a> {
		&mut self.delegate
	}
	fn forward(&mut self/* Tensor */) /* -> Tensor */ {

	}
}

<|endoftext|>


<commit_before>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
extern crate std;
use core::prelude::*;
use self::std::io::Error as IoError;
use stack;
mod sys;

pub struct StackSource;

unsafe impl Send for StackSource {}
unsafe impl Sync for StackSource {}

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Stack {
  ptr: *mut u8,
  len: usize
}

unsafe impl Send for Stack {}

impl stack::StackSource for StackSource {
  type Output = Stack;
  type Error = IoError;

  fn get_stack(size: usize) -> Result<Stack, IoError> {
    let page_size = sys::page_size();

    // round the page size up,
    // using the fact that it is a power of two
    let len = (size + page_size - 1) & !(page_size - 1);

    let stack = unsafe {
      let ptr = try!(match sys::map_stack(size) {
        None => Err(IoError::last_os_error()),
        Some(ptr) => Ok(ptr)
      });

      Stack { ptr: ptr as *mut u8, len: len }
    };

    try!(unsafe {
      if sys::protect_stack(stack.ptr) { Ok(()) }
      else { Err(IoError::last_os_error()) }
    });

    Ok(stack)
  }
}

impl stack::Stack for Stack {
  fn top(&mut self) -> *mut u8 {
    unsafe {
      self.ptr.offset(self.len as isize)
    }
  }

  fn limit(&self) -> *const u8 {
    unsafe {
      self.ptr.offset(sys::page_size() as isize)
    }
  }
}

impl Drop for Stack {
  fn drop(&mut self) {
    unsafe {
      if !sys::unmap_stack(self.ptr, self.len) {
        panic!("munmap for stack {:p} of size {} failed: {}",
               self.ptr, self.len, IoError::last_os_error())
      }
    }
  }
}
<commit_msg>document os<commit_after>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
//! This module provides stacks using the operating system's
//! anonymous memory mapping facility, usually `mmap`.
//! The stacks it provides come with a guard page, which is not included
//! in the stack limit.

extern crate std;
use core::prelude::*;
use self::std::io::Error as IoError;
use stack;
mod sys;

pub struct StackSource;

unsafe impl Send for StackSource {}
unsafe impl Sync for StackSource {}

#[allow(raw_pointer_derive)]
#[derive(Debug)]
pub struct Stack {
  ptr: *mut u8,
  len: usize
}

unsafe impl Send for Stack {}

impl stack::StackSource for StackSource {
  type Output = Stack;
  type Error = IoError;

  fn get_stack(size: usize) -> Result<Stack, IoError> {
    let page_size = sys::page_size();

    // round the page size up,
    // using the fact that it is a power of two
    let len = (size + page_size - 1) & !(page_size - 1);

    let stack = unsafe {
      let ptr = try!(match sys::map_stack(size) {
        None => Err(IoError::last_os_error()),
        Some(ptr) => Ok(ptr)
      });

      Stack { ptr: ptr as *mut u8, len: len }
    };

    try!(unsafe {
      if sys::protect_stack(stack.ptr) { Ok(()) }
      else { Err(IoError::last_os_error()) }
    });

    Ok(stack)
  }
}

impl stack::Stack for Stack {
  fn top(&mut self) -> *mut u8 {
    unsafe {
      self.ptr.offset(self.len as isize)
    }
  }

  fn limit(&self) -> *const u8 {
    unsafe {
      self.ptr.offset(sys::page_size() as isize)
    }
  }
}

impl Drop for Stack {
  fn drop(&mut self) {
    unsafe {
      if !sys::unmap_stack(self.ptr, self.len) {
        panic!("munmap for stack {:p} of size {} failed: {}",
               self.ptr, self.len, IoError::last_os_error())
      }
    }
  }
}
<|endoftext|>