The Battle for Wesnoth  1.15.9+dev
lua_common.hpp
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 https://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 
15 /**
16  * Common callbacks and functions to manipulate config, vconfig, tstring
17  * in lua, and macros to get them from the stack.
18  */
19 
20 #pragma once
21 
22 struct lua_State;
23 class t_string;
24 class vconfig;
25 
26 #include "config.hpp"
27 #include "variable_info.hpp"
28 #include "map/location.hpp"
29 
30 #include <string>
31 #include <string_view>
32 #include <vector>
33 
34 namespace lua_common {
35  int intf_textdomain(lua_State *L);
36  int intf_tovconfig(lua_State* L);
37 
38  std::string register_gettext_metatable(lua_State *L);
39  std::string register_tstring_metatable(lua_State *L);
40  std::string register_vconfig_metatable(lua_State *L);
41 
42 }
43 
44 void* operator new(std::size_t sz, lua_State *L);
45 void operator delete(void* p, lua_State *L);
46 
47 /**
48  * Like luaL_getmetafield, but returns false if key is an empty string
49  * or begins with two underscores.
50  */
51 bool luaW_getmetafield(lua_State *L, int idx, const char* key);
52 
53 /**
54  * Pushes a vconfig on the top of the stack.
55  */
56 void luaW_pushvconfig(lua_State *L, const vconfig& cfg);
57 
58 /**
59  * Pushes a t_string on the top of the stack.
60  */
61 void luaW_pushtstring(lua_State *L, const t_string& v);
62 
63 /**
64  * Converts an attribute value into a Lua object pushed at the top of the stack.
65  */
67 
68 /**
69  * Converts the value at the top of the stack to an attribute value
70  */
72 
73 /**
74  * Converts a scalar to a translatable string.
75  */
76 bool luaW_totstring(lua_State *L, int index, t_string &str);
77 
78 /**
79  * Converts a scalar to a translatable string.
80  */
82 
83 /*
84  * Test if a scalar is either a plain or translatable string.
85  * Also returns true if it's a number since that's convertible to string.
86  */
87 bool luaW_iststring(lua_State* L, int index);
88 
89 /**
90  * Converts a config object to a Lua table.
91  * The destination table should be at the top of the stack on entry. It is
92  * still at the top on exit.
93  */
94 void luaW_filltable(lua_State *L, const config& cfg);
95 
96 /**
97  * Converts a map location object to a Lua table pushed at the top of the stack.
98  */
99 void luaW_pushlocation(lua_State *L, const map_location& loc);
100 
101 /**
102  * Converts an optional table or pair of integers to a map location object.
103  * @param L the pointer to the lua interpreter.
104  * @param index stack position of the table or first integer.
105  * @param loc the location to write to.
106  * @return false if a map location couldn't be matched.
107  */
108 bool luaW_tolocation(lua_State *L, int index, map_location &loc);
109 
110 /**
111  * Converts an optional table or pair of integers to a map location object.
112  * @note If a pair of integers was found, the first one will be removed
113  * from the stack when the function returns.
114  */
116 
117 /**
118  * Converts a config object to a Lua table pushed at the top of the stack.
119  */
120 void luaW_pushconfig(lua_State *L, const config& cfg);
121 
122 /**
123  * Converts an optional table or vconfig to a config object.
124  * @param L the pointer to the lua interpreter.
125  * @param index stack position of the table.
126  * @param cfg the config to write the data to.
127  * @return false if some attributes had not the proper type.
128  * @note If the table has holes in the integer keys or floating-point keys,
129  * some keys will be ignored and the error will go undetected.
130  */
131 bool luaW_toconfig(lua_State *L, int index, config &cfg);
132 
133 /**
134  * Converts an optional table or vconfig to a config object.
135  */
137 
138 /**
139  * Gets an optional vconfig from either a table or a userdata.
140  * @return false in case of failure.
141  */
142 bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg);
143 
144 /**
145  * Gets an optional vconfig from either a table or a userdata.
146  * @param L the pointer to the lua interpreter.
147  * @param index the location in the current lua execution stack to look at.
148  * @param allow_missing true if missing values are allowed; the function
149  * then returns an unconstructed vconfig.
150  */
151 vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing = false);
152 
153 /**
154  * Like the two-argument version, but if it was a vconfig, also
155  * returns a pointer to that vconfig.
156  */
157 config luaW_checkconfig(lua_State *L, int index, const vconfig*& vcfg);
158 
159 /**
160  * Pushes the value found by following the variadic names (char *), if the
161  * value is not nil.
162  * @return true if an element was pushed.
163  */
164 bool luaW_getglobal(lua_State *L, const std::vector<std::string>& path);
165 
166 /**
167  * Pushes the value found by following the variadic names (char *), if the
168  * value is not nil.
169  * @return true if an element was pushed.
170  */
171 template<typename... T>
172 bool luaW_getglobal(lua_State *L, T... path) {
173  return luaW_getglobal(L, std::vector<std::string> {path...} );
174 }
175 
176 bool luaW_toboolean(lua_State *L, int n);
177 
178 
180 
182 
183 bool luaW_tableget(lua_State *L, int index, const char* key);
184 
185 std::string_view luaW_tostring(lua_State *L, int index);
186 std::string_view luaW_tostring_or_default(lua_State *L, int index, std::string_view def = std::string_view());
187 
188 /**
189  * Displays a message in the chat window.
190  */
191 void chat_message(const std::string& caption, const std::string& msg);
192 
193 /**
194  * Calls a Lua function stored below its @a nArgs arguments at the top of the stack.
195  * @param L the pointer to the lua interpreter.
196  * @param nArgs
197  * @param nRets LUA_MULTRET for unbounded return values.
198  * @param allow_wml_error controls where any stack traces are output.
199  * @return true if the call was successful and @a nRets return values are available.
200  */
201 bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error = false);
202 
203 // Don't use these directly
205 int luaW_pcall_internal(lua_State *L, int nArgs, int nRets);
206 
207 int luaW_type_error(lua_State *L, int narg, const char *tname);
208 int luaW_type_error(lua_State *L, int narg, const char* kpath, const char *tname);
209 
210 #define return_tstring_attrib(name, accessor) \
211 do { \
212  if (strcmp(m, (name)) == 0) { \
213  luaW_pushtstring(L, (accessor)); \
214  return 1; \
215  } \
216 } while(false)
217 
218 #define return_cstring_attrib(name, accessor) \
219 do { \
220  if (strcmp(m, (name)) == 0) { \
221  lua_pushstring(L, (accessor)); \
222  return 1; \
223  } \
224 } while(false)
225 
226 #define return_string_attrib(name, accessor) \
227 do { \
228  if (strcmp(m, (name)) == 0) { \
229  const std::string& str = (accessor); \
230  lua_pushlstring(L, str.c_str(), str.length()); \
231  return 1; \
232  } \
233 } while(false)
234 
235 #define return_int_attrib(name, accessor) \
236 do { \
237  if (strcmp(m, (name)) == 0) { \
238  lua_pushinteger(L, (accessor)); \
239  return 1; \
240  } \
241 } while(false)
242 
243 #define return_float_attrib(name, accessor) \
244 do { \
245  if (strcmp(m, (name)) == 0) { \
246  lua_pushnumber(L, (accessor)); \
247  return 1; \
248  } \
249 } while(false)
250 
251 #define return_bool_attrib(name, accessor) \
252 do { \
253  if (strcmp(m, (name)) == 0) { \
254  lua_pushboolean(L, (accessor)); \
255  return 1; \
256  } \
257 } while(false)
258 
259 #define return_cfg_attrib(name, accessor) \
260 do { \
261  if (strcmp(m, (name)) == 0) { \
262  config cfg; \
263  {accessor;} \
264  luaW_pushconfig(L, cfg); \
265  return 1; \
266  } \
267 } while(false)
268 
269 #define return_cfgref_attrib(name, accessor) \
270 do { \
271  if (strcmp(m, (name)) == 0) { \
272  luaW_pushconfig(L, (accessor)); \
273  return 1; \
274  } \
275 } while(false)
276 
277 #define return_vector_string_attrib(name, accessor) \
278 do { \
279  if (strcmp(m, (name)) == 0) { \
280  const std::vector<std::string>& vector = (accessor); \
281  lua_createtable(L, vector.size(), 0); \
282  int i = 1; \
283  for (const std::string& s : vector) { \
284  lua_pushlstring(L, s.c_str(), s.length()); \
285  lua_rawseti(L, -2, i); \
286  ++i; \
287  } \
288  return 1; \
289  } \
290 } while(false)
291 
292 #define modify_tstring_attrib(name, accessor) \
293 do { \
294  if (strcmp(m, (name)) == 0) { \
295  t_string value = luaW_checktstring(L, 3); \
296  {accessor;} \
297  return 0; \
298  } \
299 } while(false)
300 
301 #define modify_string_attrib(name, accessor) \
302 do { \
303  if (strcmp(m, (name)) == 0) { \
304  const char *value = luaL_checkstring(L, 3); \
305  {accessor;} \
306  return 0; \
307  } \
308 } while(false)
309 
310 #define modify_int_attrib(name, accessor) \
311 do { \
312  if (strcmp(m, (name)) == 0) { \
313  int value = static_cast<int>(luaL_checknumber(L, 3)); \
314  {accessor;} \
315  return 0; \
316  } \
317 } while(false)
318 
319 #define modify_int_attrib_check_range(name, accessor, allowed_min, allowed_max) \
320 do { \
321  if (strcmp(m, (name)) == 0) { \
322  int value = static_cast<int>(luaL_checknumber(L, 3)); \
323  if (value < (allowed_min) || (allowed_max) < value) return luaL_argerror(L, 3, "out of bounds"); \
324  {accessor;} \
325  return 0; \
326  } \
327 } while(false)
328 
329 #define modify_float_attrib(name, accessor) \
330 do { \
331  if (strcmp(m, (name)) == 0) { \
332  lua_Number value = luaL_checknumber(L, 3); \
333  {accessor;} \
334  return 0; \
335  } \
336 } while(false)
337 
338 #define modify_float_attrib_check_range(name, accessor, allowed_min, allowed_max) \
339 do { \
340  if (strcmp(m, (name)) == 0) { \
341  lua_Number value = luaL_checknumber(L, 3); \
342  if (value < (allowed_min) || (allowed_max) < value) return luaL_argerror(L, 3, "out of bounds"); \
343  {accessor;} \
344  return 0; \
345  } \
346 } while(false)
347 
348 #define modify_bool_attrib(name, accessor) \
349 do { \
350  if (strcmp(m, (name)) == 0) { \
351  bool value = luaW_toboolean(L, 3); \
352  {accessor;} \
353  return 0; \
354  } \
355 } while(false)
356 
357 #define modify_cfg_attrib(name, accessor) \
358 do { \
359  if (strcmp(m, (name)) == 0) { \
360  const config& cfg = luaW_checkconfig(L, 3); \
361  {accessor;} \
362  return 0; \
363  } \
364 } while(false)
365 
366 #define modify_vector_string_attrib(name, accessor) \
367 do { \
368  if (strcmp(m, (name)) == 0) { \
369  std::vector<std::string> value; \
370  char const* message = "table with unnamed indices holding strings expected"; \
371  if (!lua_istable(L, 3)) return luaL_argerror(L, 3, message); \
372  unsigned length = lua_rawlen(L, 3); \
373  for (unsigned i = 1; i <= length; ++i) { \
374  lua_rawgeti(L, 3, i); \
375  char const* string = lua_tostring(L, 4); \
376  if(!string) return luaL_argerror(L, 2 + i, message); \
377  value.push_back(string); \
378  lua_pop(L, 1); \
379  } \
380  {accessor;} \
381  return 0; \
382  } \
383 } while(false)
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:733
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:822
std::string register_tstring_metatable(lua_State *L)
Adds the tstring metatable.
Definition: lua_common.cpp:430
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:745
Variant for storing WML attributes.
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores...
Definition: lua_common.cpp:512
bool luaW_iststring(lua_State *L, int index)
Definition: lua_common.cpp:631
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error=false)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:725
int intf_textdomain(lua_State *L)
Creates an interface for gettext.
Definition: lua_common.cpp:93
bool luaW_tableget(lua_State *L, int index, const char *key)
Definition: lua_common.cpp:969
void luaW_pushtstring(lua_State *L, const t_string &v)
Pushes a t_string on the top of the stack.
Definition: lua_common.cpp:533
void push_error_handler(lua_State *L)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
Additional functionality for a non-const variable_info.
Definitions for the interface to Wesnoth Markup Language (WML).
bool luaW_toscalar(lua_State *L, int index, config::attribute_value &v)
Converts the value at the top of the stack to an attribute value.
Definition: lua_common.cpp:571
bool luaW_totstring(lua_State *L, int index, t_string &str)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:598
std::string register_vconfig_metatable(lua_State *L)
Adds the vconfig metatable.
Definition: lua_common.cpp:462
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
Definition: lua_common.cpp:898
int luaW_pcall_internal(lua_State *L, int nArgs, int nRets)
std::string_view luaW_tostring_or_default(lua_State *L, int index, std::string_view def=std::string_view())
Definition: lua_common.cpp:991
std::string path
Definition: game_config.cpp:38
Encapsulates the map of the game.
Definition: location.hpp:37
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:874
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:893
std::string register_gettext_metatable(lua_State *L)
Adds the gettext metatable.
Definition: lua_common.cpp:410
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
Definition: lua_common.cpp:926
mock_party p
void luaW_pushlocation(lua_State *L, const map_location &loc)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:665
vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing=false)
Gets an optional vconfig from either a table or a userdata.
Definition: lua_common.cpp:866
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
std::string_view luaW_tostring(lua_State *L, int index)
Definition: lua_common.cpp:981
void luaW_pushvconfig(lua_State *L, const vconfig &cfg)
Pushes a vconfig on the top of the stack.
Definition: lua_common.cpp:527
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:676
int luaW_type_error(lua_State *L, int narg, const char *tname)
void chat_message(const std::string &caption, const std::string &msg)
Displays a message in the chat window.
Information on a WML variable.
void luaW_filltable(lua_State *L, const config &cfg)
Converts a config object to a Lua table.
Definition: lua_common.cpp:642
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:58
int intf_tovconfig(lua_State *L)
Creates a vconfig containing the WML table.
Definition: lua_common.cpp:400
static map_location::DIRECTION n
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:623
void luaW_pushscalar(lua_State *L, const config::attribute_value &v)
Converts an attribute value into a Lua object pushed at the top of the stack.
Definition: lua_common.cpp:566
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
Gets an optional vconfig from either a table or a userdata.
Definition: lua_common.cpp:839