|
1 | 1 | //! Contains definitions from `lauxlib.h`. |
2 | 2 |
|
3 | | -use std::os::raw::{c_char, c_int, c_uint, c_void}; |
4 | | -use std::ptr; |
| 3 | +use std::os::raw::{c_char, c_double, c_int, c_long, c_uint, c_void}; |
| 4 | +use std::{mem, ptr}; |
5 | 5 |
|
6 | 6 | use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State}; |
7 | 7 |
|
@@ -95,7 +95,7 @@ unsafe extern "C-unwind" { |
95 | 95 |
|
96 | 96 | pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer; |
97 | 97 |
|
98 | | - // TODO: luaL_addgsub |
| 98 | + pub fn luaL_addgsub(B: *mut luaL_Buffer, s: *const c_char, p: *const c_char, r: *const c_char); |
99 | 99 |
|
100 | 100 | pub fn luaL_gsub( |
101 | 101 | L: *mut lua_State, |
@@ -166,8 +166,6 @@ pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) { |
166 | 166 | lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n); |
167 | 167 | } |
168 | 168 |
|
169 | | -// luaL_opt would be implemented here but it is undocumented, so it's omitted |
170 | | - |
171 | 169 | #[inline(always)] |
172 | 170 | pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int { |
173 | 171 | luaL_loadbufferx(L, s, sz, n, ptr::null()) |
@@ -206,6 +204,96 @@ pub unsafe fn luaL_makeseed(L: *mut lua_State) -> c_uint { |
206 | 204 | luaL_makeseed_(L) |
207 | 205 | } |
208 | 206 |
|
| 207 | +#[inline(always)] |
| 208 | +pub unsafe fn luaL_opt<T>( |
| 209 | + L: *mut lua_State, |
| 210 | + f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T, |
| 211 | + n: c_int, |
| 212 | + d: T, |
| 213 | +) -> T { |
| 214 | + if lua::lua_isnoneornil(L, n) != 0 { |
| 215 | + d |
| 216 | + } else { |
| 217 | + f(L, n) |
| 218 | + } |
| 219 | +} |
| 220 | + |
209 | 221 | // |
210 | | -// TODO: Generic Buffer Manipulation |
| 222 | +// Generic Buffer Manipulation |
211 | 223 | // |
| 224 | + |
| 225 | +// The buffer size used by the lauxlib buffer system. |
| 226 | +// LUAL_BUFFERSIZE = (int)(16 * sizeof(void*) * sizeof(lua_Number)) |
| 227 | +#[rustfmt::skip] |
| 228 | +pub const LUAL_BUFFERSIZE: usize = 16 * mem::size_of::<*const ()>() * mem::size_of::<lua_Number>(); |
| 229 | + |
| 230 | +// Union used for the initial buffer with maximum alignment. |
| 231 | +// This ensures proper alignment for the buffer data. |
| 232 | +#[repr(C)] |
| 233 | +pub union luaL_BufferInit { |
| 234 | + // Alignment matches LUAI_MAXALIGN |
| 235 | + pub _align_n: lua_Number, |
| 236 | + pub _align_u: c_double, |
| 237 | + pub _align_s: *mut c_void, |
| 238 | + pub _align_i: lua_Integer, |
| 239 | + pub _align_l: c_long, |
| 240 | + // Initial buffer space |
| 241 | + pub b: [c_char; LUAL_BUFFERSIZE], |
| 242 | +} |
| 243 | + |
| 244 | +#[repr(C)] |
| 245 | +pub struct luaL_Buffer { |
| 246 | + pub b: *mut c_char, // buffer address |
| 247 | + pub size: usize, // buffer size |
| 248 | + pub n: usize, // number of characters in buffer |
| 249 | + pub L: *mut lua_State, |
| 250 | + pub init: luaL_BufferInit, // initial buffer (union with alignment) |
| 251 | +} |
| 252 | + |
| 253 | +#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))] |
| 254 | +unsafe extern "C-unwind" { |
| 255 | + pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer); |
| 256 | + pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char; |
| 257 | + pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize); |
| 258 | + pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char); |
| 259 | + pub fn luaL_addvalue(B: *mut luaL_Buffer); |
| 260 | + pub fn luaL_pushresult(B: *mut luaL_Buffer); |
| 261 | + pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize); |
| 262 | + pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char; |
| 263 | +} |
| 264 | + |
| 265 | +// Macro implementations as inline functions |
| 266 | + |
| 267 | +#[inline(always)] |
| 268 | +pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char { |
| 269 | + luaL_prepbuffsize(B, LUAL_BUFFERSIZE) |
| 270 | +} |
| 271 | + |
| 272 | +#[inline(always)] |
| 273 | +pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) { |
| 274 | + if (*B).n >= (*B).size { |
| 275 | + luaL_prepbuffsize(B, 1); |
| 276 | + } |
| 277 | + *(*B).b.add((*B).n) = c; |
| 278 | + (*B).n += 1; |
| 279 | +} |
| 280 | + |
| 281 | +#[inline(always)] |
| 282 | +pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) { |
| 283 | + (*B).n += n; |
| 284 | +} |
| 285 | + |
| 286 | +#[inline(always)] |
| 287 | +pub unsafe fn luaL_buffsub(B: *mut luaL_Buffer, n: usize) { |
| 288 | + (*B).n -= n; |
| 289 | +} |
| 290 | + |
| 291 | +#[inline(always)] |
| 292 | +pub unsafe fn luaL_bufflen(B: *mut luaL_Buffer) -> usize { |
| 293 | + (*B).n |
| 294 | +} |
| 295 | + |
| 296 | +#[inline(always)] |
| 297 | +pub unsafe fn luaL_buffaddr(B: *mut luaL_Buffer) -> *mut c_char { |
| 298 | + (*B).b |
| 299 | +} |
0 commit comments