summary refs log tree commit diff stats
path: root/src/lib.rs
diff options
context:
space:
mode:
authorSoniEx2 <endermoneymod@gmail.com>2022-12-12 10:43:53 -0300
committerSoniEx2 <endermoneymod@gmail.com>2022-12-12 10:43:53 -0300
commitc12eb456be7cf5e183ef2b34812060ee2ed08a8a (patch)
tree3d622f8baa0f2d8657cb422d3c7b53bd1ae6b8c9 /src/lib.rs
parent43a79374e0d9592ccd709082f23c63da5a83d609 (diff)
Initial work on using LtPtr + selfref update
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs103
1 files changed, 70 insertions, 33 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 00d0845..0ef9354 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,8 +15,7 @@
 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 #![cfg_attr(feature="nightly_tests", feature(c_variadic))]
-#![cfg_attr(feature="nightly_tests", feature(generic_associated_types))]
-//#![deny(unsafe_op_in_unsafe_fn)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 //! Write hexchat plugins in Rust!
 //!
@@ -257,6 +256,9 @@ pub use libc::{c_char, c_int, c_void, time_t};
 #[doc(hidden)]
 pub use ltptr::MutLtPtr;
 
+use ltptr::ConstLtPtr;
+use ltptr::FromLtPtr;
+
 // ****** //
 // PUBLIC //
 // ****** //
@@ -2213,12 +2215,16 @@ fn check_pluginpref_var(var: impl Into<Vec<u8>>) -> Result<CString, PluginPrefEr
 // *********************** //
 
 #[doc(hidden)]
-pub unsafe fn hexchat_plugin_init<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>,
-                                     plugin_name: *mut *const c_char,
-                                     plugin_desc: *mut *const c_char,
-                                     plugin_version: *mut *const c_char,
-                                     arg: *const c_char) -> c_int
-                                     where T: Plugin<'ph> + Default + 'ph {
+pub unsafe fn hexchat_plugin_init<'ph, T>(
+    ph: MutLtPtr<'ph, RawPh<'ph>>,
+    plugin_name: *mut *const c_char,
+    plugin_desc: *mut *const c_char,
+    plugin_version: *mut *const c_char,
+    arg: ConstLtPtr<'_, c_char>,
+) -> c_int
+where
+    T: Plugin<'ph> + Default + 'ph,
+{
     if ph.as_raw().is_null() || plugin_name.is_null() || plugin_desc.is_null() || plugin_version.is_null() {
         // we can't really do anything here. just hope this doesn't panic.
         eprintln!("hexchat_plugin_init called with a null pointer that shouldn't be null - broken hexchat");
@@ -2266,7 +2272,7 @@ pub unsafe fn hexchat_plugin_init<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>,
     }
     // we got banned from an IRC network over the following line of code.
     hexchat_print_str(ph, "hexchat-unsafe-plugin  Copyright (C) 2018, 2021, 2022 Soni L.  GPL-3.0-or-later  This software is made with love by a queer trans person.", false);
-    let mut pluginfo = if let Some(pluginfo) = PluginInfo::new(plugin_name, plugin_desc, plugin_version) {
+    let mut pluginfo = if let Some(pluginfo) = unsafe { PluginInfo::new(plugin_name, plugin_desc, plugin_version) } {
         pluginfo
     } else {
         return 0;
@@ -2287,16 +2293,18 @@ pub unsafe fn hexchat_plugin_init<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>,
             });
             let contexts = Rc::clone(&pluginhandle.contexts);
             let mut plug = Box::pin(T::default());
-            if plug.as_mut().init(&mut pluginhandle, &filename, if !arg.is_null() { Some(CStr::from_ptr(arg).to_str().expect("arg not valid utf-8 - broken hexchat")) } else { None }) {
-                if !(pluginfo.name.is_null() || pluginfo.desc.is_null() || pluginfo.vers.is_null()) {
+            if plug.as_mut().init(&mut pluginhandle, &filename, if !arg.is_null() { Some(unsafe { CStr::from_lt_ptr(arg) }.to_str().expect("arg not valid utf-8 - broken hexchat")) } else { None }) {
+                if unsafe { pluginfo.is_registered() } {
                     Some(Box::new(PhUserdata { plug, pluginfo, contexts, _context_hook: context_hook }))
                 } else {
                     // TODO log: forgot to call register
                     None
                 }
             } else {
-                if !(pluginfo.name.is_null() || pluginfo.desc.is_null() || pluginfo.vers.is_null()) {
-                    pluginfo.drop_info()
+                if unsafe { pluginfo.is_registered() } {
+                    unsafe {
+                        pluginfo.drop_info()
+                    }
                 }
                 None
             }
@@ -2304,12 +2312,16 @@ pub unsafe fn hexchat_plugin_init<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>,
     };
     match r {
         Result::Ok(Option::Some(plug @ _)) => {
-            put_userdata(ph, plug);
+            unsafe {
+                put_userdata(ph, plug);
+            }
             1
         },
         r @ _ => {
             if let Err(e) = r {
-                log_panic(ph, e);
+                unsafe {
+                    log_panic(ph, e);
+                }
             }
             0
         },
@@ -2317,22 +2329,24 @@ pub unsafe fn hexchat_plugin_init<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>,
 }
 
 #[doc(hidden)]
-pub unsafe extern "C" fn hexchat_plugin_deinit<'ph, T>(ph: MutLtPtr<'ph, RawPh<'ph>>) -> c_int where T: Plugin<'ph> {
+pub unsafe extern "C" fn hexchat_plugin_deinit<'ph, T: Plugin<'ph>>(
+    ph: MutLtPtr<'ph, RawPh<'ph>>,
+) -> c_int {
     let mut safe_to_unload = 1;
     // plugin_handle should never be null, but just in case.
-    if !ph.as_raw().is_null() {
+    if !unsafe { ph.as_raw() }.is_null() {
         // userdata should also never be null.
-        if !(*ph.as_raw()).userdata.is_null() {
+        if !unsafe { (*ph.as_raw()).userdata }.is_null() {
             {
                 let mut info: Option<PluginInfo> = None;
                 {
                     let ausph = AssertUnwindSafe(ph);
                     let mut ausinfo = AssertUnwindSafe(&mut info);
                     safe_to_unload = match catch_unwind(move || {
-                        let mut userdata = pop_userdata(*ausph);
+                        let mut userdata = unsafe { pop_userdata(*ausph) };
                         let pluginfo = userdata.pluginfo;
                         if let Err(e) = catch_unwind(AssertUnwindSafe(|| {
-                            userdata.plug.as_mut().deinit(&mut {
+                            userdata.plug.as_mut().deinit(&mut unsafe {
                                 PluginHandle::new(
                                     *ausph,
                                     pluginfo,
@@ -2343,7 +2357,9 @@ pub unsafe extern "C" fn hexchat_plugin_deinit<'ph, T>(ph: MutLtPtr<'ph, RawPh<'
                             // panics in deinit may be retried.
                             // however, one may need to close hexchat if that
                             // happens.
-                            put_userdata(*ausph, userdata);
+                            unsafe {
+                                put_userdata(*ausph, userdata);
+                            }
                             std::panic::resume_unwind(e);
                         }
                         **ausinfo = Some(pluginfo);
@@ -2351,18 +2367,28 @@ pub unsafe extern "C" fn hexchat_plugin_deinit<'ph, T>(ph: MutLtPtr<'ph, RawPh<'
                     }) {
                         Ok(_) => 1,
                         Err(e) => {
-                            log_panic(ph, e);
+                            unsafe {
+                                log_panic(ph, e);
+                            }
                             0
                         }
                     };
                 }
                 if let Some(mut info) = info {
-                    info.drop_info();
+                    unsafe {
+                        info.drop_info();
+                    }
                     safe_to_unload = 1;
                 }
             }
         } else {
-            hexchat_print_str(ph, "plugin userdata was null, broken hexchat-unsafe-plugin?", false);
+            unsafe {
+                hexchat_print_str(
+                    ph,
+                    "plugin userdata was null, broken hexchat-unsafe-plugin?",
+                    false
+                );
+            }
         }
     } else {
         // we are once again hoping for the best here.
@@ -2377,18 +2403,29 @@ pub unsafe extern "C" fn hexchat_plugin_deinit<'ph, T>(ph: MutLtPtr<'ph, RawPh<'
 macro_rules! hexchat_plugin {
     ($l:lifetime, $t:ty) => {
         #[no_mangle]
-        pub unsafe extern "C" fn hexchat_plugin_init<$l>(plugin_handle: $crate::MutLtPtr<$l, $crate::RawPh<$l>>,
-                                              plugin_name: *mut *const $crate::c_char,
-                                              plugin_desc: *mut *const $crate::c_char,
-                                              plugin_version: *mut *const $crate::c_char,
-                                              arg: *const $crate::c_char) -> $crate::c_int {
-            $crate::hexchat_plugin_init::<$l, $t>(plugin_handle, plugin_name, plugin_desc, plugin_version, arg)
+        pub unsafe extern "C" fn hexchat_plugin_init<$l>(
+            plugin_handle: $crate::MutLtPtr<$l, $crate::RawPh<$l>>,
+            plugin_name: *mut *const $crate::c_char,
+            plugin_desc: *mut *const $crate::c_char,
+            plugin_version: *mut *const $crate::c_char,
+            arg: *const $crate::c_char,
+        ) -> $crate::c_int {
+            $crate::hexchat_plugin_init::<$l, $t>(
+                plugin_handle,
+                plugin_name,
+                plugin_desc,
+                plugin_version,
+                arg
+            )
         }
         #[no_mangle]
-        pub unsafe extern "C" fn hexchat_plugin_deinit<$l>(plugin_handle: $crate::MutLtPtr<$l, $crate::RawPh<$l>>) -> $crate::c_int {
+        pub unsafe extern "C" fn hexchat_plugin_deinit<$l>(
+            plugin_handle: $crate::MutLtPtr<$l, $crate::RawPh<$l>>,
+        ) -> $crate::c_int {
             $crate::hexchat_plugin_deinit::<$l, $t>(plugin_handle)
         }
-        // unlike what the documentation states, there's no need to define hexchat_plugin_get_info.
-        // so we don't. it'd be impossible to make it work well with rust anyway.
+        // unlike what the documentation states, there's no need to define
+        // hexchat_plugin_get_info. so we don't. it'd be impossible to make it
+        // work well with rust anyway.
     };
 }