diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-04-26 22:55:06 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-04-26 22:55:06 -0300 |
commit | cd895073b6f44239ba65147783e0d305b1d49a64 (patch) | |
tree | 70d39f5e8bcb64460c694a19e5197848a93397b2 | |
parent | b5b6d25d6ad1473128697e3c3bf09b441a65c359 (diff) |
Increase mocking
-rw-r--r-- | src/internals.rs | 2 | ||||
-rw-r--r-- | src/mock/mod.rs | 148 |
2 files changed, 134 insertions, 16 deletions
diff --git a/src/internals.rs b/src/internals.rs index dc93aaa..d1b714f 100644 --- a/src/internals.rs +++ b/src/internals.rs @@ -83,7 +83,7 @@ pub struct Ph { fd: libc::c_int, flags: libc::c_int, /* CALLBACK */ - callback: Option<unsafe extern "C" fn(fd: libc::c_int, flags: libc::c_int, user_data: *mut libc::c_void) -> libc::c_int>, + callback: unsafe extern "C" fn(fd: libc::c_int, flags: libc::c_int, user_data: *mut libc::c_void) -> libc::c_int, userdata: *mut libc::c_void) -> *const HexchatHook, pub hexchat_unhook: unsafe extern "C" fn(ph: *mut HexchatPlugin, hook: *const HexchatHook) -> *const libc::c_void, diff --git a/src/mock/mod.rs b/src/mock/mod.rs index 4edb907..f4193e0 100644 --- a/src/mock/mod.rs +++ b/src/mock/mod.rs @@ -1,20 +1,112 @@ +// This file is part of Hexchat Plugin API Bindings for Rust +// Copyright (C) 2022 Soni L. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +// +// Based on hexchat's plugin.c +// +/* X-Chat + * Copyright (C) 2002 Peter Zelezny. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + //! Internal mock test framework. //! //! This API is not stable. Do not rely on this API to be stable. +use std::cell::RefCell; +use std::ffi::CStr; +use std::ffi::CString; +use std::marker::PhantomData; +use std::pin::Pin; +use std::ptr; + +use libc::c_char; + #[repr(C)] pub struct MockPlugin { // NOTE: MUST be first thing in the struct. methods: crate::internals::Ph, + filename: *const c_char, + plugin_name: *const c_char, + plugin_desc: *const c_char, + plugin_vers: *const c_char, + free_strings: bool, } -unsafe extern "C" fn hexchat_hook_command(ph: *mut crate::internals::HexchatPlugin, - name: *const libc::c_char, - pri: libc::c_int, - /* CALLBACK */ - callback: unsafe extern "C" fn(word: *const *const libc::c_char, word_eol: *const *const libc::c_char, user_data: *mut libc::c_void) -> libc::c_int, - help_text: *const libc::c_char, - userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook { +enum MockCallback { + HookCommand { + help: Option<Box<str>>, + f: unsafe extern "C" fn(word: *const *const libc::c_char, word_eol: *const *const libc::c_char, user_data: *mut libc::c_void) -> libc::c_int, + }, + HookServer { + f: unsafe extern "C" fn(word: *const *const libc::c_char, word_eol: *const *const libc::c_char, user_data: *mut libc::c_void) -> libc::c_int, + }, + HookServerAttrs { + f: unsafe extern "C" fn(word: *const *const libc::c_char, word_eol: *const *const libc::c_char, attrs: *const crate::internals::HexchatEventAttrs, user_data: *mut libc::c_void) -> libc::c_int, + }, + HookPrint { + f: unsafe extern "C" fn(word: *const *const libc::c_char, user_data: *mut libc::c_void) -> libc::c_int, + }, + HookPrintAttrs { + f: unsafe extern "C" fn(word: *const *const libc::c_char, attrs: *const crate::internals::HexchatEventAttrs, user_data: *mut libc::c_void) -> libc::c_int + }, + HookTimer { + tag: libc::c_int, + f: unsafe extern "C" fn(user_data: *mut libc::c_void) -> libc::c_int, + }, + HookFd { + tag: libc::c_int, + f: unsafe extern "C" fn(fd: libc::c_int, flags: libc::c_int, user_data: *mut libc::c_void) -> libc::c_int + }, + HookDeleted, +} + +// This MockHook is deliberately incompatible with hexchat's own hook struct. +struct MockHook { + pl: *mut MockPlugin, + cb: RefCell<MockCallback>, + name: Option<Box<str>>, + pri_or_fd: libc::c_int, +} + +struct PluginEnvironment { +} + +unsafe extern "C" fn hexchat_hook_command( + ph: *mut crate::internals::HexchatPlugin, + name: *const libc::c_char, + pri: libc::c_int, + /* CALLBACK */ + callback: unsafe extern "C" fn(word: *const *const libc::c_char, word_eol: *const *const libc::c_char, user_data: *mut libc::c_void) -> libc::c_int, + help_text: *const libc::c_char, + userdata: *mut libc::c_void +) -> *const crate::internals::HexchatHook { + let ph = ph as *mut MockPlugin; todo!(); } unsafe extern "C" fn hexchat_hook_server(ph: *mut crate::internals::HexchatPlugin, @@ -44,7 +136,7 @@ unsafe extern "C" fn hexchat_hook_fd(ph: *mut crate::internals::HexchatPlugin, fd: libc::c_int, flags: libc::c_int, /* CALLBACK */ - callback: Option<unsafe extern "C" fn(fd: libc::c_int, flags: libc::c_int, user_data: *mut libc::c_void) -> libc::c_int>, + callback: unsafe extern "C" fn(fd: libc::c_int, flags: libc::c_int, user_data: *mut libc::c_void) -> libc::c_int, userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook { todo!(); } @@ -56,7 +148,7 @@ unsafe extern "C" fn hexchat_print(ph: *mut crate::internals::HexchatPlugin, text: *const libc::c_char) { todo!(); } -pub unsafe extern "C" fn hexchat_printf_do_not_use(ph: *mut crate::internals::HexchatPlugin, +pub unsafe extern "C" fn hexchat_printf(ph: *mut crate::internals::HexchatPlugin, format: *const libc::c_char, ...) { unimplemented!(); } @@ -64,7 +156,7 @@ unsafe extern "C" fn hexchat_command(ph: *mut crate::internals::HexchatPlugin, command: *const libc::c_char) { todo!(); } -unsafe extern "C" fn hexchat_commandf_do_not_use(ph: *mut crate::internals::HexchatPlugin, +unsafe extern "C" fn hexchat_commandf(ph: *mut crate::internals::HexchatPlugin, format: *const libc::c_char, ...) { unimplemented!(); } @@ -226,8 +318,12 @@ unsafe extern "C" fn hexchat_event_attrs_free(ph: *mut crate::internals::Hexchat } impl MockPlugin { - fn new() -> MockPlugin { - MockPlugin { + pub fn new<T: for<'ph> crate::Plugin<'ph> + Default>( + filename: CString, + arg: Option<&CStr>, + ) -> Option<Pin<Box<MockPlugin>>> { + let filename = filename.into_raw(); + let mut plug = Box::pin(MockPlugin { methods: crate::internals::Ph { hexchat_hook_command, hexchat_hook_server, @@ -236,9 +332,9 @@ impl MockPlugin { hexchat_hook_fd, hexchat_unhook, hexchat_print, - userdata: std::ptr::null_mut(), + userdata: hexchat_printf as *mut libc::c_void, hexchat_command, - hexchat_commandf_do_not_use, + hexchat_commandf_do_not_use: hexchat_commandf, hexchat_nickcmp, hexchat_set_context, hexchat_find_context, @@ -271,7 +367,29 @@ impl MockPlugin { hexchat_emit_print_attrs, hexchat_event_attrs_create, hexchat_event_attrs_free, - } + }, + filename: filename, + plugin_name: filename, + plugin_desc: ptr::null(), + plugin_vers: ptr::null(), + free_strings: false, + }); + if unsafe { + let ptr: *mut MockPlugin = &mut *plug; + crate::hexchat_plugin_init::<'_, T>( + crate::LtPhPtr { + ph: ptr as *mut crate::internals::Ph, + _lt: PhantomData, + }, + ptr::addr_of_mut!((*ptr).plugin_name), + ptr::addr_of_mut!((*ptr).plugin_desc), + ptr::addr_of_mut!((*ptr).plugin_vers), + arg.map(|arg| arg.as_ptr()).unwrap_or(ptr::null()), + ) != 0 + } { + Some(plug) + } else { + None } } } |