|
1 | 1 | //! Contains definitions from `lauxlib.h`. |
2 | 2 |
|
3 | 3 | use std::os::raw::{c_char, c_int, c_void}; |
4 | | -use std::ptr; |
| 4 | +use std::{mem, ptr}; |
5 | 5 |
|
6 | 6 | use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State}; |
7 | 7 |
|
@@ -166,13 +166,72 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> |
166 | 166 | luaL_tolstring_(L, lua::lua_absindex(L, idx), len) |
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()) |
174 | 172 | } |
175 | 173 |
|
| 174 | +#[inline(always)] |
| 175 | +pub unsafe fn luaL_opt<T>( |
| 176 | + L: *mut lua_State, |
| 177 | + f: unsafe extern "C-unwind" fn(*mut lua_State, c_int) -> T, |
| 178 | + n: c_int, |
| 179 | + d: T, |
| 180 | +) -> T { |
| 181 | + if lua::lua_isnoneornil(L, n) != 0 { |
| 182 | + d |
| 183 | + } else { |
| 184 | + f(L, n) |
| 185 | + } |
| 186 | +} |
| 187 | + |
176 | 188 | // |
177 | | -// TODO: Generic Buffer Manipulation |
| 189 | +// Generic Buffer Manipulation |
178 | 190 | // |
| 191 | + |
| 192 | +// The buffer size used by the lauxlib buffer system. |
| 193 | +// In Lua 5.3: LUAL_BUFFERSIZE = (int)(0x80 * sizeof(void*) * sizeof(lua_Integer)) |
| 194 | +#[rustfmt::skip] |
| 195 | +pub const LUAL_BUFFERSIZE: usize = 0x80 * mem::size_of::<*const ()>() * mem::size_of::<lua_Integer>(); |
| 196 | + |
| 197 | +#[repr(C)] |
| 198 | +pub struct luaL_Buffer { |
| 199 | + pub b: *mut c_char, // buffer address |
| 200 | + pub size: usize, // buffer size |
| 201 | + pub n: usize, // number of characters in buffer |
| 202 | + pub L: *mut lua_State, |
| 203 | + pub initb: [c_char; LUAL_BUFFERSIZE], // initial buffer space |
| 204 | +} |
| 205 | + |
| 206 | +#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))] |
| 207 | +unsafe extern "C-unwind" { |
| 208 | + pub fn luaL_buffinit(L: *mut lua_State, B: *mut luaL_Buffer); |
| 209 | + pub fn luaL_prepbuffsize(B: *mut luaL_Buffer, sz: usize) -> *mut c_char; |
| 210 | + pub fn luaL_addlstring(B: *mut luaL_Buffer, s: *const c_char, l: usize); |
| 211 | + pub fn luaL_addstring(B: *mut luaL_Buffer, s: *const c_char); |
| 212 | + pub fn luaL_addvalue(B: *mut luaL_Buffer); |
| 213 | + pub fn luaL_pushresult(B: *mut luaL_Buffer); |
| 214 | + pub fn luaL_pushresultsize(B: *mut luaL_Buffer, sz: usize); |
| 215 | + pub fn luaL_buffinitsize(L: *mut lua_State, B: *mut luaL_Buffer, sz: usize) -> *mut c_char; |
| 216 | +} |
| 217 | + |
| 218 | +// Macro implementations as inline functions |
| 219 | + |
| 220 | +#[inline(always)] |
| 221 | +pub unsafe fn luaL_prepbuffer(B: *mut luaL_Buffer) -> *mut c_char { |
| 222 | + luaL_prepbuffsize(B, LUAL_BUFFERSIZE) |
| 223 | +} |
| 224 | + |
| 225 | +#[inline(always)] |
| 226 | +pub unsafe fn luaL_addchar(B: *mut luaL_Buffer, c: c_char) { |
| 227 | + if (*B).n >= (*B).size { |
| 228 | + luaL_prepbuffsize(B, 1); |
| 229 | + } |
| 230 | + *(*B).b.add((*B).n) = c; |
| 231 | + (*B).n += 1; |
| 232 | +} |
| 233 | + |
| 234 | +#[inline(always)] |
| 235 | +pub unsafe fn luaL_addsize(B: *mut luaL_Buffer, n: usize) { |
| 236 | + (*B).n += n; |
| 237 | +} |
0 commit comments