Update BUILD
[lqt/mk.git] / generator / generator.lua
blob402348c5fab5ea52fdc15cbd96d824e889cc2f29
1 #!/usr/bin/lua
3 --[[
5 Copyright (c) 2007-2009 Mauro Iazzi
6 Copyright (c) 2008 Peter K�mmel
7 Copyright (c) 2010 Michal Kottman
9 Permission is hereby granted, free of charge, to any person
10 obtaining a copy of this software and associated documentation
11 files (the "Software"), to deal in the Software without
12 restriction, including without limitation the rights to use,
13 copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the
15 Software is furnished to do so, subject to the following
16 conditions:
18 The above copyright notice and this permission notice shall be
19 included in all copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 OTHER DEALINGS IN THE SOFTWARE.
30 --]]
32 local osseparator = package.config:sub(1,1)
34 local path = string.match(arg[0], '(.*'..osseparator..')[^%'..osseparator..']+') or ''
35 if path == "" then
36 --- remove script name
37 path = string.sub(arg[0], 1, #arg[0] - #'generator.lua')
38 end
40 local filename = nil
41 local dirname = nil
42 module_name = nil
43 template_file = path .. 'qtemplates.lua'
44 local typefiles = {}
45 local filterfiles = {}
46 output_includes = {
47 'lqt_common.hpp',
51 local i = 1
52 while select(i, ...) do
53 local argi = select(i, ...)
54 if argi=='-n' then
55 i = i + 1
56 module_name = select(i, ...)
57 elseif argi=='-i' then
58 i = i + 1
59 table.insert(output_includes, (select(i, ...)))
60 elseif argi=='-t' then
61 i = i + 1
62 table.insert(typefiles, (select(i, ...)))
63 elseif argi=='-f' then
64 i = i + 1
65 table.insert(filterfiles, (select(i, ...)))
66 elseif argi=='-c' then
67 i = i + 1
68 template_file = select(i, ...)
69 elseif argi=='-v' then
70 VERBOSE_BUILD = true
71 else
72 filename = filename and error'duplicate filename' or argi
73 end
74 i = i + 1
75 end
76 end
78 local my_includes = ''
79 for _, i in ipairs(output_includes) do
80 if string.match(i, '^<.+>$') then
81 my_includes = my_includes .. '#include '..i..'\n'
82 elseif string.match(i, '^".+"$') then
83 my_includes = my_includes .. '#include '..i..'\n'
84 else
85 my_includes = my_includes .. '#include "'..i..'"\n'
86 end
87 end
88 output_includes = my_includes .. '\n'
90 local readfile = function(fn)
91 local f = assert(io.open(fn))
92 local s = f:read'*a'
93 f:close()
94 return s
95 end
97 function fprint(f)
98 return function(...)
99 for i = 1, select('#',...) do
100 f:write((i==1) and '' or '\t', tostring(select(i,...)))
102 f:write'\n'
103 f:flush()
107 _src = '_src'..osseparator
108 local debug = fprint(io.stderr)
110 local warn = true
111 local ignore_file = assert(io.open('ignores_'..module_name..'.csv', 'w'))
112 function ignore(name, cause, context)
113 if warn then
114 ignore_file:write(name..';'..cause..';'..(context or '')..'\n')
118 local xmlstream, idindex = dofile(path..'xml.lua')(readfile(filename))
120 -- Remove duplicate entries (~4300/20000 for QtCore)
121 local dups = {}
122 local remove = {}
123 for e in pairs(idindex) do
124 if e.xarg and e.xarg.id and dups[e.xarg.id] then
125 -- print('Duplicate!', dups[e.xarg.id], e.xarg.name, e.xarg.id)
126 remove[e] = true
128 dups[e.xarg.id] = true
130 for e in pairs(remove) do
131 idindex[e] = nil
134 package.path = path..'?.lua;' .. package.path
136 require('class_types')
138 ----------------------------------------------------------------------------------
140 typesystem = dofile(path..'types.lua')
142 local ts = {}
143 for i, ft in ipairs(typefiles) do
144 ts = assert(loadfile(ft))(ts)
146 setmetatable(typesystem, {
147 __newindex = function(t, k, v)
148 --debug('added type', k)
149 ts[k] = v
150 end,
151 __index = function(t, k)
152 local ret = ts[k]
153 -- if not ret then debug("unknown type:", tostring(k), ret) end
154 return ret
155 end,
160 -- helper function
161 function argument_name(tn, an)
162 local ret
163 if string.match(tn, '%(%*%)') then
164 ret = string.gsub(tn, '%(%*%)', '(*'..an..')', 1)
165 elseif string.match(tn, '%[.*%]') then
166 ret = string.gsub(tn, '%s*(%[.*%])', ' '..an..'%1')
167 else
168 ret = tn .. ' ' .. an
170 return ret
173 local gen_id = 0
174 for e in pairs(idindex) do
175 if e.xarg and e.xarg.id then
176 local id = assert(tonumber(e.xarg.id:match("_(%d+)")))
177 if id > gen_id then gen_id = id + 1 end
179 end
181 function next_id() gen_id = gen_id + 1; return "_" .. gen_id end
184 --- Constructs the code that pushes arguments to the Lua stack.
185 -- Returns the code as a string, and stack increment. In case that an unknown
186 -- type is encountered, nil and the unknown type is returned.
187 function make_pushlines(args)
188 local pushlines, stack = '', 0
189 for i, a in ipairs(args) do
190 if not typesystem[a.xarg.type_name] then return nil, a.xarg.type_name end
191 local apush, an = typesystem[a.xarg.type_name].push('arg'..i)
192 pushlines = pushlines .. ' ' .. apush .. ';\n'
193 stack = stack + an
195 return pushlines, stack
198 require 'enums'
199 require 'classes'
201 fullnames = {}
203 for e in pairs(idindex) do
204 if e.xarg.fullname then fullnames[e.xarg.fullname] = e end
207 enums.preprocess(idindex)
208 classes.preprocess(idindex)
210 enums.process(idindex, typesystem)
211 classes.process(idindex, typesystem, filterfiles)
213 ------------- BEGIN OUTPUT
215 enums.output()
216 classes.output()
218 --print_openmodule(module_name) -- does that