mirror of https://github.com/lua/lua
Better error messages for some polymorphic functions
New auxiliary functions/macros 'luaL_argexpected'/'luaL_typeerror' ease the creation of error messages such as bad argument #2 to 'setmetatable' (nil or table expected, got boolean) (The novelty being the "got boolean" part...)
This commit is contained in:
parent
28d829c867
commit
46beca5bed
|
@ -185,7 +185,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
|
|||
}
|
||||
|
||||
|
||||
static int typeerror (lua_State *L, int arg, const char *tname) {
|
||||
int luaL_typeerror (lua_State *L, int arg, const char *tname) {
|
||||
const char *msg;
|
||||
const char *typearg; /* name for the type of the actual argument */
|
||||
if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
|
||||
|
@ -200,7 +200,7 @@ static int typeerror (lua_State *L, int arg, const char *tname) {
|
|||
|
||||
|
||||
static void tag_error (lua_State *L, int arg, int tag) {
|
||||
typeerror(L, arg, lua_typename(L, tag));
|
||||
luaL_typeerror(L, arg, lua_typename(L, tag));
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,7 +339,7 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
|
|||
|
||||
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
|
||||
void *p = luaL_testudata(L, ud, tname);
|
||||
if (p == NULL) typeerror(L, ud, tname);
|
||||
luaL_argexpected(L, p != NULL, ud, tname);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
|
|||
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
|
||||
LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
|
||||
LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
|
||||
LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname);
|
||||
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
|
||||
size_t *l);
|
||||
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
|
||||
|
@ -126,6 +127,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
|
|||
|
||||
#define luaL_argcheck(L, cond,arg,extramsg) \
|
||||
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
|
||||
|
||||
#define luaL_argexpected(L,cond,arg,tname) \
|
||||
((void)((cond) || luaL_typeerror(L, (arg), (tname))))
|
||||
|
||||
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
|
||||
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
|
||||
|
||||
|
|
|
@ -125,8 +125,7 @@ static int luaB_getmetatable (lua_State *L) {
|
|||
static int luaB_setmetatable (lua_State *L) {
|
||||
int t = lua_type(L, 2);
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
|
||||
"nil or table expected");
|
||||
luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
|
||||
if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
|
||||
return luaL_error(L, "cannot change a protected metatable");
|
||||
lua_settop(L, 2);
|
||||
|
@ -145,8 +144,8 @@ static int luaB_rawequal (lua_State *L) {
|
|||
|
||||
static int luaB_rawlen (lua_State *L) {
|
||||
int t = lua_type(L, 1);
|
||||
luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
|
||||
"table or string expected");
|
||||
luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
|
||||
"table or string");
|
||||
lua_pushinteger(L, lua_rawlen(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
static lua_State *getco (lua_State *L) {
|
||||
lua_State *co = lua_tothread(L, 1);
|
||||
luaL_argcheck(L, co, 1, "thread expected");
|
||||
luaL_argexpected(L, co, 1, "thread");
|
||||
return co;
|
||||
}
|
||||
|
||||
|
|
3
ldblib.c
3
ldblib.c
|
@ -55,8 +55,7 @@ static int db_getmetatable (lua_State *L) {
|
|||
|
||||
static int db_setmetatable (lua_State *L) {
|
||||
int t = lua_type(L, 2);
|
||||
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
|
||||
"nil or table expected");
|
||||
luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
|
||||
lua_settop(L, 2);
|
||||
lua_setmetatable(L, 1);
|
||||
return 1; /* return 1st argument */
|
||||
|
|
|
@ -857,9 +857,9 @@ static int str_gsub (lua_State *L) {
|
|||
lua_Integer n = 0; /* replacement count */
|
||||
MatchState ms;
|
||||
luaL_Buffer b;
|
||||
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
||||
luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
||||
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
|
||||
"string/function/table expected");
|
||||
"string/function/table");
|
||||
luaL_buffinit(L, &b);
|
||||
if (anchor) {
|
||||
p++; lp--; /* skip anchor character */
|
||||
|
|
|
@ -4979,6 +4979,19 @@ This function never returns.
|
|||
|
||||
}
|
||||
|
||||
@APIEntry{
|
||||
void luaL_argexpected (lua_State *L,
|
||||
int cond,
|
||||
int arg,
|
||||
const char *tname);|
|
||||
@apii{0,0,v}
|
||||
|
||||
Checks whether @id{cond} is true.
|
||||
If it is not, raises an error about the type of the argument @id{arg}
|
||||
with a standard message @seeF{luaL_typeerror}.
|
||||
|
||||
}
|
||||
|
||||
@APIEntry{typedef struct luaL_Buffer luaL_Buffer;|
|
||||
|
||||
Type for a @def{string buffer}.
|
||||
|
@ -5713,6 +5726,19 @@ to start the traceback.
|
|||
|
||||
}
|
||||
|
||||
@APIEntry{const char *luaL_typeerror (lua_State *L,
|
||||
int arg,
|
||||
const char *tname);|
|
||||
@apii{0,0,v}
|
||||
|
||||
Raises a type error for argument @id{arg}
|
||||
of the @N{C function} that called it,
|
||||
using a standard message;
|
||||
@id{tname} is a @Q{name} for the expected type.
|
||||
This function never returns.
|
||||
|
||||
}
|
||||
|
||||
@APIEntry{const char *luaL_typename (lua_State *L, int index);|
|
||||
@apii{0,0,-}
|
||||
|
||||
|
|
Loading…
Reference in New Issue