Libraries may be registered with an API using the libraries
API feature.
Example:
#include <primer/api/libraries.hpp> struct my_api : primer::api::base<my_api> { { ... API_FEATURE(primer::api::libraries<lua_base_lib, lua_table_lib, lua_debug_lib, lua_coroutine_lib>, libs_); ... };
Here, an individual library is a struct
with static class members
const char
* name
and luaCFunction func.
For instance,
struct lua_base_lib { static constexpr const char * name = ""; static constexpr lua_CFunction func = &luaopen_base; };
There are corresponding definitions in primer for the following:
primer::api::lua_base_lib primer::api::lua_table_lib primer::api::lua_string_lib primer::api::lua_math_lib primer::api::lua_coroutine_lib primer::api::lua_debug_lib primer::api::lua_io_lib primer::api::lua_os_lib
There are also some "sandboxed" versions of some of these libs to help in situations where you want a tightly encapsulated lua vm.
struct lua_base_lib_sandboxed { static constexpr const char * name = ""; static int get_clean_base(lua_State * L) { luaopen_base(L); lua_pushnil(L); lua_setfield(L, -2, "print"); lua_pushnil(L); lua_setfield(L, -2, "loadfile"); lua_pushnil(L); lua_setfield(L, -2, "dofile"); return 1; } static constexpr lua_CFunction func = &get_clean_base; };
Besides this there are
primer::api::lua_math_lib_sandboxed
You can easily make your own sandboxing decisions of course.
The libraries object itself
has no data members and no nontrivial initialization.
The libraries feature does
the following:
When initialize_api is
called,
_LOADED
registry table as usual with lua,
There are also three typedefs which shorten the list of libraries:
API_FEATURE(primer::api::basic_libraries, libs_); // Only base, table, string, math, and coroutine
API_FEATURE(primer::api::all_core_libraries, libs_); // All standard libraries: at time of writing, basic, table, string, math, io, os, debug, coroutine
API_FEATURE(primer::api::sanbdoxed_basic_libraries, libs_); // Same as basic, but with sandboxed versions of base lib and math lib.