diff --git a/src/scripts/elua/apps/empty.txt b/src/scripts/elua/apps/empty.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/scripts/elua/apps/lualian.lua b/src/scripts/elua/apps/lualian.lua deleted file mode 100644 index f0837d7e35..0000000000 --- a/src/scripts/elua/apps/lualian.lua +++ /dev/null @@ -1,65 +0,0 @@ --- Lualian application --- for use with Elua - -local lualian = require("lualian") -local getopt = require("getopt") - -local gen_file = function(opts, i, fname) - local printv = opts["v"] and print or function() end - printv("Generating for file: " .. fname) - local ofile = opts["o"] and opts["o"][i] or nil - local fstream = io.stdout - if ofile then - printv(" Output file: " .. ofile) - fstream = io.open(ofile, "w") - if not fstream then - error("Cannot open output file: " .. ofile) - end - else - printv(" Output file: printing to stdout...") - end - lualian.generate(fname, fstream) -end - -getopt.parse { - usage = "Usage: %prog [OPTIONS] file1.eo file2.eo ... fileN.eo", - args = arg, - descs = { - { category = "General" }, - - { "h", "help", nil, help = "Show this message.", metavar = "CATEGORY", - callback = getopt.help_cb(io.stdout) - }, - { "v", "verbose", false, help = "Be verbose." }, - - { category = "Generator" }, - - { "I", "include", true, help = "Include a directory.", metavar = "DIR", - list = {} - }, - { "o", "output", true, help = "Specify output file name(s), by " - .. "default goes to stdout.", - list = {} - } - }, - error_cb = function(parser, msg) - io.stderr:write(msg, "\n") - getopt.help(parser, io.stderr) - end, - done_cb = function(parser, opts, args) - if not opts["h"] then - for i, v in ipairs(opts["I"] or {}) do - lualian.include_dir(v) - end - if os.getenv("EFL_RUN_IN_TREE") then - lualian.system_directory_add() - end - lualian.load_eot_files() - for i, fname in ipairs(args) do - gen_file(opts, i, fname) - end - end - end -} - -return true diff --git a/src/scripts/elua/modules/lualian.lua b/src/scripts/elua/modules/lualian.lua deleted file mode 100644 index e515aaf8bc..0000000000 --- a/src/scripts/elua/modules/lualian.lua +++ /dev/null @@ -1,718 +0,0 @@ --- Elua lualian module - -local cutil = require("cutil") -local util = require("util") -local log = require("eina.log") -local eolian = require("eolian") - -local M = {} - -local dom - -local type_type = eolian.type_type -local class_type = eolian.class_type -local func_type = eolian.function_type -local obj_scope = eolian.object_scope -local param_dir = eolian.parameter_dir - -local gen_unit -local gen_state - -local get_state = function() - if not gen_state then - gen_state = eolian.new() - end - return assert(gen_state, "could not create eolian state") -end - -cutil.init_module(function() - dom = log.Domain("lualian") - if not dom:is_valid() then - log.err("Could not register log domain: lualian") - error("Could not register log domain: lualian") - end -end, function() - dom:unregister() - dom = nil -end) - -local lua_kw = { - ["and"] = true, ["end"] = true, ["in"] = true, ["local"] = true, - ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, - ["then"] = true, ["until"] = true -} - -local kw_t = function(n) - if lua_kw[n] then - return n .. "_" - end - return n -end - -local int_builtin = { - ["byte" ] = true, ["short"] = true, ["int"] = true, ["long"] = true, - ["llong"] = true, - - ["int8" ] = true, ["int16"] = true, ["int32"] = true, ["int64"] = true, - ["int128"] = true, - - ["intptr"] = true -} - -local num_others = { - ["size" ] = true, ["ssize" ] = true, ["ptrdiff"] = true, - ["float"] = true, ["double"] = true -} - -local is_num = function(x) - if not x then - return false - end - if num_others [x ] then return true end - if int_builtin[x ] then return true end - if int_builtin["u" .. x] then return true end - return false -end - -local known_out = { - ["Evas_Coord"] = function(expr) return ("tonumber(%s)"):format(expr) end, - ["bool"] = function(expr) return ("((%s) ~= 0)"):format(expr) end, - ["char"] = function(expr) return ("string.char(%s)"):format(expr) end -} - -local known_in = { - ["Evas_Coord"] = function(expr) return expr end, - ["bool"] = function(expr) return expr end -} - -local known_ptr_out = { - ["const char"] = function(expr) return ("ffi.string(%s)"):format(expr) end -} - -local known_ptr_in = { - ["const char"] = function(expr) return expr end -} - -local convfuncs = {} - -local build_calln = function(tps, expr, isin) - return expr -end - -local typeconv = function(tps, expr, isin) - if tps:type_get() == type_type.POINTER then - local base = tps:base_type_get() - local f = (isin and known_ptr_in or known_ptr_out)[base:c_type_get(eolian.c_type_type.DEFAULT)] - if f then return f(expr) end - return build_calln(tps, expr, isin) - end - - local tp = tps:short_name_get() - - if is_num(tp) then - return isin and expr or ("tonumber(%s)"):format(expr) - end - - local f = (isin and known_in or known_out)[tp] - if f then - return f(expr) - end - - return build_calln(tps, expr, isin) -end - -local Node = util.Object:clone { - generate = function(self, s) - end, - - gen_children = function(self, s) - local len = #self.children - - local evs = self.events - local evslen - if evs then evslen = #evs end - local hasevs = evs and evslen > 0 - - local hasprops = false - local nprops = 0 - local props = {} - - for i, v in ipairs(self.children) do - v.parent_node = self - if v.generate_prop then - if v:generate_prop(props) then - nprops = nprops + 1 - end - hasprops = true - end - v:generate(s, (not hasevs) and (not hasprops) and (i == len)) - end - - if hasevs then - s:write(" __events = {\n") - for i, v in ipairs(evs) do - v.parent_node = self - v:generate(s, i == evslen) - end - s:write(" }", hasprops and "," or "", "\n") - end - - if hasprops then - if hasevs then - s:write("\n") - end - s:write(" __properties = {\n") - local pi = 0 - for k, v in pairs(props) do - pi = pi + 1 - s:write(" [\"", k, "\"] = { ", table.concat(v, ", "), - " }", pi ~= nprops and "," or "", "\n") - end - s:write(" }\n") - end - end -} - -local Method = Node:clone { - __ctor = function(self, meth) - self.method = meth - end, - - gen_proto = function(self) - if self.cached_proto then return self.cached_proto end - - local meth = self.method - local pars = meth:parameters_get() - local rett = meth:return_type_get(func_type.METHOD) - - local proto = { - name = meth:name_get() - } - proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void" - local args, cargs, vargs = { "self" }, {}, {} - proto.args, proto.cargs, proto.vargs = args, cargs, vargs - local rets = {} - proto.rets = rets - local allocs = {} - proto.allocs = allocs - - proto.full_name = meth:full_c_name_get(func_type.METHOD) - - local fulln = proto.full_name - - if rett then - rets[#rets + 1] = typeconv(rett, "v", false) - end - - for v in pars do - local dir, tps, nm = v:direction_get(), v:type_get(), kw_t(v:name_get()) - local tp = tps:c_type_get(eolian.c_type_type.PARAM) - if dir == param_dir.OUT or dir == param_dir.INOUT then - if dir == param_dir.INOUT then - args[#args + 1] = nm - end - cargs [#cargs + 1] = tp .. " *" .. nm - vargs [#vargs + 1] = nm - allocs[#allocs + 1] = { tp, nm, (dir == param_dir.INOUT) - and typeconv(tps, nm, true) or nil } - rets [#rets + 1] = typeconv(tps, nm .. "[0]", false) - else - args [#args + 1] = nm - cargs [#cargs + 1] = tp .. " " .. nm - vargs [#vargs + 1] = typeconv(tps, nm, true) - end - end - - if #cargs == 0 then cargs[1] = "void" end - - self.cached_proto = proto - - return proto - end, - - generate = function(self, s, last) - local proto = self:gen_proto() - s:write(" ", proto.name, proto.suffix or "", " = function(", - table.concat(proto.args, ", "), ")\n") - s:write( " eo.__do_start(self, __class)\n") - for i, v in ipairs(proto.allocs) do - s:write(" local ", v[2], " = ffi.new(\"", v[1], "[1]\")\n") - end - local genv = (proto.ret_type ~= "void") - s:write(" ", genv and "local v = " or "", "__lib.", - proto.full_name, "(", table.concat(proto.vargs, ", "), ")\n") - s:write(" eo.__do_end()\n") - if #proto.rets > 0 then - s:write(" return ", table.concat(proto.rets, ", "), "\n") - end - s:write(" end", last and "" or ",", last and "\n" or "\n\n") - end, - - gen_ffi = function(self, s) - local proto = self:gen_proto() - local ret = proto.ret_type - if ret:match("[a-zA-Z0-9_]$") then - ret = ret .. " " - end - local cproto = { - " ", ret, proto.full_name, "(", table.concat(proto.cargs, ", "), - ");\n" - } - s:write(table.concat(cproto)) - end -} - -local Property = Method:clone { - __ctor = function(self, prop, ftype) - self.property = prop - self.isget = (ftype == func_type.PROP_GET) - self.ftype = ftype - end, - - gen_proto = function(self) - if self.cached_proto then return self.cached_proto end - - local prop = self.property - local keys = prop:property_keys_get(self.ftype):to_array() - local vals = prop:property_values_get(self.ftype):to_array() - local rett = prop:return_type_get(self.ftype) - - local proto = { - name = prop:name_get(), - suffix = (self.isget and "_get" or "_set"), - nkeys = #keys, - nvals = #vals - } - proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void" - local args, cargs, vargs = { "self" }, {}, {} - proto.args, proto.cargs, proto.vargs = args, cargs, vargs - local rets = {} - proto.rets = rets - local allocs = {} - proto.allocs = allocs - - proto.full_name = prop:full_c_name_get(self.ftype) - - local fulln = proto.full_name - if #keys > 0 then - for i, v in ipairs(keys) do - local nm = kw_t(v:name_get()) - local tps = v:type_get() - local tp = tps:c_type_get(eolian.c_type_type.PARAM) - args [#args + 1] = nm - cargs[#cargs + 1] = tp .. " " .. nm - vargs[#vargs + 1] = typeconv(tps, nm, true) - end - end - proto.kprop = #keys > 0 - - if #vals > 0 then - if self.isget then - if #vals == 1 and not rett then - local tps = vals[1]:type_get() - proto.ret_type = tps:c_type_get(eolian.c_type_type.PARAM) - rets[#rets + 1] = typeconv(tps, "v", false) - else - for i, v in ipairs(vals) do - local dir, tps, nm = v:direction_get(), v:type_get(), - kw_t(v:name_get()) - local tp = tps:c_type_get(eolian.c_type_type.PARAM) - cargs [#cargs + 1] = tp .. " *" .. nm - vargs [#vargs + 1] = nm - allocs[#allocs + 1] = { tp, nm } - rets [#rets + 1] = typeconv(tps, nm .. "[0]", false) - end - end - else - for i, v in ipairs(vals) do - local dir, tps, nm = v:direction_get(), v:type_get(), - kw_t(v:name_get()) - local tp = tps:c_type_get(eolian.c_type_type.PARAM) - args [#args + 1] = nm - cargs[#cargs + 1] = tp .. " " .. nm - vargs[#vargs + 1] = typeconv(tps, nm, true) - end - end - end - - if #cargs == 0 then cargs[1] = "void" end - - self.cached_proto = proto - - return proto - end, - - generate_prop = function(self, props) - local proto = self:gen_proto() - local prop = props[proto.name] - local hasprop = true - if not prop then - prop = { 0, 0, 0, 0, "false", "false" } - props[proto.name] = prop - hasprop = false - end - if self.isget then - prop[1] = proto.nkeys - prop[3] = math.max(proto.nvals, 1) - prop[5] = "true" - else - prop[2] = proto.nkeys - prop[4] = math.max(proto.nvals, 1) - prop[6] = "true" - end - return not hasprop - end -} - -local Event = Node:clone { - __ctor = function(self, ename, etype, ecname) - self.ename = ename - self.etype = etype - self.ecname = ecname - end, - - generate = function(self, s, last) - s:write(" [\"", self.ename, "\"] = __lib.", - "_" .. self.ecname, last and "\n" or ",\n") - end, - - gen_ffi = function(self, s) - s:write(" extern const Eo_Event_Description ", - "_" .. self.ecname, ";\n") - end -} - -local gen_ns = function(klass, s) - local nspaces = klass:namespaces_get():to_array() - if #nspaces > 1 then - local lnspaces = {} - for i = 2, #nspaces do - lnspaces[i - 1] = '"' .. nspaces[i]:lower() .. '"' - end - s:write("local __M = util.get_namespace(M, { ", - table.concat(lnspaces, ", "), " })\n") - return "__M" - else - return "M" - end -end - -local Mixin = Node:clone { - __ctor = function(self, iface, klass, ch, evs) - self.klass = klass - self.children = ch - self.events = evs - self.iface = iface - end, - - generate = function(self, s) - dom:log(log.level.INFO, " Generating for interface/mixin: " - .. self.klass:name_get()) - - s:write("ffi.cdef [[\n") - self:gen_ffi(s) - s:write("]]\n\n") - - gen_ns(self.klass, s) - - s:write("__body = {\n") - self:gen_children(s) - s:write("}\n") - - local knu = self.klass:name_get():gsub("%.", "_") - if not self.iface then - s:write(("__body[\"__mixin_%s\"] = true\n"):format(knu)) - else - s:write(("__body[\"__iface_%s\"] = true\n"):format(knu)) - end - end, - - gen_ffi = function(self, s) - s:write(" const Eo_Class *", self.klass:c_get_function_name_get(), - "(void);\n") - for i, v in ipairs(self.children) do - v.parent_node = self - v:gen_ffi(s) - end - if self.events then - for i, v in ipairs(self.events) do - v.parent_node = self - v:gen_ffi(s) - end - end - end -} - -local build_pn = function(fn, pn) - if fn == pn then - return kw_t(pn) - end - return fn .. "_" .. pn -end - -local Class = Node:clone { - __ctor = function(self, klass, parents, mixins, ch, evs) - self.klass = klass - self.parents = parents - self.interfaces = interfaces - self.mixins = mixins - self.children = ch - self.events = evs - end, - - generate = function(self, s) - dom:log(log.level.INFO, " Generating for class: " - .. self.klass:name_get()) - - s:write("ffi.cdef [[\n") - self:gen_ffi(s) - s:write("]]\n\n") - - local mname = gen_ns(self.klass, s) - - s:write("__body = {\n") - self:gen_ctor(s) - self:gen_children(s) - s:write("}\n") - - -- write the constructor - s:write(([[ - -%s.%s = function(parent, ...) - return eo.__ctor_common(__class, parent, eo.class_get("%s").__eo_ctor, - 1, ...) -end -]]):format(mname, self.klass:short_name_get(), self.klass:name_get():gsub("%.", - "_"))) - end, - - gen_ffi = Mixin.gen_ffi, - - gen_ctor = function(self, s) - local ctors = self.klass:constructors_get() - if not ctors then return end - -- collect constructor information - s:write(" __eo_ctor = function(self, ") - local cfuncs, parnames, upars = {}, {}, {} - for ctor in ctors do - local cfunc = ctor:function_get() - local cn = cfunc:name_get() - local tp = cfunc:type_get() - if tp == func_type.PROPERTY or tp == func_type.PROP_SET - or tp == func_type.METHOD then - cfuncs[#cfuncs + 1] = cfunc - if tp ~= func_type.METHOD then - for par in cfunc:property_keys_get(func_type.PROP_SET) do - parnames[#parnames + 1] = build_pn(cn, par:name_get()) - end - end - local iter = (tp ~= func_type.METHOD) - and cfunc:property_values_get(func_type.PROP_SET) - or cfunc:parameters_get() - for par in iter do - if par:direction_get() ~= param_dir.OUT then - parnames[#parnames + 1] = build_pn(cn, par:name_get()) - end - end - end - end - s:write(table.concat(parnames, ", ")) - if #parnames == 0 then - s:write("__func") - else - s:write(", __func") - end - s:write(")\n") - -- write ctor body - local j = 1 - for i, cfunc in ipairs(cfuncs) do - local tp = cfunc:type_get() - s:write(" self:", cfunc:name_get()) - if cfunc:type_get() ~= func_type.METHOD then - s:write("_set") - end - s:write("(") - local fpars = {} - if tp ~= func_type.METHOD then - for par in cfunc:property_keys_get(func_type.PROP_SET) do - fpars[#fpars + 1] = parnames[j] - j = j + 1 - end - end - local iter = (tp ~= func_type.METHOD) - and cfunc:property_values_get(func_type.PROP_SET) - or cfunc:parameters_get() - for par in iter do - if par:direction_get() ~= param_dir.OUT then - fpars[#fpars + 1] = parnames[j] - j = j + 1 - end - end - s:write(table.concat(fpars, ", ")) - s:write(")\n") - end - s:write(" if __func then __func() end\n") - s:write(" end") - if #self.children > 0 then - s:write(",\n\n") - else - s:write("\n") - end - end -} - -local File = Node:clone { - __ctor = function(self, fname, klass, ch) - self.fname = fname:match(".+/(.+)") or fname - self.klass = klass - self.children = ch - end, - - generate = function(self, s) - local kls = self.klass - local ckls = self.children[1] - - local kn = kls:name_get() - - dom:log(log.level.INFO, "Generating for file: " .. self.fname) - dom:log(log.level.INFO, " Class : " .. kn) - - local knu = kn:gsub("%.", "_") - - local pars = ckls.parents or {} - local mins = ckls.mixins or {} - - -- serialize both - local pv = {} - local mv = {} - for i = 1, #pars do pv[i] = '"' .. pars[i]:gsub("%.", "_") .. '"' end - for i = 1, #mins do mv[i] = '"' .. mins[i]:gsub("%.", "_") .. '"' end - pars = (#pars > 0) and ("{" .. table.concat(pv, ", ") .. "}") or "nil" - mins = (#mins > 0) and ("{" .. table.concat(mv, ", ") .. "}") or "nil" - - s:write(([[ --- EFL LuaJIT bindings: %s (class %s) --- For use with Elua; automatically generated, do not modify - -local cutil = require("cutil") -local util = require("util") -local ffi = require("ffi") -local eo = require("eo") - -local M, __lib = ... - -local __class -local __body - -local init = function() - __class = __lib.%s() - eo.class_register("%s", %s, %s, __body, __class) -end - -cutil.init_module(init, function() end) - -]]):format(self.fname, kn, kls:c_get_function_name_get(), knu, pars, mins)) - - self:gen_children(s) - - s:write([[ - -return M -]]) - - local first = true - for name, v in pairs(convfuncs) do - if first then - print("\nRequired conversion functions:") - first = false - end - print(" " .. name) - end - end -} - -local gen_contents = function(klass) - local cnt = {} - -- first try properties - local props = klass:functions_get(func_type.PROPERTY):to_array() - for i, v in ipairs(props) do - local gscope = v:scope_get(func_type.PROP_GET) - local sscope = v:scope_get(func_type.PROP_SET) - if (gscope == obj_scope.PUBLIC or sscope == obj_scope.PUBLIC) then - local ftype = v:type_get() - local fread = (ftype == func_type.PROPERTY or ftype == func_type.PROP_GET) - local fwrite = (ftype == func_type.PROPERTY or ftype == func_type.PROP_SET) - if fwrite and sscope == obj_scope.PUBLIC then - cnt[#cnt + 1] = Property(v, func_type.PROP_SET) - end - if fread and gscope == obj_scope.PUBLIC then - cnt[#cnt + 1] = Property(v, func_type.PROP_GET) - end - end - end - -- then methods - local meths = klass:functions_get(func_type.METHOD):to_array() - for i, v in ipairs(meths) do - if v:scope_get(func_type.METHOD) == obj_scope.PUBLIC then - cnt[#cnt + 1] = Method(v) - end - end - -- events - local evs = {} - local events = klass:events_get():to_array() - for i, v in ipairs(events) do - evs[#evs + 1] = Event(v:name_get(), v:type_get(), v:c_name_get()) - end - return cnt, evs -end - -local gen_class = function(klass) - local tp = klass:type_get() - if tp == class_type.UNKNOWN then - error(klass:name_get() .. ": unknown type") - elseif tp == class_type.MIXIN or tp == class_type.INTERFACE then - return Mixin(tp == class_type.INTERFACE, klass, gen_contents(klass)) - end - local inherits = klass:inherits_get():to_array() - -- figure out the correct lookup order - local parents = {} - local mixins = {} -- also includes ifaces, they're separated later - for i = 1, #inherits do - local tp = inherits[i]:type_get() - if tp == class_type.REGULAR or tp == class_type.ABSTRACT then - parents[#parents + 1] = v - elseif tp == class_type.INTERFACE or tp == class_type.MIXIN then - mixins[#mixins + 1] = v - else - error(klass:name_get() .. ": unknown inherit " .. v) - end - end - return Class(klass, parents, mixins, gen_contents(klass)) -end - -M.include_dir = function(dir) - if not get_state():directory_add(dir) then - error("Failed including directory: " .. dir) - end -end - -M.load_eot_files = function() - return get_state():all_eot_files_parse() -end - -M.system_directory_add = function() - return get_state():system_directory_add() -end - -M.generate = function(fname, fstream) - local unit = get_state():file_parse(fname) - if unit == nil then - error("Failed parsing file: " .. fname) - end - gen_unit = unit - local sfn = fname:match(".*[\\/](.+)$") or fname - local klass = get_state():class_by_file_get(sfn) - File(fname, klass, { gen_class(klass) }):generate(fstream or io.stdout) -end - -return M