160 lines
4.9 KiB
Lua
Executable File
160 lines
4.9 KiB
Lua
Executable File
#!/usr/bin/env lua
|
|
-- cdbus-codegen - generate cdbus bindings from dbus xml files
|
|
-- SPDX-FileCopyrightText: Copyright © 2023 Nedko Arnaudov
|
|
-- SPDX-License-Identifier: GPL-3
|
|
|
|
local lxp = require('lxp')
|
|
local table = require('table')
|
|
|
|
interfaces = {}
|
|
|
|
local interface
|
|
local callable
|
|
|
|
cdbus_codegen = {}
|
|
|
|
cdbus_codegen.StartElement = function (parser, name, attr)
|
|
if (name == "interface") then
|
|
interface = {}
|
|
interface.name = attr['name']
|
|
-- interface.attr = attr
|
|
-- for k, v in pairs(attr) do print(" ", k, v1) end
|
|
end
|
|
if (name == "method") then
|
|
callable = {}
|
|
callable.typestr = name
|
|
callable.name = attr['name']:gsub("%s+", "")
|
|
--print("method", interface.name, callable.name)
|
|
--for k, v in pairs(attr) do print(" ", k, v1) end
|
|
end
|
|
if (name == "signal") then
|
|
callable = {}
|
|
callable.typestr = name
|
|
callable.name = attr['name']
|
|
--print("signal", interface.name, signal.name)
|
|
end
|
|
local arg
|
|
if (name == "arg") then
|
|
arg = {}
|
|
if attr.name then arg.name = attr.name end
|
|
arg.type = attr.type
|
|
arg.direction = attr.direction
|
|
--print(" arg", arg.name, arg.type, arg.direction)
|
|
callable.args = callable.args or {}
|
|
callable.args[#callable.args + 1] = arg
|
|
end
|
|
end
|
|
|
|
cdbus_codegen.EndElement = function (parser, name)
|
|
if (name == "interface") then
|
|
interfaces[interface.name] = interface
|
|
interface = nil
|
|
end
|
|
if (name == "method") then
|
|
interface.methods = interface.methods or {}
|
|
interface.methods[#interface.methods + 1] = callable
|
|
interface.callables = interface.callables or {}
|
|
interface.callables[#interface.callables + 1] = callable
|
|
callable = nil
|
|
end
|
|
if (name == "signal") then
|
|
interface.signals = interface.signals or {}
|
|
interface.signals[#interface.signals + 1] = callable
|
|
interface.callables = interface.callables or {}
|
|
interface.callables[#interface.callables + 1] = callable
|
|
callable = nil
|
|
end
|
|
end
|
|
|
|
p = lxp.new(cdbus_codegen)
|
|
|
|
for l in io.lines() do -- iterate lines
|
|
p:parse(l) -- parses the line
|
|
-- p:parse("\n") -- parses the end of line
|
|
end
|
|
p:parse() -- finishes the document
|
|
p:close() -- closes the parser
|
|
|
|
for name, iface in pairs(interfaces) do
|
|
--print(("interface: \"%s\""):format(name))
|
|
for _, callable in pairs(iface.callables) do
|
|
local rettype
|
|
local argtokens = {}
|
|
if callable.args then
|
|
for _, arg in ipairs(callable.args) do
|
|
if not arg.name and arg.direction == "out" then
|
|
rettype = arg.type
|
|
else
|
|
argtokens[#argtokens + 1] = ("%s %s %s"):format(arg.name, arg.type, arg.direction)
|
|
end
|
|
end
|
|
end
|
|
if callable.typestr == "method" then rettype = "void" end
|
|
if rettype then rettype = " => " .. rettype else rettype = "" end
|
|
--print(("%s %s(%s)%s"):format(callable.typestr, callable.name, table.concat(argtokens, ", "), rettype))
|
|
end
|
|
end
|
|
|
|
print("/* This data is GENERATED from D-Bus interface description XML")
|
|
print(" * Edit by hand only if you know what you are doing */")
|
|
print()
|
|
|
|
namespace = tostring(arg[1]) .. "_cdbus_"
|
|
|
|
for name, iface in pairs(interfaces) do
|
|
for _, callable in pairs(iface.callables) do
|
|
local typestr2
|
|
local direction2
|
|
if callable.typestr == "method" then
|
|
typestr2 = "METHOD"
|
|
elseif callable.typestr == "signal" then
|
|
typestr2 = "SIGNAL"
|
|
end
|
|
print(("CDBUS_%s_ARGS_BEGIN(%s, \"\")"):format(typestr2, callable.name))
|
|
if callable.args then
|
|
for _, arg in ipairs(callable.args) do
|
|
if arg.name then
|
|
if callable.typestr == "method" then
|
|
typestr2 = "METHOD"
|
|
direction2 = "_" .. arg.direction:upper()
|
|
elseif callable.typestr == "signal" then
|
|
typestr2 = "SIGNAL"
|
|
direction2 = ""
|
|
end
|
|
print((" CDBUS_%s_ARG_DESCRIBE%s(\"%s\", \"%s\", \"\")"): format(typestr2, direction2, arg.name, arg.type))
|
|
end
|
|
end
|
|
end
|
|
print(("CDBUS_%s_ARGS_END"):format(typestr2))
|
|
print()
|
|
end
|
|
|
|
print("CDBUS_METHODS_BEGIN")
|
|
for _, method in ipairs(iface.methods) do
|
|
print("CDBUS_METHOD_DESCRIBE(" .. method.name .. ", " .. namespace .. method.name .. "_dbus)")
|
|
end
|
|
print("CDBUS_METHODS_END")
|
|
print()
|
|
|
|
if iface.signals then
|
|
print("CDBUS_SIGNALS_BEGIN")
|
|
for _, signal in ipairs(iface.signals) do
|
|
print("CDBUS_SIGNAL_DESCRIBE(" .. signal.name .. ")")
|
|
end
|
|
print("CDBUS_SIGNALS_END")
|
|
end
|
|
print()
|
|
|
|
local iface_varname = namespace .. "interface_" .. iface.name:gsub("%.", "_")
|
|
local iface_name_define = namespace:upper() .. "IFACE_" .. iface.name:gsub("%.", "_"):upper()
|
|
|
|
print("#define " .. iface_name_define .. " \"" .. iface.name .. "\"")
|
|
print()
|
|
|
|
if not iface.signals then
|
|
print(("CDBUS_INTERFACE_DEFAULT_HANDLER_METHODS_ONLY(%s, %s)"):format(iface_varname, iface_name_define))
|
|
else
|
|
print(("CDBUS_INTERFACE_DEFAULT_HANDLER_METHODS_AND_SIGNALS(%s, %s)"):format(iface_varname, iface_name_define))
|
|
end
|
|
end
|