Skip to content

Commit 0ccce1d

Browse files
authored
Merge pull request #2240 from joto/check-metatable
Check that Lua functions on OSM object are called correctly
2 parents 7406ff3 + 28c4dc2 commit 0ccce1d

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

src/output-flex.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <limits>
4646
#include <memory>
4747
#include <mutex>
48+
#include <set>
4849
#include <stdexcept>
4950
#include <string>
5051
#include <string_view>
@@ -295,6 +296,40 @@ void create_expire_tables(std::vector<expire_output_t> const &expire_outputs,
295296
}
296297
}
297298

299+
void check_for_object(lua_State *lua_state, char const *const function_name)
300+
{
301+
// This is used to make sure we are printing warnings only once per
302+
// function name.
303+
static std::set<std::string> message_shown;
304+
if (message_shown.count(function_name)) {
305+
return;
306+
}
307+
308+
int const num_params = lua_gettop(lua_state);
309+
if (num_params == 0) {
310+
log_warn("You should use the syntax 'object:{}()' (with the colon, not "
311+
"a point) to call functions on the OSM object.",
312+
function_name);
313+
314+
message_shown.emplace(function_name);
315+
return;
316+
}
317+
318+
if (lua_getmetatable(lua_state, 1)) {
319+
luaL_getmetatable(lua_state, osm2pgsql_object_metatable.data());
320+
if (lua_rawequal(lua_state, -1, -2)) {
321+
lua_pop(lua_state, 2); // remove the two metatables
322+
return;
323+
}
324+
lua_pop(lua_state, 2); // remove the two metatables
325+
}
326+
327+
message_shown.emplace(function_name);
328+
log_warn("First and only parameter for {0}() must be the OSM object. Call "
329+
"it like this: 'object:{0}()'.",
330+
function_name);
331+
}
332+
298333
} // anonymous namespace
299334

300335
/**
@@ -304,6 +339,8 @@ void create_expire_tables(std::vector<expire_output_t> const &expire_outputs,
304339
void output_flex_t::check_context_and_state(char const *name,
305340
char const *context, bool condition)
306341
{
342+
check_for_object(lua_state(), name);
343+
307344
if (condition) {
308345
throw fmt_error(
309346
"The function {}() can only be called (directly or indirectly) "

0 commit comments

Comments
 (0)