aboutsummaryrefslogtreecommitdiff
path: root/src/l52util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/l52util.c')
-rw-r--r--src/l52util.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/l52util.c b/src/l52util.c
new file mode 100644
index 0000000..592c1d1
--- /dev/null
+++ b/src/l52util.c
@@ -0,0 +1,117 @@
1#include "l52util.h"
2
3#include <memory.h>
4#include <assert.h>
5
6#if LUA_VERSION_NUM >= 502
7
8int luaL_typerror (lua_State *L, int narg, const char *tname) {
9 const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
10 luaL_typename(L, narg));
11 return luaL_argerror(L, narg, msg);
12}
13
14void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l){
15 if(libname) lua_newtable(L);
16 luaL_setfuncs(L, l, 0);
17}
18
19#else
20
21void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup){
22 luaL_checkstack(L, nup, "too many upvalues");
23 for (; l->name != NULL; l++) { /* fill the table with given functions */
24 int i;
25 for (i = 0; i < nup; i++) /* copy upvalues to the top */
26 lua_pushvalue(L, -nup);
27 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
28 lua_setfield(L, -(nup + 2), l->name);
29 }
30 lua_pop(L, nup); /* remove upvalues */
31}
32
33void lua_rawgetp(lua_State *L, int index, const void *p){
34 index = lua_absindex(L, index);
35 lua_pushlightuserdata(L, (void *)p);
36 lua_rawget(L, index);
37}
38
39void lua_rawsetp (lua_State *L, int index, const void *p){
40 index = lua_absindex(L, index);
41 lua_pushlightuserdata(L, (void *)p);
42 lua_insert(L, -2);
43 lua_rawset(L, index);
44}
45
46#endif
47
48int lutil_newmetatablep (lua_State *L, const void *p) {
49 lua_rawgetp(L, LUA_REGISTRYINDEX, p);
50 if (!lua_isnil(L, -1)) /* name already in use? */
51 return 0; /* leave previous value on top, but return 0 */
52 lua_pop(L, 1);
53
54 lua_newtable(L); /* create metatable */
55 lua_pushvalue(L, -1); /* duplicate metatable to set*/
56 lua_rawsetp(L, LUA_REGISTRYINDEX, p);
57
58 return 1;
59}
60
61void lutil_getmetatablep (lua_State *L, const void *p) {
62 lua_rawgetp(L, LUA_REGISTRYINDEX, p);
63}
64
65void lutil_setmetatablep (lua_State *L, const void *p) {
66 lutil_getmetatablep(L, p);
67 assert(lua_istable(L,-1));
68 lua_setmetatable (L, -2);
69}
70
71int lutil_isudatap (lua_State *L, int ud, const void *p) {
72 if (lua_isuserdata(L, ud)){
73 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
74 int res;
75 lutil_getmetatablep(L,p); /* get correct metatable */
76 res = lua_rawequal(L, -1, -2); /* does it have the correct mt? */
77 lua_pop(L, 2); /* remove both metatables */
78 return res;
79 }
80 }
81 return 0;
82}
83
84void *lutil_checkudatap (lua_State *L, int ud, const void *p) {
85 void *up = lua_touserdata(L, ud);
86 if (up != NULL) { /* value is a userdata? */
87 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
88 lutil_getmetatablep(L,p); /* get correct metatable */
89 if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
90 lua_pop(L, 2); /* remove both metatables */
91 return up;
92 }
93 }
94 }
95 luaL_typerror(L, ud, p); /* else error */
96 return NULL; /* to avoid warnings */
97}
98
99int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, int nup) {
100 if (!lutil_newmetatablep(L, p))
101 return 0;
102
103 lua_insert(L, -1 - nup); /* move mt prior upvalues */
104 luaL_setfuncs (L, methods, nup); /* define methods */
105 lua_pushliteral (L, "__index"); /* define metamethods */
106 lua_pushvalue (L, -2);
107 lua_settable (L, -3);
108
109 return 1;
110}
111
112void *lutil_newudatap_impl(lua_State *L, size_t size, const void *p){
113 void *obj = lua_newuserdata (L, size);
114 memset(obj, 0, size);
115 lutil_setmetatablep(L, p);
116 return obj;
117}