65 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua) 66 #define LOG_LUA LOG_STREAM(info, log_scripting_lua) 67 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua) 68 #define ERR_LUA LOG_STREAM(err, log_scripting_lua) 71 static const char *
Gen =
"name generator";
73 static const char *
Interp =
"lua interpreter";
88 if(vop ==
OP_INVALID)
return luaL_argerror(L, 2,
"unknown version comparison operator - allowed are ==, !=, <, <=, > and >=");
104 DBG_LUA <<
"intf_print called:\n";
108 for (std::size_t
i = 1;
i <= nargs; ++
i) {
114 LOG_LUA <<
"'tostring' must return a value to 'print'\n";
121 DBG_LUA <<
"'" << str <<
"'\n";
133 static const char*
const prefix =
"Warning:\n ";
134 static std::ostringstream warning(prefix);
135 warning.seekp(0, std::ios::end);
136 warning << msg <<
' ';
143 auto& lk = lua_kernel_base::get_lua_kernel<lua_kernel_base>(L);
151 DBG_LUA <<
"'" << msg <<
"'\n";
166 return luaL_argerror(L, 3,
"binary chunks are not allowed for security reasons");
183 if(upvalue_name ==
nullptr) {
196 std::string message =
"There is already an external logger attached to this lua kernel, you cannot open the lua console right now.";
224 if(type ==
"markov" || type ==
"markov_chain") {
225 std::vector<std::string> input;
227 input = lua_check<std::vector<std::string>>(L, 2);
235 assert(static_cast<void*>(gen) == dynamic_cast<markov_generator*>(gen));
236 }
else if(type ==
"context_free" || type ==
"cfg" || type ==
"CFG") {
238 std::map<std::string, std::vector<std::string>> data;
241 lua_pushstring(L,
"CFG generator: invalid nonterminal name (must be a string)");
246 if(productions.size() > 1) {
247 deprecated_message(
"wesnoth.name_generator('cfg', {nonterminal = 'a|b'})",
DEP_LEVEL::INDEFINITE,
"1.17",
"Non-terminals should now be assigned an array of productions instead of a single string containing productions separated by | - but a single string is fine if it's only one production");
250 const auto&
split = lua_check<std::vector<t_string>>(L, -1);
254 lua_pushstring(L,
"CFG generator: invalid nonterminal value (must be a string or list of strings)");
265 assert(static_cast<void*>(gen) == dynamic_cast<context_free_grammar_generator*>(gen));
268 return luaL_argerror(L, 1,
"should be either 'markov_chain' or 'context_free'");
291 double r_max =
static_cast<double>(std::numeric_limits<uint32_t>::max());
299 min = lua_check<int32_t>(L, 1);
300 max = lua_check<int32_t>(L, 2);
304 max = lua_check<int32_t>(L, 1);
322 if(msg.empty() || msg.back() !=
'\n') {
326 if(logger ==
"err" || logger ==
"error") {
328 }
else if(logger ==
"warn" || logger ==
"wrn" || logger ==
"warning") {
330 }
else if((logger ==
"debug" || logger ==
"dbg")) {
398 template <member_callback method>
400 return ((lua_kernel_base::get_lua_kernel<lua_kernel_base>(L)).*method)(L);
415 cmd_log_ <<
"Adding boost function proxy...\n";
421 cmd_log_ <<
"Adding standard libs...\n";
450 if(strcmp(
function,
"clock") == 0 || strcmp(
function,
"date") == 0
451 || strcmp(
function,
"time") == 0 || strcmp(
function,
"difftime") == 0)
continue;
464 cmd_log_ <<
"Adding error handler...\n";
471 cmd_log_ <<
"Registering basic wesnoth API...\n";
480 {
"dofile", &dispatch<&lua_kernel_base::intf_dofile> },
481 {
"require", &dispatch<&lua_kernel_base::intf_require> },
482 {
"kernel_type", &dispatch<&lua_kernel_base::intf_kernel_type> },
510 cmd_log_ <<
"Redirecting print function...\n";
525 cmd_log_ <<
"Initializing package repository...\n";
535 cmd_log_ <<
"Error: Failed to initialize package repository. Falling back to less flexible C++ implementation.\n";
539 cmd_log_ <<
"Adding map table...\n";
541 static luaL_Reg const map_callbacks[] {
563 cmd_log_ <<
"Adding game_config table...\n";
579 cmd_log_ <<
"Adding rng tables...\n";
582 cmd_log_ <<
"Adding name generator metatable...\n";
597 cmd_log_ <<
"Sandboxing Lua interpreter...\nTo make variables visible outside the interpreter, assign to _G.variable.\n";
598 cmd_log_ <<
"The special variable _ holds the result of the last expression (if any).\n";
617 cmd_log_ <<
"Failed to activate strict mode.\n";
619 cmd_log_ <<
"Activated strict mode.\n";
624 cmd_log_ <<
"Error: failed to load ilua.\n";
635 if(strcmp(
function,
"traceback") == 0 || strcmp(
function,
"getinfo") == 0)
continue;
652 ERR_LUA << context <<
": " << msg <<
'\n';
684 std::string context =
"When executing, ";
686 context +=
"Lua runtime error: ";
688 context +=
"Lua error in attached debugger: ";
690 context +=
"Lua out of memory error: ";
692 context +=
"unknown lua error: ";
695 context += msg ?
msg :
"null string";
702 e_h(context.c_str(),
"Lua Error");
716 std::string message = msg ?
msg :
"null string";
718 std::string context =
"When parsing a string to lua, ";
721 context +=
" a syntax error";
723 context +=
" a memory error";
725 context +=
" an unknown error";
730 e_h(message.c_str(), context.c_str());
744 this->
run(cfg[
"code"].str().c_str(), cfg[
"name"].str(), nArgs);
775 std::string experiment =
"return ";
784 this->
load_string(experiment.c_str(),
"interactive", eh);
809 for(
int i = top + 2;
i < env_idx;
i++)
847 return luaL_argerror(L, 1,
"found a null string argument to wesnoth require");
869 DBG_LUA <<
"require: loaded a file, now calling it\n";
911 std::string err_msg =
"unknown modifiable property of game_config: ";
937 cmd_log_ <<
"Error: Failed to load core.\n";
947 std::vector<std::string> ret;
970 std::vector<std::string> ret;
971 std::string base_path = input;
972 std::size_t last_dot = base_path.find_last_of(
'.');
973 std::string partial_name = base_path.substr(last_dot + 1);
974 base_path.erase(last_dot);
975 std::string
load =
"return " + base_path;
982 LOG_LUA <<
"Error when attempting tab completion:\n";
997 ret = lua_check<std::vector<std::string>>(L, -1);
999 LOG_LUA <<
"Userdata missing __tab_enum meta-function for tab completion";
1011 if(!isalpha(attr[0]) && attr[0] !=
'_') {
1014 if(std::any_of(attr.begin(), attr.end(), [](
char c){
1015 return !isalpha(
c) && !isdigit(
c) &&
c !=
'_';
1019 if(attr.substr(0, partial_name.size()) == partial_name) {
1020 ret.push_back(base_path +
"." + attr);
1033 #pragma GCC diagnostic push 1034 #pragma GCC diagnostic ignored "-Wold-style-cast" 1038 #pragma GCC diagnostic pop int dispatch(lua_State *L)
void interactive_run(char const *prog)
Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it nor...
LUALIB_API void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb)
#define lua_isnoneornil(L, n)
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
static int intf_name_generator(lua_State *L)
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
#define lua_pushcfunction(L, f)
int show_lua_console(lua_State *, lua_kernel_base *lk)
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
std::string register_tstring_metatable(lua_State *L)
Adds the tstring metatable.
int intf_read_file(lua_State *L)
Reads a file into a string, or a directory into a list of files therein.
LUALIB_API lua_State * luaL_newstate(void)
LUAMOD_API int luaopen_debug(lua_State *L)
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
LUA_API void lua_settop(lua_State *L, int idx)
LUA_API int lua_type(lua_State *L, int idx)
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
int intf_have_file(lua_State *L)
Checks if a file exists (not necessarily a Lua script).
Interfaces for manipulating version numbers of engine, add-ons, etc.
static int intf_get_image_size(lua_State *L)
Gets the dimension of an image.
LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
int intf_canonical_path(lua_State *L)
LUA_API void lua_pushboolean(lua_State *L, int b)
VERSION_COMP_OP parse_version_op(const std::string &op_str)
std::vector< game_tip > load(const config &cfg)
Loads the tips from a config.
std::function< void(char const *, char const *)> error_handler
std::string generate(const std::map< std::string, std::string > &variables) const
int intf_get_direction(lua_State *L)
Expose map_location::get_direction function to lua Arg 1: a location Arg 2: a direction Arg 3: (optio...
LUALIB_API int luaL_getmetafield(lua_State *L, int obj, const char *event)
LUA_API int lua_gettop(lua_State *L)
LUA_API int lua_gettable(lua_State *L, int idx)
LUAMOD_API int luaopen_math(lua_State *L)
LUA_API int lua_getglobal(lua_State *L, const char *name)
LUA_API void lua_settable(lua_State *L, int idx)
#define return_string_attrib(name, accessor)
int intf_textdomain(lua_State *L)
Creates an interface for gettext.
std::vector< std::tuple< std::string, std::string > > registered_widget_definitions_
LUA_API int lua_rawget(lua_State *L, int idx)
#define luaL_getmetatable(L, n)
int intf_kernel_type(lua_State *L)
virtual ~lua_kernel_base()
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int arg, lua_Integer def)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
LUA_API int lua_isuserdata(lua_State *L, int idx)
void lua_push(lua_State *L, const T &val)
#define LOG_STREAM(level, domain)
static lg::log_domain log_scripting_lua("scripting/lua")
bool do_version_check(const version_info &a, VERSION_COMP_OP op, const version_info &b)
int luaW_open(lua_State *L)
LUA_API int lua_absindex(lua_State *L, int idx)
int intf_vector_diff(lua_State *L)
Expose map_location::vector_difference to lua.
LUAMOD_API int luaopen_base(lua_State *L)
int intf_distance_between(lua_State *L)
Expose map_location distance_between.
void remove_single_widget_definition(const std::string &widget_type, const std::string &definition_id)
Removes a widget definition from the default GUI.
int intf_rotate_right_around_center(lua_State *L)
Expose map_location::rotate_right_around_center to lua.
static void impl_warn(void *p, const char *msg, int tocont)
int intf_get_relative_dir(lua_State *L)
Expose map_location get_relative_dir.
LUAMOD_API int luaopen_coroutine(lua_State *L)
void lua_warning(lua_State *L, const char *msg, int tocont)
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
LUAMOD_API int luaopen_os(lua_State *L)
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
#define return_int_attrib(name, accessor)
void load_core()
Loads the "core" library into the Lua environment.
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
LUAMOD_API int luaopen_string(lua_State *L)
LUA_API int lua_isstring(lua_State *L, int idx)
int luaW_open(lua_State *L)
static int intf_get_language(lua_State *L)
LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t size, const char *name, const char *mode)
int intf_show_lua_console(lua_State *L)
static lg::log_domain log_user("scripting/lua/user")
virtual ~name_generator()
LUA_API void * lua_newuserdatauv(lua_State *L, size_t size, int nuvalue)
LUAMOD_API int luaopen_table(lua_State *L)
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
static int intf_deprecated_message(lua_State *L)
Logs a deprecation message.
LUAMOD_API int luaopen_package(lua_State *L)
void load_package()
Loads the package library into lua environment.
LUA_API void lua_close(lua_State *L)
bool protected_call(int nArgs, int nRets, error_handler)
#define lua_getextraspace(L)
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
LUA_API void lua_setglobal(lua_State *L, const char *name)
std::string register_metatables(lua_State *L)
LUA_API int lua_setmetatable(lua_State *L, int objindex)
static int impl_name_generator_collect(lua_State *L)
const char * what() const noexcept
int(lua_kernel_base::* member_callback)(lua_State *L)
int luaW_pcall_internal(lua_State *L, int nArgs, int nRets)
int luaW_open(lua_State *L)
LUA_API void lua_pushnil(lua_State *L)
LUA_API const char * lua_setupvalue(lua_State *L, int funcindex, int n)
int intf_tiles_adjacent(lua_State *L)
Expose map_location tiles_adjacent.
LUAMOD_API int() luaopen_utf8(lua_State *L)
Generic locator abstracting the location of an image.
virtual int impl_game_config_get(lua_State *L)
int intf_vector_negation(lua_State *L)
Expose map_location::vector_negation to lua.
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
LUA_API void * lua_touserdata(lua_State *L, int idx)
void run(char const *prog, const std::string &name, int nArgs=0)
Runs a plain script.
static int intf_random(lua_State *L)
Returns a random numer, same interface as math.random.
int intf_print(lua_State *L)
Replacement print function – instead of printing to std::cout, print to the command log...
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int arg)
std::string register_gettext_metatable(lua_State *L)
Adds the gettext metatable.
int intf_get_in_basis_N_NE(lua_State *L)
Expose map_location get_in_basis_N_NE.
static map_location::DIRECTION s
const language_def & get_language()
virtual uint32_t get_random_seed()
#define lua_tostring(L, i)
static int intf_get_time_stamp(lua_State *L)
Returns the time stamp, exactly as [set_variable] time=stamp does.
static int intf_compare_versions(lua_State *L)
Compares 2 version strings - which is newer.
void throwing_run(char const *prog, const std::string &name, int nArgs, bool in_interpreter=false)
Runs a plain script, but reports errors by throwing lua_error.
LUA_API void lua_rotate(lua_State *L, int idx, int n)
LUA_API void lua_pushvalue(lua_State *L, int idx)
int intf_get_adjacent_tiles(lua_State *L)
Expose map_location get_adjacent_tiles.
int load_file(lua_State *L)
Loads a Lua file and pushes the contents on the stack.
LUA_API int lua_isnumber(lua_State *L, int idx)
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
const version_info wesnoth_version(VERSION)
rng * generator
This generator is automatically synced during synced context.
bool load_string(char const *prog, const std::string &name, error_handler)
#define lua_call(L, n, r)
virtual int impl_game_config_set(lua_State *L)
Represents version numbers.
std::vector< std::string > get_global_var_names()
Get tab completion strings.
int intf_vector_sum(lua_State *L)
Expose map_location::vector_sum to lua.
#define LUA_REGISTRYINDEX
#define return_bool_attrib(name, accessor)
static int impl_name_generator_call(lua_State *L)
LUA_API int lua_error(lua_State *L)
std::vector< std::string > get_attribute_names(const std::string &var_path)
Gets all attribute names of an extended variable name.
#define lua_istable(L, n)
std::vector< std::string > split(const config_attribute_value &val)
DEP_LEVEL
See https://wiki.wesnoth.org/CompatibilityStandards for more info.
virtual void throw_exception(char const *msg, char const *context="Lua error")
#define lua_insert(L, idx)
Standard logging facilities (interface).
std::string str() const
Serializes the version number into string form.
uint32_t next_random()
Provides the next random draw.
void lua_setwarnf(lua_State *L, lua_WarnFunction f, void *ud)
void register_metatable(lua_State *L)
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
void push_error_handler(lua_State *L)
A config object defines a single node in a WML file, with access to child nodes.
int intf_dofile(lua_State *L)
Loads and executes a Lua file.
const std::string & str() const
static const char * Interp
LUA_API int lua_getfield(lua_State *L, int idx, const char *k)
static int intf_load(lua_State *L)
Replacement load function.
external_log_type external_log_
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
#define luaL_optstring(L, n, d)
bool file_exists() const
Tests whether the file the locator points at exists.
int intf_require(lua_State *L)
Loads and executes a Lua file, if there is no corresponding entry in wesnoth.package.
void load_tables(lua_State *L)
Creates the metatable for RNG objects, and adds the Rng table which contains the constructor.
void add_log_to_console(const std::string &msg)
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
LUA_API int lua_next(lua_State *L, int idx)
const char * what() const noexcept
static lua_kernel_base *& get_lua_kernel_base_ptr(lua_State *L)
LUA_API const char * lua_typename(lua_State *L, int t)
std::vector< std::string > parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Splits a string based either on a separator, except then the text appears within specified parenthesi...
static int intf_log(lua_State *L)
Logs a message Arg 1: (optional) Logger Arg 2: Message.
#define luaL_checkstring(L, n)
Error used to report an error in a lua script or in the lua interpreter.