mirror of
https://github.com/lua/lua
synced 2024-11-22 04:41:23 +03:00
New function 'luaL_openselectedlibs'
Makes it easier to start Lua with only some standard libraries.
This commit is contained in:
parent
0270c204c2
commit
d738c8d18b
51
linit.c
51
linit.c
@ -8,21 +8,6 @@
|
||||
#define linit_c
|
||||
#define LUA_LIB
|
||||
|
||||
/*
|
||||
** If you embed Lua in your program and need to open the standard
|
||||
** libraries, call luaL_openlibs in your program. If you need a
|
||||
** different set of libraries, copy this file to your project and edit
|
||||
** it to suit your needs.
|
||||
**
|
||||
** You can also *preload* libraries, so that a later 'require' can
|
||||
** open the library, which is already linked to the application.
|
||||
** For that, do the following code:
|
||||
**
|
||||
** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
** lua_pushcfunction(L, luaopen_modname);
|
||||
** lua_setfield(L, -2, modname);
|
||||
** lua_pop(L, 1); // remove PRELOAD table
|
||||
*/
|
||||
|
||||
#include "lprefix.h"
|
||||
|
||||
@ -36,30 +21,44 @@
|
||||
|
||||
|
||||
/*
|
||||
** these libs are loaded by lua.c and are readily available to any Lua
|
||||
** program
|
||||
** Standard Libraries
|
||||
*/
|
||||
static const luaL_Reg loadedlibs[] = {
|
||||
static const luaL_Reg stdlibs[] = {
|
||||
{LUA_GNAME, luaopen_base},
|
||||
{LUA_LOADLIBNAME, luaopen_package},
|
||||
|
||||
{LUA_COLIBNAME, luaopen_coroutine},
|
||||
{LUA_TABLIBNAME, luaopen_table},
|
||||
{LUA_DBLIBNAME, luaopen_debug},
|
||||
{LUA_IOLIBNAME, luaopen_io},
|
||||
{LUA_MATHLIBNAME, luaopen_math},
|
||||
{LUA_OSLIBNAME, luaopen_os},
|
||||
{LUA_STRLIBNAME, luaopen_string},
|
||||
{LUA_MATHLIBNAME, luaopen_math},
|
||||
{LUA_TABLIBNAME, luaopen_table},
|
||||
{LUA_UTF8LIBNAME, luaopen_utf8},
|
||||
{LUA_DBLIBNAME, luaopen_debug},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
LUALIB_API void luaL_openlibs (lua_State *L) {
|
||||
/*
|
||||
** require selected standard libraries and add the others to the
|
||||
** preload table.
|
||||
*/
|
||||
LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) {
|
||||
int mask = 1;
|
||||
const luaL_Reg *lib;
|
||||
/* "require" functions from 'loadedlibs' and set results to global table */
|
||||
for (lib = loadedlibs; lib->func; lib++) {
|
||||
luaL_requiref(L, lib->name, lib->func, 1);
|
||||
lua_pop(L, 1); /* remove lib */
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) {
|
||||
if (what & mask) { /* selected? */
|
||||
luaL_requiref(L, lib->name, lib->func, 1); /* require library */
|
||||
lua_pop(L, 1); /* remove result from the stack */
|
||||
}
|
||||
else { /* add library to PRELOAD table */
|
||||
lua_pushcfunction(L, lib->func);
|
||||
lua_setfield(L, -2, lib->name);
|
||||
}
|
||||
}
|
||||
lua_assert((mask >> 1) == LUA_UTF8LIBK);
|
||||
lua_pop(L, 1); // remove PRELOAD table
|
||||
}
|
||||
|
||||
|
24
ltests.c
24
ltests.c
@ -1178,31 +1178,15 @@ static lua_State *getstate (lua_State *L) {
|
||||
|
||||
|
||||
static int loadlib (lua_State *L) {
|
||||
static const luaL_Reg libs[] = {
|
||||
{LUA_GNAME, luaopen_base},
|
||||
{"coroutine", luaopen_coroutine},
|
||||
{"debug", luaopen_debug},
|
||||
{"io", luaopen_io},
|
||||
{"os", luaopen_os},
|
||||
{"math", luaopen_math},
|
||||
{"string", luaopen_string},
|
||||
{"table", luaopen_table},
|
||||
{"T", luaB_opentests},
|
||||
{NULL, NULL}
|
||||
};
|
||||
lua_State *L1 = getstate(L);
|
||||
int i;
|
||||
luaL_requiref(L1, "package", luaopen_package, 0);
|
||||
int what = luaL_checkinteger(L, 2);
|
||||
luaL_openselectedlibs(L1, what);
|
||||
luaL_requiref(L1, "T", luaB_opentests, 0);
|
||||
lua_assert(lua_type(L1, -1) == LUA_TTABLE);
|
||||
/* 'requiref' should not reload module already loaded... */
|
||||
luaL_requiref(L1, "package", NULL, 1); /* seg. fault if it reloads */
|
||||
luaL_requiref(L1, "T", NULL, 1); /* seg. fault if it reloads */
|
||||
/* ...but should return the same module */
|
||||
lua_assert(lua_compare(L1, -1, -2, LUA_OPEQ));
|
||||
luaL_getsubtable(L1, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
for (i = 0; libs[i].name; i++) {
|
||||
lua_pushcfunction(L1, libs[i].func);
|
||||
lua_setfield(L1, -2, libs[i].name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
4
ltests.h
4
ltests.h
@ -103,8 +103,8 @@ LUA_API void *debug_realloc (void *ud, void *block,
|
||||
|
||||
#if defined(lua_c)
|
||||
#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
|
||||
#define luaL_openlibs(L) \
|
||||
{ (luaL_openlibs)(L); \
|
||||
#define luai_openlibs(L) \
|
||||
{ luaL_openlibs(L); \
|
||||
luaL_requiref(L, "T", luaB_opentests, 1); \
|
||||
lua_pop(L, 1); }
|
||||
#endif
|
||||
|
6
lua.c
6
lua.c
@ -609,6 +609,10 @@ static void doREPL (lua_State *L) {
|
||||
|
||||
/* }================================================================== */
|
||||
|
||||
#if !defined(luai_openlibs)
|
||||
#define luai_openlibs(L) luaL_openlibs(L)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Main body of stand-alone interpreter (to be called in protected mode).
|
||||
@ -631,7 +635,7 @@ static int pmain (lua_State *L) {
|
||||
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
|
||||
}
|
||||
luaL_openlibs(L); /* open standard libraries */
|
||||
luai_openlibs(L); /* open standard libraries */
|
||||
createargtable(L, argv, argc, script); /* create table 'arg' */
|
||||
lua_gc(L, LUA_GCRESTART); /* start GC... */
|
||||
lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */
|
||||
|
67
lualib.h
67
lualib.h
@ -14,39 +14,52 @@
|
||||
/* version suffix for environment variable names */
|
||||
#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
|
||||
|
||||
|
||||
#define LUA_GK 1
|
||||
LUAMOD_API int (luaopen_base) (lua_State *L);
|
||||
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
LUAMOD_API int (luaopen_coroutine) (lua_State *L);
|
||||
|
||||
#define LUA_TABLIBNAME "table"
|
||||
LUAMOD_API int (luaopen_table) (lua_State *L);
|
||||
|
||||
#define LUA_IOLIBNAME "io"
|
||||
LUAMOD_API int (luaopen_io) (lua_State *L);
|
||||
|
||||
#define LUA_OSLIBNAME "os"
|
||||
LUAMOD_API int (luaopen_os) (lua_State *L);
|
||||
|
||||
#define LUA_STRLIBNAME "string"
|
||||
LUAMOD_API int (luaopen_string) (lua_State *L);
|
||||
|
||||
#define LUA_UTF8LIBNAME "utf8"
|
||||
LUAMOD_API int (luaopen_utf8) (lua_State *L);
|
||||
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
LUAMOD_API int (luaopen_math) (lua_State *L);
|
||||
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
LUAMOD_API int (luaopen_debug) (lua_State *L);
|
||||
|
||||
#define LUA_LOADLIBNAME "package"
|
||||
#define LUA_LOADLIBK (LUA_GK << 1)
|
||||
LUAMOD_API int (luaopen_package) (lua_State *L);
|
||||
|
||||
|
||||
/* open all previous libraries */
|
||||
LUALIB_API void (luaL_openlibs) (lua_State *L);
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
#define LUA_COLIBK (LUA_LOADLIBK << 1)
|
||||
LUAMOD_API int (luaopen_coroutine) (lua_State *L);
|
||||
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
#define LUA_DBLIBK (LUA_COLIBK << 1)
|
||||
LUAMOD_API int (luaopen_debug) (lua_State *L);
|
||||
|
||||
#define LUA_IOLIBNAME "io"
|
||||
#define LUA_IOLIBK (LUA_DBLIBK << 1)
|
||||
LUAMOD_API int (luaopen_io) (lua_State *L);
|
||||
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
#define LUA_MATHLIBK (LUA_IOLIBK << 1)
|
||||
LUAMOD_API int (luaopen_math) (lua_State *L);
|
||||
|
||||
#define LUA_OSLIBNAME "os"
|
||||
#define LUA_OSLIBK (LUA_MATHLIBK << 1)
|
||||
LUAMOD_API int (luaopen_os) (lua_State *L);
|
||||
|
||||
#define LUA_STRLIBNAME "string"
|
||||
#define LUA_STRLIBK (LUA_OSLIBK << 1)
|
||||
LUAMOD_API int (luaopen_string) (lua_State *L);
|
||||
|
||||
#define LUA_TABLIBNAME "table"
|
||||
#define LUA_TABLIBK (LUA_STRLIBK << 1)
|
||||
LUAMOD_API int (luaopen_table) (lua_State *L);
|
||||
|
||||
#define LUA_UTF8LIBNAME "utf8"
|
||||
#define LUA_UTF8LIBK (LUA_TABLIBK << 1)
|
||||
LUAMOD_API int (luaopen_utf8) (lua_State *L);
|
||||
|
||||
|
||||
/* open selected libraries */
|
||||
LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what);
|
||||
|
||||
/* open all libraries */
|
||||
#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1039,10 +1039,12 @@ assert(a == nil and b == 2) -- 2 == run-time error
|
||||
a, b, c = T.doremote(L1, "return a+")
|
||||
assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error
|
||||
|
||||
T.loadlib(L1)
|
||||
T.loadlib(L1, 2) -- load only 'package'
|
||||
a, b, c = T.doremote(L1, [[
|
||||
string = require'string'
|
||||
a = require'_G'; assert(a == _G and require("_G") == a)
|
||||
local initialG = _G -- not loaded yet
|
||||
local a = require'_G'; assert(a == _G and require("_G") == a)
|
||||
assert(initialG == nil and io == nil) -- now we have 'assert'
|
||||
io = require'io'; assert(type(io.read) == "function")
|
||||
assert(require("io") == io)
|
||||
a = require'table'; assert(type(a.insert) == "function")
|
||||
@ -1056,7 +1058,7 @@ T.closestate(L1);
|
||||
|
||||
|
||||
L1 = T.newstate()
|
||||
T.loadlib(L1)
|
||||
T.loadlib(L1, 0)
|
||||
T.doremote(L1, "a = {}")
|
||||
T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1;
|
||||
settable -3]])
|
||||
@ -1436,10 +1438,10 @@ end
|
||||
|
||||
do -- garbage collection with no extra memory
|
||||
local L = T.newstate()
|
||||
T.loadlib(L)
|
||||
T.loadlib(L, 1 | 2) -- load _G and 'package'
|
||||
local res = (T.doremote(L, [[
|
||||
_ENV = require"_G"
|
||||
local T = require"T"
|
||||
_ENV = _G
|
||||
assert(string == nil)
|
||||
local a = {}
|
||||
for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table
|
||||
local stsize, stuse = T.querystr()
|
||||
|
@ -694,7 +694,7 @@ else
|
||||
|
||||
T.testC(state, "settop 0")
|
||||
|
||||
T.loadlib(state)
|
||||
T.loadlib(state, 1 | 2) -- load _G and 'package'
|
||||
|
||||
assert(T.doremote(state, [[
|
||||
coroutine = require'coroutine';
|
||||
|
Loading…
Reference in New Issue
Block a user