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.
12 #include "genericwrapper.h"
19 #define ARG_CHECK(exp, func) \
20 if (n != (exp)) luaL_error(l, "Wrong argument count for %s::%s", class_name() ,#func)
25 class Wrapper
<HLine
> : public GenericWrapper
<HLine
> {
27 static const char* class_name() {
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
);
48 const char* str
= lua_tostring(l
, 1);
51 HLine
* hline
= new HLine(str
, QTextCharFormat());
57 * Release the object at @a index from Lua's ownership.
59 static void release(lua_State
* l
, int index
) {
62 lua_getmetatable(l
, index
);
63 lua_pushstring(l
, "__gc");
69 static int clone(lua_State
* l
) {
70 const int n
= lua_gettop(l
);
73 HLine
* self
= retrieve(l
, 1, AssertOk
);
76 allocate(l
, new HLine(*self
));
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));
89 allocate(l
, self
->extract(begin
, end
));
93 static int append(lua_State
* l
) {
94 const int n
= lua_gettop(l
);
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));
103 allocate(l
, self
->append(*other
, begin
, end
));
107 static int mid(lua_State
* l
) {
108 const int n
= lua_gettop(l
);
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));
116 lua_pushstring(l
, qPrintable(self
->mid(from
, to
)));
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);
130 self
->setBold(from
, to
, value
);
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);
144 self
->setItalic(from
, to
, value
);
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);
158 self
->setColor(from
, to
, color
);
162 static int dump(lua_State
* l
) {
163 const int n
= lua_gettop(l
);
166 HLine
* self
= retrieve(l
, 1, AssertOk
);
177 static const luaL_Reg lualibs
[] = {
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
},
189 LUALIB_API
void luaL_openlibs (lua_State
*) { }
192 lua_State
* l
= lua_open();
195 for (const luaL_Reg
*lib
= lualibs
; lib
->func
; lib
++) {
196 lua_pushcfunction(l
, lib
->func
);
197 lua_pushstring(l
, lib
->name
);
201 Wrapper
<QColor
>::register_class(l
);
202 Wrapper
<HLine
>::register_class(l
);
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
);
215 kDebug() << "LOADFILE FOR " << file
<< " FAILED";
216 kDebug() << lua_tostring(m_state
, -1);
220 kDebug() << "FILE " << 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: " << lua_tostring(m_state
, -1);
230 int Api::create_line(lua_State
* l
) {
231 const char* line
= lua_tostring(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";
241 void Api::loadTest() {
243 lua_pushcfunction(m_state
, &create_line
);
244 lua_setglobal(m_state
, "create_line");
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("%", "\\"));
262 std::pair
<bool, HLine
*> res
= runEvent(text
, i
, re
);
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)) << ") **";
298 return std::pair
<bool, HLine
*>(false, 0);
302 lua_getglobal(m_state
, "__patterns__");
303 if (!lua_istable(m_state
, -1)) {
304 kDebug() << "** ERROR: __patterns__ is corrupted **";
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);
313 lua_pushstring(m_state
, qPrintable(text
));
316 pushpair(index
, index
+ pattern
.matchedLength());
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);
329 lua_newtable(m_state
);
334 if (lua_isnil(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));
345 lua_pushstring(m_state
, "to");
346 lua_gettable(m_state
, -2);
347 int to
= static_cast<int>(lua_tonumber(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);
357 res
= res
->extract(from
, to
);
361 return std::make_pair(true, res
);
365 } // namespace LuaApi