/****************************************************************************** * Author: Alexey Melnichuk <mimir@newmail.ru> * * Copyright (C) 2014 Alexey Melnichuk <mimir@newmail.ru> * * Licensed according to the included 'LICENSE' document * * This file is part of lua-lcurl library. ******************************************************************************/ #include "l52util.h" #include <memory.h> #include <string.h> /* for memset */ #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); } #ifndef luaL_register void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l){ if(libname) lua_newtable(L); luaL_setfuncs(L, l, 0); } #endif #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, (const char*)p); /* else error */ return NULL; /* to avoid warnings */ } int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, int nup) { if (!lutil_newmetatablep(L, p)){ lua_insert(L, -1 - nup); /* move mt prior upvalues */ return 0; } lua_insert(L, -1 - nup); /* move mt prior upvalues */ luaL_setfuncs (L, methods, nup); /* define methods */ lua_pushliteral (L, "__index"); /* define metamethods */ 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; } void lutil_pushint64(lua_State *L, int64_t v){ if(sizeof(lua_Integer) >= sizeof(int64_t)){ lua_pushinteger(L, (lua_Integer)v); return; } lua_pushnumber(L, (lua_Number)v); } int64_t lutil_checkint64(lua_State *L, int idx){ if(sizeof(lua_Integer) >= sizeof(int64_t)) return luaL_checkinteger(L, idx); return (int64_t)luaL_checknumber(L, idx); } int64_t lutil_optint64(lua_State *L, int idx, int64_t v){ if(sizeof(lua_Integer) >= sizeof(int64_t)) return luaL_optinteger(L, idx, v); return (int64_t)luaL_optnumber(L, idx, v); } void lutil_pushnvalues(lua_State *L, int n){ for(;n;--n) lua_pushvalue(L, -n); } int lutil_is_null(lua_State *L, int i){ return lua_islightuserdata(L, i) && 0 == lua_touserdata(L, i); } void lutil_push_null(lua_State *L){ lua_pushlightuserdata(L, (void*)0); }