luaur_vm/functions/
lua_o_pushvfstring.rs1use crate::macros::incr_top::incr_top;
2use crate::macros::lua_buffersize::LUA_BUFFERSIZE;
3use crate::macros::lua_s_new::luaS_new;
4use crate::macros::setsvalue::setsvalue;
5use crate::macros::svalue::svalue;
6use crate::type_aliases::lua_state::lua_State;
7use core::ffi::c_char;
8use core::ffi::c_int;
9
10#[allow(non_snake_case)]
11pub fn luaO_pushvfstring(
12 L: *mut lua_State,
13 _fmt: *const c_char,
14 args: core::fmt::Arguments<'_>,
15) -> *const c_char {
16 let mut buffer = [0u8; LUA_BUFFERSIZE as usize];
20 let mut writer = BufferWriter {
21 buf: &mut buffer,
22 pos: 0,
23 };
24
25 let _ = core::fmt::write(&mut writer, args);
26
27 let len = writer.pos;
29 if len < buffer.len() {
30 buffer[len] = 0;
31 } else {
32 buffer[buffer.len() - 1] = 0;
33 }
34
35 unsafe {
36 setsvalue!(L, (*L).top, luaS_new(L, buffer.as_ptr() as *const c_char));
38
39 let n = 1;
46 let stack_last = (*L).stack_last as *mut u8;
47 let top = (*L).top as *mut u8;
48 let limit_reached = (stack_last as usize).wrapping_sub(top as usize)
49 <= (n as usize * core::mem::size_of::<crate::type_aliases::t_value::TValue>());
50
51 if limit_reached {
52 crate::functions::lua_d_growstack::lua_d_growstack(L, n);
53 } else {
54 type LuaDReallocStackFn = unsafe fn(*mut lua_State, c_int, c_int);
58 let realloc_stack: LuaDReallocStackFn = core::mem::transmute(
59 crate::functions::lua_d_reallocstack::lua_d_reallocstack as *const (),
60 );
61 realloc_stack(
62 L,
63 (*L).stacksize - crate::macros::extra_stack::EXTRA_STACK,
64 0,
65 );
66 }
67
68 (*L).top = (*L).top.add(1);
70
71 svalue!((*L).top.offset(-1))
73 }
74}
75
76struct BufferWriter<'a> {
77 buf: &'a mut [u8],
78 pos: usize,
79}
80
81impl<'a> core::fmt::Write for BufferWriter<'a> {
82 fn write_str(&mut self, s: &str) -> core::fmt::Result {
83 let bytes = s.as_bytes();
84 let remain = self.buf.len().saturating_sub(self.pos);
85 let to_copy = core::cmp::min(remain, bytes.len());
86 if to_copy > 0 {
87 self.buf[self.pos..self.pos + to_copy].copy_from_slice(&bytes[..to_copy]);
88 self.pos += to_copy;
89 }
90 Ok(())
91 }
92}