--- /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 <glib.h> // g_ascii_strcasecmp
+#include <lua.h>
+#include <lauxlib.h>
+
+#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);
+}
+