Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/lua-winreg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/l52util.c')
-rw-r--r--src/l52util.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/l52util.c b/src/l52util.c
new file mode 100644
index 0000000..5675114
--- /dev/null
+++ b/src/l52util.c
@@ -0,0 +1,119 @@
+#include "l52util.h"
+
+#include <memory.h>
+#include <assert.h>
+
+#if LUA_VERSION_NUM >= 502
+
+int luaL_typerror (lua_State *L, int narg, const char *tname) {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
+ luaL_typename(L, narg));
+ return luaL_argerror(L, narg, msg);
+}
+
+void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l){
+ if(libname) lua_newtable(L);
+ luaL_setfuncs(L, l, 0);
+}
+
+#else
+
+void 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 */
+ int i;
+ for (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 */
+}
+
+void lua_rawgetp(lua_State *L, int index, const void *p){
+ index = lua_absindex(L, index);
+ lua_pushlightuserdata(L, (void *)p);
+ lua_rawget(L, index);
+}
+
+void lua_rawsetp (lua_State *L, int index, const void *p){
+ index = lua_absindex(L, index);
+ lua_pushlightuserdata(L, (void *)p);
+ lua_insert(L, -2);
+ lua_rawset(L, index);
+}
+
+#endif
+
+int lutil_newmetatablep (lua_State *L, const void *p) {
+ lua_rawgetp(L, LUA_REGISTRYINDEX, p);
+ if (!lua_isnil(L, -1)) /* name already in use? */
+ return 0; /* leave previous value on top, but return 0 */
+ lua_pop(L, 1);
+
+ lua_newtable(L); /* create metatable */
+ lua_pushvalue(L, -1); /* duplicate metatable to set*/
+ lua_rawsetp(L, LUA_REGISTRYINDEX, p);
+
+ return 1;
+}
+
+void lutil_getmetatablep (lua_State *L, const void *p) {
+ lua_rawgetp(L, LUA_REGISTRYINDEX, p);
+}
+
+void lutil_setmetatablep (lua_State *L, const void *p) {
+ lutil_getmetatablep(L, p);
+ assert(lua_istable(L,-1));
+ lua_setmetatable (L, -2);
+}
+
+int lutil_isudatap (lua_State *L, int ud, const void *p) {
+ if (lua_isuserdata(L, ud)){
+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
+ int res;
+ lutil_getmetatablep(L,p); /* get correct metatable */
+ res = lua_rawequal(L, -1, -2); /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return res;
+ }
+ }
+ return 0;
+}
+
+void *lutil_checkudatap (lua_State *L, int ud, const void *p) {
+ void *up = lua_touserdata(L, ud);
+ if (up != NULL) { /* value is a userdata? */
+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
+ lutil_getmetatablep(L,p); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return up;
+ }
+ }
+ }
+ luaL_typerror(L, ud, p); /* else error */
+ return NULL; /* to avoid warnings */
+}
+
+int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods) {
+ if (!lutil_newmetatablep(L, p))
+ return 0;
+
+ /* define methods */
+ luaL_setfuncs (L, methods, 0);
+
+ /* define metamethods */
+ lua_pushliteral (L, "__index");
+ lua_pushvalue (L, -2);
+ lua_settable (L, -3);
+
+ return 1;
+}
+
+void *lutil_newudatap_impl(lua_State *L, size_t size, const void *p){
+ void *obj = lua_newuserdata (L, size);
+ memset(obj, 0, size);
+ lutil_setmetatablep(L, p);
+ return obj;
+}