From 93fe0b36b768a5e681bf5bf0943ba3e98aa12c1d Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 25 Jul 2011 15:42:39 +0200 Subject: Add checkudata and checkargno functions to lua::state These can be used by functions to check the saneness of arguments. They throw an exception on error. In the future, I might add more informative error messages. --- src/FbTk/Luamm.cc | 31 +++++++++++++++++++++++++++++++ src/FbTk/Luamm.hh | 12 ++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/FbTk/Luamm.cc b/src/FbTk/Luamm.cc index 1ef751f..80d0926 100644 --- a/src/FbTk/Luamm.cc +++ b/src/FbTk/Luamm.cc @@ -24,6 +24,8 @@ #include "Luamm.hh" +#include + namespace lua { namespace { // keys for storing values in lua registry @@ -274,6 +276,35 @@ namespace lua { throw lua::exception(this); } + void state::checkargno(int argno) throw(lua::check_error) + { + if(gettop() != argno) { + std::ostringstream str; + str << "Wrong number of arguments: expected " << argno << ", got " << gettop(); + throw lua::check_error(str.str()); + } + } + + void *state::checkudata(int narg, const char *tname) throw(lua::check_error, std::bad_alloc) + { + checkstack(2); + stack_sentry s(*this); + + void *p = touserdata(narg); + if(p != NULL) { + if(getmetatable(narg)) { + rawgetfield(REGISTRYINDEX, tname); + if(rawequal(-1, -2)) + return p; + pop(2); + } + } + std::ostringstream str; + str << "Invalid argument #" << narg << ": expected " << type_name(TUSERDATA) + << ", got " << type_name(type(narg)); + throw lua::check_error(str.str()); + } + void state::checkstack(int extra) throw(std::bad_alloc) { if(not lua_checkstack(cobj, extra)) diff --git a/src/FbTk/Luamm.hh b/src/FbTk/Luamm.hh index 110ac97..b75fb12 100644 --- a/src/FbTk/Luamm.hh +++ b/src/FbTk/Luamm.hh @@ -131,6 +131,14 @@ namespace lua { {} }; + // thrown by check* functions when they detect an invalid argument + class check_error: public std::runtime_error { + public: + check_error(const std::string &msg) + : std::runtime_error(msg) + {} + }; + // a fancy wrapper around lua_State class state { lua_State *cobj; @@ -264,6 +272,10 @@ namespace lua { // type c, throw everything but the kitchen sink // call() is a protected mode call, we don't allow unprotected calls void call(int nargs, int nresults, int errfunc = 0); + void checkargno(int argno) throw(lua::check_error); + void *checkudata(int narg, const char *tname) throw(lua::check_error, std::bad_alloc); + template + T *checkudata(int narg, const char *tname) throw(lua::check_error, std::bad_alloc) { return static_cast(checkudata(narg, tname)); } void concat(int n); bool equal(int index1, int index2); int gc(int what, int data); -- cgit v0.11.2