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,-}