/* toType* functions with a bonus error message */ void* expectType(lua_State* luaSt, int idx, const char* typeName) { void* p; p = mw_tonamedudata(luaSt, idx, typeName); if (!p) mw_lua_typecheck(luaSt, idx, LUA_TUSERDATA, typeName); return p; }
void handleNamedArgumentTable(lua_State* luaSt, const MWNamedArg* args, int table) { const MWNamedArg* p; char buf[128]; int item; p = args; while (p->name) { lua_pushstring(luaSt, p->name); lua_pushvalue(luaSt, -1); /* Copy the key since lua_gettable pops it */ lua_gettable(luaSt, table); item = lua_gettop(luaSt); if (lua_isnil(luaSt, item)) { if (!p->required) { lua_pop(luaSt, 2); ++p; continue; } if (snprintf(buf, sizeof(buf), "Missing required named argument '%s'", p->name) == sizeof(buf)) mw_panic("Error message buffer too small for key name '%s'\n", p->name); luaL_argerror(luaSt, table, buf); } /* We do our own type checking and errors to avoid Confusing and innaccurate error messages, which suggest the use of the table is wrong. */ if (!typeEqualOrConversionOK(luaSt, p->type, -1)) { namedArgumentError(luaSt, p, table, item); } if (p->type == LUA_TUSERDATA) /* We must do another level of checking for the actual type */ { if (!mw_tonamedudata(luaSt, item, p->userDataTypeName)) namedArgumentError(luaSt, p, table, -1); } else if (p->type == LUA_TLIGHTUSERDATA) { mw_panic("Unhandled named argument type lightuserdata\n"); } setValueFromType(luaSt, p, item); lua_pop(luaSt, 2); ++p; } checkExtraArguments(luaSt, args, table); }
NBodyCtx* toNBodyCtx(lua_State* luaSt, int idx) { return (NBodyCtx*) mw_tonamedudata(luaSt, idx, NBODYCTX_TYPE); }