util.c
changeset 0 84fdfb0344c9
child 4 5770be2d5f3f
equal deleted inserted replaced
-1:000000000000 0:84fdfb0344c9
       
     1 
       
     2 #include <glib.h>	// g_ascii_strcasecmp
       
     3 #include <lua.h>
       
     4 #include <lauxlib.h>
       
     5 
       
     6 #include "util.h"
       
     7 
       
     8 enum_value_t string2enum (const char *string, const string2enum_t *set)
       
     9 {
       
    10 	while (set->string) {
       
    11 		if (!g_ascii_strcasecmp (string, set->string))
       
    12 			return set->value;
       
    13 		++set;
       
    14 	}
       
    15 	return set->value;
       
    16 }
       
    17 
       
    18 const char *enum2string (enum_value_t value, const string2enum_t *set)
       
    19 {
       
    20 	while (set->string) {
       
    21 		if (value == set->value)
       
    22 			return set->string;
       
    23 		++set;
       
    24 	}
       
    25 	return NULL;
       
    26 }
       
    27 
       
    28 enum_value_t luaL_checkenum (lua_State *L, int index, const string2enum_t *set)
       
    29 {
       
    30 	if (lua_type (L, index) == LUA_TNUMBER)
       
    31 		return lua_tointeger (L, index);
       
    32 	else
       
    33 		return string2enum (luaL_checkstring (L, index), set);
       
    34 }
       
    35 
       
    36 void luaL_pushenum (lua_State *L, enum_value_t value, const string2enum_t *set)
       
    37 {
       
    38 	const char *string = enum2string (value, set);
       
    39 	if (string != NULL)
       
    40 		lua_pushstring (L, string);
       
    41 	else
       
    42 		lua_pushinteger (L, value);
       
    43 }
       
    44 
       
    45 enum_value_t luaL_checkenum_multi (lua_State *L, int index, const string2enum_t *set)
       
    46 {
       
    47 	int type = lua_type (L, index);
       
    48 	if (type == LUA_TNUMBER)
       
    49 		return lua_tointeger (L, index);
       
    50 	else if (type == LUA_TSTRING)
       
    51 		return string2enum (lua_tostring (L, index), set);
       
    52 	else if (type == LUA_TTABLE) {
       
    53 		enum_value_t retval = 0;
       
    54 		lua_pushnil (L);
       
    55 		while (lua_next (L, index) != 0) {
       
    56 			type = lua_type (L, -2);
       
    57 			if (type == LUA_TNUMBER) {
       
    58 				type = lua_type (L, -1);
       
    59 				if (type == LUA_TNUMBER)
       
    60 					retval |= lua_tointeger (L, -1);
       
    61 				else if (type == LUA_TSTRING)
       
    62 					retval |= string2enum (lua_tostring (L, -1), set);
       
    63 				else
       
    64 					luaL_argerror (L, index, "wrong value type of flag");
       
    65 			} else if (type == LUA_TSTRING) {
       
    66 				if (lua_toboolean (L, -1))
       
    67 					retval |= string2enum (lua_tostring (L, -2), set);
       
    68 			} else
       
    69 				luaL_argerror (L, index, "wrong key type of flags table");
       
    70 			lua_pop (L, 1);
       
    71 		}
       
    72 	} else
       
    73 		luaL_argerror (L, index, "integer, string, or table of ones expected");
       
    74 	return 0; // never happens
       
    75 }
       
    76 
       
    77 void luaL_pushenum_multi (lua_State *L, enum_value_t value, const string2enum_t *set)
       
    78 {
       
    79 	enum_value_t matched = 0;
       
    80 	lua_newtable (L);
       
    81 	while (set->string) {
       
    82 		if (value & set->value) {
       
    83 			matched |= set->value & value;
       
    84 			lua_pushstring (L, set->string);
       
    85 			lua_pushboolean (L, 1);
       
    86 			lua_settable (L, -3);
       
    87 		}
       
    88 		++set;
       
    89 	}
       
    90 	if (value ^ matched) {
       
    91 		lua_pushinteger (L, 1);
       
    92 		lua_pushinteger (L, value ^ matched);
       
    93 		lua_settable (L, -3);
       
    94 	}
       
    95 }
       
    96 
       
    97 void *luaL_malloc (lua_State *L, size_t size)
       
    98 {
       
    99 	void      *ud;
       
   100 	lua_Alloc  allocf = lua_getallocf (L, &ud);
       
   101 	return (*allocf) (ud, NULL, 0, size);
       
   102 }
       
   103 
       
   104 void *luaL_realloc (lua_State *L, void *ptr, size_t osize, size_t nsize)
       
   105 {
       
   106 	void      *ud;
       
   107 	lua_Alloc  allocf = lua_getallocf (L, &ud);
       
   108 	return (*allocf) (ud, ptr, osize, nsize);
       
   109 }
       
   110 
       
   111 void  luaL_free (lua_State *L, void *ptr)
       
   112 {
       
   113 	void      *ud;
       
   114 	lua_Alloc  allocf = lua_getallocf (L, &ud);
       
   115 	(*allocf) (ud, ptr, 1, 0);
       
   116 }
       
   117