1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use libc::c_int;
use weechat::{ArgsWeechat, Weechat};

extern crate weechat_sys;

#[macro_export]
macro_rules! weechat_plugin(
    ($plugin:ty, $($name:ident: $value:expr; $length:expr),+) => {
        static mut __PLUGIN: Option<$plugin> = None;
        #[no_mangle]
        pub static mut weechat_plugin_api_version: [u8; weechat_sys::WEECHAT_PLUGIN_API_VERSION_LENGTH]
            = *weechat_sys::WEECHAT_PLUGIN_API_VERSION;

        #[no_mangle]
        pub extern "C" fn weechat_plugin_init(plugin: *mut weechat_sys::t_weechat_plugin,
                                              argc: libc::c_int, argv: *mut *mut ::libc::c_char) -> libc::c_int {
            let plugin = Weechat::from_ptr(plugin);
            let args = ArgsWeechat::new(argc, argv);
            match <$plugin as $crate::WeechatPlugin>::init(plugin, args) {
                Ok(p) => {
                    unsafe {
                        __PLUGIN = Some(p)
                    }
                    return weechat_sys::WEECHAT_RC_OK;
                }
                Err(_e) => {
                    return weechat_sys::WEECHAT_RC_ERROR;
                }
            }
        }
        #[no_mangle]
        pub extern "C" fn weechat_plugin_end(_plugin: *mut weechat_sys::t_weechat_plugin) -> ::libc::c_int {
            unsafe {
                // Invokes drop() on __PLUGIN, which should be used for cleanup.
                __PLUGIN = None;
            }

            weechat_sys::WEECHAT_RC_OK
        }
        $(
            weechat_plugin!(@attribute $name, $value, $length);
        )*

    };

    (@attribute $name:ident, $value:expr, $length:expr) => {
        weechat_plugin_info!($name, $value, $length);
    };
);

pub trait WeechatPlugin: Sized {
    fn init(weechat: Weechat, args: ArgsWeechat) -> WeechatResult<Self>;
}

pub struct Error(c_int);
pub type WeechatResult<T> = Result<T, Error>;

#[macro_export]
macro_rules! weechat_plugin_name(
    ($name:expr, $length:expr) => {
        #[allow(non_upper_case_globals)]
        #[no_mangle]
        pub static weechat_plugin_name: [u8; $length] = *$name;
    }
);

#[macro_export]
macro_rules! weechat_plugin_author(
    ($author:expr, $length:expr) => {
        #[allow(non_upper_case_globals)]
        #[no_mangle]
        pub static mut weechat_plugin_author: [u8; $length] = *$author;
    }
);

#[macro_export]
macro_rules! weechat_plugin_description(
    ($description:expr, $length:expr) => {
        #[allow(non_upper_case_globals)]
        #[no_mangle]
        pub static mut weechat_plugin_description: [u8; $length] = *$description;
    }
);

#[macro_export]
macro_rules! weechat_plugin_version(
    ($version:expr, $length:expr) => {
        #[allow(non_upper_case_globals)]
        #[no_mangle]
        pub static mut weechat_plugin_version: [u8; $length] = *$version;
    }
);

#[macro_export]
macro_rules! weechat_plugin_license(
    ($license:expr, $length:expr) => {
        #[allow(non_upper_case_globals)]
        #[no_mangle]
        pub static mut weechat_plugin_license: [u8; $length] = *$license;
    }
);

#[macro_export]
macro_rules! weechat_plugin_info(
    (name, $name:expr, $length:expr) => {
        weechat_plugin_name!($name, $length);
    };
    (author, $author:expr, $length:expr) => {
        weechat_plugin_author!($author, $length);
    };
    (description, $description:expr, $length:expr) => {
        weechat_plugin_description!($description, $length);
    };
    (version, $version:expr, $length:expr) => {
        weechat_plugin_version!($version, $length);
    };
    (license, $license:expr, $length:expr) => {
        weechat_plugin_license!($license, $length);
    };
);