1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
use std::mem;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;

#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
pub mod bindings;

pub const LUA_OK: c_int = bindings::LUA_OK as c_int;
pub const LUA_YIELD: c_int = bindings::LUA_YIELD as c_int;
pub const LUA_ERRRUN: c_int = bindings::LUA_ERRRUN as c_int;
pub const LUA_ERRSYNTAX: c_int = bindings::LUA_ERRSYNTAX as c_int;
pub const LUA_ERRMEM: c_int = bindings::LUA_ERRMEM as c_int;
pub const LUA_ERRERR: c_int = bindings::LUA_ERRERR as c_int;

pub const LUA_NOREF: c_int = bindings::LUA_NOREF as c_int;
pub const LUA_REFNIL: c_int = bindings::LUA_REFNIL as c_int;

pub const LUA_MULTRET: c_int = bindings::LUA_MULTRET as c_int;
pub const LUAI_MAXSTACK: c_int = bindings::LUAI_MAXSTACK as c_int;
pub const LUA_REGISTRYINDEX: c_int = bindings::LUA_REGISTRYINDEX as c_int;
pub const LUA_RIDX_MAINTHREAD: bindings::lua_Integer =
    bindings::LUA_RIDX_MAINTHREAD as bindings::lua_Integer;
pub const LUA_RIDX_GLOBALS: bindings::lua_Integer =
    bindings::LUA_RIDX_GLOBALS as bindings::lua_Integer;
pub const LUA_IDSIZE: c_int = bindings::LUA_IDSIZE as c_int;
pub const LUA_MINSTACK: c_int = bindings::LUA_MINSTACK as c_int;
// Not actually defined in lua.h / luaconf.h
pub const LUA_MAX_UPVALUES: c_int = 255;

pub const LUA_TNONE: c_int = bindings::LUA_TNONE as c_int;
pub const LUA_TNIL: c_int = bindings::LUA_TNIL as c_int;
pub const LUA_TBOOLEAN: c_int = bindings::LUA_TBOOLEAN as c_int;
pub const LUA_TLIGHTUSERDATA: c_int = bindings::LUA_TLIGHTUSERDATA as c_int;
pub const LUA_TNUMBER: c_int = bindings::LUA_TNUMBER as c_int;
pub const LUA_TSTRING: c_int = bindings::LUA_TSTRING as c_int;
pub const LUA_TTABLE: c_int = bindings::LUA_TTABLE as c_int;
pub const LUA_TFUNCTION: c_int = bindings::LUA_TFUNCTION as c_int;
pub const LUA_TUSERDATA: c_int = bindings::LUA_TUSERDATA as c_int;
pub const LUA_TTHREAD: c_int = bindings::LUA_TTHREAD as c_int;

pub const LUA_GCSTOP: c_int = bindings::LUA_GCSTOP as c_int;
pub const LUA_GCRESTART: c_int = bindings::LUA_GCRESTART as c_int;
pub const LUA_GCCOLLECT: c_int = bindings::LUA_GCCOLLECT as c_int;
pub const LUA_GCCOUNT: c_int = bindings::LUA_GCCOUNT as c_int;
pub const LUA_GCCOUNTB: c_int = bindings::LUA_GCCOUNTB as c_int;
pub const LUA_GCSTEP: c_int = bindings::LUA_GCSTEP as c_int;
#[deprecated(note = "please use `LUA_GCINC` instead")]
pub const LUA_GCSETPAUSE: c_int = bindings::LUA_GCSETPAUSE as c_int;
#[deprecated(note = "please use `LUA_GCINC` instead")]
pub const LUA_GCSETSTEPMUL: c_int = bindings::LUA_GCSETSTEPMUL as c_int;
pub const LUA_GCISRUNNING: c_int = bindings::LUA_GCISRUNNING as c_int;
pub const LUA_GCGEN: c_int = bindings::LUA_GCGEN as c_int;
pub const LUA_GCINC: c_int = bindings::LUA_GCINC as c_int;

pub const LUA_MASKCALL: c_int = bindings::LUA_MASKCALL as c_int;
pub const LUA_MASKRET: c_int = bindings::LUA_MASKRET as c_int;
pub const LUA_MASKLINE: c_int = bindings::LUA_MASKLINE as c_int;
pub const LUA_MASKCOUNT: c_int = bindings::LUA_MASKCOUNT as c_int;

pub use {
    bindings::LUA_AUTHORS, bindings::LUA_COPYRIGHT, bindings::LUA_VERSION,
    bindings::LUA_VERSION_MAJOR, bindings::LUA_VERSION_MINOR, bindings::LUA_VERSION_NUM,
    bindings::LUA_VERSION_RELEASE, bindings::LUA_VERSION_RELEASE_NUM,
};

pub use {
    bindings::lua_compare, bindings::lua_getinfo, bindings::lua_getlocal, bindings::lua_getupvalue,
    bindings::lua_rawequal, bindings::lua_sethook, bindings::lua_setlocal,
    bindings::lua_setupvalue,
};

pub use {
    bindings::lua_Alloc, bindings::lua_CFunction, bindings::lua_Debug, bindings::lua_Integer,
    bindings::lua_KContext, bindings::lua_Number, bindings::lua_State, bindings::lua_Unsigned,
    bindings::lua_setcstacklimit,
};

/*
** state manipulation
*/
pub use {
    bindings::lua_atpanic, bindings::lua_close, bindings::lua_newstate, bindings::lua_newthread,
    bindings::lua_resetthread, bindings::lua_version,
};

/*
** basic stack manipulation
*/
pub use {
    bindings::lua_absindex, bindings::lua_checkstack, bindings::lua_copy, bindings::lua_gettop,
    bindings::lua_pushvalue, bindings::lua_rotate, bindings::lua_settop, bindings::lua_xmove,
};

/*
** access functions (stack -> C)
*/
pub use {
    bindings::lua_iscfunction, bindings::lua_isinteger, bindings::lua_isnumber,
    bindings::lua_isstring, bindings::lua_isuserdata, bindings::lua_rawlen,
    bindings::lua_toboolean, bindings::lua_tocfunction, bindings::lua_tointegerx,
    bindings::lua_tolstring, bindings::lua_tonumberx, bindings::lua_topointer,
    bindings::lua_tothread, bindings::lua_touserdata, bindings::lua_type, bindings::lua_typename,
};

/*
** push functions (C -> stack)
*/
pub use {
    bindings::lua_pushboolean, bindings::lua_pushcclosure, bindings::lua_pushfstring,
    bindings::lua_pushinteger, bindings::lua_pushlightuserdata, bindings::lua_pushlstring,
    bindings::lua_pushnil, bindings::lua_pushnumber, bindings::lua_pushstring,
    bindings::lua_pushthread, bindings::lua_pushvfstring,
};

/*
** get functions (Lua -> stack)
*/
pub use {
    bindings::lua_createtable, bindings::lua_getfield, bindings::lua_getglobal, bindings::lua_geti,
    bindings::lua_getiuservalue, bindings::lua_getmetatable, bindings::lua_gettable,
    bindings::lua_newuserdatauv, bindings::lua_rawget, bindings::lua_rawgeti,
    bindings::lua_rawgetp,
};

/*
** set functions (stack -> Lua)
*/
pub use {
    bindings::lua_rawset, bindings::lua_rawseti, bindings::lua_rawsetp, bindings::lua_setfield,
    bindings::lua_setglobal, bindings::lua_seti, bindings::lua_setiuservalue,
    bindings::lua_setmetatable, bindings::lua_settable,
};

/*
** 'load' and 'call' functions (load and run Lua code)
*/

pub use {bindings::lua_callk, bindings::lua_dump, bindings::lua_load, bindings::lua_pcallk};
/*
** coroutine functions
*/
pub use {
    bindings::lua_isyieldable, bindings::lua_resume, bindings::lua_status, bindings::lua_yieldk,
};

/*
** Warning-related functions
*/
pub use {bindings::lua_setwarnf, bindings::lua_warning};

/*
** garbage-collection function and options
*/
pub use bindings::lua_gc;

/*
** miscellaneous functions
*/
pub use {
    bindings::lua_concat, bindings::lua_error, bindings::lua_getallocf, bindings::lua_len,
    bindings::lua_next, bindings::lua_setallocf, bindings::lua_stringtonumber,
    bindings::lua_toclose,
};

/*
** lauxlib.h
*/
pub use {
    bindings::luaL_Buffer, bindings::luaL_Reg, bindings::luaL_Stream, bindings::luaL_addgsub,
    bindings::luaL_addlstring, bindings::luaL_addstring, bindings::luaL_addvalue,
    bindings::luaL_argerror, bindings::luaL_buffinit, bindings::luaL_buffinitsize,
    bindings::luaL_callmeta, bindings::luaL_checkany, bindings::luaL_checkinteger,
    bindings::luaL_checklstring, bindings::luaL_checknumber, bindings::luaL_checkoption,
    bindings::luaL_checkstack, bindings::luaL_checktype, bindings::luaL_checkudata,
    bindings::luaL_error, bindings::luaL_execresult, bindings::luaL_getmetafield,
    bindings::luaL_getsubtable, bindings::luaL_gsub, bindings::luaL_len,
    bindings::luaL_loadbufferx, bindings::luaL_loadfilex, bindings::luaL_loadstring,
    bindings::luaL_newmetatable, bindings::luaL_newstate, bindings::luaL_optinteger,
    bindings::luaL_optlstring, bindings::luaL_optnumber, bindings::luaL_prepbuffsize,
    bindings::luaL_pushresult, bindings::luaL_pushresultsize, bindings::luaL_ref,
    bindings::luaL_requiref, bindings::luaL_setfuncs, bindings::luaL_setmetatable,
    bindings::luaL_testudata, bindings::luaL_tolstring, bindings::luaL_traceback,
    bindings::luaL_typeerror, bindings::luaL_unref, bindings::luaL_where,
};

/*
** lualib.h
*/
pub use {
    bindings::luaopen_base, bindings::luaopen_coroutine, bindings::luaopen_debug,
    bindings::luaopen_io, bindings::luaopen_math, bindings::luaopen_os, bindings::luaopen_package,
    bindings::luaopen_string, bindings::luaopen_table, bindings::luaopen_utf8,
};

// The following are re-implementations of what are macros in the Lua C API
pub unsafe fn lua_getextraspace(state: *mut lua_State) -> *mut c_void {
    (state as *mut c_void).offset(-(mem::size_of::<*mut c_void>() as isize))
}

pub unsafe fn lua_pcall(
    state: *mut lua_State,
    nargs: c_int,
    nresults: c_int,
    msgh: c_int,
) -> c_int {
    lua_pcallk(state, nargs, nresults, msgh, 0, None)
}

pub unsafe fn lua_newuserdata(state: *mut lua_State, s: usize) -> *mut ::std::os::raw::c_void {
    lua_newuserdatauv(state, s, 1)
}

pub unsafe fn lua_getuservalue(state: *mut lua_State, idx: c_int) -> c_int {
    lua_getiuservalue(state, idx, 1)
}

pub unsafe fn lua_setuservalue(state: *mut lua_State, idx: c_int) -> c_int {
    lua_setiuservalue(state, idx, 1)
}

pub unsafe fn lua_tonumber(state: *mut lua_State, idx: c_int) -> lua_Number {
    return lua_tonumberx(state, idx, ptr::null_mut());
}
pub unsafe fn lua_tointeger(state: *mut lua_State, idx: c_int) -> lua_Number {
    return lua_tonumberx(state, idx, ptr::null_mut());
}
pub unsafe fn lua_pop(state: *mut lua_State, n: c_int) {
    lua_settop(state, -(n) - 1);
}
pub unsafe fn lua_isfunction(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TFUNCTION as i32;
}
pub unsafe fn lua_istable(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TTABLE as i32;
}
pub unsafe fn lua_islightuserdata(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TLIGHTUSERDATA as i32;
}
pub unsafe fn lua_isnil(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TNIL as i32;
}
pub unsafe fn lua_isboolean(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TBOOLEAN as i32;
}
pub unsafe fn lua_isthread(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TTHREAD as i32;
}
pub unsafe fn lua_isnone(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TNONE as i32;
}
pub unsafe fn lua_isnoneornil(state: *mut lua_State, n: c_int) -> bool {
    return lua_type(state, n) == LUA_TNONE as i32;
}

pub unsafe fn lua_pushliteral(state: *mut lua_State, str: *const c_char) -> *const c_char {
    return lua_pushstring(state, str);
}

pub unsafe fn lua_pushglobaltable(state: *mut lua_State) {
    lua_rawgeti(state, LUA_REGISTRYINDEX as i32, LUA_RIDX_GLOBALS as i64);
}

pub unsafe fn lua_newtable(state: *mut lua_State) {
    lua_createtable(state, 0, 0);
}

pub unsafe fn lua_register(state: *mut lua_State, n: *const c_char, f: lua_CFunction) {
    lua_pushcfunction(state, f);
    lua_setglobal(state, n);
}

pub unsafe fn lua_pushcfunction(state: *mut lua_State, f: lua_CFunction) {
    lua_pushcclosure(state, f, 0);
}

pub unsafe fn lua_tostring(state: *mut lua_State, i: c_int) -> *const c_char {
    return lua_tolstring(state, i, ptr::null_mut());
}

pub unsafe fn lua_insert(state: *mut lua_State, idx: c_int) {
    lua_rotate(state, idx, 1);
}

pub unsafe fn lua_remove(state: *mut lua_State, idx: c_int) {
    lua_rotate(state, idx, -1);
    lua_pop(state, 1);
}

pub unsafe fn lua_replace(state: *mut lua_State, idx: c_int) {
    lua_copy(state, -1, idx);
    lua_pop(state, 1);
}

pub unsafe fn lua_upvalueindex(index: c_int) -> i32 {
    return LUA_REGISTRYINDEX - index;
}

pub unsafe fn lua_call(state: *mut lua_State, nargs: c_int, nresults: c_int) {
    lua_callk(state, nargs, nresults, 0, None)
}