Skip to content

Commit

Permalink
sdbus++: change binding namespace format
Browse files Browse the repository at this point in the history
Change the generated binding namespace name such that the interface
`xyz.openbmc_project.Foo` becomes
`sdbusplus::server::xyz::openbmc_project::Foo` instead of
`sdbusplus::xyz::openbmc_project::server::Foo`.  This both simplifies
the namespace generation and makes the correlation from interface to
binding name much more obvious.

An alias namespace to the old name is still generated so that users
have a chance to migrate.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Id82a5b6dcb26be8644b04bf14ddaf8a58dad8479
  • Loading branch information
williamspatrick committed Apr 21, 2023
1 parent a412ca8 commit 5011340
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 72 deletions.
4 changes: 2 additions & 2 deletions example/calculator-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <string_view>

using Calculator_inherit =
sdbusplus::server::object_t<sdbusplus::net::poettering::server::Calculator>;
sdbusplus::server::object_t<sdbusplus::server::net::poettering::Calculator>;

/** Example implementation of net.poettering.Calculator */
struct Calculator : Calculator_inherit
Expand Down Expand Up @@ -56,7 +56,7 @@ int main()

static_assert(
std::string_view(
sdbusplus::net::poettering::client::Calculator::interface) ==
sdbusplus::client::net::poettering::Calculator::interface) ==
std::string_view(Calculator::interface));

// Create a new bus and affix an object manager for the subtree path we
Expand Down
33 changes: 5 additions & 28 deletions tools/sdbusplus/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,49 +31,26 @@ def __init__(self, **kwargs):

super(Interface, self).__init__(**kwargs)

self.namespaces = self.name.split(".")
self.classname = self.namespaces.pop()

def cppNamespace(self, typename="server"):
return "::".join(self.namespaces) + "::" + typename

def cppNamespacedClass(self, typename="server"):
return self.cppNamespace(typename) + "::" + self.classname

def joinedName(self, join_str, append):
return join_str.join(self.namespaces + [self.classname, append])

def enum_includes(self, inc_list):
includes = []
namespaces = []
for e in inc_list:
namespaces.extend(e.enum_namespaces(self.name))
for e in sorted(set(namespaces)):
es = e.split("::")
# Skip empty, non-enum values and self references like '::'
if len(es) < 2:
continue
# All elements will be formatted (x::)+
# If the requested enum is xyz.openbmc_project.Network.IP.Protocol
# for a server_* configuration, the enum_namespace will be
# xyz::openbmc_project::Network::server::IP:: and we need to
# convert to xyz/openbmc_project/Network/IP/server.hpp
es.pop() # Remove trailing empty element
e_class = es.pop() # Remove class name
e_type = es.pop() # Remove injected type namespace
es.append(e_class)
es.append(e_type)
includes.append("/".join(es) + ".hpp")
return includes
includes.extend(e.enum_headers(self.name, self.typename))
return sorted(set(includes))

def markdown(self, loader):
return self.render(loader, "interface.md.mako", interface=self)

def server_header(self, loader):
self.typename = "server"
return self.render(loader, "interface.server.hpp.mako", interface=self)

def server_cpp(self, loader):
self.typename = "server"
return self.render(loader, "interface.server.cpp.mako", interface=self)

def client_header(self, loader):
self.typename = "client"
return self.render(loader, "interface.client.hpp.mako", interface=self)
22 changes: 22 additions & 0 deletions tools/sdbusplus/namedelement.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ def __init__(self, **kwargs):
"missing quotes around original name."
)

self.old_namespaces = self.name.split(".")
self.old_classname = self.old_namespaces.pop()
self.namespaces = [
inflection.underscore(x) for x in self.old_namespaces
]
self.classname = inflection.camelize(self.old_classname)

def __getattribute__(self, name):
lam = {
"CamelCase": lambda: inflection.camelize(self.name),
Expand All @@ -32,6 +39,21 @@ def __getattribute__(self, name):
% (name, self.__module__)
)

def old_cppNamespace(self, typename="server"):
return "::".join(self.old_namespaces) + "::" + typename

def old_cppNamespacedClass(self, typename="server"):
return self.old_cppNamespace(typename) + "::" + self.old_classname

def headerFile(self, typename):
return self.name.replace(".", "/") + f"/{typename}.hpp"

def cppNamespace(self):
return "::".join(self.namespaces)

def cppNamespacedClass(self):
return self.cppNamespace() + "::" + self.classname

""" Some names are reserved in some languages. Fixup names to avoid using
reserved words.
"""
Expand Down
56 changes: 31 additions & 25 deletions tools/sdbusplus/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,19 @@ def is_floating_point(self):
Currently only 'enum' requires conversion.
"""

def cppTypeParam(self, interface, full=False, server=True):
return self.__cppTypeParam(interface, self.cppTypeName, full, server)
def cppTypeParam(self, interface, full=False, typename="server"):
return self.__cppTypeParam(interface, self.cppTypeName, full, typename)

def default_value(self):
if self.defaultValue is not None:
return " = " + str(self.defaultValue)
else:
return ""

def __cppTypeParam(self, interface, cppTypeName, full=False, server=True):
ns_type = "server" if server else "client"

iface = interface.split(".")
iface.insert(-1, ns_type)
iface = "::".join(iface)
iface = "sdbusplus::" + iface

def __cppTypeParam(
self, interface, cppTypeName, full=False, typename="server"
):
iface = NamedElement(name=interface).cppNamespacedClass()
r = cppTypeName

# Fix up local enum placeholders.
Expand All @@ -109,27 +105,29 @@ def __cppTypeParam(self, interface, cppTypeName, full=False, server=True):
r = r.replace(self.LOCAL_ENUM_MAGIC + "::", "")

# Fix up non-local enum placeholders.
r = r.replace(self.NONLOCAL_ENUM_MAGIC, ns_type)
r = r.replace(self.NONLOCAL_ENUM_MAGIC, typename)

return r

""" Determine the C++ namespaces of an enumeration-type property.
""" Determine the C++ header of an enumeration-type property.
"""

def enum_namespaces(self, interface):
def enum_headers(self, interface, typename="server"):
typeTuple = self.__type_tuple()
return self.__enum_namespaces(interface, typeTuple)
return self.__enum_headers(interface, typeTuple, typename)

def __enum_namespaces(self, interface, typeTuple):
def __enum_headers(self, interface, typeTuple, typename):
# Enums can be processed directly.
if "enum" == typeTuple[0]:
cppType = self.__cppTypeParam(
interface, self.__parse_cpp_type__(typeTuple)
)
ns = cppType.split("::")[0:-1]
if len(ns) != 0:
return ["::".join(ns) + "::"]
return []
# Get enum type from typeTuple.
enumType = typeTuple[1][0][0]

# Local enums don't need a header.
if "self." in enumType:
return []

enumType = ".".join(enumType.split(".")[0:-1])
return [NamedElement(name=enumType).headerFile(typename)]

# If the details part of the tuple has zero entries, no enums are
# present
Expand All @@ -140,7 +138,7 @@ def __enum_namespaces(self, interface, typeTuple):
# them recursively.
r = []
for t in typeTuple[1]:
r.extend(self.__enum_namespaces(interface, t))
r.extend(self.__enum_headers(interface, t, typename))
return r

""" Convert the property type into a C++ type.
Expand Down Expand Up @@ -271,8 +269,16 @@ def __parse_cpp_type__(self, typeTuple):

# Insert place-holder for header-type namespace (ex. "server")
result = result.split(".")
result.insert(-2, self.NONLOCAL_ENUM_MAGIC)
result = "::".join(result)
result = "::".join(
[
"sdbusplus",
self.NONLOCAL_ENUM_MAGIC,
NamedElement(
name=".".join(result[0:-1])
).cppNamespacedClass(),
NamedElement(name=result[-1]).classname,
]
)
return result

# Parse each parameter entry, if appropriate, and create C++ template
Expand Down
13 changes: 11 additions & 2 deletions tools/sdbusplus/templates/interface.client.hpp.mako
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
#pragma once

namespace sdbusplus::${interface.cppNamespacedClass("client")}
namespace sdbusplus::client::${interface.cppNamespacedClass()}
{

static constexpr auto interface = "${interface.name}";

} // namespace sdbusplus::${interface.cppNamespacedClass("client")}
} // namespace sdbusplus::client::${interface.cppNamespacedClass()}

#ifndef SDBUSPP_REMOVE_DEPRECATED_NAMESPACE
namespace sdbusplus::${interface.old_cppNamespacedClass("client")}
{

using sdbusplus::client::${interface.cppNamespacedClass()}::interface;

} // namespace sdbusplus::${interface.old_cppNamespacedClass("client")}
#endif
15 changes: 8 additions & 7 deletions tools/sdbusplus/templates/interface.server.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
#include <string>
#include <tuple>

#include <${interface.joinedName("/", "server.hpp")}>
#include <${interface.headerFile("server")}>
% for m in interface.methods + interface.properties + interface.signals:
${ m.cpp_prototype(loader, interface=interface, ptype='callback-cpp-includes') }
% endfor
namespace sdbusplus::${interface.cppNamespace()}
namespace sdbusplus::server::${interface.cppNamespace()}
{

% for m in interface.methods:
Expand Down Expand Up @@ -72,8 +72,8 @@ mapping${interface.classname}${e.name}[] =

} // anonymous namespace

auto ${interface.classname}::convertStringTo${e.name}(const std::string& s) noexcept ->
std::optional<${e.name}>
auto ${interface.classname}::convertStringTo${e.name}(
const std::string& s) noexcept -> std::optional<${e.name}>
{
auto i = std::find_if(
std::begin(mapping${interface.classname}${e.name}),
Expand All @@ -90,7 +90,7 @@ auto ${interface.classname}::convertStringTo${e.name}(const std::string& s) noex
}

auto ${interface.classname}::convert${e.name}FromString(const std::string& s) ->
${e.name}
${e.name}
{
auto r = convertStringTo${e.name}(s);

Expand All @@ -104,7 +104,8 @@ auto ${interface.classname}::convert${e.name}FromString(const std::string& s) ->
}
}

std::string ${interface.classname}::convert${e.name}ToString(${interface.classname}::${e.name} v)
std::string ${interface.classname}::convert${e.name}ToString(
${interface.classname}::${e.name} v)
{
auto i = std::find_if(
std::begin(mapping${interface.classname}${e.name}),
Expand Down Expand Up @@ -143,4 +144,4 @@ ${ s.cpp_prototype(loader, interface=interface, ptype='vtable') }
vtable::end()
};

} // namespace sdbusplus::${interface.cppNamespace()}
} // namespace sdbusplus::server::${interface.cppNamespace()}
30 changes: 23 additions & 7 deletions tools/sdbusplus/templates/interface.server.hpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ${ m.cpp_prototype(loader, interface=interface, ptype='callback-hpp-includes') }
interface.properties);
%>

namespace sdbusplus::${interface.cppNamespace()}
namespace sdbusplus::server::${interface.cppNamespace()}
{

class ${interface.classname}
Expand Down Expand Up @@ -208,26 +208,42 @@ inline std::string convertForMessage(${interface.classname}::${e.name} e)
}
% endfor

} // namespace sdbusplus::${interface.cppNamespace()}
} // namespace sdbusplus::server::${interface.cppNamespace()}

#ifndef SDBUSPP_REMOVE_DEPRECATED_NAMESPACE
namespace sdbusplus::${interface.old_cppNamespace()} {

using sdbusplus::server::${interface.cppNamespacedClass()};
% if interface.enums:
using sdbusplus::server::${interface.cppNamespace()}::convertForMessage;
% endif

} // namespace sdbusplus::${interface.old_cppNamespace()}
#endif

namespace sdbusplus::message::details
{
% for e in interface.enums:
template <>
struct convert_from_string<${interface.cppNamespacedClass()}::${e.name}>
struct convert_from_string<
server::${interface.cppNamespacedClass()}::${e.name}>
{
static auto op(const std::string& value) noexcept
{
return ${interface.cppNamespacedClass()}::convertStringTo${e.name}(value);
return server::
${interface.cppNamespacedClass()}::convertStringTo${e.name}(value);
}
};

template <>
struct convert_to_string<${interface.cppNamespacedClass()}::${e.name}>
struct convert_to_string<
server::${interface.cppNamespacedClass()}::${e.name}>
{
static std::string op(${interface.cppNamespacedClass()}::${e.name} value)
static std::string op(
server::${interface.cppNamespacedClass()}::${e.name} value)
{
return ${interface.cppNamespacedClass()}::convert${e.name}ToString(value);
return server::
${interface.cppNamespacedClass()}::convert${e.name}ToString(value);
}
};
% endfor
Expand Down
2 changes: 1 addition & 1 deletion tools/sdbusplus/templates/signal.prototype.hpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
void ${interface.classname}::${ signal.camelCase }(
${ parameters() })
{
auto& i = _${"_".join(interface.name.split('.'))}_interface;
auto& i = _${interface.joinedName("_", "interface")};
auto m = i.new_signal("${ signal.name }");

m.append(${ parameters_as_list() });
Expand Down

0 comments on commit 5011340

Please sign in to comment.