aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-10 13:46:03 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-10 13:46:03 -0200
commit46beca5bed8a7700b18100fe48a78373be5055f9 (patch)
tree499de35c048605434d9adb7ace964adf673041ac
parent28d829c86712ce5bc453feccc5129a32f78d80c0 (diff)
downloadlua-46beca5bed8a7700b18100fe48a78373be5055f9.tar.gz
lua-46beca5bed8a7700b18100fe48a78373be5055f9.tar.bz2
lua-46beca5bed8a7700b18100fe48a78373be5055f9.zip
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...)
-rw-r--r--lauxlib.c6
-rw-r--r--lauxlib.h5
-rw-r--r--lbaselib.c7
-rw-r--r--lcorolib.c2
-rw-r--r--ldblib.c3
-rw-r--r--lstrlib.c4
-rw-r--r--manual/manual.of26
7 files changed, 41 insertions, 12 deletions
diff --git a/lauxlib.c b/lauxlib.c
index fd4acbd1..769586b6 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -185,7 +185,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
185} 185}
186 186
187 187
188static int typeerror (lua_State *L, int arg, const char *tname) { 188int luaL_typeerror (lua_State *L, int arg, const char *tname) {
189 const char *msg; 189 const char *msg;
190 const char *typearg; /* name for the type of the actual argument */ 190 const char *typearg; /* name for the type of the actual argument */
191 if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) 191 if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
@@ -200,7 +200,7 @@ static int typeerror (lua_State *L, int arg, const char *tname) {
200 200
201 201
202static void tag_error (lua_State *L, int arg, int tag) { 202static void tag_error (lua_State *L, int arg, int tag) {
203 typeerror(L, arg, lua_typename(L, tag)); 203 luaL_typeerror(L, arg, lua_typename(L, tag));
204} 204}
205 205
206 206
@@ -339,7 +339,7 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
339 339
340LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { 340LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
341 void *p = luaL_testudata(L, ud, tname); 341 void *p = luaL_testudata(L, ud, tname);
342 if (p == NULL) typeerror(L, ud, tname); 342 luaL_argexpected(L, p != NULL, ud, tname);
343 return p; 343 return p;
344} 344}
345 345
diff --git a/lauxlib.h b/lauxlib.h
index 9ec0f531..e5d378ae 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -48,6 +48,7 @@ LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
48LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 48LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
49LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 49LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
50LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); 50LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
51LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname);
51LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, 52LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
52 size_t *l); 53 size_t *l);
53LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, 54LUALIB_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,
126 127
127#define luaL_argcheck(L, cond,arg,extramsg) \ 128#define luaL_argcheck(L, cond,arg,extramsg) \
128 ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) 129 ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
130
131#define luaL_argexpected(L,cond,arg,tname) \
132 ((void)((cond) || luaL_typeerror(L, (arg), (tname))))
133
129#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 134#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
130#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 135#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
131 136
diff --git a/lbaselib.c b/lbaselib.c
index e776c2a2..201c93e3 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -125,8 +125,7 @@ static int luaB_getmetatable (lua_State *L) {
125static int luaB_setmetatable (lua_State *L) { 125static int luaB_setmetatable (lua_State *L) {
126 int t = lua_type(L, 2); 126 int t = lua_type(L, 2);
127 luaL_checktype(L, 1, LUA_TTABLE); 127 luaL_checktype(L, 1, LUA_TTABLE);
128 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 128 luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
129 "nil or table expected");
130 if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL) 129 if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
131 return luaL_error(L, "cannot change a protected metatable"); 130 return luaL_error(L, "cannot change a protected metatable");
132 lua_settop(L, 2); 131 lua_settop(L, 2);
@@ -145,8 +144,8 @@ static int luaB_rawequal (lua_State *L) {
145 144
146static int luaB_rawlen (lua_State *L) { 145static int luaB_rawlen (lua_State *L) {
147 int t = lua_type(L, 1); 146 int t = lua_type(L, 1);
148 luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, 147 luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
149 "table or string expected"); 148 "table or string");
150 lua_pushinteger(L, lua_rawlen(L, 1)); 149 lua_pushinteger(L, lua_rawlen(L, 1));
151 return 1; 150 return 1;
152} 151}
diff --git a/lcorolib.c b/lcorolib.c
index 9038f9fb..34462b53 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -20,7 +20,7 @@
20 20
21static lua_State *getco (lua_State *L) { 21static lua_State *getco (lua_State *L) {
22 lua_State *co = lua_tothread(L, 1); 22 lua_State *co = lua_tothread(L, 1);
23 luaL_argcheck(L, co, 1, "thread expected"); 23 luaL_argexpected(L, co, 1, "thread");
24 return co; 24 return co;
25} 25}
26 26
diff --git a/ldblib.c b/ldblib.c
index 20010842..ada35250 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -55,8 +55,7 @@ static int db_getmetatable (lua_State *L) {
55 55
56static int db_setmetatable (lua_State *L) { 56static int db_setmetatable (lua_State *L) {
57 int t = lua_type(L, 2); 57 int t = lua_type(L, 2);
58 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, 58 luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table");
59 "nil or table expected");
60 lua_settop(L, 2); 59 lua_settop(L, 2);
61 lua_setmetatable(L, 1); 60 lua_setmetatable(L, 1);
62 return 1; /* return 1st argument */ 61 return 1; /* return 1st argument */
diff --git a/lstrlib.c b/lstrlib.c
index a635e9d4..e9c60c0f 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -857,9 +857,9 @@ static int str_gsub (lua_State *L) {
857 lua_Integer n = 0; /* replacement count */ 857 lua_Integer n = 0; /* replacement count */
858 MatchState ms; 858 MatchState ms;
859 luaL_Buffer b; 859 luaL_Buffer b;
860 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || 860 luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
861 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, 861 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
862 "string/function/table expected"); 862 "string/function/table");
863 luaL_buffinit(L, &b); 863 luaL_buffinit(L, &b);
864 if (anchor) { 864 if (anchor) {
865 p++; lp--; /* skip anchor character */ 865 p++; lp--; /* skip anchor character */
diff --git a/manual/manual.of b/manual/manual.of
index 8b5e5d93..0e8e3d72 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -4979,6 +4979,19 @@ This function never returns.
4979 4979
4980} 4980}
4981 4981
4982@APIEntry{
4983void luaL_argexpected (lua_State *L,
4984 int cond,
4985 int arg,
4986 const char *tname);|
4987@apii{0,0,v}
4988
4989Checks whether @id{cond} is true.
4990If it is not, raises an error about the type of the argument @id{arg}
4991with a standard message @seeF{luaL_typeerror}.
4992
4993}
4994
4982@APIEntry{typedef struct luaL_Buffer luaL_Buffer;| 4995@APIEntry{typedef struct luaL_Buffer luaL_Buffer;|
4983 4996
4984Type for a @def{string buffer}. 4997Type for a @def{string buffer}.
@@ -5713,6 +5726,19 @@ to start the traceback.
5713 5726
5714} 5727}
5715 5728
5729@APIEntry{const char *luaL_typeerror (lua_State *L,
5730 int arg,
5731 const char *tname);|
5732@apii{0,0,v}
5733
5734Raises a type error for argument @id{arg}
5735of the @N{C function} that called it,
5736using a standard message;
5737@id{tname} is a @Q{name} for the expected type.
5738This function never returns.
5739
5740}
5741
5716@APIEntry{const char *luaL_typename (lua_State *L, int index);| 5742@APIEntry{const char *luaL_typename (lua_State *L, int index);|
5717@apii{0,0,-} 5743@apii{0,0,-}
5718 5744