[PATCH] libubus: Add UBUS_OBJECT() macro
Karsten Sperling
ksperling at apple.com
Mon Jun 8 17:14:03 PDT 2026
Especially in C++ (where depending on compiler settings, field order and
completeness is enforced), initializing an ubus_object is a little tedious.
Introduce an UBUS_OBJECT() macro that can be used to initialize an
ubus_object with a name and type.
The n_methods field is set to -1 to signal to ubus_add_object() that
methods should be copied from the object type (if they haven't been changed
in the meantime). Copying them from the type in UBUS_OBJECT() directly is
not desirable because it would make for a non-constant initializer.
The cpptest now compiles with c++20 so the test can enforce constinit.
Signed-off-by: Karsten Sperling <ksperling at apple.com>
---
examples/server.c | 8 ++------
libubus-obj.c | 5 +++++
libubus.h | 13 +++++++++++++
tests/CMakeLists.txt | 2 +-
tests/test-cplusplus.cpp | 5 +++--
5 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/examples/server.c b/examples/server.c
index 0913fff..42ce3f7 100644
--- a/examples/server.c
+++ b/examples/server.c
@@ -204,12 +204,8 @@ static const struct ubus_method test_methods[] = {
static struct ubus_object_type test_object_type =
UBUS_OBJECT_TYPE("test", test_methods);
-static struct ubus_object test_object = {
- .name = "test",
- .type = &test_object_type,
- .methods = test_methods,
- .n_methods = ARRAY_SIZE(test_methods),
-};
+static struct ubus_object test_object =
+ UBUS_OBJECT("test", test_object_type);
static void server_main(void)
{
diff --git a/libubus-obj.c b/libubus-obj.c
index 4a56110..1fb2ff6 100644
--- a/libubus-obj.c
+++ b/libubus-obj.c
@@ -233,6 +233,11 @@ int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)
return UBUS_STATUS_INVALID_ARGUMENT;
}
+ if (obj->n_methods < 0 && obj->type) { /* initialized via UBUS_OBJECT() */
+ obj->methods = obj->type->methods;
+ obj->n_methods = obj->type->n_methods;
+ }
+
if (ubus_start_request(ctx, &req, b.head, UBUS_MSG_ADD_OBJECT, 0) < 0)
return UBUS_STATUS_INVALID_ARGUMENT;
diff --git a/libubus.h b/libubus.h
index 4f33339..787ea4d 100644
--- a/libubus.h
+++ b/libubus.h
@@ -108,6 +108,19 @@ typedef bool (*ubus_new_object_handler_t)(struct ubus_context *ctx, struct ubus_
#define UBUS_TAG_ADMIN (1ul << 1)
#define UBUS_TAG_PRIVATE (1ul << 2)
+#define UBUS_OBJECT(_name, _type) \
+ { \
+ .avl = {}, \
+ .name = _name, \
+ .id = 0, \
+ .path = NULL, \
+ .type = &(_type), \
+ .subscribe_cb = NULL, \
+ .has_subscribers = false, \
+ .methods = NULL, \
+ .n_methods = -1 \
+ }
+
struct ubus_method {
const char *name;
ubus_handler_t handler;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index f0900e9..14ab660 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -22,7 +22,7 @@ FOREACH(test_case ${test_cases})
ENDFOREACH(test_case)
ENABLE_LANGUAGE(CXX)
-ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:-std=gnu++11>)
+ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:CXX>:-std=gnu++20>)
ADD_UNIT_TEST_CPP(test-cplusplus)
ADD_TEST(NAME cplusplus COMMAND test-cplusplus)
diff --git a/tests/test-cplusplus.cpp b/tests/test-cplusplus.cpp
index 89c5ffb..441a913 100644
--- a/tests/test-cplusplus.cpp
+++ b/tests/test-cplusplus.cpp
@@ -25,10 +25,11 @@ constexpr ubus_method test_methods[] = {
UBUS_METHOD_TAG_NOARG("hello5", handler, UBUS_TAG_STATUS),
};
-constexpr ubus_object_type test_object_type = UBUS_OBJECT_TYPE("test", test_methods);
+constinit ubus_object_type test_object_type = UBUS_OBJECT_TYPE("test", test_methods);
+constinit ubus_object test_object = UBUS_OBJECT("testobj", test_object_type);
int main()
{
- (void) test_object_type;
+ (void) test_object;
return 0;
}
--
2.50.1 (Apple Git-155)
More information about the openwrt-devel
mailing list