use libc::c_char;
use std::ffi::{CString, CStr};
use crate::{Context, PHEXCHAT};
#[inline]
pub (crate)
fn str2cstring(s: &str) -> CString {
CString::new(s).unwrap()
}
#[macro_export]
macro_rules! hc_print {
( ctx = ($network:expr, $channel:expr), $( $arg:tt )* ) => {
hexchat_api::
print_with_ctx_inner(&$network, &$channel, &format!( $( $arg )* ));
};
( $( $arg:tt )* ) => {
hexchat_api::print_inner(&format!( $( $arg )* ))
};
}
#[doc(hidden)]
pub fn print_with_ctx_inner(network: &str, channel: &str, msg: &str) {
let hc = unsafe { &*PHEXCHAT };
if let Some(orig_ctx) = hc.get_context() {
if let Some(ctx) = Context::find(network, channel) {
let _ = ctx.set();
hc.print(msg);
let _ = orig_ctx.set();
} else {
panic!("Can't find context for ({}, {})", network, channel);
}
} else {
panic!("Unable to acquire local context.");
}
}
#[doc(hidden)]
pub fn print_inner(msg: &str) {
let hc = unsafe { &*PHEXCHAT };
hc.print(msg);
}
#[cfg(feature = "threadsafe")]
#[macro_export]
macro_rules! hc_print_th {
( ctx = ($network:expr, $channel:expr), $( $arg:tt )* ) => {
let fm_msg = format!( $( $arg )* );
let data = ($fm_msg.to_string(),
$network.to_string(),
$channel.to_string());
hexchat_api::main_thread(move |_| {
hexchat_api::print_with_ctx_inner(&data.1, &data.2, &data.0);
});
};
( $( $arg:tt )* ) => {
let rc_msg = format!( $( $arg )* );
hexchat_api::main_thread(move |_| hexchat_api::print_inner(&rc_msg));
};
}
#[macro_export]
macro_rules! hc_command {
( $( $arg:tt )* ) => {
hexchat_api::command_inner(&format!( $( $arg )* ));
};
}
#[cfg(feature = "threadsafe")]
#[macro_export]
macro_rules! hc_command_th {
( $( $arg:tt )* ) => {
let rc_cmd = format!( $( $arg )* );
hexchat_api::main_thread(move |_| hexchat_api::command_inner(&rc_cmd));
};
}
#[doc(hidden)]
pub fn command_inner(cmd: &str) {
let hc = unsafe { &*PHEXCHAT };
hc.command(cmd);
}
#[inline]
pub (crate)
fn pchar2cstring(p_char: *const c_char) -> CString {
unsafe { CStr::from_ptr(p_char).to_owned() }
}
pub (crate)
fn pchar2string(p_char: *const c_char) -> String {
if p_char.is_null() {
String::new()
} else {
unsafe {
CStr::from_ptr(p_char).to_string_lossy().into_owned()
}
}
}
pub (crate)
fn argv2svec(pchar: *const *const c_char, start: usize) -> Vec<String>
{
unsafe {
let mut svec = vec![];
let mut i = start;
let mut pval = *pchar.add(i);
loop {
let s = CStr::from_ptr(pval)
.to_string_lossy()
.into_owned();
if (*pchar.add(i)).is_null() || s.is_empty() {
break;
}
i += 1;
pval = *pchar.add(i);
svec.push(s);
}
svec
}
}
pub (crate)
fn cstring2string(cstring: &CString) -> String {
cstring.to_string_lossy().into_owned()
}