1 /* tolua: functions to check types.
2 ** Support code for Lua bindings.
3 ** Written by Waldemar Celes
9 /* This code is free software; you can redistribute it and/or modify it.
10 ** The software provided hereunder is on an "as is" basis, and
11 ** the author has no obligation to provide maintenance, support, updates,
12 ** enhancements, or modifications.
21 /* a fast check if a is b, without parameter validation
22 i.e. if b is equal to a or a superclass of a. */
23 TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)
26 if (lua_rawequal(L,mt_indexa,mt_indexb))
31 lua_pushvalue(L, super_index);
33 lua_pushliteral(L,"tolua_super");
34 lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */
36 lua_pushvalue(L,mt_indexa); /* stack: super mta */
37 lua_rawget(L,-2); /* stack: super super[mta] */
38 lua_pushvalue(L,mt_indexb); /* stack: super super[mta] mtb */
39 lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super super[mta] typenameB */
40 lua_rawget(L,-2); /* stack: super super[mta] bool */
41 result = lua_toboolean(L,-1);
47 /* Push and returns the corresponding object typename */
48 TOLUA_API const char* tolua_typename (lua_State* L, int lo)
50 int tag = lua_type(L,lo);
52 lua_pushstring(L,"[no object]");
53 else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
54 lua_pushstring(L,lua_typename(L,tag));
55 else if (tag == LUA_TUSERDATA)
57 if (!lua_getmetatable(L,lo))
58 lua_pushstring(L,lua_typename(L,tag));
61 lua_rawget(L,LUA_REGISTRYINDEX);
62 if (!lua_isstring(L,-1))
65 lua_pushstring(L,"[undefined]");
72 lua_rawget(L,LUA_REGISTRYINDEX);
73 if (!lua_isstring(L,-1))
76 lua_pushstring(L,"table");
80 lua_pushstring(L,"class ");
85 return lua_tostring(L,-1);
88 TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
92 const char* expected = err->type;
93 const char* provided = tolua_typename(L,err->index);
96 int narg = err->index;
98 luaL_error(L,"%s\n argument #%d is array of '%s'; array of '%s' expected.\n",
99 msg+2,narg,provided,expected);
101 luaL_error(L,"%s\n argument #%d is '%s'; '%s' expected.\n",
102 msg+2,narg,provided,expected);
104 else if (msg[1]=='v')
107 luaL_error(L,"%s\n value is array of '%s'; array of '%s' expected.\n",
108 msg+2,provided,expected);
110 luaL_error(L,"%s\n value is '%s'; '%s' expected.\n",
111 msg+2,provided,expected);
118 /* the equivalent of lua_is* for usertable */
119 static int lua_isusertable (lua_State* L, int lo, const const char* type)
122 if (lo < 0) lo = lua_gettop(L)+lo+1;
124 lua_rawget(L,LUA_REGISTRYINDEX); /* get registry[t] */
125 if (lua_isstring(L,-1))
127 r = strcmp(lua_tostring(L,-1),type)==0;
131 lua_pushstring(L,"const ");
134 r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0;
141 int push_table_instance(lua_State* L, int lo) {
143 if (lua_istable(L, lo)) {
145 lua_pushstring(L, ".c_instance");
147 if (lua_isuserdata(L, -1)) {
163 /* the equivalent of lua_is* for usertype */
164 static int lua_isusertype (lua_State* L, int lo, const char* type)
166 if (!lua_isuserdata(L,lo)) {
167 if (!push_table_instance(L, lo)) {
172 /* check if it is of the same type */
175 if (lua_getmetatable(L,lo)) /* if metatable? */
177 lua_rawget(L,LUA_REGISTRYINDEX); /* get registry[mt] */
178 tn = lua_tostring(L,-1);
179 r = tn && (strcmp(tn,type) == 0);
185 /* check if it is a specialized class */
186 lua_pushstring(L,"tolua_super");
187 lua_rawget(L,LUA_REGISTRYINDEX); /* get super */
188 lua_getmetatable(L,lo);
189 lua_rawget(L,-2); /* get super[mt] */
190 if (lua_istable(L,-1))
193 lua_pushstring(L,type);
194 lua_rawget(L,-2); /* get super[mt][type] */
195 b = lua_toboolean(L,-1);
206 TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err)
208 if (lua_gettop(L)<abs(lo))
212 err->type = "[no object]";
216 TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
218 if (def && lua_gettop(L)<abs(lo))
220 if (lua_isnil(L,lo) || lua_isboolean(L,lo))
224 err->type = "boolean";
228 TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
230 if (def && lua_gettop(L)<abs(lo))
232 if (lua_isnumber(L,lo))
236 err->type = "number";
240 TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
242 if (def && lua_gettop(L)<abs(lo))
244 if (lua_isnil(L,lo) || lua_isstring(L,lo))
248 err->type = "string";
252 TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
254 if (def && lua_gettop(L)<abs(lo))
256 if (lua_istable(L,lo))
264 TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
266 if (def && lua_gettop(L)<abs(lo))
268 if (lua_isusertable(L,lo,type))
277 TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
279 if (def && lua_gettop(L)<abs(lo))
281 if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
285 err->type = "userdata";
289 TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err) {
291 if (lua_gettop(L)<abs(lo))
292 return 0; /* somebody else should chack this */
293 if (!lua_isnil(L, lo))
302 TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
304 if (def || abs(lo)<=lua_gettop(L)) /* any valid index */
312 TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
314 if (def && lua_gettop(L)<abs(lo))
316 if (lua_isnil(L,lo) || lua_isusertype(L,lo,type))
324 TOLUA_API int tolua_isvaluearray
325 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
327 if (!tolua_istable(L,lo,def,err))
333 TOLUA_API int tolua_isbooleanarray
334 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
336 if (!tolua_istable(L,lo,def,err))
341 for (i=1; i<=dim; ++i)
345 if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
346 !(def && lua_isnil(L,-1))
351 err->type = "boolean";
360 TOLUA_API int tolua_isnumberarray
361 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
363 if (!tolua_istable(L,lo,def,err))
368 for (i=1; i<=dim; ++i)
372 if (!lua_isnumber(L,-1) &&
373 !(def && lua_isnil(L,-1))
378 err->type = "number";
387 TOLUA_API int tolua_isstringarray
388 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
390 if (!tolua_istable(L,lo,def,err))
395 for (i=1; i<=dim; ++i)
399 if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
400 !(def && lua_isnil(L,-1))
405 err->type = "string";
414 TOLUA_API int tolua_istablearray
415 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
417 if (!tolua_istable(L,lo,def,err))
422 for (i=1; i<=dim; ++i)
426 if (! lua_istable(L,-1) &&
427 !(def && lua_isnil(L,-1))
441 TOLUA_API int tolua_isuserdataarray
442 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
444 if (!tolua_istable(L,lo,def,err))
449 for (i=1; i<=dim; ++i)
453 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
454 !(def && lua_isnil(L,-1))
459 err->type = "userdata";
468 TOLUA_API int tolua_isusertypearray
469 (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err)
471 if (!tolua_istable(L,lo,def,err))
476 for (i=1; i<=dim; ++i)
480 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
481 !(def && lua_isnil(L,-1))
496 int tolua_isbooleanfield
497 (lua_State* L, int lo, int i, int def, tolua_Error* err)
501 if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
502 !(def && lua_isnil(L,-1))
507 err->type = "boolean";
514 int tolua_isnumberfield
515 (lua_State* L, int lo, int i, int def, tolua_Error* err)
519 if (!lua_isnumber(L,-1) &&
520 !(def && lua_isnil(L,-1))
525 err->type = "number";
532 int tolua_isstringfield
533 (lua_State* L, int lo, int i, int def, tolua_Error* err)
537 if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
538 !(def && lua_isnil(L,-1))
543 err->type = "string";
550 int tolua_istablefield
551 (lua_State* L, int lo, int i, int def, tolua_Error* err)
553 lua_pushnumber(L,i+1);
555 if (! lua_istable(L,-1) &&
556 !(def && lua_isnil(L,-1))
567 int tolua_isusertablefield
568 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
572 if (! lua_isusertable(L,-1,type) &&
573 !(def && lua_isnil(L,-1))
585 int tolua_isuserdatafield
586 (lua_State* L, int lo, int i, int def, tolua_Error* err)
590 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
591 !(def && lua_isnil(L,-1))
596 err->type = "userdata";
603 int tolua_isusertypefield
604 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
608 if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) &&
609 !(def && lua_isnil(L,-1))