/* ** Compat-5.1 ** Copyright Kepler Project 2004-2006 (http://www.keplerproject.org/compat) ** $Id: compat-5.1.c,v 1.13 2006/02/20 21:12:47 carregal Exp $ */ #include #include #include "lua.h" #include "lauxlib.h" #include "compat-5.1.h" static void getfield(lua_State *L, int idx, const char *name) { const char *end = strchr(name, '.'); lua_pushvalue(L, idx); while (end) { lua_pushlstring(L, name, end - name); lua_gettable(L, -2); lua_remove(L, -2); if (lua_isnil(L, -1)) return; name = end+1; end = strchr(name, '.'); } lua_pushstring(L, name); lua_gettable(L, -2); lua_remove(L, -2); } static void setfield(lua_State *L, int idx, const char *name) { const char *end = strchr(name, '.'); lua_pushvalue(L, idx); while (end) { lua_pushlstring(L, name, end - name); lua_gettable(L, -2); /* create table if not found */ if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushlstring(L, name, end - name); lua_pushvalue(L, -2); lua_settable(L, -4); } lua_remove(L, -2); name = end+1; end = strchr(name, '.'); } lua_pushstring(L, name); lua_pushvalue(L, -3); lua_settable(L, -3); lua_pop(L, 2); } LUALIB_API void luaL_module(lua_State *L, const char *libname, const luaL_reg *l, int nup) { if (libname) { getfield(L, LUA_GLOBALSINDEX, libname); /* check whether lib already exists */ if (lua_isnil(L, -1)) { int env, ns; lua_pop(L, 1); /* get rid of nil */ lua_pushliteral(L, "require"); lua_gettable(L, LUA_GLOBALSINDEX); /* look for require */ lua_getfenv(L, -1); /* getfenv(require) */ lua_remove(L, -2); /* remove function require */ env = lua_gettop(L); lua_newtable(L); /* create namespace for lib */ ns = lua_gettop(L); getfield(L, env, "package.loaded"); /* get package.loaded table */ if (lua_isnil(L, -1)) { /* create package.loaded table */ lua_pop(L, 1); /* remove previous result */ lua_newtable(L); lua_pushvalue(L, -1); setfield(L, env, "package.loaded"); } else if (!lua_istable(L, -1)) luaL_error(L, "name conflict for library `%s'", libname); lua_pushstring(L, libname); lua_pushvalue(L, ns); lua_settable(L, -3); /* package.loaded[libname] = ns */ lua_pop(L, 1); /* get rid of package.loaded table */ lua_pushvalue(L, ns); /* copy namespace */ setfield(L, LUA_GLOBALSINDEX, libname); lua_remove (L, env); /* remove env */ } lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { int i; lua_pushstring(L, l->name); for (i=0; ifunc, nup); lua_settable(L, -(nup+3)); } lua_pop(L, nup); /* remove upvalues */ }