aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-07 15:12:52 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-07 15:12:52 -0300
commitd738c8d18bcc5651109b3a46103d6aa983772e68 (patch)
treee66f2f38d7cc1600da3ea19b134c7c21636a3870
parent0270c204c235a495ce4702ac3891eb30752d0c8d (diff)
downloadlua-d738c8d18bcc5651109b3a46103d6aa983772e68.tar.gz
lua-d738c8d18bcc5651109b3a46103d6aa983772e68.tar.bz2
lua-d738c8d18bcc5651109b3a46103d6aa983772e68.zip
New function 'luaL_openselectedlibs'
Makes it easier to start Lua with only some standard libraries.
Diffstat (limited to '')
-rw-r--r--linit.c51
-rw-r--r--ltests.c24
-rw-r--r--ltests.h4
-rw-r--r--lua.c6
-rw-r--r--lualib.h39
-rw-r--r--testes/api.lua14
-rw-r--r--testes/coroutine.lua2
7 files changed, 71 insertions, 69 deletions
diff --git a/linit.c b/linit.c
index 69808f84..675fb65f 100644
--- a/linit.c
+++ b/linit.c
@@ -8,21 +8,6 @@
8#define linit_c 8#define linit_c
9#define LUA_LIB 9#define LUA_LIB
10 10
11/*
12** If you embed Lua in your program and need to open the standard
13** libraries, call luaL_openlibs in your program. If you need a
14** different set of libraries, copy this file to your project and edit
15** it to suit your needs.
16**
17** You can also *preload* libraries, so that a later 'require' can
18** open the library, which is already linked to the application.
19** For that, do the following code:
20**
21** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
22** lua_pushcfunction(L, luaopen_modname);
23** lua_setfield(L, -2, modname);
24** lua_pop(L, 1); // remove PRELOAD table
25*/
26 11
27#include "lprefix.h" 12#include "lprefix.h"
28 13
@@ -36,30 +21,44 @@
36 21
37 22
38/* 23/*
39** these libs are loaded by lua.c and are readily available to any Lua 24** Standard Libraries
40** program
41*/ 25*/
42static const luaL_Reg loadedlibs[] = { 26static const luaL_Reg stdlibs[] = {
43 {LUA_GNAME, luaopen_base}, 27 {LUA_GNAME, luaopen_base},
44 {LUA_LOADLIBNAME, luaopen_package}, 28 {LUA_LOADLIBNAME, luaopen_package},
29
45 {LUA_COLIBNAME, luaopen_coroutine}, 30 {LUA_COLIBNAME, luaopen_coroutine},
46 {LUA_TABLIBNAME, luaopen_table}, 31 {LUA_DBLIBNAME, luaopen_debug},
47 {LUA_IOLIBNAME, luaopen_io}, 32 {LUA_IOLIBNAME, luaopen_io},
33 {LUA_MATHLIBNAME, luaopen_math},
48 {LUA_OSLIBNAME, luaopen_os}, 34 {LUA_OSLIBNAME, luaopen_os},
49 {LUA_STRLIBNAME, luaopen_string}, 35 {LUA_STRLIBNAME, luaopen_string},
50 {LUA_MATHLIBNAME, luaopen_math}, 36 {LUA_TABLIBNAME, luaopen_table},
51 {LUA_UTF8LIBNAME, luaopen_utf8}, 37 {LUA_UTF8LIBNAME, luaopen_utf8},
52 {LUA_DBLIBNAME, luaopen_debug}, 38
53 {NULL, NULL} 39 {NULL, NULL}
54}; 40};
55 41
56 42
57LUALIB_API void luaL_openlibs (lua_State *L) { 43/*
44** require selected standard libraries and add the others to the
45** preload table.
46*/
47LUALIB_API void luaL_openselectedlibs (lua_State *L, int what) {
48 int mask = 1;
58 const luaL_Reg *lib; 49 const luaL_Reg *lib;
59 /* "require" functions from 'loadedlibs' and set results to global table */ 50 luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
60 for (lib = loadedlibs; lib->func; lib++) { 51 for (lib = stdlibs; lib->func; (lib++, mask <<= 1)) {
61 luaL_requiref(L, lib->name, lib->func, 1); 52 if (what & mask) { /* selected? */
62 lua_pop(L, 1); /* remove lib */ 53 luaL_requiref(L, lib->name, lib->func, 1); /* require library */
54 lua_pop(L, 1); /* remove result from the stack */
55 }
56 else { /* add library to PRELOAD table */
57 lua_pushcfunction(L, lib->func);
58 lua_setfield(L, -2, lib->name);
59 }
63 } 60 }
61 lua_assert((mask >> 1) == LUA_UTF8LIBK);
62 lua_pop(L, 1); // remove PRELOAD table
64} 63}
65 64
diff --git a/ltests.c b/ltests.c
index 3f67c23a..d5d2ae68 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1178,31 +1178,15 @@ static lua_State *getstate (lua_State *L) {
1178 1178
1179 1179
1180static int loadlib (lua_State *L) { 1180static int loadlib (lua_State *L) {
1181 static const luaL_Reg libs[] = {
1182 {LUA_GNAME, luaopen_base},
1183 {"coroutine", luaopen_coroutine},
1184 {"debug", luaopen_debug},
1185 {"io", luaopen_io},
1186 {"os", luaopen_os},
1187 {"math", luaopen_math},
1188 {"string", luaopen_string},
1189 {"table", luaopen_table},
1190 {"T", luaB_opentests},
1191 {NULL, NULL}
1192 };
1193 lua_State *L1 = getstate(L); 1181 lua_State *L1 = getstate(L);
1194 int i; 1182 int what = luaL_checkinteger(L, 2);
1195 luaL_requiref(L1, "package", luaopen_package, 0); 1183 luaL_openselectedlibs(L1, what);
1184 luaL_requiref(L1, "T", luaB_opentests, 0);
1196 lua_assert(lua_type(L1, -1) == LUA_TTABLE); 1185 lua_assert(lua_type(L1, -1) == LUA_TTABLE);
1197 /* 'requiref' should not reload module already loaded... */ 1186 /* 'requiref' should not reload module already loaded... */
1198 luaL_requiref(L1, "package", NULL, 1); /* seg. fault if it reloads */ 1187 luaL_requiref(L1, "T", NULL, 1); /* seg. fault if it reloads */
1199 /* ...but should return the same module */ 1188 /* ...but should return the same module */
1200 lua_assert(lua_compare(L1, -1, -2, LUA_OPEQ)); 1189 lua_assert(lua_compare(L1, -1, -2, LUA_OPEQ));
1201 luaL_getsubtable(L1, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
1202 for (i = 0; libs[i].name; i++) {
1203 lua_pushcfunction(L1, libs[i].func);
1204 lua_setfield(L1, -2, libs[i].name);
1205 }
1206 return 0; 1190 return 0;
1207} 1191}
1208 1192
diff --git a/ltests.h b/ltests.h
index ec520498..45d5beba 100644
--- a/ltests.h
+++ b/ltests.h
@@ -103,8 +103,8 @@ LUA_API void *debug_realloc (void *ud, void *block,
103 103
104#if defined(lua_c) 104#if defined(lua_c)
105#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) 105#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
106#define luaL_openlibs(L) \ 106#define luai_openlibs(L) \
107 { (luaL_openlibs)(L); \ 107 { luaL_openlibs(L); \
108 luaL_requiref(L, "T", luaB_opentests, 1); \ 108 luaL_requiref(L, "T", luaB_opentests, 1); \
109 lua_pop(L, 1); } 109 lua_pop(L, 1); }
110#endif 110#endif
diff --git a/lua.c b/lua.c
index 715430a0..af20754e 100644
--- a/lua.c
+++ b/lua.c
@@ -609,6 +609,10 @@ static void doREPL (lua_State *L) {
609 609
610/* }================================================================== */ 610/* }================================================================== */
611 611
612#if !defined(luai_openlibs)
613#define luai_openlibs(L) luaL_openlibs(L)
614#endif
615
612 616
613/* 617/*
614** Main body of stand-alone interpreter (to be called in protected mode). 618** Main body of stand-alone interpreter (to be called in protected mode).
@@ -631,7 +635,7 @@ static int pmain (lua_State *L) {
631 lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ 635 lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
632 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 636 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
633 } 637 }
634 luaL_openlibs(L); /* open standard libraries */ 638 luai_openlibs(L); /* open standard libraries */
635 createargtable(L, argv, argc, script); /* create table 'arg' */ 639 createargtable(L, argv, argc, script); /* create table 'arg' */
636 lua_gc(L, LUA_GCRESTART); /* start GC... */ 640 lua_gc(L, LUA_GCRESTART); /* start GC... */
637 lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */ 641 lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */
diff --git a/lualib.h b/lualib.h
index 26255290..e124cf1b 100644
--- a/lualib.h
+++ b/lualib.h
@@ -14,39 +14,52 @@
14/* version suffix for environment variable names */ 14/* version suffix for environment variable names */
15#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 15#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
16 16
17 17#define LUA_GK 1
18LUAMOD_API int (luaopen_base) (lua_State *L); 18LUAMOD_API int (luaopen_base) (lua_State *L);
19 19
20#define LUA_LOADLIBNAME "package"
21#define LUA_LOADLIBK (LUA_GK << 1)
22LUAMOD_API int (luaopen_package) (lua_State *L);
23
24
20#define LUA_COLIBNAME "coroutine" 25#define LUA_COLIBNAME "coroutine"
26#define LUA_COLIBK (LUA_LOADLIBK << 1)
21LUAMOD_API int (luaopen_coroutine) (lua_State *L); 27LUAMOD_API int (luaopen_coroutine) (lua_State *L);
22 28
23#define LUA_TABLIBNAME "table" 29#define LUA_DBLIBNAME "debug"
24LUAMOD_API int (luaopen_table) (lua_State *L); 30#define LUA_DBLIBK (LUA_COLIBK << 1)
31LUAMOD_API int (luaopen_debug) (lua_State *L);
25 32
26#define LUA_IOLIBNAME "io" 33#define LUA_IOLIBNAME "io"
34#define LUA_IOLIBK (LUA_DBLIBK << 1)
27LUAMOD_API int (luaopen_io) (lua_State *L); 35LUAMOD_API int (luaopen_io) (lua_State *L);
28 36
37#define LUA_MATHLIBNAME "math"
38#define LUA_MATHLIBK (LUA_IOLIBK << 1)
39LUAMOD_API int (luaopen_math) (lua_State *L);
40
29#define LUA_OSLIBNAME "os" 41#define LUA_OSLIBNAME "os"
42#define LUA_OSLIBK (LUA_MATHLIBK << 1)
30LUAMOD_API int (luaopen_os) (lua_State *L); 43LUAMOD_API int (luaopen_os) (lua_State *L);
31 44
32#define LUA_STRLIBNAME "string" 45#define LUA_STRLIBNAME "string"
46#define LUA_STRLIBK (LUA_OSLIBK << 1)
33LUAMOD_API int (luaopen_string) (lua_State *L); 47LUAMOD_API int (luaopen_string) (lua_State *L);
34 48
49#define LUA_TABLIBNAME "table"
50#define LUA_TABLIBK (LUA_STRLIBK << 1)
51LUAMOD_API int (luaopen_table) (lua_State *L);
52
35#define LUA_UTF8LIBNAME "utf8" 53#define LUA_UTF8LIBNAME "utf8"
54#define LUA_UTF8LIBK (LUA_TABLIBK << 1)
36LUAMOD_API int (luaopen_utf8) (lua_State *L); 55LUAMOD_API int (luaopen_utf8) (lua_State *L);
37 56
38#define LUA_MATHLIBNAME "math"
39LUAMOD_API int (luaopen_math) (lua_State *L);
40
41#define LUA_DBLIBNAME "debug"
42LUAMOD_API int (luaopen_debug) (lua_State *L);
43
44#define LUA_LOADLIBNAME "package"
45LUAMOD_API int (luaopen_package) (lua_State *L);
46 57
58/* open selected libraries */
59LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int what);
47 60
48/* open all previous libraries */ 61/* open all libraries */
49LUALIB_API void (luaL_openlibs) (lua_State *L); 62#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0)
50 63
51 64
52#endif 65#endif
diff --git a/testes/api.lua b/testes/api.lua
index bd85a923..f8e36ae3 100644
--- a/testes/api.lua
+++ b/testes/api.lua
@@ -1039,10 +1039,12 @@ assert(a == nil and b == 2) -- 2 == run-time error
1039a, b, c = T.doremote(L1, "return a+") 1039a, b, c = T.doremote(L1, "return a+")
1040assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error 1040assert(a == nil and c == 3 and type(b) == "string") -- 3 == syntax error
1041 1041
1042T.loadlib(L1) 1042T.loadlib(L1, 2) -- load only 'package'
1043a, b, c = T.doremote(L1, [[ 1043a, b, c = T.doremote(L1, [[
1044 string = require'string' 1044 string = require'string'
1045 a = require'_G'; assert(a == _G and require("_G") == a) 1045 local initialG = _G -- not loaded yet
1046 local a = require'_G'; assert(a == _G and require("_G") == a)
1047 assert(initialG == nil and io == nil) -- now we have 'assert'
1046 io = require'io'; assert(type(io.read) == "function") 1048 io = require'io'; assert(type(io.read) == "function")
1047 assert(require("io") == io) 1049 assert(require("io") == io)
1048 a = require'table'; assert(type(a.insert) == "function") 1050 a = require'table'; assert(type(a.insert) == "function")
@@ -1056,7 +1058,7 @@ T.closestate(L1);
1056 1058
1057 1059
1058L1 = T.newstate() 1060L1 = T.newstate()
1059T.loadlib(L1) 1061T.loadlib(L1, 0)
1060T.doremote(L1, "a = {}") 1062T.doremote(L1, "a = {}")
1061T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1; 1063T.testC(L1, [[getglobal "a"; pushstring "x"; pushint 1;
1062 settable -3]]) 1064 settable -3]])
@@ -1436,10 +1438,10 @@ end
1436 1438
1437do -- garbage collection with no extra memory 1439do -- garbage collection with no extra memory
1438 local L = T.newstate() 1440 local L = T.newstate()
1439 T.loadlib(L) 1441 T.loadlib(L, 1 | 2) -- load _G and 'package'
1440 local res = (T.doremote(L, [[ 1442 local res = (T.doremote(L, [[
1441 _ENV = require"_G" 1443 _ENV = _G
1442 local T = require"T" 1444 assert(string == nil)
1443 local a = {} 1445 local a = {}
1444 for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table 1446 for i = 1, 1000 do a[i] = 'i' .. i end -- grow string table
1445 local stsize, stuse = T.querystr() 1447 local stsize, stuse = T.querystr()
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 15fccc30..f05672a5 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -694,7 +694,7 @@ else
694 694
695 T.testC(state, "settop 0") 695 T.testC(state, "settop 0")
696 696
697 T.loadlib(state) 697 T.loadlib(state, 1 | 2) -- load _G and 'package'
698 698
699 assert(T.doremote(state, [[ 699 assert(T.doremote(state, [[
700 coroutine = require'coroutine'; 700 coroutine = require'coroutine';