-
Notifications
You must be signed in to change notification settings - Fork 1
/
lextlib_lua52.h
120 lines (94 loc) · 3.89 KB
/
lextlib_lua52.h
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
#ifndef LEXTLIB_LUA52_H
#define LEXTLIB_LUA52_H
#include <assert.h>
#include <lua.h>
#include <lauxlib.h>
#if LUA_VERSION_NUM < 502
/* Error codes for lua_load: */
# define LUA_OK 0
/* WARNING: This error does not exist in Lua 5.1 */
# define LUA_ERRGCMM (-1)
/* Comparison types for lua_compare: */
# define LUA_OPEQ 0
# define LUA_OPLT 1
# define LUA_OPLE 2
/* WARNING: Not entirely correct, but should work anyway */
# define lua_rawlen lua_objlen
# define lua_absindex(L, i) (((i) > 0 || (i) < LUA_REGISTRYINDEX) ? (i) : lua_gettop(L)+(i)+1)
/* WARNING: Something very different, but it might get your job done */
# define lua_getuservalue lua_getfenv
# define lua_setuservalue lua_setfenv
/* WARNING: Probably slower than Lua 5.2's implementation */
# define lua_compare luaX52_lua_compare
# define lua_tonumberx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tonumber(L,(i))) : (*(b)=0, 0))
# define lua_tointegerx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tointeger(L,(i))) : (*(b)=0, 0))
# define luaL_getsubtable luaX52_luaL_getsubtable
# define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
# define luaL_newlibtable(L,l) (lua_createtable(L,0,sizeof(l)))
# define luaL_requiref(L,l,f,g) luaX52_luaL_requiref(L,(l),(f),(g))
# define luaL_setfuncs luaX52_luaL_setfuncs
# define luaL_setmetatable(L,t) (luaL_getmetatable(L,t), lua_setmetatable(L,-2))
# define luaL_testudata(L,i,t) luaX52_luaL_testudata(L,(i),(t))
static inline void luaX52_luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
for (int i = 0; i < nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
lua_setfield(L, -(nup + 2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
}
static inline int luaX52_lua_compare(lua_State *L, int index1, int index2, int op) {
assert(op == LUA_OPEQ || op == LUA_OPLT || op == LUA_OPLE);
switch (op) {
case LUA_OPEQ:
return lua_equal(L, index1, index2);
case LUA_OPLT:
return lua_lessthan(L, index1, index2);
case LUA_OPLE:
return lua_lessthan(L, index1, index2) || lua_equal(L, index1, index2);
default:
return luaL_error(L, "Call to lua_compare with unsupported operator %d", op);
}
}
static inline int luaX52_luaL_getsubtable(lua_State *L, int idx, const char *fname) {
lua_getfield(L, idx, fname);
if (lua_istable(L, -1)) return 1; /* table already there */
else {
lua_pop(L, 1); /* remove previous result */
idx = lua_absindex(L, idx);
lua_newtable(L);
lua_pushvalue(L, -1); /* copy to be left at top */
lua_setfield(L, idx, fname); /* assign new table to field */
return 0; /* false, because did not find table there */
}
}
static inline void luaX52_luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) {
lua_pushcfunction(L, openf);
lua_pushstring(L, modname); /* argument to open function */
lua_call(L, 1, 1); /* open module */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
lua_pushvalue(L, -2); /* make copy of module (call result) */
lua_setfield(L, -2, modname); /* _LOADED[modname] = module */
lua_pop(L, 1); /* remove _LOADED table */
if (glb) {
lua_pushvalue(L, -1); /* copy of 'mod' */
lua_setglobal(L, modname); /* _G[modname] = module */
}
}
static inline void *luaX52_luaL_testudata(lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return NULL; /* value is not a userdata with a metatable */
}
#endif
#endif