diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-12-12 10:43:53 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-12-12 10:43:53 -0300 |
commit | c12eb456be7cf5e183ef2b34812060ee2ed08a8a (patch) | |
tree | 3d622f8baa0f2d8657cb422d3c7b53bd1ae6b8c9 /src/lib.rs | |
parent | 43a79374e0d9592ccd709082f23c63da5a83d609 (diff) |
Initial work on using LtPtr + selfref update
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 103 |
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. }; } |