summary refs log blame commit diff stats
path: root/src/mock/mod.rs
blob: 92de66c057e3af6f84e4f637ea068bd31e0bb908 (plain) (tree)



































                                                                            



                                                                 
                    



                             
                               

                  
                


                 




                                                 
          
                                    

                                               
                            


                                     
                       
                                                  
                        

 



























                                                                                                                                                                                                        


                                                              


                              
                                
                        

 



















                                                                                        

 

                                                                                               









                                                                                                                                                        




























                                                                                                                                                            
                                                                                                                         










                                                                              
                                                                                 






                                                                              
                                                                               































































































































































                                                                                                                                                                                                               


                                                          

                                        
                                            
                                      


         
















































































                                                                     
// 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::Cell;
use std::cell::RefCell;
use std::ffi::CStr;
use std::ffi::CString;
use std::marker::PhantomData;
use std::marker::PhantomPinned;
use std::pin::Pin;
use std::ptr;
use std::rc::Rc;

use libc::c_char;

use ::ltptr::*;

use ::selfref::{Holder, Opaque, SelfRef, opaque};

// MUST be repr(C)
#[repr(C)]
struct MockPlugin<'dangling, 'env> {
    // NOTE: MUST be first thing in the struct.
    methods: crate::internals::Ph,
    filename: *const c_char,
    plugin_name: Cell<*const c_char>,
    plugin_desc: Cell<*const c_char>,
    plugin_vers: Cell<*const c_char>,
    free_strings: bool,
    env: &'env PluginEnvironment<'dangling, 'env>,
    _pin: PhantomPinned,
}

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,
}

struct MockHook<'dangling, 'env> {
    //pl: Rc<Holder<'dangling, MockPluginK<'dangling, 'env>>>,
    pl: Rc<MockPlugin<'dangling, 'env>>,
    cb: RefCell<MockCallback>,
    name: Option<Box<str>>,
    pri_or_fd: libc::c_int,
    userdata: *mut libc::c_void,
    _pin: PhantomPinned,
}

pub struct PluginEnvironment<'dangling, 'env> {
    //plugins: RefCell<Vec<Pin<Rc<Holder<'dangling, MockPluginK<'dangling, 'env>>>>>>,
    plugins: RefCell<Vec<Pin<Rc<MockPlugin<'dangling, 'env>>>>>,
    // priority-based hooks
    //hooks: RefCell<Vec<Pin<Rc<Holder<'dangling, MockHookK<'dangling, 'env>>>>>>,
    hooks: RefCell<Vec<Pin<Rc<MockHook<'dangling, 'env>>>>>,
    // fd/timer hooks
    //extra_hooks: RefCell<Vec<Pin<Rc<Holder<'dangling, MockHookK<'dangling, 'env>>>>>>,
    extra_hooks: RefCell<Vec<Pin<Rc<MockHook<'dangling, 'env>>>>>,
    depth: Cell<usize>,
}
impl<'dangling, 'env> SelfRef<'env> for PluginEnvironment<'dangling, 'env> {}

pub struct PluginEnvironmentK<'dangling> {
    _p: PhantomData<&'dangling ()>,
}
opaque! {
    impl['dangling] Opaque for PluginEnvironmentK<'dangling> {
        type Kind<'env> = PluginEnvironment<'dangling, 'env>;
    }
}

pub type GlobalPluginEnvironment<'dangling> = Holder<'dangling, PluginEnvironmentK<'dangling>>;

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,
        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,
        userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook {
    todo!();
}
unsafe extern "C" fn hexchat_hook_print(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, user_data: *mut libc::c_void) -> libc::c_int,
        userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook {
    todo!();
}
unsafe extern "C" fn hexchat_hook_timer(ph: *mut crate::internals::HexchatPlugin,
        timeout: libc::c_int,
        /* CALLBACK */
        callback: unsafe extern "C" fn(user_data: *mut libc::c_void) -> libc::c_int,
        userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook {
    todo!();
}
unsafe extern "C" fn hexchat_hook_fd(ph: *mut crate::internals::HexchatPlugin,
        fd: libc::c_int,
        flags: libc::c_int,
        /* CALLBACK */
        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!();
}
unsafe extern "C" fn hexchat_unhook(ph: *mut crate::internals::HexchatPlugin,
        hook: *const crate::internals::HexchatHook) -> *const libc::c_void {
    todo!();
}
unsafe extern "C" fn hexchat_print(ph: *mut crate::internals::HexchatPlugin,
        text: *const libc::c_char) {
    todo!();
}
pub unsafe extern "C" fn hexchat_printf(ph: *mut crate::internals::HexchatPlugin,
        format: *const libc::c_char, ...) {
    unimplemented!();
}
unsafe extern "C" fn hexchat_command(ph: *mut crate::internals::HexchatPlugin,
        command: *const libc::c_char) {
    todo!();
}
unsafe extern "C" fn hexchat_commandf(ph: *mut crate::internals::HexchatPlugin,
        format: *const libc::c_char, ...) {
    unimplemented!();
}
unsafe extern "C" fn hexchat_nickcmp(ph: *mut crate::internals::HexchatPlugin,
        s1: *const libc::c_char,
        s2: *const libc::c_char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_set_context(ph: *mut crate::internals::HexchatPlugin,
        ctx: *const crate::internals::HexchatContext) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_find_context(ph: *mut crate::internals::HexchatPlugin,
        servname: *const libc::c_char,
        channel: *const libc::c_char) -> *const crate::internals::HexchatContext {
    todo!();
}
unsafe extern "C" fn hexchat_get_context(ph: *mut crate::internals::HexchatPlugin) -> *const crate::internals::HexchatContext {
    todo!();
}
unsafe extern "C" fn hexchat_get_info(ph: *mut crate::internals::HexchatPlugin,
        id: *const libc::c_char) -> *const libc::c_char {
    todo!();
}
unsafe extern "C" fn hexchat_get_prefs(ph: *mut crate::internals::HexchatPlugin,
        name: *const libc::c_char,
        string: *mut *const libc::c_char,
        integer: *mut libc::c_int) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_list_get(ph: *mut crate::internals::HexchatPlugin,
        name: *const libc::c_char) -> *mut crate::internals::HexchatList {
    todo!();
}
unsafe extern "C" fn hexchat_list_free(ph: *mut crate::internals::HexchatPlugin,
        xlist: *const crate::internals::HexchatList) {
    todo!();
}
unsafe extern "C" fn hexchat_list_fields(ph: *mut crate::internals::HexchatPlugin,
        name: *const libc::c_char) -> *const *const libc::c_char {
    todo!();
}
unsafe extern "C" fn hexchat_list_next(ph: *mut crate::internals::HexchatPlugin,
        xlist: *const crate::internals::HexchatList) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_list_str(ph: *mut crate::internals::HexchatPlugin,
        xlist: *const crate::internals::HexchatList,
        name: *const libc::c_char) -> *const libc::c_char {
    todo!();
}
unsafe extern "C" fn hexchat_list_int(ph: *mut crate::internals::HexchatPlugin,
        xlist: *const crate::internals::HexchatList,
        name: *const libc::c_char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_plugingui_add(ph: *mut crate::internals::HexchatPlugin,
        filename: *const libc::c_char,
        name: *const libc::c_char,
        desc: *const libc::c_char,
        version: *const libc::c_char,
        reserved: *mut char) -> *const crate::internals::PluginGuiHandle {
    todo!();
}
unsafe extern "C" fn hexchat_plugingui_remove(ph: *mut crate::internals::HexchatPlugin,
        handle: *const crate::internals::PluginGuiHandle) {
    todo!();
}
unsafe extern "C" fn hexchat_emit_print(ph: *mut crate::internals::HexchatPlugin,
        event_name: *const libc::c_char, ...) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_read_fd(ph: *mut crate::internals::HexchatPlugin,
        src: *const libc::c_void,
        buf: *mut char,
        len: *mut libc::c_int) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_list_time(ph: *mut crate::internals::HexchatPlugin,
        xlist: *const crate::internals::HexchatList,
        name: *const libc::c_char) -> libc::time_t {
    todo!();
}
unsafe extern "C" fn hexchat_gettext(ph: *mut crate::internals::HexchatPlugin,
        msgid: *const libc::c_char) -> *const libc::c_char {
    todo!();
}
unsafe extern "C" fn hexchat_send_modes(ph: *mut crate::internals::HexchatPlugin,
        targets: *mut *const libc::c_char,
        ntargets: libc::c_int,
        modes_per_line: libc::c_int,
        sign: libc::c_char,
        mode: libc::c_char) {
    todo!();
}
unsafe extern "C" fn hexchat_strip(ph: *mut crate::internals::HexchatPlugin,
        string: *const libc::c_char,
        len: libc::c_int,
        flags: libc::c_int) -> *const libc::c_char {
    todo!();
}
unsafe extern "C" fn hexchat_free(ph: *mut crate::internals::HexchatPlugin,
        ptr: *const libc::c_void) {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_set_str(ph: *mut crate::internals::HexchatPlugin,
        var: *const libc::c_char,
        value: *const libc::c_char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_get_str(ph: *mut crate::internals::HexchatPlugin,
        var: *const libc::c_char,
        dest: *mut char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_set_int(ph: *mut crate::internals::HexchatPlugin,
        var: *const libc::c_char,
        value: libc::c_int) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_get_int(ph: *mut crate::internals::HexchatPlugin,
        var: *const libc::c_char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_delete(ph: *mut crate::internals::HexchatPlugin,
        var: *const libc::c_char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_pluginpref_list(ph: *mut crate::internals::HexchatPlugin,
        dest: *mut char) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_hook_server_attrs(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, attrs: *const crate::internals::HexchatEventAttrs, user_data: *mut libc::c_void) -> libc::c_int,
        userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook {
    todo!();
}
unsafe extern "C" fn hexchat_hook_print_attrs(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, attrs: *const crate::internals::HexchatEventAttrs, user_data: *mut libc::c_void) -> libc::c_int,
        userdata: *mut libc::c_void) -> *const crate::internals::HexchatHook {
    todo!();
}
unsafe extern "C" fn hexchat_emit_print_attrs(ph: *mut crate::internals::HexchatPlugin, attrs: *const crate::internals::HexchatEventAttrs,
        event_name: *const libc::c_char, ...) -> libc::c_int {
    todo!();
}
unsafe extern "C" fn hexchat_event_attrs_create(ph: *mut crate::internals::HexchatPlugin) -> *mut crate::internals::HexchatEventAttrs {
    todo!();
}
unsafe extern "C" fn hexchat_event_attrs_free(ph: *mut crate::internals::HexchatPlugin,
        attrs: *mut crate::internals::HexchatEventAttrs) {
    todo!();
}

impl<'dangling, 'env> PluginEnvironment<'dangling, 'env> {
    pub fn new() -> Self {
        Self {
            plugins: Default::default(),
            hooks: Default::default(),
            extra_hooks: Default::default(),
            depth: Default::default(),
        }
    }
}

//
//impl MockPlugin {
//    pub fn new<T: for<'ph> crate::Plugin<'ph> + Default>(
//        env: Pin<&PluginEnvironment>,
//        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,
//                hexchat_hook_print,
//                hexchat_hook_timer,
//                hexchat_hook_fd,
//                hexchat_unhook,
//                hexchat_print,
//                userdata: hexchat_printf as *mut libc::c_void,
//                hexchat_command,
//                hexchat_commandf_do_not_use: hexchat_commandf,
//                hexchat_nickcmp,
//                hexchat_set_context,
//                hexchat_find_context,
//                hexchat_get_context,
//                hexchat_get_info,
//                hexchat_get_prefs,
//                hexchat_list_get,
//                hexchat_list_free,
//                hexchat_list_fields,
//                hexchat_list_next,
//                hexchat_list_str,
//                hexchat_list_int,
//                hexchat_plugingui_add,
//                hexchat_plugingui_remove,
//                hexchat_emit_print,
//                hexchat_read_fd,
//                hexchat_list_time,
//                hexchat_gettext,
//                hexchat_send_modes,
//                hexchat_strip,
//                hexchat_free,
//                hexchat_pluginpref_set_str,
//                hexchat_pluginpref_get_str,
//                hexchat_pluginpref_set_int,
//                hexchat_pluginpref_get_int,
//                hexchat_pluginpref_delete,
//                hexchat_pluginpref_list,
//                hexchat_hook_server_attrs,
//                hexchat_hook_print_attrs,
//                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,
//            env: &*env,
//            _pin: PhantomPinned,
//        });
//        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
//        }
//    }
//}