From patchwork Wed Aug 14 05:26:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Karsten Sperling X-Patchwork-Id: 1972192 X-Patchwork-Delegate: hauke@hauke-m.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=cfcTQ/p2; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.openwrt.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WkGy44G1kz1ygB for ; Wed, 14 Aug 2024 15:28:42 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type:List-Help: Reply-To:List-Archive:List-Unsubscribe:List-Subscribe:From:List-Post:List-Id: Message-ID:MIME-Version:To:Date:Subject:Cc:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=9xBOkLGsYxN/4D0sAbxoC3osHBocD/lAmoL9CgDw1OA=; b=cfcTQ/p2PahMfCK3J6yS6pYtjA gspWadViNpod3ioDkeY0iX4PrYAzm0y6DRnsYL0H3+qYvbmQkekpo6NhRRd2FdJgIa/Kc1uBkL5s3 57MfTTHrAw7oUM2yQfWkrolc9oQY7gy9PpOVGHZBbg/6RgQdtVEq6pdzvhisLmZQd4YtC7MwusJDC lqg2FddNVCR5X+W+dLe1kfbzLlV1d8BBKGz9CfGSc4jU1B8QiwX9QTIUc6bN494eJAOPjS9sCBiyS YAjn9v5brncjUd+SQMw+0MI6MoI2T3A8xHXCX6WWmIaqcnM5mbMYvjC/ojj0zT1P0aO4SHXU8vU1/ 1v9Tovrg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1se6XW-00000005ngF-1aAr; Wed, 14 Aug 2024 05:27:18 +0000 Subject: [PATCH] libubus: Make UBUS_* macros work cleanly in C++ Date: Wed, 14 Aug 2024 17:26:13 +1200 To: openwrt-devel@lists.openwrt.org MIME-Version: 1.0 Message-ID: List-Id: OpenWrt Development List List-Post: X-Patchwork-Original-From: Karsten Sperling via openwrt-devel From: Karsten Sperling Precedence: list X-Mailman-Version: 2.1.34 X-BeenThere: openwrt-devel@lists.openwrt.org List-Subscribe: , List-Unsubscribe: , List-Archive: Reply-To: Karsten Sperling List-Help: Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org The sender domain has a DMARC Reject/Quarantine policy which disallows sending mailing list messages using the original "From" header. To mitigate this problem, the original message has been wrapped automatically by the mailing list software. Note: I’ve also submitted this patch as a GitHub PR (https://github.com/openwrt/ubus/pull/3) but I’m not sure anyone actually looks there for contributions, so I’m submitting it as a patch here as well. -- >8 -- C++ is picky about initializer order, and (depending on flags) missing fields. This fix makes UBUS_METHOD_* and UBUS_OBJECT_TYPE initialize all fields of the respective structs in the correct order, making those macros usable from C++. Also replace BIT(x) with an explicit expression since BIT() may not be defined. Signed-off-by: Karsten Sperling --- CMakeLists.txt | 9 +++++---- libubus.h | 41 +++++++++++++++++++++------------------- tests/CMakeLists.txt | 11 +++++++++++ tests/test-cplusplus.cpp | 34 +++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 tests/test-cplusplus.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ae853b..03c3012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,12 +2,13 @@ cmake_minimum_required(VERSION 3.13) PROJECT(ubus C) -ADD_DEFINITIONS(-Wall -Werror) +ADD_COMPILE_OPTIONS(-Wall -Werror) IF(CMAKE_C_COMPILER_VERSION VERSION_GREATER 6) - ADD_DEFINITIONS(-Wextra -Werror=implicit-function-declaration) - ADD_DEFINITIONS(-Wformat -Werror=format-security -Werror=format-nonliteral) + ADD_COMPILE_OPTIONS(-Wextra -Wformat -Werror=format-security -Werror=format-nonliteral) + ADD_COMPILE_OPTIONS($<$:-Werror=implicit-function-declaration>) ENDIF() -ADD_DEFINITIONS(-Os -std=gnu99 -g3 -Wmissing-declarations -Wno-unused-parameter) +ADD_COMPILE_OPTIONS(-Os -g3 -Wmissing-declarations -Wno-unused-parameter) +ADD_COMPILE_OPTIONS($<$:-std=gnu99>) OPTION(BUILD_LUA "build Lua plugin" ON) OPTION(BUILD_EXAMPLES "build examples" ON) diff --git a/libubus.h b/libubus.h index b74a823..fcf62c8 100644 --- a/libubus.h +++ b/libubus.h @@ -69,41 +69,44 @@ typedef bool (*ubus_new_object_handler_t)(struct ubus_context *ctx, struct ubus_ { \ .name = _name, \ .id = 0, \ - .n_methods = ARRAY_SIZE(_methods), \ - .methods = _methods \ + .methods = _methods, \ + .n_methods = ARRAY_SIZE(_methods) \ } -#define __UBUS_METHOD_NOARG(_name, _handler, _tags) \ - .name = _name, \ - .handler = _handler, \ +#define __UBUS_METHOD_BASE(_name, _handler, _mask, _tags) \ + .name = _name, \ + .handler = _handler, \ + .mask = _mask, \ .tags = _tags -#define __UBUS_METHOD(_name, _handler, _policy, _tags) \ - __UBUS_METHOD_NOARG(_name, _handler, _tags), \ - .policy = _policy, \ +#define __UBUS_METHOD_NOARG(_name, _handler, _mask, _tags) \ + __UBUS_METHOD_BASE(_name, _handler, _mask, _tags), \ + .policy = NULL, \ + .n_policy = 0 + +#define __UBUS_METHOD(_name, _handler, _mask, _policy, _tags) \ + __UBUS_METHOD_BASE(_name, _handler, _mask, _tags), \ + .policy = _policy, \ .n_policy = ARRAY_SIZE(_policy) #define UBUS_METHOD(_name, _handler, _policy) \ - { __UBUS_METHOD(_name, _handler, _policy, 0) } + { __UBUS_METHOD(_name, _handler, 0, _policy, 0) } #define UBUS_METHOD_TAG(_name, _handler, _policy, _tags)\ - { __UBUS_METHOD(_name, _handler, _policy, _tags) } + { __UBUS_METHOD(_name, _handler, 0, _policy, _tags) } #define UBUS_METHOD_MASK(_name, _handler, _policy, _mask) \ - { \ - __UBUS_METHOD(_name, _handler, _policy, 0),\ - .mask = _mask \ - } + { __UBUS_METHOD(_name, _handler, _mask, _policy, 0) } #define UBUS_METHOD_NOARG(_name, _handler) \ - { __UBUS_METHOD_NOARG(_name, _handler, 0) } + { __UBUS_METHOD_NOARG(_name, _handler, 0, 0) } #define UBUS_METHOD_TAG_NOARG(_name, _handler, _tags) \ - { __UBUS_METHOD_NOARG(_name, _handler, _tags) } + { __UBUS_METHOD_NOARG(_name, _handler, 0, _tags) } -#define UBUS_TAG_STATUS BIT(0) -#define UBUS_TAG_ADMIN BIT(1) -#define UBUS_TAG_PRIVATE BIT(2) +#define UBUS_TAG_STATUS (1ul << 0) +#define UBUS_TAG_ADMIN (1ul << 1) +#define UBUS_TAG_PRIVATE (1ul << 2) struct ubus_method { const char *name; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0cb3342..5549a40 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,6 +6,12 @@ MACRO(ADD_UNIT_TEST name) TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR}) ENDMACRO(ADD_UNIT_TEST) +MACRO(ADD_UNIT_TEST_CPP name) + ADD_EXECUTABLE(${name} ${name}.cpp) + TARGET_LINK_LIBRARIES(${name} ubox blobmsg_json json_script ${json}) + TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR}) +ENDMACRO(ADD_UNIT_TEST_CPP) + FILE(GLOB test_cases "test-*.c") FOREACH(test_case ${test_cases}) GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE) @@ -13,6 +19,11 @@ FOREACH(test_case ${test_cases}) ADD_UNIT_TEST_SAN(${test_case}) ENDFOREACH(test_case) +ENABLE_LANGUAGE(CXX) +ADD_COMPILE_OPTIONS($<$:-std=gnu++11>) +ADD_UNIT_TEST_CPP(test-cplusplus) +ADD_TEST(NAME cplusplus COMMAND test-cplusplus) + IF(CMAKE_C_COMPILER_ID STREQUAL "Clang") ADD_SUBDIRECTORY(fuzz) ENDIF() diff --git a/tests/test-cplusplus.cpp b/tests/test-cplusplus.cpp new file mode 100644 index 0000000..89c5ffb --- /dev/null +++ b/tests/test-cplusplus.cpp @@ -0,0 +1,34 @@ +#include "libubus.h" + +// Ensure UBUS_* macros can be used from C++ + +static int handler(ubus_context *, ubus_object *, ubus_request_data *, const char *, blob_attr *) +{ + return 0; +} + +enum { + HELLO_ID, + HELLO_MSG, +}; + +constexpr blobmsg_policy hello_policy[] = { + [HELLO_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 }, + [HELLO_MSG] = { .name = "msg", .type = BLOBMSG_TYPE_STRING }, +}; + +constexpr ubus_method test_methods[] = { + UBUS_METHOD("hello1", handler, hello_policy), + UBUS_METHOD_TAG("hello2", handler, hello_policy, UBUS_TAG_ADMIN | UBUS_TAG_PRIVATE), + UBUS_METHOD_MASK("hello3", handler, hello_policy, 0), + UBUS_METHOD_NOARG("hello4", handler), + UBUS_METHOD_TAG_NOARG("hello5", handler, UBUS_TAG_STATUS), +}; + +constexpr ubus_object_type test_object_type = UBUS_OBJECT_TYPE("test", test_methods); + +int main() +{ + (void) test_object_type; + return 0; +}