1 /*
2 * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3 *
4 * Solarus is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Solarus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "solarus/core/Map.h"
18 #include "solarus/graphics/Color.h"
19 #include "solarus/lua/LuaException.h"
20 #include "solarus/lua/LuaTools.h"
21 #include "solarus/lua/LuaContext.h"
22 #include "solarus/lua/ScopedLuaRef.h"
23 #include <cctype>
24 #include <sstream>
25
26 namespace Solarus {
27 namespace LuaTools {
28
29 /**
30 * \brief For an index in the Lua stack, returns an equivalent positive index.
31 *
32 * Pseudo-indexes are unchanged.
33 *
34 * \param l A Lua state.
35 * \param index An index in the stack.
36 * \return The corresponding positive index.
37 */
get_positive_index(lua_State * l,int index)38 int get_positive_index(lua_State* l, int index) {
39
40 int positive_index = index;
41 if (index < 0 && index >= -lua_gettop(l)) {
42 positive_index = lua_gettop(l) + index + 1;
43 }
44
45 return positive_index;
46 }
47
48 /**
49 * \brief Returns whether the specified name is a valid Lua identifier.
50 * \param name The name to check.
51 * \return \c true if the name only contains alphanumeric characters or '_' and
52 * does not start with a digit.
53 */
is_valid_lua_identifier(const std::string & name)54 bool is_valid_lua_identifier(const std::string& name) {
55
56 if (name.empty() || std::isdigit(name[0])) {
57 return false;
58 }
59
60 for (char character: name) {
61 if (!std::isalnum(character) && character != '_') {
62 return false;
63 }
64 }
65 return true;
66 }
67
68 /**
69 * \brief Returns the type name of a value.
70 * Similar to the standard Lua function type(), except that for userdata
71 * known by Solarus, it returns the exact Solarus type name.
72 * \param l A Lua state.
73 * \param index An index in the stack.
74 * \return The type name.
75 */
get_type_name(lua_State * l,int index)76 std::string get_type_name(lua_State*l, int index) {
77
78 std::string module_name;
79 if (!LuaContext::is_solarus_userdata(l, index, module_name)) {
80 // Return the same thing as the usual Lua type() function.
81 return luaL_typename(l, index);
82 }
83
84 // This is a Solarus type.
85 return get_type_name(module_name);
86 }
87
88 /**
89 * \brief Returns the type name of a Solarus module.
90 *
91 * Converts Solarus module names into the name of the type the module wraps.
92 *
93 * \param module_name
94 * \return The type name.
95 */
get_type_name(const std::string & module_name)96 std::string get_type_name(const std::string& module_name) {
97
98 // Just remove the "sol." prefix.
99 return module_name.substr(4);
100 }
101
102 /**
103 * \brief Creates a reference to the Lua value on top of the stack and pops
104 * this value.
105 * \param l A Lua state.
106 * \return The reference created, wrapped in an object that manages its
107 * lifetime.
108 */
create_ref(lua_State * l)109 ScopedLuaRef create_ref(lua_State* l) {
110 lua_State* main = LuaContext::get().get_main_state();
111 //Cross move values to main state to avoid coroutines GC to invalidate them
112 if(l != main) {
113 lua_xmove(l,main,1);
114 }
115 return ScopedLuaRef(main, luaL_ref(main, LUA_REGISTRYINDEX));
116 }
117
118 /**
119 * \brief Creates a reference to the Lua value at the specified index.
120 * \param l A Lua state.
121 * \param index An index in the Lua stack.
122 * \return The reference created, wrapped in an object that manages its
123 * lifetime.
124 */
create_ref(lua_State * l,int index)125 ScopedLuaRef create_ref(lua_State* l, int index) {
126 lua_pushvalue(l, index);
127 return create_ref(l);
128 }
129
130 /**
131 * \brief Calls the Lua function with its arguments on top of the stack.
132 *
133 * This function is like lua_pcall, except that it additionally handles the
134 * error message if an error occurs in the Lua code (the error is printed).
135 * This function leaves the results on the stack if there is no error,
136 * and leaves nothing on the stack in case of error.
137 *
138 * \param l A Lua state.
139 * \param nb_arguments Number of arguments placed on the Lua stack above the
140 * function to call.
141 * \param nb_results Number of results expected (you get them on the stack if
142 * there is no error).
143 * \param function_name A name describing the Lua function (only used to print
144 * the error message if any).
145 * This is not a <tt>const std::string&</tt> but a <tt>const char*</tt> on
146 * purpose to avoid costly conversions as this function is called very often.
147 * \return \c true in case of success.
148 */
call_function(lua_State * l,int nb_arguments,int nb_results,const char * function_name)149 bool call_function(
150 lua_State* l,
151 int nb_arguments,
152 int nb_results,
153 const char* function_name
154 ) {
155 Debug::check_assertion(lua_gettop(l) > nb_arguments, "Missing arguments");
156 int base = lua_gettop(l) - nb_arguments;
157 lua_pushcfunction(l, &LuaContext::l_backtrace);
158 lua_insert(l, base);
159 int status = lua_pcall(l, nb_arguments, nb_results, base);
160 lua_remove(l, base);
161 if (status != 0) {
162 Debug::check_assertion(lua_isstring(l, -1), "Missing error message");
163 Debug::error(std::string("In ") + function_name + ": "
164 + lua_tostring(l, -1)
165 );
166 lua_pop(l, 1);
167 return false;
168 }
169 return true;
170 }
171
172 /**
173 * \brief Similar to luaL_error() but throws a LuaException.
174 *
175 * This function never returns.
176 *
177 * \param l A Lua state.
178 * \param message Error message.
179 */
error(lua_State * l,const std::string & message)180 void error(lua_State* l, const std::string& message) {
181 throw LuaException(l, message);
182 }
183
184 /**
185 * \brief Similar to luaL_argerror() but throws a LuaException.
186 *
187 * This function never returns.
188 *
189 * \param l A Lua state.
190 * \param arg_index Index of an argument in the stack.
191 * \param message Error message.
192 */
arg_error(lua_State * l,int arg_index,const std::string & message)193 void arg_error(lua_State* l, int arg_index, const std::string& message) {
194
195 // The code below is very similar to luaL_argerror(), but ends with
196 // an exception instead of a luaL_error() call.
197
198 std::ostringstream oss;
199 lua_Debug info;
200 if (!lua_getstack(l, 0, &info)) {
201 // No stack frame.
202 oss << "bad argument #" << arg_index << " (" << message << ")";
203 error(l, oss.str());
204 }
205
206 lua_getinfo(l, "n", &info);
207 if (std::string(info.namewhat) == "method") {
208 arg_index--; // Do not count self.
209 if (arg_index == 0) {
210 // Error is in the self argument itself.
211 oss << "calling " << info.name << " on bad self (" << message << ")";
212 error(l, oss.str());
213 }
214 }
215
216 if (info.name == nullptr) {
217 info.name = "?";
218 }
219 oss << "bad argument #" << arg_index << " to " << info.name << " (" << message << ")";
220 error(l, oss.str());
221 }
222
223 /**
224 * \brief Similar to luaL_typerror() but throws a LuaException.
225 *
226 * This function never returns.
227 *
228 * \param l A Lua state.
229 * \param arg_index Index of an argument in the stack.
230 * \param expected_type_name A name describing the type that was expected.
231 */
type_error(lua_State * l,int arg_index,const std::string & expected_type_name)232 void type_error(
233 lua_State* l,
234 int arg_index,
235 const std::string& expected_type_name
236 ) {
237 arg_error(l, arg_index, std::string(expected_type_name) +
238 " expected, got " + get_type_name(l, arg_index));
239 }
240
241 /**
242 * \brief Like luaL_checktype() but throws a LuaException in case of error.
243 * \param l A Lua state.
244 * \param arg_index Index of an argument in the stack.
245 * \param expected_type A Lua type value.
246 */
check_type(lua_State * l,int arg_index,int expected_type)247 void check_type(
248 lua_State* l,
249 int arg_index,
250 int expected_type
251 ) {
252 if (lua_type(l, arg_index) != expected_type) {
253 arg_error(l, arg_index, std::string(lua_typename(l, expected_type)) +
254 " expected, got " + get_type_name(l, arg_index));
255 }
256 }
257
258 /**
259 * \brief Like luaL_checkany() but throws a LuaException in case of error.
260 * \param l A Lua state.
261 * \param arg_index Index of an argument in the stack.
262 */
check_any(lua_State * l,int arg_index)263 void check_any(
264 lua_State* l,
265 int arg_index
266 ) {
267 if (lua_type(l, arg_index) == LUA_TNONE) {
268 arg_error(l, arg_index, "value expected");
269 }
270 }
271
272 /**
273 * \brief Checks that a value is a number and returns it as an integer.
274 *
275 * This function acts like luaL_checkint() except that it throws a LuaException
276 * in case of error.
277 *
278 * \param l A Lua state.
279 * \param index Index of a table in the stack.
280 * \return The value as an integer.
281 */
check_int(lua_State * l,int index)282 int check_int(
283 lua_State* l,
284 int index
285 ) {
286 if (!lua_isnumber(l, index)) {
287 arg_error(l, index,
288 std::string("integer expected, got ")
289 + get_type_name(l, index) + ")"
290 );
291 }
292
293 return (int) lua_tointeger(l, index);
294 }
295
296 /**
297 * \brief Checks that a table field is a number and returns it as an integer.
298 *
299 * This function acts like lua_getfield() followed by LuaTools::check_int().
300 *
301 * \param l A Lua state.
302 * \param table_index Index of a table in the stack.
303 * \param key Key of the field to get in that table.
304 * \return The wanted field as an integer.
305 */
check_int_field(lua_State * l,int table_index,const std::string & key)306 int check_int_field(
307 lua_State* l,
308 int table_index,
309 const std::string& key
310 ) {
311 lua_getfield(l, table_index, key.c_str());
312 if (!lua_isnumber(l, -1)) {
313 arg_error(l, table_index,
314 std::string("Bad field '") + key + "' (integer expected, got "
315 + get_type_name(l, -1) + ")"
316 );
317 }
318
319 int value = (int) lua_tointeger(l, -1);
320 lua_pop(l, 1);
321 return value;
322 }
323
324 /**
325 * \brief Like LuaTools::check_int() but with a default value.
326 *
327 * This function acts like luaL_optint() except that it throws a LuaException
328 * in case of error.
329 *
330 * \param l A Lua state.
331 * \param index Index of a value in the stack.
332 * \param default_value The default value to return if the value is \c nil.
333 * \return The wanted value as an integer.
334 */
opt_int(lua_State * l,int index,int default_value)335 int opt_int(
336 lua_State* l,
337 int index,
338 int default_value
339 ) {
340 if (lua_isnoneornil(l, index)) {
341 return default_value;
342 }
343 return check_int(l, index);
344 }
345
346 /**
347 * \brief Like LuaTools::check_int_field() but with a default value.
348 *
349 * This function acts like lua_getfield() followed by luaL_optint().
350 *
351 * \param l A Lua state.
352 * \param table_index Index of a table in the stack.
353 * \param key Key of the field to get in that table.
354 * \param default_value The default value to return if the field is \c nil.
355 * \return The wanted field as an integer.
356 */
opt_int_field(lua_State * l,int table_index,const std::string & key,int default_value)357 int opt_int_field(
358 lua_State* l,
359 int table_index,
360 const std::string& key,
361 int default_value
362 ) {
363 lua_getfield(l, table_index, key.c_str());
364 if (lua_isnil(l, -1)) {
365 lua_pop(l, 1);
366 return default_value;
367 }
368
369 if (!lua_isnumber(l, -1)) {
370 arg_error(l, table_index,
371 std::string("Bad field '") + key + "' (integer expected, got "
372 + get_type_name(l, -1) + ")"
373 );
374 }
375 int value = (int) lua_tointeger(l, -1);
376 lua_pop(l, 1);
377 return value;
378 }
379
380 /**
381 * \brief Checks that a value is a number and returns it as a double.
382 *
383 * This function acts like luaL_checknumber() except that it throws a
384 * LuaException in case of error.
385 *
386 * \param l A Lua state.
387 * \param index Index of a value in the stack.
388 * \return The number value.
389 */
check_number(lua_State * l,int index)390 double check_number(
391 lua_State* l,
392 int index
393 ) {
394 if (!lua_isnumber(l, index)) {
395 arg_error(l, index,
396 std::string("number expected, got ")
397 + get_type_name(l, index) + ")"
398 );
399 }
400
401 return lua_tonumber(l, index);
402 }
403
404 /**
405 * \brief Checks that a table field is a number and returns it as a double.
406 *
407 * This function acts like lua_getfield() followed by LuaTools::check_number().
408 *
409 * \param l A Lua state.
410 * \param table_index Index of a table in the stack.
411 * \param key Key of the field to get in that table.
412 * \return The wanted field as a double.
413 */
check_number_field(lua_State * l,int table_index,const std::string & key)414 double check_number_field(
415 lua_State* l,
416 int table_index,
417 const std::string& key
418 ) {
419 lua_getfield(l, table_index, key.c_str());
420 if (!lua_isnumber(l, -1)) {
421 arg_error(l, table_index,
422 std::string("Bad field '") + key + "' (number expected, got "
423 + get_type_name(l, -1) + ")"
424 );
425 }
426
427 double value = lua_tonumber(l, -1);
428 lua_pop(l, 1);
429 return value;
430 }
431
432 /**
433 * \brief Like LuaTools::check_number() but with a default value.
434 *
435 * This function acts like luaL_optnumber() except that it throws a
436 * LuaException in case of error.
437 *
438 * \param l A Lua state.
439 * \param index Index of a value in the stack.
440 * \param default_value The default value to return if the value is \c nil.
441 * \return The wanted value as a double.
442 */
opt_number(lua_State * l,int index,double default_value)443 double opt_number(
444 lua_State* l,
445 int index,
446 double default_value
447 ) {
448 if (lua_isnoneornil(l, index)) {
449 return default_value;
450 }
451 return check_number(l, index);
452 }
453
454 /**
455 * \brief Like LuaTools::check_number_field() but with a default value.
456 *
457 * This function acts like lua_getfield() followed by LuaTools::opt_number().
458 *
459 * \param l A Lua state.
460 * \param table_index Index of a table in the stack.
461 * \param key Key of the field to get in that table.
462 * \param default_value The default value to return if the field is \c nil.
463 * \return The wanted field as a double.
464 */
opt_number_field(lua_State * l,int table_index,const std::string & key,double default_value)465 double opt_number_field(
466 lua_State* l,
467 int table_index,
468 const std::string& key,
469 double default_value
470 ) {
471 lua_getfield(l, table_index, key.c_str());
472 if (lua_isnil(l, -1)) {
473 lua_pop(l, 1);
474 return default_value;
475 }
476
477 if (!lua_isnumber(l, -1)) {
478 arg_error(l, table_index,
479 std::string("Bad field '") + key + "' (number expected, got "
480 + luaL_typename(l, -1) + ")"
481 );
482 }
483 double value = lua_tonumber(l, -1);
484 lua_pop(l, 1);
485 return value;
486 }
487
488 /**
489 * \brief Checks that a value is a string and returns it.
490 *
491 * This function acts like luaL_checkstring() except that it throws a
492 * LuaException in case of error.
493 *
494 * \param l A Lua state.
495 * \param index Index of a value in the stack.
496 * \return The string value.
497 */
check_string(lua_State * l,int index)498 std::string check_string(
499 lua_State* l,
500 int index
501 ) {
502 if (!lua_isstring(l, index)) {
503 arg_error(l, index,
504 std::string("string expected, got ")
505 + get_type_name(l, index) + ")"
506 );
507 }
508 size_t size = 0;
509 const char* data = lua_tolstring(l, index, &size);
510 return {data, size};
511 }
512
513 /**
514 * \brief Checks that a table field is a string and returns it.
515 *
516 * This function acts like lua_getfield() followed by LuaTools::check_string().
517 *
518 * \param l A Lua state.
519 * \param table_index Index of a table in the stack.
520 * \param key Key of the field to get in that table.
521 * \return The wanted field as a string.
522 */
check_string_field(lua_State * l,int table_index,const std::string & key)523 std::string check_string_field(
524 lua_State* l,
525 int table_index,
526 const std::string& key
527 ) {
528 lua_getfield(l, table_index, key.c_str());
529 if (!lua_isstring(l, -1)) {
530 arg_error(l, table_index,
531 std::string("Bad field '") + key + "' (string expected, got "
532 + get_type_name(l, -1) + ")"
533 );
534 }
535
536 size_t size = 0;
537 const char* data = lua_tolstring(l, -1, &size);
538 const std::string value = {data, size};
539 lua_pop(l, 1);
540 return value;
541 }
542
543 /**
544 * \brief Like LuaTools::check_string() but with a default value.
545 *
546 * This function acts like luaL_optstring() except that it throws a
547 * LuaException in case of error.
548 *
549 * \param l A Lua state.
550 * \param index Index of a value in the stack.
551 * \param default_value The default value to return if the value is \c nil.
552 * \return The wanted value as a string.
553 */
opt_string(lua_State * l,int index,const std::string & default_value)554 std::string opt_string(
555 lua_State* l,
556 int index,
557 const std::string& default_value
558 ) {
559 if (lua_isnoneornil(l, index)) {
560 return default_value;
561 }
562 return check_string(l, index);
563 }
564
565 /**
566 * \brief Like LuaTools::check_string_field() but with a default value.
567 *
568 * This function acts like lua_getfield() followed by LuaTools::opt_string().
569 *
570 * \param l A Lua state.
571 * \param table_index Index of a table in the stack.
572 * \param key Key of the field to get in that table.
573 * \param default_value The default value to return if the field is \c nil.
574 * \return The wanted field as a string.
575 */
opt_string_field(lua_State * l,int table_index,const std::string & key,const std::string & default_value)576 std::string opt_string_field(
577 lua_State* l,
578 int table_index,
579 const std::string& key,
580 const std::string& default_value
581 ) {
582 lua_getfield(l, table_index, key.c_str());
583 if (lua_isnil(l, -1)) {
584 lua_pop(l, 1);
585 return default_value;
586 }
587
588 if (!lua_isstring(l, -1)) {
589 arg_error(l, table_index,
590 std::string("Bad field '") + key + "' (string expected, got "
591 + get_type_name(l, -1) + ")"
592 );
593 }
594 size_t size = 0;
595 const char* data = lua_tolstring(l, -1, &size);
596 const std::string value = {data, size};
597 lua_pop(l, 1);
598 return value;
599 }
600
601 /**
602 * \brief Checks that a value is a boolean and returns it.
603 *
604 * This function throws a LuaException in case of error.
605 *
606 * \param l A Lua state.
607 * \param index Index of a value in the stack.
608 * \return The boolean value.
609 */
check_boolean(lua_State * l,int index)610 bool check_boolean(
611 lua_State* l,
612 int index
613 ) {
614 if (!lua_isboolean(l, index)) {
615 arg_error(l, index,
616 std::string("boolean expected, got ")
617 + get_type_name(l, index) + ")"
618 );
619 }
620 return lua_toboolean(l, index);
621 }
622
623 /**
624 * \brief Checks that a table field is a boolean and returns it.
625 * \param l A Lua state.
626 * \param table_index Index of a table in the stack.
627 * \param key Key of the field to get in that table.
628 * \return The wanted field as a boolean.
629 */
check_boolean_field(lua_State * l,int table_index,const std::string & key)630 bool check_boolean_field(
631 lua_State* l,
632 int table_index,
633 const std::string& key
634 ) {
635 lua_getfield(l, table_index, key.c_str());
636 if (lua_type(l, -1) != LUA_TBOOLEAN) {
637 arg_error(l, table_index,
638 std::string("Bad field '") + key + "' (boolean expected, got "
639 + get_type_name(l, -1) + ")"
640 );
641 }
642
643 bool value = lua_toboolean(l, -1);
644 lua_pop(l, 1);
645 return value;
646 }
647
648 /**
649 * \brief Like LuaTools::check_boolean() but with a default value.
650 * \param l A Lua state.
651 * \param index Index of a value in the stack.
652 * \param default_value The default value to return if the value is \c nil.
653 * \return The wanted value as a boolean.
654 */
opt_boolean(lua_State * l,int index,bool default_value)655 bool opt_boolean(
656 lua_State* l,
657 int index,
658 bool default_value
659 ) {
660 if (lua_isnoneornil(l, index)) {
661 return default_value;
662 }
663 return check_boolean(l, index);
664 }
665
666 /**
667 * \brief Like check_boolean_field() but with a default value.
668 *
669 * This function acts like lua_getfield() followed by lua_toboolean().
670 *
671 * \param l A Lua state.
672 * \param table_index Index of a table in the stack.
673 * \param key Key of the field to get in that table.
674 * \param default_value The default value to return if the field is \c nil.
675 * \return The wanted field as a string.
676 */
opt_boolean_field(lua_State * l,int table_index,const std::string & key,bool default_value)677 bool opt_boolean_field(
678 lua_State* l,
679 int table_index,
680 const std::string& key,
681 bool default_value
682 ) {
683 lua_getfield(l, table_index, key.c_str());
684 if (lua_isnil(l, -1)) {
685 lua_pop(l, 1);
686 return default_value;
687 }
688
689 if (lua_type(l, -1) != LUA_TBOOLEAN) {
690 arg_error(l, table_index,
691 std::string("Bad field '") + key + "' (boolean expected, got "
692 + get_type_name(l, -1) + ")"
693 );
694 }
695 return lua_toboolean(l, -1);
696 }
697
698 /**
699 * \brief Checks that a value is a function and returns a ref to it.
700 *
701 * This function throws a LuaException in case of error.
702 *
703 * \param l A Lua state.
704 * \param index Index of a value in the stack.
705 * \return The wanted value as a Lua ref to the function.
706 */
check_function(lua_State * l,int index)707 ScopedLuaRef check_function(
708 lua_State* l,
709 int index
710 ) {
711 check_type(l, index, LUA_TFUNCTION);
712 return create_ref(l, index); // Leave the function in the stack.
713 }
714
715 /**
716 * \brief Checks that a table field is a function and returns a ref to it.
717 * \param l A Lua state.
718 * \param table_index Index of a table in the stack.
719 * \param key Key of the field to get in that table.
720 * \return The wanted field as a Lua ref to the function.
721 */
check_function_field(lua_State * l,int table_index,const std::string & key)722 ScopedLuaRef check_function_field(
723 lua_State* l,
724 int table_index,
725 const std::string& key
726 ) {
727 lua_getfield(l, table_index, key.c_str());
728 if (!lua_isfunction(l, -1)) {
729 arg_error(l, table_index,
730 std::string("Bad field '") + key + "' (function expected, got "
731 + get_type_name(l, -1) + ")"
732 );
733 }
734
735 return create_ref(l); // This also pops the function from the stack.
736 }
737
738 /**
739 * \brief Like LuaTools::check_function() but the value is optional.
740 * \param l A Lua state.
741 * \param index Index of a value in the stack.
742 * \return The wanted value as a Lua ref to the function, or an empty ref.
743 */
opt_function(lua_State * l,int index)744 ScopedLuaRef opt_function(
745 lua_State* l,
746 int index
747 ) {
748 if (lua_isnoneornil(l, index)) {
749 return ScopedLuaRef();
750 }
751 return check_function(l, index);
752 }
753
754 /**
755 * \brief Like LuaTools::check_function_field() but the field is optional.
756 * \param l A Lua state.
757 * \param table_index Index of a table in the stack.
758 * \param key Key of the field to get in that table.
759 * \return The wanted field as a Lua ref to the function, or an empty ref.
760 */
opt_function_field(lua_State * l,int table_index,const std::string & key)761 ScopedLuaRef opt_function_field(
762 lua_State* l,
763 int table_index,
764 const std::string& key
765 ) {
766 lua_getfield(l, table_index, key.c_str());
767 if (lua_isnil(l, -1)) {
768 lua_pop(l, 1);
769 return ScopedLuaRef();
770 }
771
772 if (!lua_isfunction(l, -1)) {
773 arg_error(l, table_index,
774 std::string("Bad field '") + key + "' (function expected, got "
775 + get_type_name(l, -1) + ")"
776 );
777 }
778 return create_ref(l); // This also pops the function from the stack.
779 }
780 /**
781 * \brief Returns whether a value is a layer.
782 * \param l A Lua context.
783 * \param index An index in the stack.
784 * \param map The map whose number of layer matters.
785 * \return \c true if the value is a valid layer for the map.
786 */
is_layer(lua_State * l,int index,const Map & map)787 bool is_layer(
788 lua_State* l,
789 int index,
790 const Map& map
791 ) {
792 if (!lua_isnumber(l, index)) {
793 return false;
794 }
795 int layer = check_int(l, index);
796 return map.is_valid_layer(layer);
797 }
798
799 /**
800 * \brief Checks that the value at the given index is a valid layer and returns it.
801 * \param l A Lua state.
802 * \param index An index in the Lua stack.
803 * \param map The map whose number of layer matters.
804 * \return The layer at this index.
805 */
check_layer(lua_State * l,int index,const Map & map)806 int check_layer(
807 lua_State* l,
808 int index,
809 const Map& map
810 ) {
811 if (!lua_isnumber(l, index)) {
812 type_error(l, index, "number");
813 }
814
815 if (!is_layer(l, index, map)) {
816 std::ostringstream oss;
817 oss << "Invalid layer: " << lua_tonumber(l, index);
818 arg_error(l, index, oss.str());
819 }
820
821 return lua_tointeger(l, index);
822 }
823
824 /**
825 * \brief Checks that a table field is a valid layer and returns it.
826 *
827 * This function acts like lua_getfield() followed by LuaTools::check_layer().
828 *
829 * \param l A Lua state.
830 * \param table_index Index of a table in the stack.
831 * \param key Key of the field to get in that table.
832 * \param map The map whose number of layer matters.
833 * \return The wanted field as a layer.
834 */
check_layer_field(lua_State * l,int table_index,const std::string & key,const Map & map)835 int check_layer_field(
836 lua_State* l,
837 int table_index,
838 const std::string& key,
839 const Map& map
840 ) {
841 lua_getfield(l, table_index, key.c_str());
842 if (!is_layer(l, -1, map)) {
843 arg_error(l, table_index,
844 std::string("Bad field '") + key + "' (layer expected, got "
845 + get_type_name(l, -1) + ")"
846 );
847 }
848
849 int value = lua_tointeger(l, -1);
850 lua_pop(l, 1);
851 return value;
852 }
853
854 /**
855 * \brief Like LuaTools::check_layer() but with a default value.
856 * \param l A Lua state.
857 * \param index Index of a value in the stack.
858 * \param map The map whose number of layer matters.
859 * \param default_value The default value to return if the value is \c nil.
860 * \return The wanted value as a layer.
861 */
opt_layer(lua_State * l,int index,const Map & map,int default_value)862 int opt_layer(
863 lua_State* l,
864 int index,
865 const Map& map,
866 int default_value
867 ) {
868 if (lua_isnoneornil(l, index)) {
869 return default_value;
870 }
871 return check_layer(l, index, map);
872 }
873
874 /**
875 * \brief Like LuaTools::check_layer_field() but with a default value.
876 * \param l A Lua state.
877 * \param table_index Index of a table in the stack.
878 * \param key Key of the field to get in that table.
879 * \param map The map whose number of layer matters.
880 * \param default_value The default value to return if the field is \c nil.
881 * \return The wanted field as a layer.
882 */
opt_layer_field(lua_State * l,int table_index,const std::string & key,const Map & map,int default_value)883 int opt_layer_field(
884 lua_State* l,
885 int table_index,
886 const std::string& key,
887 const Map& map,
888 int default_value
889 ) {
890 lua_getfield(l, table_index, key.c_str());
891 if (lua_isnil(l, -1)) {
892 lua_pop(l, 1);
893 return default_value;
894 }
895
896 if (!is_layer(l, -1, map)) {
897 arg_error(l, table_index,
898 std::string("Bad field '") + key + "' (layer expected, got "
899 + get_type_name(l, -1) + ")"
900 );
901 }
902 int value = lua_tointeger(l, -1);
903 lua_pop(l, 1);
904 return value;
905 }
906
907 /**
908 * \brief Returns whether a value is a color.
909 * \param l A Lua context.
910 * \param index An index in the stack.
911 * \return true if the value is a color, that is, an array with three integers.
912 */
is_color(lua_State * l,int index)913 bool is_color(lua_State* l, int index) {
914
915 index = get_positive_index(l, index);
916
917 if (lua_type(l, index) != LUA_TTABLE) {
918 return false;
919 }
920
921 lua_rawgeti(l, index, 1);
922 lua_rawgeti(l, index, 2);
923 lua_rawgeti(l, index, 3);
924 lua_rawgeti(l, index, 4);
925 bool result = lua_isnumber(l, -4) &&
926 lua_isnumber(l, -3) &&
927 lua_isnumber(l, -2) &&
928 (lua_isnumber(l, -1) || lua_isnil(l, -1));
929 lua_pop(l, 4);
930 return result;
931 }
932
933 /**
934 * \brief Checks that the value at the given index is a color and returns it.
935 *
936 * Set opaque by default if alpha channel is not specified.
937 *
938 * \param l a Lua state
939 * \param index an index in the Lua stack
940 * \return the color at this index
941 */
check_color(lua_State * l,int index)942 Color check_color(lua_State* l, int index) {
943
944 index = get_positive_index(l, index);
945
946 check_type(l, index, LUA_TTABLE);
947 lua_rawgeti(l, index, 1);
948 lua_rawgeti(l, index, 2);
949 lua_rawgeti(l, index, 3);
950 lua_rawgeti(l, index, 4);
951 Color color(
952 check_int(l, -4),
953 check_int(l, -3),
954 check_int(l, -2),
955 opt_int(l, -1, 255)
956 );
957 lua_pop(l, 4);
958
959 return color;
960 }
961
962 /**
963 * \brief Checks that a table field is a color and returns it.
964 *
965 * This function acts like lua_getfield() followed by LuaTools::check_color().
966 *
967 * \param l A Lua state.
968 * \param table_index Index of a table in the stack.
969 * \param key Key of the field to get in that table.
970 * \return The wanted field as a layer.
971 */
check_color_field(lua_State * l,int table_index,const std::string & key)972 Color check_color_field(
973 lua_State* l,
974 int table_index,
975 const std::string& key
976 ) {
977 lua_getfield(l, table_index, key.c_str());
978 if (!is_color(l, -1)) {
979 arg_error(l, table_index,
980 std::string("Bad field '") + key + "' (color table expected, got "
981 + get_type_name(l, -1) + ")"
982 );
983 }
984
985 const Color& value = check_color(l, -1);
986 lua_pop(l, 1);
987 return value;
988 }
989
990 /**
991 * \brief Like LuaTools::check_color() but with a default value.
992 * \param l A Lua state.
993 * \param index Index of a value in the stack.
994 * \param default_value The default value to return if the value is \c nil.
995 * \return The wanted value as a color.
996 */
opt_color(lua_State * l,int index,const Color & default_value)997 Color opt_color(
998 lua_State* l,
999 int index,
1000 const Color& default_value
1001 ) {
1002 if (lua_isnoneornil(l, index)) {
1003 return default_value;
1004 }
1005 return check_color(l, index);
1006 }
1007
1008 /**
1009 * \brief Like LuaTools::check_color_field() but with a default value.
1010 * \param l A Lua state.
1011 * \param table_index Index of a table in the stack.
1012 * \param key Key of the field to get in that table.
1013 * \param default_value The default value to return if the field is \c nil.
1014 * \return The wanted field as a color.
1015 */
opt_color_field(lua_State * l,int table_index,const std::string & key,const Color & default_value)1016 Color opt_color_field(
1017 lua_State* l,
1018 int table_index,
1019 const std::string& key,
1020 const Color& default_value
1021 ) {
1022 lua_getfield(l, table_index, key.c_str());
1023 if (lua_isnil(l, -1)) {
1024 lua_pop(l, 1);
1025 return default_value;
1026 }
1027
1028 if (!is_color(l, -1)) {
1029 arg_error(l, table_index,
1030 std::string("Bad field '") + key + "' (color expected, got "
1031 + get_type_name(l, -1) + ")"
1032 );
1033 }
1034 const Color& color = check_color(l, -1);
1035 lua_pop(l, 1);
1036 return color;
1037 }
1038
1039 } // namespace LuaTools
1040
1041 } // namespace Solarus
1042