Merge commit '2e1ed8c1e92f3af12165112b333e63ace34bfe2a'

This commit is contained in:
Rochet2
2014-08-09 01:30:56 +03:00
2 changed files with 69 additions and 97 deletions

View File

@@ -24,7 +24,6 @@
extern "C" extern "C"
{ {
#include "lua.h"
#include "lualib.h" #include "lualib.h"
#include "lauxlib.h" #include "lauxlib.h"
}; };
@@ -462,150 +461,115 @@ void Eluna::Push(lua_State* L, Object const* obj)
ElunaTemplate<Object>::push(L, obj); ElunaTemplate<Object>::push(L, obj);
} }
} }
static int32 CheckIntegerRange(lua_State *L, int narg, int32 min, int32 max)
{
int64 value = luaL_checknumber(L, narg);
char error_buffer[64];
if (value > max)
{
snprintf(error_buffer, 64, "value must be less than %d", max);
return luaL_argerror(L, narg, error_buffer);
}
if (value < min)
{
snprintf(error_buffer, 64, "value must be greater than %d", min);
return luaL_argerror(L, narg, error_buffer);
}
return value;
}
static uint32 CheckUnsignedRange(lua_State *L, int narg, uint32 max)
{
int64 value = luaL_checknumber(L, narg);
char error_buffer[64];
if (value < 0)
return luaL_argerror(L, narg, "value must be greater than 0");
if (value > max)
{
snprintf(error_buffer, 64, "value must be less than %u", max);
return luaL_argerror(L, narg, error_buffer);
}
return value;
}
template<> bool Eluna::CHECKVAL<bool>(lua_State* L, int narg) template<> bool Eluna::CHECKVAL<bool>(lua_State* L, int narg)
{ {
return lua_isnumber(L, narg) != 0 ? luaL_optnumber(L, narg, 1) ? true : false : lua_toboolean(L, narg) != 0; return lua_toboolean(L, narg);
}
template<> bool Eluna::CHECKVAL<bool>(lua_State* L, int narg, bool def)
{
return lua_isnone(L, narg) != 0 ? def : lua_isnumber(L, narg) != 0 ? luaL_optnumber(L, narg, 1) != 0 ? true : false : lua_toboolean(L, narg) != 0;
} }
template<> float Eluna::CHECKVAL<float>(lua_State* L, int narg) template<> float Eluna::CHECKVAL<float>(lua_State* L, int narg)
{ {
return luaL_checknumber(L, narg); return luaL_checknumber(L, narg);
} }
template<> float Eluna::CHECKVAL<float>(lua_State* L, int narg, float def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optnumber(L, narg, def);
}
template<> double Eluna::CHECKVAL<double>(lua_State* L, int narg) template<> double Eluna::CHECKVAL<double>(lua_State* L, int narg)
{ {
return luaL_checknumber(L, narg); return luaL_checknumber(L, narg);
} }
template<> double Eluna::CHECKVAL<double>(lua_State* L, int narg, double def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optnumber(L, narg, def);
}
template<> int8 Eluna::CHECKVAL<int8>(lua_State* L, int narg) template<> int8 Eluna::CHECKVAL<int8>(lua_State* L, int narg)
{ {
return luaL_checkint(L, narg); return CheckIntegerRange(L, narg, SCHAR_MIN, SCHAR_MAX);
}
template<> int8 Eluna::CHECKVAL<int8>(lua_State* L, int narg, int8 def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optint(L, narg, def);
} }
template<> uint8 Eluna::CHECKVAL<uint8>(lua_State* L, int narg) template<> uint8 Eluna::CHECKVAL<uint8>(lua_State* L, int narg)
{ {
return luaL_checkunsigned(L, narg); return CheckUnsignedRange(L, narg, UCHAR_MAX);
}
template<> uint8 Eluna::CHECKVAL<uint8>(lua_State* L, int narg, uint8 def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optunsigned(L, narg, def);
} }
template<> int16 Eluna::CHECKVAL<int16>(lua_State* L, int narg) template<> int16 Eluna::CHECKVAL<int16>(lua_State* L, int narg)
{ {
return luaL_checkint(L, narg); return CheckIntegerRange(L, narg, SHRT_MIN, SHRT_MAX);
}
template<> int16 Eluna::CHECKVAL<int16>(lua_State* L, int narg, int16 def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optint(L, narg, def);
} }
template<> uint16 Eluna::CHECKVAL<uint16>(lua_State* L, int narg) template<> uint16 Eluna::CHECKVAL<uint16>(lua_State* L, int narg)
{ {
return luaL_checkunsigned(L, narg); return CheckUnsignedRange(L, narg, USHRT_MAX);
}
template<> uint16 Eluna::CHECKVAL<uint16>(lua_State* L, int narg, uint16 def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optunsigned(L, narg, def);
}
template<> uint32 Eluna::CHECKVAL<uint32>(lua_State* L, int narg)
{
return luaL_checkunsigned(L, narg);
}
template<> uint32 Eluna::CHECKVAL<uint32>(lua_State* L, int narg, uint32 def)
{
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg))
return def;
return luaL_optunsigned(L, narg, def);
} }
template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg) template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg)
{ {
return luaL_checklong(L, narg); return CheckIntegerRange(L, narg, INT_MIN, INT_MAX);
} }
template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg, int32 def) template<> uint32 Eluna::CHECKVAL<uint32>(lua_State* L, int narg)
{ {
if (lua_isnoneornil(L, narg) || !lua_isnumber(L, narg)) return CheckUnsignedRange(L, narg, UINT_MAX);
return def;
return luaL_optlong(L, narg, def);
} }
template<> const char* Eluna::CHECKVAL<const char*>(lua_State* L, int narg) template<> const char* Eluna::CHECKVAL<const char*>(lua_State* L, int narg)
{ {
return luaL_checkstring(L, narg); return luaL_checkstring(L, narg);
} }
template<> const char* Eluna::CHECKVAL<const char*>(lua_State* L, int narg, const char* def)
{
if (lua_isnoneornil(L, narg) || !lua_isstring(L, narg))
return def;
return luaL_optstring(L, narg, def);
}
template<> std::string Eluna::CHECKVAL<std::string>(lua_State* L, int narg) template<> std::string Eluna::CHECKVAL<std::string>(lua_State* L, int narg)
{ {
return luaL_checkstring(L, narg); return luaL_checkstring(L, narg);
} }
template<> std::string Eluna::CHECKVAL<std::string>(lua_State* L, int narg, std::string def)
{
if (lua_isnoneornil(L, narg) || !lua_isstring(L, narg))
return def;
return luaL_optstring(L, narg, def.c_str());
}
template<> uint64 Eluna::CHECKVAL<uint64>(lua_State* L, int narg)
{
const char* c_str = CHECKVAL<const char*>(L, narg, NULL);
if (!c_str)
return luaL_argerror(L, narg, "uint64 (as string) expected");
uint64 l = 0;
sscanf(c_str, UI64FMTD, &l);
return l;
}
template<> uint64 Eluna::CHECKVAL<uint64>(lua_State* L, int narg, uint64 def)
{
const char* c_str = CHECKVAL<const char*>(L, narg, NULL);
if (!c_str)
return def;
uint64 l = 0;
sscanf(c_str, UI64FMTD, &l);
return l;
}
template<> int64 Eluna::CHECKVAL<int64>(lua_State* L, int narg) template<> int64 Eluna::CHECKVAL<int64>(lua_State* L, int narg)
{ {
const char* c_str = CHECKVAL<const char*>(L, narg, NULL); const char* c_str = CHECKVAL<const char*>(L, narg, NULL);
if (!c_str) if (!c_str)
return luaL_argerror(L, narg, "int64 (as string) expected"); return luaL_argerror(L, narg, "int64 (as string) expected");
int64 l = 0; int64 l = 0;
sscanf(c_str, SI64FMTD, &l); int parsed_count = sscanf(c_str, SI64FMTD, &l);
if (parsed_count != 1)
return luaL_argerror(L, narg, "int64 (as string) could not be converted");
return l; return l;
} }
template<> int64 Eluna::CHECKVAL<int64>(lua_State* L, int narg, int64 def) template<> uint64 Eluna::CHECKVAL<uint64>(lua_State* L, int narg)
{ {
const char* c_str = CHECKVAL<const char*>(L, narg, NULL); const char* c_str = CHECKVAL<const char*>(L, narg, NULL);
if (!c_str) if (!c_str)
return def; return luaL_argerror(L, narg, "uint64 (as string) expected");
int64 l = 0;
sscanf(c_str, SI64FMTD, &l); uint64 l = 0;
int parsed_count = sscanf(c_str, UI64FMTD, &l);
if (parsed_count != 1)
return luaL_argerror(L, narg, "uint64 (as string) could not be converted");
return l; return l;
} }
#define TEST_OBJ(T, O, E, F)\ #define TEST_OBJ(T, O, E, F)\
{\ {\
if (!O || !O->F())\ if (!O || !O->F())\

View File

@@ -20,6 +20,11 @@
#include "World.h" #include "World.h"
#include "HookMgr.h" #include "HookMgr.h"
extern "C"
{
#include "lua.h"
};
#ifdef TRINITY #ifdef TRINITY
struct ItemTemplate; struct ItemTemplate;
#else #else
@@ -163,7 +168,10 @@ public:
// Checks // Checks
template<typename T> static T CHECKVAL(lua_State* L, int narg); template<typename T> static T CHECKVAL(lua_State* L, int narg);
template<typename T> static T CHECKVAL(lua_State* L, int narg, T def); template<typename T> static T CHECKVAL(lua_State* L, int narg, T def)
{
return lua_isnoneornil(L, narg) ? def : CHECKVAL<T>(L, narg);
}
template<typename T> static T* CHECKOBJ(lua_State* L, int narg, bool error = true) template<typename T> static T* CHECKOBJ(lua_State* L, int narg, bool error = true)
{ {
return ElunaTemplate<T>::check(L, narg, error); return ElunaTemplate<T>::check(L, narg, error);