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...)
diff --git a/lauxlib.c b/lauxlib.c
index fd4acbd..769586b 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -185,7 +185,7 @@
}
-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 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_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;
}
diff --git a/lauxlib.h b/lauxlib.h
index 9ec0f53..e5d378a 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -48,6 +48,7 @@
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 @@
#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))
diff --git a/lbaselib.c b/lbaselib.c
index e776c2a..201c93e 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -125,8 +125,7 @@
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_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;
}
diff --git a/lcorolib.c b/lcorolib.c
index 9038f9f..34462b5 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -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;
}
diff --git a/ldblib.c b/ldblib.c
index 2001084..ada3525 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -55,8 +55,7 @@
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 */
diff --git a/lstrlib.c b/lstrlib.c
index a635e9d..e9c60c0 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -857,9 +857,9 @@
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 */
diff --git a/manual/manual.of b/manual/manual.of
index 8b5e5d9..0e8e3d7 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -4979,6 +4979,19 @@
}
+@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 @@
}
+@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,-}