00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "tolua++.h"
00015 #include "lauxlib.h"
00016
00017 #include <stdlib.h>
00018 #include <string.h>
00019
00020
00021
00022 TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)
00023 {
00024 int result;
00025 if (lua_rawequal(L,mt_indexa,mt_indexb))
00026 result = 1;
00027 else
00028 {
00029 if (super_index) {
00030 lua_pushvalue(L, super_index);
00031 } else {
00032 lua_pushliteral(L,"tolua_super");
00033 lua_rawget(L,LUA_REGISTRYINDEX);
00034 };
00035 lua_pushvalue(L,mt_indexa);
00036 lua_rawget(L,-2);
00037 lua_pushvalue(L,mt_indexb);
00038 lua_rawget(L,LUA_REGISTRYINDEX);
00039 lua_rawget(L,-2);
00040 result = lua_toboolean(L,-1);
00041 lua_pop(L,3);
00042 }
00043 return result;
00044 }
00045
00046
00047 TOLUA_API const char* tolua_typename (lua_State* L, int lo)
00048 {
00049 int tag = lua_type(L,lo);
00050 if (tag == LUA_TNONE)
00051 lua_pushstring(L,"[no object]");
00052 else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
00053 lua_pushstring(L,lua_typename(L,tag));
00054 else if (tag == LUA_TUSERDATA)
00055 {
00056 if (!lua_getmetatable(L,lo))
00057 lua_pushstring(L,lua_typename(L,tag));
00058 else
00059 {
00060 lua_rawget(L,LUA_REGISTRYINDEX);
00061 if (!lua_isstring(L,-1))
00062 {
00063 lua_pop(L,1);
00064 lua_pushstring(L,"[undefined]");
00065 }
00066 }
00067 }
00068 else
00069 {
00070 lua_pushvalue(L,lo);
00071 lua_rawget(L,LUA_REGISTRYINDEX);
00072 if (!lua_isstring(L,-1))
00073 {
00074 lua_pop(L,1);
00075 lua_pushstring(L,"table");
00076 }
00077 else
00078 {
00079 lua_pushstring(L,"class ");
00080 lua_insert(L,-2);
00081 lua_concat(L,2);
00082 }
00083 }
00084 return lua_tostring(L,-1);
00085 }
00086
00087 TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
00088 {
00089 if (msg[0] == '#')
00090 {
00091 const char* expected = err->type;
00092 const char* provided = tolua_typename(L,err->index);
00093 if (msg[1]=='f')
00094 {
00095 int narg = err->index;
00096 if (err->array)
00097 luaL_error(L,"%s\n argument #%d is array of '%s'; array of '%s' expected.\n",
00098 msg+2,narg,provided,expected);
00099 else
00100 luaL_error(L,"%s\n argument #%d is '%s'; '%s' expected.\n",
00101 msg+2,narg,provided,expected);
00102 }
00103 else if (msg[1]=='v')
00104 {
00105 if (err->array)
00106 luaL_error(L,"%s\n value is array of '%s'; array of '%s' expected.\n",
00107 msg+2,provided,expected);
00108 else
00109 luaL_error(L,"%s\n value is '%s'; '%s' expected.\n",
00110 msg+2,provided,expected);
00111 }
00112 }
00113 else
00114 luaL_error(L,msg);
00115 }
00116
00117
00118 static int lua_isusertable (lua_State* L, int lo, const char* type)
00119 {
00120 int r = 0;
00121 if (lo < 0) lo = lua_gettop(L)+lo+1;
00122 lua_pushvalue(L,lo);
00123 lua_rawget(L,LUA_REGISTRYINDEX);
00124 if (lua_isstring(L,-1))
00125 {
00126 r = strcmp(lua_tostring(L,-1),type)==0;
00127 if (!r)
00128 {
00129
00130 lua_pushstring(L,"const ");
00131 lua_insert(L,-2);
00132 lua_concat(L,2);
00133 r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0;
00134 }
00135 }
00136 lua_pop(L, 1);
00137 return r;
00138 }
00139
00140 int push_table_instance(lua_State* L, int lo) {
00141
00142 if (lua_istable(L, lo)) {
00143
00144 lua_pushstring(L, ".c_instance");
00145 lua_gettable(L, lo);
00146 if (lua_isuserdata(L, -1)) {
00147
00148 lua_replace(L, lo);
00149 return 1;
00150 } else {
00151
00152 lua_pop(L, 1);
00153 return 0;
00154 };
00155 } else {
00156 return 0;
00157 };
00158
00159 return 0;
00160 };
00161
00162
00163 static int lua_isusertype (lua_State* L, int lo, const char* type)
00164 {
00165 if (!lua_isuserdata(L,lo)) {
00166 if (!push_table_instance(L, lo)) {
00167 return 0;
00168 };
00169 };
00170 {
00171
00172 int r;
00173 const char *tn;
00174 if (lua_getmetatable(L,lo))
00175 {
00176 lua_rawget(L,LUA_REGISTRYINDEX);
00177 tn = lua_tostring(L,-1);
00178 r = tn && (strcmp(tn,type) == 0);
00179 lua_pop(L, 1);
00180 if (r)
00181 return 1;
00182 else
00183 {
00184
00185 lua_pushstring(L,"tolua_super");
00186 lua_rawget(L,LUA_REGISTRYINDEX);
00187 lua_getmetatable(L,lo);
00188 lua_rawget(L,-2);
00189 if (lua_istable(L,-1))
00190 {
00191 int b;
00192 lua_pushstring(L,type);
00193 lua_rawget(L,-2);
00194 b = lua_toboolean(L,-1);
00195 lua_pop(L,3);
00196 if (b)
00197 return 1;
00198 }
00199 }
00200 }
00201 }
00202 return 0;
00203 }
00204
00205 TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err)
00206 {
00207 if (lua_gettop(L)<abs(lo))
00208 return 1;
00209 err->index = lo;
00210 err->array = 0;
00211 err->type = "[no object]";
00212 return 0;
00213 }
00214 TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
00215 {
00216 if (def || abs(lo)<=lua_gettop(L))
00217 return 1;
00218 err->index = lo;
00219 err->array = 0;
00220 err->type = "value";
00221 return 0;
00222 }
00223
00224 TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
00225 {
00226 if (def && lua_gettop(L)<abs(lo))
00227 return 1;
00228 if (lua_isnil(L,lo) || lua_isboolean(L,lo))
00229 return 1;
00230 err->index = lo;
00231 err->array = 0;
00232 err->type = "boolean";
00233 return 0;
00234 }
00235
00236 TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
00237 {
00238 if (def && lua_gettop(L)<abs(lo))
00239 return 1;
00240 if (lua_isnumber(L,lo))
00241 return 1;
00242 err->index = lo;
00243 err->array = 0;
00244 err->type = "number";
00245 return 0;
00246 }
00247
00248 TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
00249 {
00250 if (def && lua_gettop(L)<abs(lo))
00251 return 1;
00252 if (lua_isnil(L,lo) || lua_isstring(L,lo))
00253 return 1;
00254 err->index = lo;
00255 err->array = 0;
00256 err->type = "string";
00257 return 0;
00258 }
00259
00260 TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
00261 {
00262 if (def && lua_gettop(L)<abs(lo))
00263 return 1;
00264 if (lua_istable(L,lo))
00265 return 1;
00266 err->index = lo;
00267 err->array = 0;
00268 err->type = "table";
00269 return 0;
00270 }
00271
00272 TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
00273 {
00274 if (def && lua_gettop(L)<abs(lo))
00275 return 1;
00276 if (lua_isusertable(L,lo,type))
00277 return 1;
00278 err->index = lo;
00279 err->array = 0;
00280 err->type = type;
00281 return 0;
00282 }
00283
00284
00285 TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
00286 {
00287 if (def && lua_gettop(L)<abs(lo))
00288 return 1;
00289 if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
00290 return 1;
00291 err->index = lo;
00292 err->array = 0;
00293 err->type = "userdata";
00294 return 0;
00295 }
00296
00297 TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
00298 {
00299 if (def && lua_gettop(L)<abs(lo))
00300 return 1;
00301 if (lua_isnil(L,lo) || lua_isusertype(L,lo,type))
00302 return 1;
00303 err->index = lo;
00304 err->array = 0;
00305 err->type = type;
00306 return 0;
00307 }
00308
00309 TOLUA_API int tolua_isvaluearray
00310 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00311 {
00312 if (!tolua_istable(L,lo,def,err))
00313 return 0;
00314 else
00315 return 1;
00316 }
00317
00318 TOLUA_API int tolua_isbooleanarray
00319 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00320 {
00321 if (!tolua_istable(L,lo,def,err))
00322 return 0;
00323 else
00324 {
00325 int i;
00326 for (i=1; i<=dim; ++i)
00327 {
00328 lua_pushnumber(L,i);
00329 lua_gettable(L,lo);
00330 if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
00331 !(def && lua_isnil(L,-1))
00332 )
00333 {
00334 err->index = lo;
00335 err->array = 1;
00336 err->type = "boolean";
00337 return 0;
00338 }
00339 lua_pop(L,1);
00340 }
00341 }
00342 return 1;
00343 }
00344
00345 TOLUA_API int tolua_isnumberarray
00346 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00347 {
00348 if (!tolua_istable(L,lo,def,err))
00349 return 0;
00350 else
00351 {
00352 int i;
00353 for (i=1; i<=dim; ++i)
00354 {
00355 lua_pushnumber(L,i);
00356 lua_gettable(L,lo);
00357 if (!lua_isnumber(L,-1) &&
00358 !(def && lua_isnil(L,-1))
00359 )
00360 {
00361 err->index = lo;
00362 err->array = 1;
00363 err->type = "number";
00364 return 0;
00365 }
00366 lua_pop(L,1);
00367 }
00368 }
00369 return 1;
00370 }
00371
00372 TOLUA_API int tolua_isstringarray
00373 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00374 {
00375 if (!tolua_istable(L,lo,def,err))
00376 return 0;
00377 else
00378 {
00379 int i;
00380 for (i=1; i<=dim; ++i)
00381 {
00382 lua_pushnumber(L,i);
00383 lua_gettable(L,lo);
00384 if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
00385 !(def && lua_isnil(L,-1))
00386 )
00387 {
00388 err->index = lo;
00389 err->array = 1;
00390 err->type = "string";
00391 return 0;
00392 }
00393 lua_pop(L,1);
00394 }
00395 }
00396 return 1;
00397 }
00398
00399 TOLUA_API int tolua_istablearray
00400 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00401 {
00402 if (!tolua_istable(L,lo,def,err))
00403 return 0;
00404 else
00405 {
00406 int i;
00407 for (i=1; i<=dim; ++i)
00408 {
00409 lua_pushnumber(L,i);
00410 lua_gettable(L,lo);
00411 if (! lua_istable(L,-1) &&
00412 !(def && lua_isnil(L,-1))
00413 )
00414 {
00415 err->index = lo;
00416 err->array = 1;
00417 err->type = "table";
00418 return 0;
00419 }
00420 lua_pop(L,1);
00421 }
00422 }
00423 return 1;
00424 }
00425
00426 TOLUA_API int tolua_isuserdataarray
00427 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
00428 {
00429 if (!tolua_istable(L,lo,def,err))
00430 return 0;
00431 else
00432 {
00433 int i;
00434 for (i=1; i<=dim; ++i)
00435 {
00436 lua_pushnumber(L,i);
00437 lua_gettable(L,lo);
00438 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
00439 !(def && lua_isnil(L,-1))
00440 )
00441 {
00442 err->index = lo;
00443 err->array = 1;
00444 err->type = "userdata";
00445 return 0;
00446 }
00447 lua_pop(L,1);
00448 }
00449 }
00450 return 1;
00451 }
00452
00453 TOLUA_API int tolua_isusertypearray
00454 (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err)
00455 {
00456 if (!tolua_istable(L,lo,def,err))
00457 return 0;
00458 else
00459 {
00460 int i;
00461 for (i=1; i<=dim; ++i)
00462 {
00463 lua_pushnumber(L,i);
00464 lua_gettable(L,lo);
00465 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
00466 !(def && lua_isnil(L,-1))
00467 )
00468 {
00469 err->index = lo;
00470 err->type = type;
00471 err->array = 1;
00472 return 0;
00473 }
00474 lua_pop(L,1);
00475 }
00476 }
00477 return 1;
00478 }
00479
00480 #if 0
00481 int tolua_isbooleanfield
00482 (lua_State* L, int lo, int i, int def, tolua_Error* err)
00483 {
00484 lua_pushnumber(L,i);
00485 lua_gettable(L,lo);
00486 if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
00487 !(def && lua_isnil(L,-1))
00488 )
00489 {
00490 err->index = lo;
00491 err->array = 1;
00492 err->type = "boolean";
00493 return 0;
00494 }
00495 lua_pop(L,1);
00496 return 1;
00497 }
00498
00499 int tolua_isnumberfield
00500 (lua_State* L, int lo, int i, int def, tolua_Error* err)
00501 {
00502 lua_pushnumber(L,i);
00503 lua_gettable(L,lo);
00504 if (!lua_isnumber(L,-1) &&
00505 !(def && lua_isnil(L,-1))
00506 )
00507 {
00508 err->index = lo;
00509 err->array = 1;
00510 err->type = "number";
00511 return 0;
00512 }
00513 lua_pop(L,1);
00514 return 1;
00515 }
00516
00517 int tolua_isstringfield
00518 (lua_State* L, int lo, int i, int def, tolua_Error* err)
00519 {
00520 lua_pushnumber(L,i);
00521 lua_gettable(L,lo);
00522 if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
00523 !(def && lua_isnil(L,-1))
00524 )
00525 {
00526 err->index = lo;
00527 err->array = 1;
00528 err->type = "string";
00529 return 0;
00530 }
00531 lua_pop(L,1);
00532 return 1;
00533 }
00534
00535 int tolua_istablefield
00536 (lua_State* L, int lo, int i, int def, tolua_Error* err)
00537 {
00538 lua_pushnumber(L,i+1);
00539 lua_gettable(L,lo);
00540 if (! lua_istable(L,-1) &&
00541 !(def && lua_isnil(L,-1))
00542 )
00543 {
00544 err->index = lo;
00545 err->array = 1;
00546 err->type = "table";
00547 return 0;
00548 }
00549 lua_pop(L,1);
00550 }
00551
00552 int tolua_isusertablefield
00553 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
00554 {
00555 lua_pushnumber(L,i);
00556 lua_gettable(L,lo);
00557 if (! lua_isusertable(L,-1,type) &&
00558 !(def && lua_isnil(L,-1))
00559 )
00560 {
00561 err->index = lo;
00562 err->array = 1;
00563 err->type = type;
00564 return 0;
00565 }
00566 lua_pop(L,1);
00567 return 1;
00568 }
00569
00570 int tolua_isuserdatafield
00571 (lua_State* L, int lo, int i, int def, tolua_Error* err)
00572 {
00573 lua_pushnumber(L,i);
00574 lua_gettable(L,lo);
00575 if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
00576 !(def && lua_isnil(L,-1))
00577 )
00578 {
00579 err->index = lo;
00580 err->array = 1;
00581 err->type = "userdata";
00582 return 0;
00583 }
00584 lua_pop(L,1);
00585 return 1;
00586 }
00587
00588 int tolua_isusertypefield
00589 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
00590 {
00591 lua_pushnumber(L,i);
00592 lua_gettable(L,lo);
00593 if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) &&
00594 !(def && lua_isnil(L,-1))
00595 )
00596 {
00597 err->index = lo;
00598 err->type = type;
00599 err->array = 1;
00600 return 0;
00601 }
00602 lua_pop(L,1);
00603 return 1;
00604 }
00605
00606 #endif