theseus_mlua_sys/lua_factorio/
compat.rs1use std::convert::TryInto;
6use std::os::raw::{c_char, c_int, c_void};
7use std::ptr;
8
9use super::lauxlib::*;
10use super::lua::*;
11
12#[inline(always)]
13unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
14 while a < b {
15 lua_pushvalue(L, a);
16 lua_pushvalue(L, b);
17 lua_replace(L, a);
18 lua_replace(L, b);
19 a += 1;
20 b -= 1;
21 }
22}
23
24pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) {
29 idx = lua_absindex(L, idx);
30 if n > 0 {
31 for _ in 0..n {
33 lua_insert(L, idx);
34 }
35 return;
36 }
37 let n_elems = lua_gettop(L) - idx + 1;
38 if n < 0 {
39 n += n_elems;
40 }
41 if n > 0 && n < n_elems {
42 luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
43 n = n_elems - n;
44 compat53_reverse(L, idx, idx + n - 1);
45 compat53_reverse(L, idx + n, idx + n_elems - 1);
46 compat53_reverse(L, idx, idx + n_elems - 1);
47 }
48}
49
50#[inline(always)]
51pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
52 if lua_type(L, idx) == LUA_TNUMBER {
53 let n = lua_tonumber(L, idx);
54 let i = lua_tointeger(L, idx);
55 if (n - i as lua_Number).abs() < lua_Number::EPSILON {
56 return 1;
57 }
58 }
59 0
60}
61
62#[inline(always)]
63pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
64 lua_tointegerx(L, i, ptr::null_mut())
65}
66
67#[inline(always)]
70pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Integer {
71 let mut ok = 0;
72 let n = lua_tonumberx(L, i, &mut ok);
73 let n_int = n as lua_Integer;
74 if ok != 0 && (n - n_int as lua_Number).abs() < lua_Number::EPSILON {
75 if !isnum.is_null() {
76 *isnum = 1;
77 }
78 return n_int;
79 }
80 if !isnum.is_null() {
81 *isnum = 0;
82 }
83 0
84}
85
86#[inline(always)]
87pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char {
88 if l == 0 {
89 lua_pushlstring_(L, cstr!(""), 0)
90 } else {
91 lua_pushlstring_(L, s, l)
92 }
93}
94
95#[inline(always)]
96pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int {
97 lua_getglobal_(L, var);
98 lua_type(L, -1)
99}
100
101#[inline(always)]
102pub unsafe fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int {
103 lua_gettable_(L, idx);
104 lua_type(L, -1)
105}
106
107#[inline(always)]
108pub unsafe fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int {
109 lua_getfield_(L, idx, k);
110 lua_type(L, -1)
111}
112
113#[inline(always)]
114pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_int {
115 idx = lua_absindex(L, idx);
116 lua_pushinteger(L, n);
117 lua_gettable(L, idx)
118}
119
120#[inline(always)]
121pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int {
122 lua_rawget_(L, idx);
123 lua_type(L, -1)
124}
125
126#[inline(always)]
127pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
128 let n = n.try_into().expect("cannot convert index to lua_Integer");
129 lua_rawgeti_(L, idx, n);
130 lua_type(L, -1)
131}
132
133#[inline(always)]
134pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int {
135 lua_rawgetp_(L, idx, p);
136 lua_type(L, -1)
137}
138
139#[inline(always)]
140pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int {
141 lua_getuservalue_(L, idx);
142 lua_type(L, -1)
143}
144
145#[inline(always)]
146pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
147 luaL_checkstack(L, 1, cstr!("not enough stack slots available"));
148 idx = lua_absindex(L, idx);
149 lua_pushinteger(L, n);
150 lua_insert(L, -2);
151 lua_settable(L, idx);
152}
153
154#[inline(always)]
155pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
156 let n = n.try_into().expect("cannot convert index from lua_Integer");
157 lua_rawseti_(L, idx, n)
158}
159
160#[inline(always)]
161pub unsafe fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut c_void, _strip: c_int) -> c_int {
162 lua_dump_(L, writer, data)
163}
164
165#[inline(always)]
186pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
187 if luaL_getmetafield_(L, obj, e) != 0 {
188 lua_type(L, -1)
189 } else {
190 LUA_TNIL
191 }
192}
193
194#[inline(always)]
195pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int {
196 if luaL_newmetatable_(L, tname) != 0 {
197 lua_pushstring(L, tname);
198 lua_setfield(L, -2, cstr!("__name"));
199 1
200 } else {
201 0
202 }
203}
204
205pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char {
206 if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
207 let t = lua_type(L, idx);
208 match t {
209 LUA_TNIL => {
210 lua_pushliteral(L, c"nil");
211 }
212 LUA_TSTRING | LUA_TNUMBER => {
213 lua_pushvalue(L, idx);
214 }
215 LUA_TBOOLEAN => {
216 if lua_toboolean(L, idx) == 0 {
217 lua_pushliteral(L, c"false");
218 } else {
219 lua_pushliteral(L, c"true");
220 }
221 }
222 _ => {
223 let tt = luaL_getmetafield(L, idx, cstr!("__name"));
224 let name = if tt == LUA_TSTRING {
225 lua_tostring(L, -1)
226 } else {
227 lua_typename(L, t)
228 };
229 lua_pushfstring(L, cstr!("%s: %p"), name, lua_topointer(L, idx));
230 if tt != LUA_TNIL {
231 lua_replace(L, -2);
232 }
233 }
234 };
235 } else if lua_isstring(L, -1) == 0 {
236 luaL_error(L, cstr!("'__tostring' must return a string"));
237 }
238 lua_tolstring(L, -1, len)
239}
240
241pub unsafe fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int) {
242 luaL_checkstack(L, 3, cstr!("not enough stack slots available"));
243 luaL_getsubtable(L, LUA_REGISTRYINDEX, cstr!("_LOADED"));
244 if lua_getfield(L, -1, modname) == LUA_TNIL {
245 lua_pop(L, 1);
246 lua_pushcfunction(L, openf);
247 lua_pushstring(L, modname);
248 lua_call(L, 1, 1);
249 lua_pushvalue(L, -1);
250 lua_setfield(L, -3, modname);
251 }
252 if glb != 0 {
253 lua_pushvalue(L, -1);
254 lua_setglobal(L, modname);
255 }
256 lua_replace(L, -2);
257}
258
259pub unsafe fn luaL_loadbufferenv(
260 L: *mut lua_State,
261 data: *const c_char,
262 size: usize,
263 name: *const c_char,
264 mode: *const c_char,
265 mut env: c_int,
266) -> c_int {
267 if env != 0 {
268 env = lua_absindex(L, env);
269 }
270 let status = luaL_loadbufferx(L, data, size, name, mode);
271 if status == LUA_OK && env != 0 {
272 lua_pushvalue(L, env);
273 lua_setupvalue(L, -2, 1);
274 }
275 status
276}