Replaced all std::cout with kDebug.
[tagua/yd.git] / src / luaapi / luahl.cpp
blob52298a4d6bd5eca16325879103146b11f6e382d9
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "luahl.h"
12 #include "genericwrapper.h"
13 #include <QColor>
14 #include <QFile>
15 #include "common.h"
16 #include "hline.h"
17 #include "imaging.h"
19 #define ARG_CHECK(exp, func) \
20 if (n != (exp)) luaL_error(l, "Wrong argument count for %s::%s", class_name() ,#func)
22 namespace LuaApi {
24 template <>
25 class Wrapper<HLine> : public GenericWrapper<HLine> {
26 public:
27 static const char* class_name() {
28 return "HLine";
31 PROPERTY_RO(length, length, number);
33 static void create_index_table(lua_State* l) {
34 SET_PROPERTY_RO(l, length);
35 set_method(l, &mid, "mid");
36 set_method(l, &set_bold, "set_bold");
37 set_method(l, &set_italic, "set_italic");
38 set_method(l, &set_color, "set_color");
39 set_method(l, &clone, "clone");
40 set_method(l, &extract, "extract");
41 set_method(l, &append, "append");
42 set_method(l, &dump, "dump");
45 static int constructor(lua_State* l) {
46 const int n = lua_gettop(l);
47 ARG_CHECK(1, HLine);
48 const char* str = lua_tostring(l, 1);
49 lua_pop(l, n);
51 HLine* hline = new HLine(str, QTextCharFormat());
52 allocate(l, hline);
53 return 1;
56 /**
57 * Release the object at @a index from Lua's ownership.
59 static void release(lua_State* l, int index) {
60 StackCheck check(l);
62 lua_getmetatable(l, index);
63 lua_pushstring(l, "__gc");
64 lua_pushnil(l);
65 lua_settable(l, -3);
66 lua_pop(l, 1);
69 static int clone(lua_State* l) {
70 const int n = lua_gettop(l);
71 ARG_CHECK(1, clone);
73 HLine* self = retrieve(l, 1, AssertOk);
74 lua_pop(l, n);
76 allocate(l, new HLine(*self));
77 return 1;
80 static int extract(lua_State* l) {
81 const int n = lua_gettop(l);
82 ARG_CHECK(3, extract);
84 HLine* self = retrieve(l, 1, AssertOk);
85 int begin = static_cast<int>(lua_tonumber(l, 2));
86 int end = static_cast<int>(lua_tonumber(l, 3));
87 lua_pop(l, n);
89 allocate(l, self->extract(begin, end));
90 return 1;
93 static int append(lua_State* l) {
94 const int n = lua_gettop(l);
95 ARG_CHECK(4, append);
97 HLine* self = retrieve(l, 1, AssertOk);
98 HLine* other = retrieve(l, 2, AssertOk);
99 int begin = static_cast<int>(lua_tonumber(l, 3));
100 int end = static_cast<int>(lua_tonumber(l, 4));
101 lua_pop(l, n);
103 allocate(l, self->append(*other, begin, end));
104 return 1;
107 static int mid(lua_State* l) {
108 const int n = lua_gettop(l);
109 ARG_CHECK(3, mid);
111 HLine* self = retrieve(l, 1, AssertOk);
112 int from = static_cast<int>(lua_tonumber(l, 2));
113 int to = static_cast<int>(lua_tonumber(l, 3));
114 lua_pop(l, n);
116 lua_pushstring(l, qPrintable(self->mid(from, to)));
117 return 1;
120 static int set_bold(lua_State* l) {
121 const int n = lua_gettop(l);
122 ARG_CHECK(4, set_bold);
124 HLine* self = retrieve(l, 1, AssertOk);
125 int from = static_cast<int>(lua_tonumber(l, 2));
126 int to = static_cast<int>(lua_tonumber(l, 3));
127 bool value = lua_toboolean(l, 4);
128 lua_pop(l, n);
130 self->setBold(from, to, value);
131 return 0;
134 static int set_italic(lua_State* l) {
135 const int n = lua_gettop(l);
136 ARG_CHECK(4, set_italic);
138 HLine* self = retrieve(l, 1, AssertOk);
139 int from = static_cast<int>(lua_tonumber(l, 2));
140 int to = static_cast<int>(lua_tonumber(l, 3));
141 bool value = lua_toboolean(l, 4);
142 lua_pop(l, n);
144 self->setItalic(from, to, value);
145 return 0;
148 static int set_color(lua_State* l) {
149 const int n = lua_gettop(l);
150 ARG_CHECK(4, set_bold);
152 HLine* self = retrieve(l, 1, AssertOk);
153 int from = static_cast<int>(lua_tonumber(l, 2));
154 int to = static_cast<int>(lua_tonumber(l, 3));
155 QColor color = Wrapper<QColor>::get(l, 4);
156 lua_pop(l, n);
158 self->setColor(from, to, color);
159 return 0;
162 static int dump(lua_State* l) {
163 const int n = lua_gettop(l);
164 ARG_CHECK(1, dump);
166 HLine* self = retrieve(l, 1, AssertOk);
167 lua_pop(l, n);
169 self->dump();
170 return 0;
177 static const luaL_Reg lualibs[] = {
178 {"", luaopen_base},
179 {LUA_LOADLIBNAME, luaopen_package},
180 {LUA_TABLIBNAME, luaopen_table},
181 {LUA_IOLIBNAME, luaopen_io},
182 {LUA_OSLIBNAME, luaopen_os},
183 {LUA_STRLIBNAME, luaopen_string},
184 {LUA_MATHLIBNAME, luaopen_math},
185 {LUA_DBLIBNAME, luaopen_debug},
186 {NULL, NULL}
189 LUALIB_API void luaL_openlibs (lua_State*) { }
191 Api::Api() {
192 lua_State* l = lua_open();
193 m_state = l;
195 for (const luaL_Reg *lib = lualibs; lib->func; lib++) {
196 lua_pushcfunction(l, lib->func);
197 lua_pushstring(l, lib->name);
198 lua_call(l, 1, 0);
201 Wrapper<QColor>::register_class(l);
202 Wrapper<HLine>::register_class(l);
205 Api::~Api() {
206 lua_close(m_state);
209 void Api::runFile(const char* file) {
210 //luaL_dofile(m_state, file);
211 if (QFile(file).exists()) {
212 if(luaL_loadfile(m_state, file) == 0)
213 pcall(0, LUA_MULTRET);
214 else {
215 kDebug() << "LOADFILE FOR " << wrap_cptr(file) << " FAILED";
216 kDebug() << wrap_cptr(lua_tostring(m_state, -1));
219 else
220 kDebug() << "FILE " << wrap_cptr(file) << " DOES NOT EXIST";
223 void Api::pcall(int nArgs, int nResults) {
224 if (lua_pcall(m_state, nArgs, nResults, 0) != 0) {
225 kDebug() << "RUNTIME ERROR: " << wrap_cptr(lua_tostring(m_state, -1));
229 #if 0
230 int Api::create_line(lua_State* l) {
231 const char* line = lua_tostring(l, -1);
232 lua_pop(l, 1);
233 lua_getglobal(l, "Text");
234 Wrapper<HLine>::allocate(l,
235 new HLine(line, QTextCharFormat()));
236 if (lua_pcall(l, 1, 1, 0) != 0)
237 kDebug() << "ERROR INSIDE create_line";
238 return 1;
241 void Api::loadTest() {
243 lua_pushcfunction(m_state, &create_line);
244 lua_setglobal(m_state, "create_line");
246 #endif
248 HLine* Api::highlight(const QString& text) {
249 // iterate through patterns
250 StackCheck check(m_state);
251 lua_getglobal(m_state, "__patterns__");
252 if (lua_istable(m_state, -1)) {
253 lua_pushnil(m_state);
254 while (lua_next(m_state, -2) != 0) {
255 int i = static_cast<int>(lua_tonumber(m_state, -2));
256 lua_pushstring(m_state, "pattern");
257 lua_gettable(m_state, -2);
258 QString pattern(lua_tostring(m_state, -1));
259 QRegExp re(pattern.replace("%", "\\"));
260 lua_pop(m_state, 2);
262 std::pair<bool, HLine*> res = runEvent(text, i, re);
263 if (res.first) {
264 lua_pop(m_state, 2);
265 return res.second;
271 lua_pop(m_state, 1);
272 return new HLine(text, QTextCharFormat());
275 void Api::pushpair(int x, int y) {
276 lua_newtable(m_state);
277 lua_pushstring(m_state, "from");
278 lua_pushnumber(m_state, x);
279 lua_settable(m_state, -3);
280 lua_pushstring(m_state, "to");
281 lua_pushnumber(m_state, y);
282 lua_settable(m_state, -3);
285 std::pair<bool, HLine*> Api::runEvent(const QString& text, int eventIndex, QRegExp& pattern) {
286 StackCheck check(m_state);
288 // match regexp against text
289 int index = pattern.indexIn(text);
290 if (index == -1) return std::pair<bool, HLine*>(false, 0);
292 lua_getglobal(m_state, "__run_event__");
294 if (!lua_isfunction(m_state, -1)) {
295 kDebug() << "** ERROR: __run_event__ is corrupted (type = " <<
296 lua_typename(m_state, lua_type(m_state, -1)) << ") **";
297 lua_pop(m_state, 1);
298 return std::pair<bool, HLine*>(false, 0);
301 // event
302 lua_getglobal(m_state, "__patterns__");
303 if (!lua_istable(m_state, -1)) {
304 kDebug() << "** ERROR: __patterns__ is corrupted **";
305 lua_pop(m_state, 2);
306 return std::pair<bool, HLine*>(false, 0);
308 lua_pushnumber(m_state, eventIndex);
309 lua_gettable(m_state, -2);
310 lua_remove(m_state, -2);
312 // str
313 lua_pushstring(m_state, qPrintable(text));
315 // match
316 pushpair(index, index + pattern.matchedLength());
318 // ref
319 lua_newtable(m_state);
320 const int n = pattern.numCaptures();
321 for (int i = 1; i <= n; i++) {
322 int pos = pattern.pos(i);
323 lua_pushnumber(m_state, i);
324 pushpair(pos, pos + pattern.cap(i).length());
325 lua_settable(m_state, -3);
328 // state
329 lua_newtable(m_state);
330 // TODO: fill state
332 pcall(5, 1);
334 if (lua_isnil(m_state, -1)) {
335 lua_pop(m_state, 1);
336 return std::pair<bool, HLine*>(true, 0);
340 lua_pushstring(m_state, "from");
341 lua_gettable(m_state, -2);
342 int from = static_cast<int>(lua_tonumber(m_state, -1));
343 lua_pop(m_state, 1);
345 lua_pushstring(m_state, "to");
346 lua_gettable(m_state, -2);
347 int to = static_cast<int>(lua_tonumber(m_state, -1));
348 lua_pop(m_state, 1);
350 lua_pushstring(m_state, "line");
351 lua_gettable(m_state, -2);
352 HLine* res = Wrapper<HLine>::retrieve(m_state, -1, AssertOk);
354 if (from == 0 && to == 0)
355 Wrapper<HLine>::release(m_state, -1);
356 else
357 res = res->extract(from, to);
359 lua_pop(m_state, 2);
361 return std::make_pair(true, res);
365 } // namespace LuaApi