|
|
- /*
- ** 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 <stdio.h>
- #include <string.h>
- #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; i<nup; i++) /* copy upvalues to the top */
- lua_pushvalue(L, -(nup+1));
- lua_pushcclosure(L, l->func, nup);
- lua_settable(L, -(nup+3));
- }
- lua_pop(L, nup); /* remove upvalues */
- }
-
|