diff options
Diffstat (limited to 'src/l52util.c')
-rw-r--r-- | src/l52util.c | 117 |
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 | |||
8 | int 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 | |||
14 | void 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 | |||
21 | void 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 | |||
33 | void 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 | |||
39 | void 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 | |||
48 | int 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 | |||
61 | void lutil_getmetatablep (lua_State *L, const void *p) { | ||
62 | lua_rawgetp(L, LUA_REGISTRYINDEX, p); | ||
63 | } | ||
64 | |||
65 | void 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 | |||
71 | int 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 | |||
84 | void *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 | |||
99 | int 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 | |||
112 | void *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 | } | ||