various fixes
[lqt.git] / qt_generator.lua
blob84a32d7fff192b5e6778186e08cc154b90154e81
1 #!/usr/bin/lua
2 --[[
4 Copyright (c) 2007-2008 Mauro Iazzi
6 Permission is hereby granted, free of charge, to any person
7 obtaining a copy of this software and associated documentation
8 files (the "Software"), to deal in the Software without
9 restriction, including without limitation the rights to use,
10 copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the
12 Software is furnished to do so, subject to the following
13 conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 OTHER DEALINGS IN THE SOFTWARE.
27 --]]
30 xml = dofile'xml.lua'
31 B = dofile'binder.lua'
33 function NOINSTANCE(b, name)
34 b.types_from_stack[name] = function(i) error('cannot copy '..name) end
35 b.types_test[name] = function(i) error('cannot copy '..name) end
36 b.types_to_stack[name] = function(i) error('cannot copy '..name) end
38 b.types_from_stack[(name..' *')] = function(i) return '*static_cast<'..name..'**>(lqtL_toudata(L, '..tostring(i)..', "'..name..'"))' end
39 b.types_test[(name..' *')] = function(i) return 'lqtL_testudata(L, '..tostring(i)..', "'..name..'*")' end
40 b.types_to_stack[(name..' *')] = function(i) return 'lqtL_pushudata(L, '..tostring(i)..', "'..name..'*")' end
41 end
43 function cp_file(src, dst)
45 local src = (type(src)=='string') and io.open(src, 'r') or src
46 local check = (type(dst)=='string') and io.open(dst, 'r') or nil
47 if type(check)=='userdata' then
48 local a, b = src:read'*a', check:read'*a'
49 if a==b then check:close() src:close() return end
50 check:close()
51 end
52 end
53 src = (type(src)=='string') and io.open(src, 'r') or src
54 dst = (type(dst)=='string') and io.open(dst, 'w') or dst
55 local content = src:read('*a')
56 dst:write(content)
57 src:close()
58 dst:close()
59 end
61 function BINDQT(n)
62 n = tostring(n)
63 local h, c = B:make_namespace(n, n, 'QtCore', 'QtGui')
64 print(n..': writing definition file')
65 f = io.open('src/lqt_bind_'..n..'.cpp', 'w')
66 f:write(c)
67 f:close()
69 print(n..': writing prototypes file')
70 f = io.open('src/lqt_bind_'..n..'.hpp', 'w')
71 f:write(h)
72 f:close()
73 end
75 function init_qt(B)
76 B.filter = function (m)
77 local n = type(m)=='table' and type(m.attr)=='table' and m.attr.name
78 if n and string.match(n, "[_%w]*[xX]11[_%w]*$") then
79 return true, 'it is X11 specific'
80 end
81 if n and string.match(n, "[_%w]*_[_%w]*$") then
82 return true, 'it is meant to be internal'
83 end
84 return false
85 end
88 NOINSTANCE(B, 'QCoreApplication')
91 B.types_from_stack['const QString&'] = function(i) return 'QString::fromAscii(lua_tostring(L, '..tostring(i)..'), lua_objlen(L, '..tostring(i)..'))' end
92 B.types_test['const QString&'] = function(i) return '(lua_type(L, ' .. tostring(i) .. ')==LUA_TSTRING)' end
93 B.types_to_stack['const QString&'] = function(i) return 'lua_pushlstring(L, '..tostring(i)..'.toAscii().data(), '..tostring(i)..'.toAscii().size())' end
94 B.types_from_stack['QString'] = function(i) return 'QString::fromAscii(lua_tostring(L, '..tostring(i)..'), lua_objlen(L, '..tostring(i)..'))' end
95 B.types_test['QString'] = function(i) return '(lua_type(L, ' .. tostring(i) .. ')==LUA_TSTRING)' end
96 B.types_to_stack['QString'] = function(i) return 'lua_pushlstring(L, '..tostring(i)..'.toAscii().data(), '..tostring(i)..'.toAscii().size())' end
98 B.types_from_stack['QByteArray'] = function(i) return 'QByteArray(lua_tostring(L, '..tostring(i)..'), lua_objlen(L, '..tostring(i)..'))' end
99 B.types_test['QByteArray'] = function(i) return '(lua_type(L, ' .. tostring(i) .. ')==LUA_TSTRING)' end
100 B.types_to_stack['QByteArray'] = function(i) return 'lua_pushlstring(L, '..tostring(i)..'.data(), '..tostring(i)..'.size())' end
103 function make_tree (cl, tf)
104 f = io.open(tf..'.cpp', 'w')
105 for n in pairs(cl) do
106 f:write('#include <'..n..'>\n')
108 f:write'\nmain() {\n'
109 for n in pairs(cl) do
110 if not ({Qt=true})[n] then f:write(' '..n..' *'..string.lower(n)..';\n') end
112 f:write'}\n'
113 f:close()
114 os.execute('gccxml `pkg-config QtGui QtCore --cflags` -fxml='..tf..'.xml '..tf..'.cpp')
115 --os.execute'gccxml -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -fxml=auto.xml auto.cpp'
116 --os.remove(tf..'.cpp')
119 function make_standard_qt(B, classlist)
120 print'copying common files'
121 cp_file('lqt_qt_utils.hpp', 'src/lqt_qt_utils.hpp')
122 cp_file('lqt_qt_utils.cpp', 'src/lqt_qt_utils.cpp')
123 cp_file('lqt_common.hpp', 'src/lqt_common.hpp')
124 cp_file('lqt_common.cpp', 'src/lqt_common.cpp')
127 local clist = {}
128 for s in string.gmatch(classlist, '([%u%l%d]+)') do
129 clist[s] = true
131 classlist = clist
134 local tmpfile='tmp/auto'
136 make_tree(classlist, tmpfile)
138 B:init(tmpfile..'.xml')
139 init_qt(B)
142 local clist = {}
143 for n in pairs(classlist) do
144 local c = B:find_name(n)
145 clist = B.set_union(clist, B:tree_of_bases(c))
147 classlist = B.set_union(classlist, clist)
150 for n in pairs(classlist) do
151 BINDQT(n)
155 function make_single_qt(B, class)
156 local classlist = { class }
158 local tmpfile='tmp/auto'
160 make_tree(classlist, tmpfile)
161 B:init(tmpfile..'.xml')
162 init_qt(B)
164 BINDQT(class)
167 function B:enum_push_body_plus_qt(id, c)
168 local enum = (type(id)=='string') and self:find_id(id) or id
169 local e_static = (self:find_id(enum.attr.context).tag == 'Class') and 'static ' or ''
170 local e_context = self:context_name(enum)
171 local e_name = 'lqt_pushenum_' .. enum.attr.name
172 local e_proto, e_def = '', ''
174 e_proto = e_proto .. ' ' .. e_static .. self.lua_proto(e_name) .. ';\n'
175 e_def = e_def .. self.lua_proto(c .. e_name) .. ' '
176 e_def = e_def .. '{\n'
177 e_def = e_def .. ' int enum_table = 0;\n'
178 e_def = e_def .. ' lua_getfield(L, LUA_REGISTRYINDEX, LQT_ENUMS);\n'
179 e_def = e_def .. ' if (!lua_istable(L, -1)) {\n'
180 e_def = e_def .. ' lua_pop(L, 1);\n'
181 e_def = e_def .. ' lua_newtable(L);\n'
182 e_def = e_def .. ' lua_pushvalue(L, -1);\n'
183 e_def = e_def .. ' lua_setfield(L, LUA_REGISTRYINDEX, LQT_ENUMS);\n'
184 e_def = e_def .. ' }\n'
186 e_def = e_def .. ' lua_newtable(L);\n'
187 e_def = e_def .. ' enum_table = lua_gettop(L);\n'
188 for i, e in ipairs(enum) do
189 if (type(e)=='table') and (e.tag=='EnumValue') then
190 e_def = e_def .. ' lua_pushstring(L, "' .. e.attr.name .. '");\n'
191 e_def = e_def .. ' lua_rawseti(L, enum_table, ' .. e.attr.init .. ');\n'
192 e_def = e_def .. ' lua_pushinteger(L, ' .. e.attr.init .. ');\n'
193 e_def = e_def .. ' lua_setfield(L, enum_table, "' .. e.attr.name .. '");\n'
196 e_def = e_def .. ' lua_pushcfunction(L, ' .. c .. e_name .. '_QFLAGS_CREATOR' .. ');\n'
197 e_def = e_def .. ' lua_setfield(L, enum_table, "QFlags");\n'
198 e_def = e_def .. ' lua_pushvalue(L, -1);\n'
199 e_def = e_def .. ' lua_setfield(L, -3, "' .. e_context .. enum.attr.name .. '");\n'
200 e_def = e_def .. ' lua_remove(L, -2);\n'
201 e_def = e_def .. ' return 1;\n'
202 e_def = e_def .. '}\n'
203 -- ######## QFLAGS SPECIFIC
204 e_proto = e_proto .. ' ' .. e_static .. self.lua_proto(e_name..'_QFLAGS_CREATOR') .. ';\n'
205 e_def = e_def .. self.lua_proto(c .. e_name .. '_QFLAGS_CREATOR') .. [[ {
206 int argn = lua_gettop(L);
207 int i = 0;
208 void *p = lua_newuserdata(L, sizeof(QFlags<]]..e_context..enum.attr.name..[[>*) + sizeof(QFlags<]]..e_context..enum.attr.name..[[>));
209 QFlags<]]..e_context..enum.attr.name..[[> *fl = static_cast<QFlags<]]..e_context..enum.attr.name..[[>*>( static_cast<void*>(&static_cast<QFlags<]]..e_context..enum.attr.name..[[>**>(p)[1]) );
210 *(void**)p = fl;
211 for (i=1;i<=argn;i++) {
212 *fl |= static_cast<]]..e_context..enum.attr.name..[[>(lqtL_toenum(L, i, "]]..e_context..enum.attr.name..[["));
214 if (luaL_newmetatable(L, "QFlags<]]..e_context..enum.attr.name..[[>*")) {
215 lua_pushstring(L, "QFlags<]]..e_context..enum.attr.name..[[>*");
216 lua_setfield(L, -2, "__qtype");
218 lua_setmetatable(L, -2);
219 return 1;
222 --print (e_def)
223 return e_proto, e_def, e_name
226 B.enum_push_body = B.enum_push_body_plus_qt
229 make_standard_qt(B,
230 --'QTimer'
232 QAbstractScrollArea
233 QAction
234 QApplication
235 QBoxLayout
236 QColor
237 QCoreApplication
238 QDialog
239 QEvent
240 QFileDialog
241 QFont
242 QFrame
243 QGraphicsItem
244 QGraphicsScene
245 QGraphicsView
246 QHBoxLayout
247 QIcon
248 QImage
249 QInputEvent
250 QKeyEvent
251 QKeySequence
252 QLabel
253 QLayout
254 QLayoutItem
255 QLineEdit
256 QMainWindow
257 QMenuBar
258 QMenu
259 QMessageBox
260 QObject
261 QPaintDevice
262 QShortcut
263 QSize
264 QSyntaxHighlighter
266 QTextBlockUserData
267 QTextCharFormat
268 QTextCursor
269 QTextDocument
270 QTextEdit
271 QTextFormat
272 QToolBar
273 QVBoxLayout
274 QWidget