-
-
Notifications
You must be signed in to change notification settings - Fork 988
/
lua_common.hpp
245 lines (200 loc) · 6.46 KB
/
lua_common.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*
Copyright (C) 2014 - 2016 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* Common callbacks and functions to manipulate config, vconfig, tstring
* in lua, and macros to get them from the stack.
*/
#ifndef LUA_COMMON_HPP_INCLUDED
#define LUA_COMMON_HPP_INCLUDED
struct lua_State;
class t_string;
class vconfig;
#include "config.hpp"
#include "scripting/lua_types.hpp"
#include "variable_info.hpp"
namespace lua_common {
int intf_textdomain(lua_State *L);
int intf_tovconfig(lua_State* L);
std::string register_gettext_metatable(lua_State *L);
std::string register_tstring_metatable(lua_State *L);
std::string register_vconfig_metatable(lua_State *L);
}
extern const char * tstringKey;
/**
* Pushes a vconfig on the top of the stack.
*/
void luaW_pushvconfig(lua_State *L, vconfig const &cfg);
/**
* Pushes a t_string on the top of the stack.
*/
void luaW_pushtstring(lua_State *L, t_string const &v);
/**
* Converts an attribute value into a Lua object pushed at the top of the stack.
*/
void luaW_pushscalar(lua_State *L, config::attribute_value const &v);
/**
* Converts the value at the top of the stack to an attribute value
*/
bool luaW_toscalar(lua_State *L, int index, config::attribute_value& v);
/**
* Returns true if the metatable of the object is the one found in the registry.
*/
bool luaW_hasmetatable(lua_State *L, int index, luatypekey key);
/**
* Converts a scalar to a translatable string.
*/
bool luaW_totstring(lua_State *L, int index, t_string &str);
/**
* Converts a scalar to a translatable string.
*/
t_string luaW_checktstring(lua_State *L, int index);
/**
* Converts a config object to a Lua table.
* The destination table should be at the top of the stack on entry. It is
* still at the top on exit.
*/
void luaW_filltable(lua_State *L, config const &cfg);
/**
* Converts a config object to a Lua table pushed at the top of the stack.
*/
void luaW_pushconfig(lua_State *L, config const &cfg);
/**
* Converts an optional table or vconfig to a config object.
* @param index absolute stack position of t_string's metatable, or 0 if none.
* @return false if some attributes had not the proper type.
* @note If the table has holes in the integer keys or floating-point keys,
* some keys will be ignored and the error will go undetected.
*/
bool luaW_toconfig(lua_State *L, int index, config &cfg);
/**
* Converts an optional table or vconfig to a config object.
*/
config luaW_checkconfig(lua_State *L, int index);
/**
* Gets an optional vconfig from either a table or a userdata.
* @return false in case of failure.
*/
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg);
/**
* Gets an optional vconfig from either a table or a userdata.
* @param allow_missing true if missing values are allowed; the function
* then returns an unconstructed vconfig.
*/
vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing = false);
/**
* Pushes the value found by following the variadic names (char *), if the
* value is not nil.
* @return true if an element was pushed.
*/
bool luaW_getglobal(lua_State *L, ...);
bool luaW_toboolean(lua_State *L, int n);
bool LuaW_pushvariable(lua_State *L, variable_access_const& v);
bool LuaW_checkvariable(lua_State *L, variable_access_create& v, int n);
#define return_tstring_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
luaW_pushtstring(L, accessor); \
return 1; \
}
#define return_cstring_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
lua_pushstring(L, accessor); \
return 1; \
}
#define return_string_attrib(name, accessor) \
return_cstring_attrib(name, (accessor).c_str())
#define return_int_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
lua_pushinteger(L, accessor); \
return 1; \
}
#define return_float_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
lua_pushnumber(L, accessor); \
return 1; \
}
#define return_bool_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
lua_pushboolean(L, accessor); \
return 1; \
}
#define return_cfg_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
config cfg; \
accessor; \
luaW_pushconfig(L, cfg); \
return 1; \
}
#define return_cfgref_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
luaW_pushconfig(L, accessor); \
return 1; \
}
#define return_vector_string_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
const std::vector<std::string>& vector = accessor; \
lua_createtable(L, vector.size(), 0); \
int i = 1; \
BOOST_FOREACH(const std::string& s, vector) { \
lua_pushstring(L, s.c_str()); \
lua_rawseti(L, -2, i); \
++i; \
} \
return 1; \
}
#define modify_tstring_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
t_string value = luaW_checktstring(L, 3); \
accessor; \
return 0; \
}
#define modify_string_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
const char *value = luaL_checkstring(L, 3); \
accessor; \
return 0; \
}
#define modify_int_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
int value = luaL_checkinteger(L, 3); \
accessor; \
return 0; \
}
#define modify_int_attrib_check_range(name, accessor, allowed_min, allowed_max) \
if (strcmp(m, name) == 0) { \
int value = luaL_checkinteger(L, 3); \
if (value < allowed_min || allowed_max < value) return luaL_argerror(L, 3, "out of bounds"); \
accessor; \
return 0; \
}
#define modify_bool_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
bool value = luaW_toboolean(L, 3); \
accessor; \
return 0; \
}
#define modify_vector_string_attrib(name, accessor) \
if (strcmp(m, name) == 0) { \
std::vector<std::string> vector; \
char const* message = "table with unnamed indices holding strings expected"; \
if (!lua_istable(L, 3)) return luaL_argerror(L, 3, message); \
unsigned length = lua_rawlen(L, 3); \
for (unsigned i = 1; i <= length; ++i) { \
lua_rawgeti(L, 3, i); \
char const* string = lua_tostring(L, 4); \
if(!string) return luaL_argerror(L, 2 + i, message); \
vector.push_back(string); \
lua_pop(L, 1); \
} \
accessor; \
return 0; \
}
#endif