moved common files into source root
[lqt.git] / lqt_common.cpp
blob5506c164e1a1ff20994b4cd99df3599865becc90
1 /*
2 * Copyright (c) 2007-2008 Mauro Iazzi
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
27 #include "lqt_common.hpp"
28 #include <cstring>
30 #include <QDebug>
32 static void lqtL_getenumtable (lua_State *L) {
33 lua_getfield(L, LUA_REGISTRYINDEX, LQT_ENUMS);
34 if (lua_isnil(L, -1)) {
35 lua_pop(L, 1);
36 lua_newtable(L);
37 lua_pushvalue(L, -1);
38 lua_setfield(L, LUA_REGISTRYINDEX, LQT_ENUMS);
42 static void lqtL_getpointertable (lua_State *L) {
43 lua_getfield(L, LUA_REGISTRYINDEX, LQT_POINTERS); // (1) get storage for pointers
44 if (lua_isnil(L, -1)) { // (1) if there is not
45 lua_pop(L, 1); // (0) pop the nil value
46 lua_newtable(L); // (1) create a new one
47 lua_pushvalue(L, -1); // (2) duplicate it
48 lua_setfield(L, LUA_REGISTRYINDEX, LQT_POINTERS); // (1) put one copy as storage
52 static int lqtL_createenum (lua_State *L, lqt_Enum e[], const char *n) {
53 lqtL_getenumtable(L); // (1)
54 lua_newtable(L); // (2)
55 lua_pushvalue(L, -1); // (3)
56 lua_setfield(L, -3, n); // (2)
57 while ( (e->name!=0) ) { // (2)
58 lua_pushstring(L, e->name); // (3)
59 lua_pushinteger(L, e->value); // (4)
60 lua_settable(L, -3); // (2)
61 lua_pushinteger(L, e->value); // (3)
62 lua_pushstring(L, e->name); // (4)
63 lua_settable(L, -3); // (2)
64 e++; // (2)
66 lua_pop(L, 2); // (0)
67 return 0;
70 int lqtL_createenumlist (lua_State *L, lqt_Enumlist list[]) {
71 while (list->enums!=0 && list->name!=0) {
72 lqtL_createenum(L, list->enums, list->name); // (0)
73 list++;
75 return 0;
78 static int lqtL_indexfunc (lua_State *L) {
79 int i = 1;
80 lua_pushnil(L); // (+1)
81 while (!lua_isnone(L, lua_upvalueindex(i))) { // (+1)
82 lua_pop(L, 1); // (+0)
83 lua_pushvalue(L, 2); // (+1)
84 if (i==1) {
85 lua_rawget(L, lua_upvalueindex(i)); // (+1)
86 } else {
87 lua_gettable(L, lua_upvalueindex(i)); // (+1)
89 if (!lua_isnil(L, -1)) break;
90 i++;
92 return 1; // (+1)
95 static int lqtL_pushindexfunc (lua_State *L, const char *name, lqt_Base *bases) {
96 int upnum = 1;
97 luaL_newmetatable(L, name); // (1)
98 while (bases->basename!=NULL) {
99 luaL_newmetatable(L, bases->basename); // (upnum)
100 upnum++;
101 bases++;
103 lua_pushcclosure(L, lqtL_indexfunc, upnum); // (1)
104 return 1;
107 int lqtL_createclasses (lua_State *L, lqt_Class *list) {
108 while (list->name!=0) { // (0)
109 luaL_newmetatable(L, list->name); // (1)
110 luaL_register(L, NULL, list->mt); // (1)
111 lua_pushstring(L, list->name); // (2)
112 lua_pushboolean(L, 1); // (3)
113 lua_settable(L, -3); // (1)
114 lqtL_pushindexfunc(L, list->name, list->bases); // (2)
115 lua_setfield(L, -2, "__index"); // (1)
116 lua_pushvalue(L, -1); // (2)
117 lua_setmetatable(L, -2); // (1)
118 lua_pop(L, 1); // (0)
119 lua_pushlstring(L, list->name, strlen(list->name)-1); // (1)
120 lua_newtable(L); // (2)
121 luaL_register(L, NULL, list->mt); // (2)
122 lua_settable(L, LUA_GLOBALSINDEX); // (0)
123 list++;
125 return 0;
128 bool lqtL_isinteger (lua_State *L, int i) {
129 if (lua_type(L, i)==LUA_TNUMBER)
130 return lua_tointeger(L, i)==lua_tonumber(L, i);
131 else
132 return false;
134 bool lqtL_isnumber (lua_State *L, int i) {
135 return lua_type(L, i)==LUA_TNUMBER;
137 bool lqtL_isstring (lua_State *L, int i) {
138 return lua_type(L, i)==LUA_TSTRING;
140 bool lqtL_isboolean (lua_State *L, int i) {
141 return lua_type(L, i)==LUA_TBOOLEAN;
143 bool lqtL_missarg (lua_State *L, int index, int n) {
144 bool ret = true;
145 int i = 0;
146 for (i=index;i<index+n;i++) {
147 if (!lua_isnoneornil(L, i)) {
148 ret = false;
149 break;
152 return ret;
155 static void lqtL_ensurepointer (lua_State *L, const void *p) { // (+1)
156 lqtL_getpointertable(L); // (1)
157 lua_pushlightuserdata(L, const_cast<void*>(p)); // (2)
158 lua_gettable(L, -2); // (2)
159 if (lua_isnil(L, -1)) { // (2)
160 lua_pop(L, 1); // (1)
161 const void **pp = static_cast<const void**>(lua_newuserdata(L, sizeof(void*))); // (2)
162 *pp = p; // (2)
163 lua_pushlightuserdata(L, const_cast<void*>(p)); // (3)
164 lua_pushvalue(L, -2); // (4)
165 lua_settable(L, -4); // (2)
167 // (2)
168 lua_remove(L, -2); // (1)
171 void lqtL_register (lua_State *L, const void *p) { // (+0)
172 lqtL_ensurepointer(L, p);
173 lua_pop(L, 1);
176 void lqtL_unregister (lua_State *L, const void *p) {
177 lqtL_getpointertable(L); // (1)
178 lua_pushlightuserdata(L, const_cast<void*>(p)); // (2)
179 lua_gettable(L, -2); // (2)
180 if (lua_isuserdata(L, -1)) {
181 const void **pp = static_cast<const void**>(lua_touserdata(L, -1)); // (2)
182 *pp = 0;
184 lua_pop(L, 1); // (1)
185 lua_pushlightuserdata(L, const_cast<void*>(p)); // (2)
186 lua_pushnil(L); // (3)
187 lua_settable(L, -3); // (1)
188 lua_pop(L, 1); // (0)
191 void lqtL_passudata (lua_State *L, const void *p, const char *name) {
192 lqtL_ensurepointer(L, p); // (1)
193 luaL_newmetatable(L, name); // (2)
194 lua_setmetatable(L, -2); // (1)
195 return;
198 void lqtL_pushudata (lua_State *L, const void *p, const char *name) {
199 lqtL_ensurepointer(L, p); // (1)
200 luaL_newmetatable(L, name); // (2)
201 lua_setmetatable(L, -2); // (1)
202 return;
205 void *lqtL_toudata (lua_State *L, int index, const char *name) {
206 void *ret = 0;
207 if (!lqtL_testudata(L, index, name)) return 0;
208 void **pp = static_cast<void**>(lua_touserdata(L, index));
209 ret = *pp;
210 return ret;
213 bool lqtL_testudata (lua_State *L, int index, const char *name) {
214 if (!lua_isuserdata(L, index) || lua_islightuserdata(L, index)) return false;
215 lua_getfield(L, index, name);
216 if (!lua_isboolean(L, -1) || !lua_toboolean(L, -1)) {
217 lua_pop(L, 1);
218 return false;
220 lua_pop(L, 1);
221 return true;
224 void lqtL_pushenum (lua_State *L, int value, const char *name) {
225 lqtL_getenumtable(L);
226 lua_getfield(L, -1, name);
227 lua_remove(L, -2);
228 if (!lua_istable(L, -1)) {
229 lua_pop(L, 1);
230 lua_pushnil(L);
231 return;
233 lua_pushnumber(L, value);
234 lua_gettable(L, -2);
235 lua_remove(L, -2);
237 bool lqtL_isenum (lua_State *L, int index, const char *name) {
238 bool ret = false;
239 if (!lua_isstring(L, index)) return false;
240 lqtL_getenumtable(L);
241 lua_getfield(L, -1, name);
242 if (!lua_istable(L, -1)) {
243 lua_pop(L, 2);
244 return false;
246 lua_remove(L, -2);
247 lua_pushvalue(L, index);
248 lua_gettable(L, -2);
249 ret = lua_isnumber(L, -1);
250 lua_pop(L, 2);
251 return ret;
253 int lqtL_toenum (lua_State *L, int index, const char *name) {
254 int ret = -1;
255 lqtL_getenumtable(L);
256 lua_pushvalue(L, index);
257 lua_gettable(L, -2);
258 ret = lua_tointeger(L, -1);
259 lua_pop(L, 2);
260 return ret;