LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { const char *msg; luaL_pushtype(L, narg); msg = lua_pushfstring(L, "%s expected, got %s", tname, lua_tostring(L, -1)); return luaL_argerror(L, narg, msg); }
int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const char *szType, bool bAllowInvalid ) { luaL_checkany( L, iPos ); if( lua_isnil(L, iPos) ) { if( bAllowInvalid ) return iInvalid; LuaHelpers::Push( L, ssprintf("Expected %s; got nil", szType) ); lua_error( L ); } iPos = LuaHelpers::AbsIndex( L, iPos ); table.PushSelf( L ); lua_pushvalue( L, iPos ); lua_gettable( L, -2 ); // If the result is nil, then a string was passed that is not a member of this enum. Throw // an error. To specify the invalid value, pass nil. That way, typos will throw an error, // and not silently result in nil, or an out-of-bounds value. if( unlikely(lua_isnil(L, -1)) ) { RString sGot; if( lua_isstring(L, iPos) ) { /* We were given a string, but it wasn't a valid value for this enum. Show * the string. */ lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sGot ); sGot = ssprintf( "\"%s\"", sGot.c_str() ); } else { /* We didn't get a string. Show the type. */ luaL_pushtype( L, iPos ); LuaHelpers::Pop( L, sGot ); } LuaHelpers::Push( L, ssprintf("Expected %s; got %s", szType, sGot.c_str() ) ); lua_error( L ); } int iRet = lua_tointeger( L, -1 ); lua_pop( L, 2 ); return iRet; }
int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const char *szType, bool bAllowInvalid, bool bAllowAnything ) { luaL_checkany( L, iPos ); if( lua_isnil(L, iPos) ) { if( bAllowInvalid ) return iInvalid; LuaHelpers::Push( L, ssprintf("Expected %s; got nil", szType) ); lua_error( L ); } iPos = LuaHelpers::AbsIndex( L, iPos ); table.PushSelf( L ); lua_pushvalue( L, iPos ); lua_gettable( L, -2 ); // If not found, check case-insensitively for legacy compatibility if( lua_isnil(L, -1) && lua_isstring(L, iPos) ) { RString sLower; // Get rid of nil value on stack lua_pop( L, 1 ); // Get the string and lowercase it lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sLower ); sLower.MakeLower(); // Try again to read the value table.PushSelf( L ); LuaHelpers::Push( L, sLower ); lua_gettable( L, -2 ); } // If the result is nil, then a string was passed that is not a member of this enum. Throw // an error. To specify the invalid value, pass nil. That way, typos will throw an error, // and not silently result in nil, or an out-of-bounds value. if( unlikely(lua_isnil(L, -1)) ) { RString sGot; if( lua_isstring(L, iPos) ) { /* We were given a string, but it wasn't a valid value for this enum. Show * the string. */ lua_pushvalue( L, iPos ); LuaHelpers::Pop( L, sGot ); sGot = ssprintf( "\"%s\"", sGot.c_str() ); } else { /* We didn't get a string. Show the type. */ luaL_pushtype( L, iPos ); LuaHelpers::Pop( L, sGot ); } LuaHelpers::Push( L, ssprintf("Expected %s; got %s", szType, sGot.c_str() ) ); // There are a couple places where CheckEnum is used outside of a // function called from lua. If we use lua_error from one of them, // StepMania crashes out completely. bAllowAnything allows those places // to avoid crashing over theme mistakes. if(bAllowAnything) { RString errmsg; LuaHelpers::Pop(L, errmsg); LOG->Warn(errmsg.c_str()); lua_pop(L, 2); return iInvalid; } lua_error( L ); } int iRet = lua_tointeger( L, -1 ); lua_pop( L, 2 ); return iRet; }