|
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 |