use crate::seqstring::global_string;
use crate::stack::{Stack, push};
use crate::value::Value;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_string_to_cstring(stack: Stack, _out: *mut u8) -> *mut u8 {
assert!(!stack.is_null(), "string_to_cstring: stack is empty");
use crate::stack::peek;
use crate::value::Value;
let val = unsafe { peek(stack) };
let s = match &val {
Value::String(s) => s,
other => panic!(
"string_to_cstring: expected String on stack, got {:?}",
other
),
};
let str_ptr = s.as_ptr();
let len = s.len();
let alloc_size = len.checked_add(1).unwrap_or_else(|| {
panic!(
"string_to_cstring: string too large for C conversion (len={})",
len
)
});
let ptr = unsafe { libc::malloc(alloc_size) as *mut u8 };
if ptr.is_null() {
panic!("string_to_cstring: malloc failed");
}
unsafe {
std::ptr::copy_nonoverlapping(str_ptr, ptr, len);
*ptr.add(len) = 0;
}
ptr
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn patch_seq_cstring_to_string(stack: Stack, cstr: *const u8) -> Stack {
if cstr.is_null() {
return unsafe { push(stack, Value::String(global_string(String::new()))) };
}
let len = unsafe { libc::strlen(cstr as *const libc::c_char) };
let slice = unsafe { std::slice::from_raw_parts(cstr, len) };
let s = String::from_utf8_lossy(slice).into_owned();
unsafe { push(stack, Value::String(global_string(s))) }
}