1
Fork 0
cdbus/cdbus-codegen

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