The Battle for Wesnoth  1.13.11+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lua_kernel_base.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
16 
17 #include "exceptions.hpp"
18 #include "game_config.hpp"
19 #include "game_errors.hpp"
21 #include "log.hpp"
22 #include "lua_jailbreak_exception.hpp" // for lua_jailbreak_exception
23 #include "random.hpp"
24 #include "seed_rng.hpp"
25 
26 #ifdef DEBUG_LUA
27 #include "scripting/debug_lua.hpp"
28 #endif
29 
30 #include "scripting/lua_common.hpp"
34 #include "scripting/lua_gui2.hpp"
36 #include "scripting/lua_rng.hpp"
37 #include "scripting/push_check.hpp"
38 
39 #include "version.hpp" // for do_version_check, etc
40 #include "image.hpp"
41 
42 #include "formula/string_utils.hpp"
44 #include "utils/functional.hpp"
45 #include "utils/name_generator.hpp"
48 #include "variable.hpp" // for config_variable_set
49 
50 #include <cstring>
51 #include <exception>
52 #include <new>
53 #include <string>
54 #include <sstream>
55 #include <vector>
56 
57 #include "lua/lauxlib.h"
58 #include "lua/lua.h"
59 #include "lua/lualib.h"
60 
61 static lg::log_domain log_scripting_lua("scripting/lua");
62 static lg::log_domain log_user("scripting/lua/user");
63 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua)
64 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
65 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
66 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
67 
68 // Registry key for metatable
69 static const char * Gen = "name generator";
70 
71 // Callback implementations
72 
73 /**
74  * Compares 2 version strings - which is newer.
75  * - Args 1,3: version strings
76  * - Arg 2: comparison operator (string)
77  * - Ret 1: comparison result
78  */
80 {
81  char const *v1 = luaL_checkstring(L, 1);
82 
84  if(vop == OP_INVALID) return luaL_argerror(L, 2, "unknown version comparison operator - allowed are ==, !=, <, <=, > and >=");
85 
86  char const *v2 = luaL_checkstring(L, 3);
87 
88  const bool result = do_version_check(version_info(v1), vop, version_info(v2));
89  lua_pushboolean(L, result);
90 
91  return 1;
92 }
93 
94 /**
95  * Replacement print function -- instead of printing to std::cout, print to the command log.
96  * Intended to be bound to this' command_log at registration time.
97  */
99 {
100  DBG_LUA << "intf_print called:\n";
101  size_t nargs = lua_gettop(L);
102 
103  lua_getglobal(L, "tostring");
104  for (size_t i = 1; i <= nargs; ++i) {
105  lua_pushvalue(L, -1); // function to call: "tostring"
106  lua_pushvalue(L, i); // value to pass through tostring() before printing
107  lua_call(L, 1, 1);
108  const char * str = lua_tostring(L, -1);
109  if (!str) {
110  LOG_LUA << "'tostring' must return a value to 'print'\n";
111  str = "";
112  }
113  if (i > 1) {
114  cmd_log_ << "\t"; //separate multiple args with tab character
115  }
116  cmd_log_ << str;
117  DBG_LUA << "'" << str << "'\n";
118  lua_pop(L, 1); // Pop the output of tostrring()
119  }
120  lua_pop(L, 1); // Pop 'tostring' global
121 
122  cmd_log_ << "\n";
123  DBG_LUA << "\n";
124 
125  return 0;
126 }
127 
128 // The show lua console callback is similarly a method of lua kernel
130 {
131  if (cmd_log_.external_log_) {
132  std::string message = "There is already an external logger attached to this lua kernel, you cannot open the lua console right now.";
133  log_error(message.c_str());
134  cmd_log_ << message << "\n";
135  return 0;
136  }
137 
138  return lua_gui2::show_lua_console(L, this);
139 }
140 
142 {
143  name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
144  lua_pushstring(L, gen->generate().c_str());
145  return 1;
146 }
147 
149 {
150  name_generator* gen = static_cast<name_generator*>(lua_touserdata(L, 1));
151  gen->~name_generator();
152  return 0;
153 }
154 
156 {
158  name_generator* gen = nullptr;
159  try {
160  if(type == "markov" || type == "markov_chain") {
161  std::vector<std::string> input;
162  if(lua_istable(L, 2)) {
163  input = lua_check<std::vector<std::string>>(L, 2);
164  } else {
165  input = utils::parenthetical_split(luaL_checkstring(L, 2), ',');
166  }
167  int chain_sz = luaL_optinteger(L, 3, 2);
168  int max_len = luaL_optinteger(L, 4, 12);
169  gen = new(L) markov_generator(input, chain_sz, max_len);
170  // Ensure the pointer didn't change when cast
171  assert(static_cast<void*>(gen) == dynamic_cast<markov_generator*>(gen));
172  } else if(type == "context_free" || type == "cfg" || type == "CFG") {
173  if(lua_istable(L, 2)) {
174  std::map<std::string, std::vector<std::string>> data;
175  for(lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
176  if(lua_type(L, -2) != LUA_TSTRING) {
177  lua_pushstring(L, "CFG generator: invalid nonterminal name (must be a string)");
178  return lua_error(L);
179  }
180  if(lua_isstring(L, -1)) {
181  data[lua_tostring(L,-2)] = utils::split(lua_tostring(L,-1),'|');
182  } else if(lua_istable(L, -1)) {
183  data[lua_tostring(L,-2)] = lua_check<std::vector<std::string>>(L, -1);
184  } else {
185  lua_pushstring(L, "CFG generator: invalid noterminal value (must be a string or list of strings)");
186  return lua_error(L);
187  }
188  }
189  if(!data.empty()) {
190  gen = new(L) context_free_grammar_generator(data);
191  }
192  } else {
194  }
195  if(gen) {
196  assert(static_cast<void*>(gen) == dynamic_cast<context_free_grammar_generator*>(gen));
197  }
198  } else {
199  return luaL_argerror(L, 1, "should be either 'markov_chain' or 'context_free'");
200  }
201  }
202  catch (const name_generator_invalid_exception& ex) {
203  lua_pushstring(L, ex.what());
204  return lua_error(L);
205  }
206 
207  // We set the metatable now, even if the generator is invalid, so that it
208  // will be properly collected if it was invalid.
210  lua_setmetatable(L, -2);
211 
212  return 1;
213 }
214 
215 /**
216 * Returns a random numer, same interface as math.random.
217 */
218 static int intf_random(lua_State *L)
219 {
220  if (lua_isnoneornil(L, 1)) {
221  double r = double(randomness::generator->next_random());
222  double r_max = double(std::numeric_limits<uint32_t>::max());
223  lua_push(L, r / (r_max + 1));
224  return 1;
225  }
226  else {
227  int32_t min;
228  int32_t max;
229  if (lua_isnumber(L, 2)) {
230  min = lua_check<int32_t>(L, 1);
231  max = lua_check<int32_t>(L, 2);
232  }
233  else {
234  min = 1;
235  max = lua_check<int32_t>(L, 1);
236  }
237  if (min > max) {
238  return luaL_argerror(L, 1, "min > max");
239  }
240  lua_push(L, randomness::generator->get_random_int(min, max));
241  return 1;
242  }
243 }
244 
246 {
247  config cfg = luaW_checkconfig(L, 1);
248  config filter = luaW_checkconfig(L, 2);
249  lua_pushboolean(L, cfg.matches(filter));
250  return 1;
251 }
252 
253 /**
254 * Logs a message
255 * Arg 1: (optional) Logger
256 * Arg 2: Message
257 */
258 static int intf_log(lua_State *L) {
259  const std::string& logger = lua_isstring(L, 2) ? luaL_checkstring(L, 1) : "";
261  if(msg.empty() || msg[msg.size() - 1] != '\n') {
262  msg += '\n';
263  }
264 
265  if(logger == "err" || logger == "error") {
266  LOG_STREAM(err, log_user) << msg;
267  } else if(logger == "warn" || logger == "wrn" || logger == "warning") {
269  } else if((logger == "debug" || logger == "dbg")) {
271  } else {
273  }
274  return 0;
275 }
276 
277 /**
278 * Gets the dimension of an image.
279 * - Arg 1: string.
280 * - Ret 1: width.
281 * - Ret 2: height.
282 */
284  char const *m = luaL_checkstring(L, 1);
285  image::locator img(m);
286  if(!img.file_exists()) return 0;
287  surface s = get_image(img);
288  lua_pushinteger(L, s->w);
289  lua_pushinteger(L, s->h);
290  return 2;
291 }
292 
293 /**
294 * Returns the time stamp, exactly as [set_variable] time=stamp does.
295 * - Ret 1: integer
296 */
298  lua_pushinteger(L, SDL_GetTicks());
299  return 1;
300 }
301 
302 static int intf_format(lua_State* L)
303 {
304  config cfg = luaW_checkconfig(L, 2);
305  config_variable_set variables(cfg);
306  if(lua_isstring(L, 1)) {
307  std::string str = lua_tostring(L, 1);
309  return 1;
310  }
311  t_string str = luaW_checktstring(L, 1);
313  return 1;
314 }
315 
316 template<bool conjunct>
318 {
319  const t_string empty = luaW_checktstring(L, 1);
320  auto values = lua_check<std::vector<t_string>>(L, 2);
321  lua_push(L, (conjunct ? utils::format_conjunct_list : utils::format_disjunct_list)(empty, values));
322  return 1;
323 }
324 
325 /**
326 * Dumps a wml table or userdata wml object into a pretty string.
327 * - Arg 1: wml table or vconfig userdata
328 * - Ret 1: string
329 */
330 static int intf_debug(lua_State* L) {
331  const config& arg = luaW_checkconfig(L, 1);
332  const std::string& result = arg.debug();
333  lua_pushstring(L, result.c_str());
334  return 1;
335 }
336 
337 // End Callback implementations
338 
339 // Template which allows to push member functions to the lua kernel base into lua as C functions, using a shim
341 
342 template <member_callback method>
344  return ((lua_kernel_base::get_lua_kernel<lua_kernel_base>(L)).*method)(L);
345 }
346 
347 // Ctor, initialization
349  : mState(luaL_newstate())
350  , cmd_log_()
351 {
353  lua_State *L = mState;
354 
355  cmd_log_ << "Initializing " << my_name() << "...\n";
356 
357  // Open safe libraries.
358  // Debug and OS are not, but most of their functions will be disabled below.
359  cmd_log_ << "Adding standard libs...\n";
360 
361  static const luaL_Reg safe_libs[] {
362  { "", luaopen_base },
363  { "table", luaopen_table },
364  { "string", luaopen_string },
365  { "math", luaopen_math },
366  { "coroutine", luaopen_coroutine },
367  { "debug", luaopen_debug },
368  { "os", luaopen_os },
369  { "utf8", luaopen_utf8 }, // added in Lua 5.3
370  { nullptr, nullptr }
371  };
372  for (luaL_Reg const *lib = safe_libs; lib->func; ++lib)
373  {
374  luaL_requiref(L, lib->name, lib->func, 1);
375  lua_pop(L, 1); /* remove lib */
376  }
377 
378  // Disable functions from os which we don't want.
379  lua_getglobal(L, "os");
380  lua_pushnil(L);
381  while(lua_next(L, -2) != 0) {
382  lua_pop(L, 1);
383  char const* function = lua_tostring(L, -1);
384  if(strcmp(function, "clock") == 0 || strcmp(function, "date") == 0
385  || strcmp(function, "time") == 0 || strcmp(function, "difftime") == 0) continue;
386  lua_pushnil(L);
387  lua_setfield(L, -3, function);
388  }
389  lua_pop(L, 1);
390 
391  // Disable functions from debug which we don't want.
392  lua_getglobal(L, "debug");
393  lua_pushnil(L);
394  while(lua_next(L, -2) != 0) {
395  lua_pop(L, 1);
396  char const* function = lua_tostring(L, -1);
397  if(strcmp(function, "traceback") == 0 || strcmp(function, "getinfo") == 0) continue; //traceback is needed for our error handler
398  lua_pushnil(L); //getinfo is needed for ilua strict mode
399  lua_setfield(L, -3, function);
400  }
401  lua_pop(L, 1);
402 
403  // Delete dofile and loadfile.
404  lua_pushnil(L);
405  lua_setglobal(L, "dofile");
406  lua_pushnil(L);
407  lua_setglobal(L, "loadfile");
408 
409  // Store the error handler.
410  cmd_log_ << "Adding error handler...\n";
412 
413  // Create the gettext metatable.
415 
416  // Create the tstring metatable.
418 
419 
420  lua_settop(L, 0);
421 
422  // Define the CPP_function metatable ( so we can override print to point to a C++ member function, add "show_dialog" for this kernel, etc. )
423  cmd_log_ << "Adding boost function proxy...\n";
424 
426 
427  // Add some callback from the wesnoth lib
428  cmd_log_ << "Registering basic wesnoth API...\n";
429 
430  static luaL_Reg const callbacks[] {
431  { "compare_versions", &intf_compare_versions },
432  { "debug", &intf_debug },
433  { "have_file", &lua_fileops::intf_have_file },
434  { "read_file", &lua_fileops::intf_read_file },
435  { "textdomain", &lua_common::intf_textdomain },
436  { "tovconfig", &lua_common::intf_tovconfig },
437  { "get_dialog_value", &lua_gui2::intf_get_dialog_value },
438  { "set_dialog_active", &lua_gui2::intf_set_dialog_active },
439  { "set_dialog_visible", &lua_gui2::intf_set_dialog_visible },
440  { "add_dialog_tree_node", &lua_gui2::intf_add_dialog_tree_node },
441  { "add_widget_definition", &lua_gui2::intf_add_widget_definition },
442  { "set_dialog_callback", &lua_gui2::intf_set_dialog_callback },
443  { "set_dialog_canvas", &lua_gui2::intf_set_dialog_canvas },
444  { "set_dialog_focus", &lua_gui2::intf_set_dialog_focus },
445  { "set_dialog_markup", &lua_gui2::intf_set_dialog_markup },
446  { "set_dialog_value", &lua_gui2::intf_set_dialog_value },
447  { "remove_dialog_item", &lua_gui2::intf_remove_dialog_item },
448  { "dofile", &dispatch<&lua_kernel_base::intf_dofile> },
449  { "require", &dispatch<&lua_kernel_base::intf_require> },
450  { "kernel_type", &dispatch<&lua_kernel_base::intf_kernel_type> },
451  { "show_dialog", &lua_gui2::show_dialog },
452  { "show_menu", &lua_gui2::show_menu },
453  { "show_message_dialog", &lua_gui2::show_message_dialog },
454  { "show_popup_dialog", &lua_gui2::show_popup_dialog },
455  { "show_story", &lua_gui2::show_story },
456  { "show_message_box", &lua_gui2::show_message_box },
457  { "show_lua_console", &dispatch<&lua_kernel_base::intf_show_lua_console> },
458  { "compile_formula", &lua_formula_bridge::intf_compile_formula},
459  { "eval_formula", &lua_formula_bridge::intf_eval_formula},
460  { "name_generator", &intf_name_generator },
461  { "random", &intf_random },
462  { "wml_matches_filter", &intf_wml_matches_filter },
463  { "log", &intf_log },
464  { "get_image_size", &intf_get_image_size },
465  { "get_time_stamp", &intf_get_time_stamp },
466  { "format", &intf_format },
467  { "format_conjunct_list", &intf_format_list<true> },
468  { "format_disjunct_list", &intf_format_list<false> },
469  { nullptr, nullptr }
470  };
471 
472  lua_getglobal(L, "wesnoth");
473  if (!lua_istable(L,-1)) {
474  lua_newtable(L);
475  }
476  luaL_setfuncs(L, callbacks, 0);
477  //lua_cpp::set_functions(L, cpp_callbacks, 0);
478  lua_setglobal(L, "wesnoth");
479 
480  // Override the print function
481  cmd_log_ << "Redirecting print function...\n";
482 
483  lua_getglobal(L, "print");
484  lua_setglobal(L, "std_print"); //storing original impl as 'std_print'
485  lua_settop(L, 0); //clear stack, just to be sure
486 
487  lua_pushcfunction(L, &dispatch<&lua_kernel_base::intf_print>);
488  lua_setglobal(L, "print");
489 
490  cmd_log_ << "Initializing package repository...\n";
491  // Create the package table.
492  lua_getglobal(L, "wesnoth");
493  lua_newtable(L);
494  lua_setfield(L, -2, "package");
495  lua_pop(L, 1);
496  lua_settop(L, 0);
497  lua_pushstring(L, "lua/package.lua");
498  int res = intf_require(L);
499  if(res != 1) {
500  cmd_log_ << "Error: Failed to initialize package repository. Falling back to less flexible C++ implementation.\n";
501  }
502 
503  // Get some callbacks for map locations
504  cmd_log_ << "Adding map table...\n";
505 
506  static luaL_Reg const map_callbacks[] {
507  { "get_direction", &lua_map_location::intf_get_direction },
508  { "vector_sum", &lua_map_location::intf_vector_sum },
509  { "vector_diff", &lua_map_location::intf_vector_diff },
510  { "vector_negation", &lua_map_location::intf_vector_negation },
511  { "rotate_right_around_center", &lua_map_location::intf_rotate_right_around_center },
512  { "tiles_adjacent", &lua_map_location::intf_tiles_adjacent },
513  { "get_adjacent_tiles", &lua_map_location::intf_get_adjacent_tiles },
514  { "distance_between", &lua_map_location::intf_distance_between },
515  { "get_in_basis_N_NE", &lua_map_location::intf_get_in_basis_N_NE },
516  { "get_relative_dir", &lua_map_location::intf_get_relative_dir },
517  { nullptr, nullptr }
518  };
519 
520  // Create the map_location table.
521  lua_getglobal(L, "wesnoth");
522  lua_newtable(L);
523  luaL_setfuncs(L, map_callbacks, 0);
524  lua_setfield(L, -2, "map");
525  lua_pop(L, 1);
526 
527  // Create the game_config variable with its metatable.
528  cmd_log_ << "Adding game_config table...\n";
529 
530  lua_getglobal(L, "wesnoth");
531  lua_newuserdata(L, 0);
532  lua_createtable(L, 0, 3);
533  lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_get>);
534  lua_setfield(L, -2, "__index");
535  lua_pushcfunction(L, &dispatch<&lua_kernel_base::impl_game_config_set>);
536  lua_setfield(L, -2, "__newindex");
537  lua_pushstring(L, "game config");
538  lua_setfield(L, -2, "__metatable");
539  lua_setmetatable(L, -2);
540  lua_setfield(L, -2, "game_config");
541  lua_pop(L, 1);
542 
543  // Add mersenne twister rng wrapper
544  cmd_log_ << "Adding rng tables...\n";
546 
547  cmd_log_ << "Adding name generator metatable...\n";
549  static luaL_Reg const generator[] {
550  { "__call", &impl_name_generator_call},
551  { "__gc", &impl_name_generator_collect},
552  { nullptr, nullptr}
553  };
554  luaL_setfuncs(L, generator, 0);
555 
556  // Create formula bridge metatables
558 
559  // Loading ilua:
560  cmd_log_ << "Loading ilua...\n";
561 
562  lua_settop(L, 0);
563  luaW_getglobal(L, "wesnoth", "require");
564  lua_pushstring(L, "lua/ilua.lua");
565  if(protected_call(1, 1)) {
566  //run "ilua.set_strict()"
567  lua_pushstring(L, "set_strict");
568  lua_gettable(L, -2);
569  if (!this->protected_call(0,0, std::bind(&lua_kernel_base::log_error, this, _1, _2))) {
570  cmd_log_ << "Failed to activate strict mode.\n";
571  } else {
572  cmd_log_ << "Activated strict mode.\n";
573  }
574 
575  lua_setglobal(L, "ilua"); //save ilua table as a global
576  } else {
577  cmd_log_ << "Error: failed to load ilua.\n";
578  }
579  lua_settop(L, 0);
580 }
581 
583 {
584  for (const auto& pair : this->registered_widget_definitions_) {
585  gui2::remove_single_widget_definition(std::get<0>(pair), std::get<1>(pair));
586  }
587  lua_close(mState);
588 }
589 
590 void lua_kernel_base::log_error(char const * msg, char const * context)
591 {
592  ERR_LUA << context << ": " << msg << '\n';
593 }
594 
595 void lua_kernel_base::throw_exception(char const * msg, char const * context)
596 {
597  throw game::lua_error(msg, context);
598 }
599 
600 bool lua_kernel_base::protected_call(int nArgs, int nRets)
601 {
602  error_handler eh = std::bind(&lua_kernel_base::log_error, this, _1, _2 );
603  return this->protected_call(nArgs, nRets, eh);
604 }
605 
606 bool lua_kernel_base::load_string(char const * prog)
607 {
608  error_handler eh = std::bind(&lua_kernel_base::log_error, this, _1, _2 );
609  return this->load_string(prog, eh);
610 }
611 
612 bool lua_kernel_base::protected_call(int nArgs, int nRets, error_handler e_h)
613 {
614  return this->protected_call(mState, nArgs, nRets, e_h);
615 }
616 
617 bool lua_kernel_base::protected_call(lua_State * L, int nArgs, int nRets, error_handler e_h)
618 {
619  int errcode = luaW_pcall_internal(L, nArgs, nRets);
620 
621  if (errcode != LUA_OK) {
622  char const * msg = lua_tostring(L, -1);
623 
624  std::string context = "When executing, ";
625  if (errcode == LUA_ERRRUN) {
626  context += "Lua runtime error: ";
627  } else if (errcode == LUA_ERRERR) {
628  context += "Lua error in attached debugger: ";
629  } else if (errcode == LUA_ERRMEM) {
630  context += "Lua out of memory error: ";
631  } else if (errcode == LUA_ERRGCMM) {
632  context += "Lua error in garbage collection metamethod: ";
633  } else {
634  context += "unknown lua error: ";
635  }
636  if(lua_isstring(L, -1)) {
637  context += msg ? msg : "null string";
638  } else {
639  context += lua_typename(L, lua_type(L, -1));
640  }
641 
642  lua_pop(L, 1);
643 
644  e_h(context.c_str(), "Lua Error");
645 
646  return false;
647  }
648 
649  return true;
650 }
651 
652 bool lua_kernel_base::load_string(char const * prog, error_handler e_h)
653 {
654  int errcode = luaL_loadstring(mState, prog);
655  if (errcode != LUA_OK) {
656  char const * msg = lua_tostring(mState, -1);
657  std::string message = msg ? msg : "null string";
658 
659  std::string context = "When parsing a string to lua, ";
660 
661  if (errcode == LUA_ERRSYNTAX) {
662  context += " a syntax error";
663  } else if(errcode == LUA_ERRMEM){
664  context += " a memory error";
665  } else if(errcode == LUA_ERRGCMM) {
666  context += " an error in garbage collection metamethod";
667  } else {
668  context += " an unknown error";
669  }
670 
671  lua_pop(mState, 1);
672 
673  e_h(message.c_str(), context.c_str());
674 
675  return false;
676  }
677  return true;
678 }
679 
681 {
682  int nArgs = 0;
683  if (const config& args = cfg.child("args")) {
684  luaW_pushconfig(this->mState, args);
685  ++nArgs;
686  }
687  this->run(cfg["code"].str().c_str(), nArgs);
688 }
689 // Call load_string and protected call. Make them throw exceptions.
690 //
691 void lua_kernel_base::throwing_run(const char * prog, int nArgs)
692 {
693  cmd_log_ << "$ " << prog << "\n";
694  error_handler eh = std::bind(&lua_kernel_base::throw_exception, this, _1, _2 );
695  this->load_string(prog, eh);
696  lua_insert(mState, -nArgs - 1);
697  this->protected_call(nArgs, 0, eh);
698 }
699 
700 // Do a throwing run, but if we catch a lua_error, reformat it with signature for this function and log it.
701 void lua_kernel_base::run(const char * prog, int nArgs)
702 {
703  try {
704  this->throwing_run(prog, nArgs);
705  } catch (game::lua_error & e) {
706  cmd_log_ << e.what() << "\n";
707  lua_kernel_base::log_error(e.what(), "In function lua_kernel::run()");
708  }
709 }
710 
711 // Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it normally. Throws exceptions.
712 void lua_kernel_base::interactive_run(char const * prog) {
713  std::string experiment = "ilua._pretty_print(";
714  experiment += prog;
715  experiment += ")";
716 
717  error_handler eh = std::bind(&lua_kernel_base::throw_exception, this, _1, _2 );
718 
719  try {
720  // Try to load the experiment without syntax errors
721  this->load_string(experiment.c_str(), eh);
722  } catch (game::lua_error &) {
723  this->throwing_run(prog, 0); // Since it failed, fall back to the usual throwing_run, on the original input.
724  return;
725  }
726  // experiment succeeded, now run but log normally.
727  cmd_log_ << "$ " << prog << "\n";
728  this->protected_call(0, 0, eh);
729 }
730 /**
731  * Loads and executes a Lua file.
732  * - Arg 1: string containing the file name.
733  * - Ret *: values returned by executing the file body.
734  */
736 {
737  luaL_checkstring(L, 1);
738  lua_rotate(L, 1, -1);
739  if (lua_fileops::load_file(L) != 1) return 0;
740  //^ should end with the file contents loaded on the stack. actually it will call lua_error otherwise, the return 0 is redundant.
741  lua_rotate(L, 1, 1);
742  // Using a non-protected call here appears to fix an issue in plugins.
743  // The protected call isn't technically necessary anyway, because this function is called from Lua code,
744  // which should already be in a protected environment.
745  lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
746  return lua_gettop(L);
747 }
748 
749 /**
750  * Loads and executes a Lua file, if there is no corresponding entry in wesnoth.package.
751  * Stores the result of the script in wesnoth.package and returns it.
752  * - Arg 1: string containing the file name.
753  * - Ret 1: value returned by the script.
754  */
756 {
757  const char * m = luaL_checkstring(L, 1);
758  if(!m) {
759  return luaL_argerror(L, 1, "found a null string argument to wesnoth require");
760  }
761 
762  // Check if there is already an entry.
763 
764  lua_getglobal(L, "wesnoth");
765  lua_pushstring(L, "package");
766  lua_rawget(L, -2);
767  lua_pushvalue(L, 1);
768  lua_rawget(L, -2);
769  if(!lua_isnil(L, -1) && !game_config::debug_lua) {
770  return 1;
771  }
772  lua_pop(L, 1);
773  lua_pushvalue(L, 1);
774  // stack is now [packagename] [wesnoth] [package] [packagename]
775 
776  if(lua_fileops::load_file(L) != 1) {
777  // should end with the file contents loaded on the stack. actually it will call lua_error otherwise, the return 0 is redundant.
778  // stack is now [packagename] [wesnoth] [package] [chunk]
779  return 0;
780  }
781  DBG_LUA << "require: loaded a file, now calling it\n";
782 
783  if (!this->protected_call(L, 0, 1, std::bind(&lua_kernel_base::log_error, this, _1, _2))) {
784  // historically if wesnoth.require fails it just yields nil and some logging messages, not a lua error
785  return 0;
786  }
787  // stack is now [packagename] [wesnoth] [package] [results]
788 
789  lua_pushvalue(L, 1);
790  lua_pushvalue(L, -2);
791  // stack is now [packagename] [wesnoth] [package] [results] [packagename] [results]
792  // Add the return value to the table.
793 
794  lua_settable(L, -4);
795  // stack is now [packagename] [wesnoth] [package] [results]
796  return 1;
797 }
799 {
800  lua_push(L, my_name());
801  return 1;
802 }
804 {
805  char const *m = luaL_checkstring(L, 2);
817  return 0;
818 }
820 {
821  std::string err_msg = "unknown modifiable property of game_config: ";
822  err_msg += luaL_checkstring(L, 2);
823  return luaL_argerror(L, 2, err_msg.c_str());
824 }
825 /**
826  * Loads the "package" package into the Lua environment.
827  * This action is inherently unsafe, as Lua scripts will now be able to
828  * load C libraries on their own, hence granting them the same privileges
829  * as the Wesnoth binary itself.
830  */
832 {
833  lua_State *L = mState;
835  lua_pushstring(L, "package");
836  lua_call(L, 1, 0);
837 }
838 
840 {
841  lua_State* L = mState;
842  lua_settop(L, 0);
843  cmd_log_ << "Loading core...\n";
844  luaW_getglobal(L, "wesnoth", "require");
845  lua_pushstring(L, "lua/core.lua");
846  if(!protected_call(1, 1)) {
847  cmd_log_ << "Error: Failed to load core.\n";
848  }
849  lua_settop(L, 0);
850 }
851 
852 /**
853  * Gets all the global variable names in the Lua environment. This is useful for tab completion.
854  */
855 std::vector<std::string> lua_kernel_base::get_global_var_names()
856 {
857  std::vector<std::string> ret;
858 
859  lua_State *L = mState;
860 
861  int idx = lua_gettop(L);
862  lua_getglobal(L, "_G");
863  lua_pushnil(L);
864 
865  while (lua_next(L, idx+1) != 0) {
866  if (lua_isstring(L, -2)) {
867  ret.push_back(lua_tostring(L,-2));
868  }
869  lua_pop(L,1);
870  }
871  lua_settop(L, idx);
872  return ret;
873 }
874 
875 /**
876  * Gets all attribute names of an extended variable name. This is useful for tab completion.
877  */
878 std::vector<std::string> lua_kernel_base::get_attribute_names(const std::string & input)
879 {
880  std::vector<std::string> ret;
881  std::string base_path = input;
882  size_t last_dot = base_path.find_last_of('.');
883  std::string partial_name = base_path.substr(last_dot + 1);
884  base_path.erase(last_dot);
885  std::string load = "return " + base_path;
886 
887  lua_State* L = mState;
888  int save_stack = lua_gettop(L);
889  int result = luaL_loadstring(L, load.c_str());
890  if(result != LUA_OK) {
891  // This isn't at error level because it's a really low priority error; it just means the user tried to tab-complete something that doesn't exist.
892  LOG_LUA << "Error when attempting tab completion:\n";
893  LOG_LUA << luaL_checkstring(L, -1) << '\n';
894  // Just return an empty list; no matches were found
895  lua_settop(L, save_stack);
896  return ret;
897  }
898 
899  luaW_pcall(L, 0, 1);
900  if(lua_istable(L, -1) || lua_isuserdata(L, -1)) {
901  int top = lua_gettop(L);
902  int obj = lua_absindex(L, -1);
903  if(luaL_getmetafield(L, obj, "__tab_enum") == LUA_TFUNCTION) {
904  lua_pushvalue(L, obj);
905  lua_pushlstring(L, partial_name.c_str(), partial_name.size());
906  luaW_pcall(L, 2, 1);
907  ret = lua_check<std::vector<std::string>>(L, -1);
908  } else if(lua_type(L, -1) != LUA_TTABLE) {
909  LOG_LUA << "Userdata missing __tab_enum meta-function for tab completion";
910  lua_settop(L, save_stack);
911  return ret;
912  } else {
913  lua_settop(L, top);
914  // Metafunction not found, so use lua_next to enumerate the table
915  for(lua_pushnil(L); lua_next(L, obj); lua_pop(L, 1)) {
916  if(lua_type(L, -2) == LUA_TSTRING) {
917  std::string attr = lua_tostring(L, -2);
918  if(attr.empty()) {
919  continue;
920  }
921  if(!isalpha(attr[0]) && attr[0] != '_') {
922  continue;
923  }
924  if(std::any_of(attr.begin(), attr.end(), [](char c){
925  return !isalpha(c) && !isdigit(c) && c != '_';
926  })) {
927  continue;
928  }
929  if(attr.substr(0, partial_name.size()) == partial_name) {
930  ret.push_back(base_path + "." + attr);
931  }
932  }
933  }
934  }
935  }
936  lua_settop(L, save_stack);
937  return ret;
938 }
939 
941 {
942  #ifdef __GNUC__
943  #pragma GCC diagnostic push
944  #pragma GCC diagnostic ignored "-Wold-style-cast"
945  #endif
946  return *reinterpret_cast<lua_kernel_base**>(lua_getextraspace(L));
947  #ifdef __GNUC__
948  #pragma GCC diagnostic pop
949  #endif
950 }
951 
953 {
954  return seed_rng::next_seed();
955 }
int dispatch(lua_State *L)
int intf_set_dialog_active(lua_State *L)
Sets a widget's state to active or inactive.
Definition: lua_gui2.cpp:876
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)
Definition: lauxlib.cpp:971
#define lua_isnoneornil(L, n)
Definition: lua.h:359
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:920
static int intf_name_generator(lua_State *L)
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:683
#define lua_pushcfunction(L, f)
Definition: lua.h:350
int show_lua_console(lua_State *, lua_kernel_base *lk)
Definition: lua_gui2.cpp:941
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...
Definition: config.cpp:417
std::string register_tstring_metatable(lua_State *L)
Adds the tstring metatable.
Definition: lua_common.cpp:407
std::string format_conjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a conjunctive list.
int intf_add_dialog_tree_node(lua_State *L)
Sets a widget's state to active or inactive.
Definition: lua_gui2.cpp:961
const char * what() const NOEXCEPT
Definition: exceptions.hpp:37
std::vector< char_t > string
int intf_read_file(lua_State *L)
Reads a file into a string, or a directory into a list of files therein.
bool matches(const config &filter) const
Definition: config.cpp:1173
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
LUALIB_API lua_State * luaL_newstate(void)
Definition: lauxlib.cpp:1026
LUAMOD_API int luaopen_debug(lua_State *L)
Definition: ldblib.cpp:452
VERSION_COMP_OP parse_version_op(const std::string &op_str)
Definition: version.cpp:279
int show_story(lua_State *L)
Displays a story screen.
Definition: lua_gui2.cpp:395
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:700
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:172
LUA_API int lua_type(lua_State *L, int idx)
Definition: lapi.cpp:251
int village_support
Definition: game_config.cpp:72
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.
Definition: lua_common.cpp:970
static int intf_format(lua_State *L)
int intf_have_file(lua_State *L)
Checks if a file exists (not necessarily a Lua script).
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)
Definition: lauxlib.cpp:764
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:556
#define LUA_MULTRET
Definition: lua.h:34
std::vector< game_tip > load(const config &cfg)
Loads the tips from a config.
Definition: tips.cpp:35
std::function< void(char const *, char const *)> error_handler
logger & info()
Definition: log.cpp:91
static int intf_format_list(lua_State *L)
int show_dialog(lua_State *L)
Displays a window.
Definition: lua_gui2.cpp:243
bool file_exists() const
Tests whether the file the locater points at exists.
Definition: image.cpp:684
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)
Definition: lauxlib.cpp:772
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:167
LUA_API int lua_gettable(lua_State *L, int idx)
Definition: lapi.cpp:611
LUAMOD_API int luaopen_math(lua_State *L)
Definition: lmathlib.cpp:398
LUA_API int lua_getglobal(lua_State *L, const char *name)
Definition: lapi.cpp:604
LUA_API void lua_settable(lua_State *L, int idx)
Definition: lapi.cpp:765
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:210
int intf_textdomain(lua_State *L)
Creates an interface for gettext.
Definition: lua_common.cpp:83
#define LOG_LUA
std::vector< std::tuple< std::string, std::string > > registered_widget_definitions_
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:646
std::string format_disjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a disjunctive list.
#define luaL_getmetatable(L, n)
Definition: lauxlib.h:135
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)
Definition: lauxlib.cpp:440
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
#define LUA_TFUNCTION
Definition: lua.h:70
LUA_API int lua_isuserdata(lua_State *L, int idx)
Definition: lapi.cpp:289
int show_message_dialog(lua_State *L)
Displays a message window.
Definition: lua_gui2.cpp:274
int intf_remove_dialog_item(lua_State *L)
Removes an entry from a list.
Definition: lua_gui2.cpp:695
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:295
std::string debug() const
Definition: config.cpp:1209
int intf_set_dialog_markup(lua_State *L)
Enables/disables Pango markup on the label of a widget of the current dialog.
Definition: lua_gui2.cpp:821
#define LOG_STREAM(level, domain)
Definition: log.hpp:189
static lg::log_domain log_scripting_lua("scripting/lua")
LUA_API int lua_absindex(lua_State *L, int idx)
Definition: lapi.cpp:160
const char * what() const NOEXCEPT
int intf_add_widget_definition(lua_State *L)
Definition: lua_gui2.cpp:986
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
int intf_vector_diff(lua_State *L)
Expose map_location::vector_difference to lua.
LUAMOD_API int luaopen_base(lua_State *L)
Definition: lbaselib.cpp:486
int rest_heal_amount
Definition: game_config.cpp:77
LUA_API void * lua_newuserdata(lua_State *L, size_t size)
Definition: lapi.cpp:1183
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.
#define lua_pop(L, n)
Definition: lua.h:344
int intf_set_dialog_focus(lua_State *L)
Sets a widget to have the focus.
Definition: lua_gui2.cpp:864
int intf_rotate_right_around_center(lua_State *L)
Expose map_location::rotate_right_around_center to lua.
lua_CFunction func
Definition: lauxlib.h:33
int intf_eval_formula(lua_State *)
Evaluates a formula in the formula engine.
int intf_get_relative_dir(lua_State *L)
Expose map_location get_relative_dir.
#define LUA_TSTRING
Definition: lua.h:68
LUAMOD_API int luaopen_coroutine(lua_State *L)
Definition: lcorolib.cpp:164
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:164
LUAMOD_API int luaopen_os(lua_State *L)
Definition: loslib.cpp:403
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:219
void load_core()
Loads the "core" library into the Lua environment.
void throwing_run(char const *prog, int nArgs)
Runs a plain script, but reports errors by throwing lua_error.
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...
Definition: lua_common.cpp:839
LUAMOD_API int luaopen_string(lua_State *L)
Definition: lstrlib.cpp:1579
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:283
int intf_show_lua_console(lua_State *L)
static lg::log_domain log_user("scripting/lua/user")
virtual ~name_generator()
LUAMOD_API int luaopen_table(lua_State *L)
Definition: ltablib.cpp:441
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:590
LUAMOD_API int luaopen_package(lua_State *L)
Definition: loadlib.cpp:767
void load_package()
Loads the package library into lua environment.
LUA_API void lua_close(lua_State *L)
Definition: lstate.cpp:341
bool protected_call(int nArgs, int nRets, error_handler)
#define lua_getextraspace(L)
Definition: lua.h:339
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.cpp:479
int kill_experience
Definition: game_config.cpp:74
LUA_API void lua_setglobal(lua_State *L, const char *name)
Definition: lapi.cpp:758
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:845
int show_menu(lua_State *L)
Displays a popup menu at the current mouse position Best used from a [set_menu_item], to show a submenu.
Definition: lua_gui2.cpp:408
static int impl_name_generator_collect(lua_State *L)
int intf_compile_formula(lua_State *)
int intf_set_dialog_canvas(lua_State *L)
Sets a canvas on a widget of the current dialog.
Definition: lua_gui2.cpp:840
int luaW_pcall_internal(lua_State *L, int nArgs, int nRets)
Definition: lua_common.cpp:947
#define lua_newtable(L)
Definition: lua.h:346
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:450
int intf_tiles_adjacent(lua_State *L)
Expose map_location tiles_adjacent.
LUAMOD_API int() luaopen_utf8(lua_State *L)
Definition: lutf8lib.cpp:250
bool load_string(char const *prog, error_handler)
int(lua_kernel_base::* member_callback)(lua_State *L)
void run(char const *prog, int nArgs=0)
Runs a plain script.
virtual int impl_game_config_get(lua_State *L)
#define LUA_ERRGCMM
Definition: lua.h:52
int show_popup_dialog(lua_State *L)
Displays a popup message.
Definition: lua_gui2.cpp:381
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)
Definition: lauxlib.cpp:299
LUA_API void * lua_touserdata(lua_State *L, int idx)
Definition: lapi.cpp:413
#define LUA_ERRERR
Definition: lua.h:53
static int intf_random(lua_State *L)
Returns a random numer, same interface as math.random.
#define lua_isnil(L, n)
Definition: lua.h:355
int intf_print(lua_State *L)
Replacement print function – instead of printing to std::cout, print to the command log...
int intf_set_dialog_value(lua_State *L)
Sets the value of a widget on the current dialog.
Definition: lua_gui2.cpp:469
VERSION_COMP_OP
Definition: version.hpp:194
logger & err()
Definition: log.cpp:79
std::string register_metatables(lua_State *)
std::string register_gettext_metatable(lua_State *L)
Adds the gettext metatable.
Definition: lua_common.cpp:388
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:787
int village_income
Definition: game_config.cpp:71
int intf_get_in_basis_N_NE(lua_State *L)
Expose map_location get_in_basis_N_NE.
static map_location::DIRECTION s
virtual uint32_t get_random_seed()
size_t i
Definition: function.cpp:933
#define LUA_ERRSYNTAX
Definition: lua.h:50
#define lua_tostring(L, i)
Definition: lua.h:366
static int intf_get_time_stamp(lua_State *L)
Returns the time stamp, exactly as [set_variable] time=stamp does.
static int intf_debug(lua_State *L)
Dumps a wml table or userdata wml object into a pretty string.
static int intf_compare_versions(lua_State *L)
Compares 2 version strings - which is newer.
LUA_API void lua_rotate(lua_State *L, int idx, int n)
Definition: lapi.cpp:207
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:237
#define debug(x)
#define LUA_ERRMEM
Definition: lua.h:51
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)
Definition: lapi.cpp:276
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
rng * generator
This generator is automatically synced during synced context.
Definition: random.cpp:57
#define lua_call(L, n, r)
Definition: lua.h:274
int intf_set_dialog_callback(lua_State *L)
Sets a callback on a widget of the current dialog.
Definition: lua_gui2.cpp:757
virtual int impl_game_config_set(lua_State *L)
#define DBG_LUA
Represents version numbers.
Definition: version.hpp:43
std::vector< std::string > get_global_var_names()
Get tab completion strings.
command_log cmd_log_
int intf_vector_sum(lua_State *L)
Expose map_location::vector_sum to lua.
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:235
static int impl_name_generator_call(lua_State *L)
uint32_t next_seed()
Definition: seed_rng.cpp:45
LUA_API int lua_error(lua_State *L)
Definition: lapi.cpp:1113
logger & warn()
Definition: log.cpp:85
std::vector< std::string > get_attribute_names(const std::string &var_path)
Gets all attribute names of an extended variable name.
#define LUA_OK
Definition: lua.h:47
#define lua_istable(L, n)
Definition: lua.h:353
virtual void throw_exception(char const *msg, char const *context="Lua error")
static int intf_wml_matches_filter(lua_State *L)
#define lua_insert(L, idx)
Definition: lua.h:369
Standard logging facilities (interface).
void register_metatable(lua_State *L)
#define ERR_LUA
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
#define e
bool do_version_check(const version_info &a, VERSION_COMP_OP op, const version_info &b)
Definition: version.cpp:298
int intf_get_dialog_value(lua_State *L)
Gets the value of a widget on the current dialog.
Definition: lua_gui2.cpp:600
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.cpp:934
void push_error_handler(lua_State *L)
Definition: lua_common.cpp:941
int show_message_box(lua_State *L)
Displays a simple message box.
Definition: lua_gui2.cpp:432
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
int intf_dofile(lua_State *L)
Loads and executes a Lua file.
mock_char c
int intf_tovconfig(lua_State *L)
Creates a vconfig containing the WML table.
Definition: lua_common.cpp:378
lua_State * mState
t_string interpolate_variables_into_tstring(const t_string &tstr, const variable_set &variables)
Function that does the same as the above, for t_stringS.
#define LUA_TTABLE
Definition: lua.h:69
Interfaces for manipulating version numbers of engine, add-ons, etc.
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:466
const std::string version
Definition: game_config.cpp:39
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.
Definition: lua_rng.cpp:80
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:491
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:776
#define LUA_ERRRUN
Definition: lua.h:49
std::string generate(const std::map< std::string, std::string > &variables) const
int intf_set_dialog_visible(lua_State *L)
Sets the visiblity of a widget in the current dialog.
Definition: lua_gui2.cpp:894
LUA_API int lua_next(lua_State *L, int idx)
Definition: lapi.cpp:1122
static lua_kernel_base *& get_lua_kernel_base_ptr(lua_State *L)
LUA_API const char * lua_typename(lua_State *L, int t)
Definition: lapi.cpp:257
static const char * Gen
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)
Definition: lauxlib.h:124
Error used to report an error in a lua script or in the lua interpreter.
Definition: game_errors.hpp:53