diff -r 000000000000 -r 84fdfb0344c9 util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util.c Sun Feb 01 21:28:57 2009 +0200 @@ -0,0 +1,117 @@ + +#include // g_ascii_strcasecmp +#include +#include + +#include "util.h" + +enum_value_t string2enum (const char *string, const string2enum_t *set) +{ + while (set->string) { + if (!g_ascii_strcasecmp (string, set->string)) + return set->value; + ++set; + } + return set->value; +} + +const char *enum2string (enum_value_t value, const string2enum_t *set) +{ + while (set->string) { + if (value == set->value) + return set->string; + ++set; + } + return NULL; +} + +enum_value_t luaL_checkenum (lua_State *L, int index, const string2enum_t *set) +{ + if (lua_type (L, index) == LUA_TNUMBER) + return lua_tointeger (L, index); + else + return string2enum (luaL_checkstring (L, index), set); +} + +void luaL_pushenum (lua_State *L, enum_value_t value, const string2enum_t *set) +{ + const char *string = enum2string (value, set); + if (string != NULL) + lua_pushstring (L, string); + else + lua_pushinteger (L, value); +} + +enum_value_t luaL_checkenum_multi (lua_State *L, int index, const string2enum_t *set) +{ + int type = lua_type (L, index); + if (type == LUA_TNUMBER) + return lua_tointeger (L, index); + else if (type == LUA_TSTRING) + return string2enum (lua_tostring (L, index), set); + else if (type == LUA_TTABLE) { + enum_value_t retval = 0; + lua_pushnil (L); + while (lua_next (L, index) != 0) { + type = lua_type (L, -2); + if (type == LUA_TNUMBER) { + type = lua_type (L, -1); + if (type == LUA_TNUMBER) + retval |= lua_tointeger (L, -1); + else if (type == LUA_TSTRING) + retval |= string2enum (lua_tostring (L, -1), set); + else + luaL_argerror (L, index, "wrong value type of flag"); + } else if (type == LUA_TSTRING) { + if (lua_toboolean (L, -1)) + retval |= string2enum (lua_tostring (L, -2), set); + } else + luaL_argerror (L, index, "wrong key type of flags table"); + lua_pop (L, 1); + } + } else + luaL_argerror (L, index, "integer, string, or table of ones expected"); + return 0; // never happens +} + +void luaL_pushenum_multi (lua_State *L, enum_value_t value, const string2enum_t *set) +{ + enum_value_t matched = 0; + lua_newtable (L); + while (set->string) { + if (value & set->value) { + matched |= set->value & value; + lua_pushstring (L, set->string); + lua_pushboolean (L, 1); + lua_settable (L, -3); + } + ++set; + } + if (value ^ matched) { + lua_pushinteger (L, 1); + lua_pushinteger (L, value ^ matched); + lua_settable (L, -3); + } +} + +void *luaL_malloc (lua_State *L, size_t size) +{ + void *ud; + lua_Alloc allocf = lua_getallocf (L, &ud); + return (*allocf) (ud, NULL, 0, size); +} + +void *luaL_realloc (lua_State *L, void *ptr, size_t osize, size_t nsize) +{ + void *ud; + lua_Alloc allocf = lua_getallocf (L, &ud); + return (*allocf) (ud, ptr, osize, nsize); +} + +void luaL_free (lua_State *L, void *ptr) +{ + void *ud; + lua_Alloc allocf = lua_getallocf (L, &ud); + (*allocf) (ud, ptr, 1, 0); +} +