diff --git a/include/common/mir/constexpr_utils.h b/include/common/mir/constexpr_utils.h
new file mode 100644
index 00000000000..65020772d5f
--- /dev/null
+++ b/include/common/mir/constexpr_utils.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 or 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#ifndef MIR_CONSTEXPR_UTILS_H_
+#define MIR_CONSTEXPR_UTILS_H_
+
+#include
+
+namespace mir
+{
+inline constexpr std::size_t strlen_c(std::string_view str)
+{
+ return str.size();
+}
+}
+
+#endif
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index a43479daba1..a79a018961b 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -49,6 +49,7 @@ add_library(mircommon SHARED
${PROJECT_SOURCE_DIR}/include/common/mir/input/mir_touchscreen_config.h
${PROJECT_SOURCE_DIR}/include/common/mir/input/mir_keyboard_config.h
${PROJECT_SOURCE_DIR}/include/common/mir/input/keyboard_leds.h
+ ${PROJECT_SOURCE_DIR}/include/common/mir/constexpr_utils.h
${MIR_COMMON_SOURCES}
)
diff --git a/src/miral/display_configuration_option.cpp b/src/miral/display_configuration_option.cpp
index d835a73360f..f6cadd06898 100644
--- a/src/miral/display_configuration_option.cpp
+++ b/src/miral/display_configuration_option.cpp
@@ -17,6 +17,7 @@
#include
#include "static_display_config.h"
+#include
#include
#include
#include
@@ -226,13 +227,13 @@ void miral::display_configuration_options(mir::Server& server)
{
layout_selector = std::make_shared();
}
- else if (display_layout.compare(0, strlen(static_opt_val), static_opt_val) == 0)
+ else if (display_layout.compare(0, mir::strlen_c(static_opt_val), static_opt_val) == 0)
{
if (scale != 1.0)
{
mir::fatal_error("Display scale option can't be used with static display configuration");
}
- auto sdc = std::make_shared(display_layout.substr(strlen(static_opt_val)));
+ auto sdc = std::make_shared(display_layout.substr(mir::strlen_c(static_opt_val)));
server.add_init_callback([sdc, &server]{ sdc->init_auto_reload(server); });
layout_selector = std::move(sdc);
}
@@ -249,7 +250,7 @@ void miral::display_configuration_options(mir::Server& server)
mir::fatal_error("Display scale option can't be used with autoscale");
}
- if (display_layout.compare(0, strlen(static_opt_val), static_opt_val) == 0)
+ if (display_layout.compare(0, mir::strlen_c(static_opt_val), static_opt_val) == 0)
{
mir::fatal_error("Display autoscale option can't be used with static display configuration");
}
diff --git a/src/platform/options/default_configuration.cpp b/src/platform/options/default_configuration.cpp
index 5899b2bf98c..6d2e9fe9ed2 100644
--- a/src/platform/options/default_configuration.cpp
+++ b/src/platform/options/default_configuration.cpp
@@ -16,12 +16,13 @@
#include
+#include
+#include
+#include
+#include
#include
#include
-#include
-#include
#include
-#include
#include
#include
@@ -573,7 +574,7 @@ void mo::DefaultConfiguration::parse_environment(
[=, this](std::string const& from) -> std::string
{
auto const prefix = "MIR_SERVER_";
- auto const sizeof_prefix = strlen(prefix);
+ auto const sizeof_prefix = strlen_c(prefix);
if (!from.starts_with(prefix))
{
diff --git a/src/platforms/evdev/platform.cpp b/src/platforms/evdev/platform.cpp
index 0d4f9123f0c..816b99eb019 100644
--- a/src/platforms/evdev/platform.cpp
+++ b/src/platforms/evdev/platform.cpp
@@ -19,12 +19,13 @@
#include "libinput_ptr.h"
#include "fd_store.h"
-#include
+#include
+#include
#include
#include
#include
#include
-#include
+#include
#include
#include
@@ -310,7 +311,7 @@ void mie::Platform::start()
std::string devnode{workaround_device->devnode()};
// Libinput filters out anything without “event” as its name
- if (strncmp(workaround_device->sysname(), "event", strlen("event")) != 0)
+ if (strncmp(workaround_device->sysname(), "event", strlen_c("event")) != 0)
{
return;
}
diff --git a/src/platforms/gbm-kms/server/kms/platform_symbols.cpp b/src/platforms/gbm-kms/server/kms/platform_symbols.cpp
index 51e40f8bae3..3ad666c0677 100644
--- a/src/platforms/gbm-kms/server/kms/platform_symbols.cpp
+++ b/src/platforms/gbm-kms/server/kms/platform_symbols.cpp
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include "one_shot_device_observer.h"
#include
#include
@@ -452,7 +453,7 @@ auto probe_rendering_platform(
if (strncmp(
"llvmpipe",
renderer_string,
- strlen("llvmpipe")) == 0)
+ mir::strlen_c("llvmpipe")) == 0)
{
mir::log_info("Detected software renderer: %s", renderer_string);
// Leave the priority at ::unsupported; if we've got a software renderer then
diff --git a/src/server/console/linux_virtual_terminal.cpp b/src/server/console/linux_virtual_terminal.cpp
index 3eebcfb3963..4efe26f5c36 100644
--- a/src/server/console/linux_virtual_terminal.cpp
+++ b/src/server/console/linux_virtual_terminal.cpp
@@ -15,11 +15,13 @@
*/
#include "linux_virtual_terminal.h"
+#include "ioctl_vt_switcher.h"
+
+#include
+#include
+#include
#include
#include
-#include
-#include
-#include "ioctl_vt_switcher.h"
#include
#include
@@ -658,9 +660,9 @@ std::future> mir::LinuxVirtualTerminal::acquire_dev
while (uevent.getline(line_buffer, sizeof(line_buffer)))
{
- if (strncmp(line_buffer, "DEVNAME=", strlen("DEVNAME=")) == 0)
+ if (strncmp(line_buffer, "DEVNAME=", strlen_c("DEVNAME=")) == 0)
{
- return std::string{"/dev/"} + std::string{line_buffer + strlen("DEVNAME=")};
+ return std::string{"/dev/"} + std::string{line_buffer + strlen_c("DEVNAME=")};
}
}
BOOST_THROW_EXCEPTION((std::runtime_error{"Failed to read DEVNAME"}));
diff --git a/src/server/console/logind_console_services.cpp b/src/server/console/logind_console_services.cpp
index 1054f491410..f5d5aff953c 100644
--- a/src/server/console/logind_console_services.cpp
+++ b/src/server/console/logind_console_services.cpp
@@ -27,9 +27,10 @@
#include "logind-session.h"
+#include
#include
-#include
#include
+#include
#define MIR_LOG_COMPONTENT "logind"
#include
@@ -265,7 +266,7 @@ mir::LogindConsoleServices::LogindConsoleServices(
session_path.c_str())},
switch_away{[](){ return true; }},
switch_to{[](){ return true; }},
- active{strncmp("active", logind_session_get_state(session_proxy.get()), strlen("active")) == 0}
+ active{strncmp("active", logind_session_get_state(session_proxy.get()), strlen_c("active")) == 0}
{
GErrorPtr error;
@@ -789,7 +790,7 @@ GDBusMessage* mir::LogindConsoleServices::resume_device_dbus_filter(
return message;
// …if it's a signal, but it's not ResumeDevice, we don't need to process it.
- if (strncmp(g_dbus_message_get_member(message), "ResumeDevice", strlen("ResumeDevice")) != 0)
+ if (strncmp(g_dbus_message_get_member(message), "ResumeDevice", strlen_c("ResumeDevice")) != 0)
return message;
// We've definitely got a ResumeDevice signal! Now to extract the parameters, and
diff --git a/src/server/console/minimal_console_services.cpp b/src/server/console/minimal_console_services.cpp
index e8a99660448..a3c4e2211c7 100644
--- a/src/server/console/minimal_console_services.cpp
+++ b/src/server/console/minimal_console_services.cpp
@@ -16,6 +16,7 @@
#include "minimal_console_services.h"
+#include
#include
#include
@@ -104,9 +105,9 @@ std::future> mir::MinimalConsoleServices::acquire_d
while (uevent.getline(line_buffer, sizeof(line_buffer)))
{
- if (strncmp(line_buffer, "DEVNAME=", strlen("DEVNAME=")) == 0)
+ if (strncmp(line_buffer, "DEVNAME=", strlen_c("DEVNAME=")) == 0)
{
- return std::string{"/dev/"} + std::string{line_buffer + strlen("DEVNAME=")};
+ return std::string{"/dev/"} + std::string{line_buffer + strlen_c("DEVNAME=")};
}
}
BOOST_THROW_EXCEPTION((std::runtime_error{"Failed to read DEVNAME"}));
diff --git a/src/server/frontend_wayland/foreign_toplevel_manager_v1.cpp b/src/server/frontend_wayland/foreign_toplevel_manager_v1.cpp
index 237f24f6cdc..db26e9d381b 100644
--- a/src/server/frontend_wayland/foreign_toplevel_manager_v1.cpp
+++ b/src/server/frontend_wayland/foreign_toplevel_manager_v1.cpp
@@ -18,17 +18,19 @@
#include "wayland_utils.h"
#include "desktop_file_manager.h"
-#include
+
+#include
+#include
#include
-#include
-#include
+#include
+#include
#include
#include
#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
#include
#include
@@ -579,9 +581,10 @@ void mf::GDesktopFileCache::refresh_app_cache()
// It is likely that [id] ends in a .desktop suffix. If that's the case, we will strip
// it out since that isn't useful in this context.
+
const char* const desktop_suffix = ".desktop";
if (id.ends_with(desktop_suffix))
- id.erase(id.length() - strlen(desktop_suffix));
+ id.erase(id.length() - strlen_c(desktop_suffix));
std::shared_ptr file = std::make_shared(id.c_str(), wm_class, exec);
if (g_app_info_should_show(app_info))
diff --git a/tests/mir_test_doubles/mock_drm.cpp b/tests/mir_test_doubles/mock_drm.cpp
index 9fe006d2460..ae852b5111b 100644
--- a/tests/mir_test_doubles/mock_drm.cpp
+++ b/tests/mir_test_doubles/mock_drm.cpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
@@ -235,7 +236,7 @@ mtd::MockDRM::MockDRM()
[this](char const* path, int flags, std::optional) -> std::optional
{
char const* const drm_prefix = "/dev/dri/";
- if (!strncmp(path, drm_prefix, strlen(drm_prefix)))
+ if (!strncmp(path, drm_prefix, strlen_c(drm_prefix)))
{
// I don't think we need to be able to distinguish based on mode. ppc64el (at least) *does*
// call the 3-parameter open()
@@ -373,11 +374,11 @@ mtd::MockDRM::MockDRM()
1,
2,
3,
- static_cast(strlen("mock_driver")),
+ static_cast(strlen_c("mock_driver")),
const_cast("mock_driver"),
- static_cast(strlen("1 Jan 1970")),
+ static_cast(strlen_c("1 Jan 1970")),
const_cast("1 Jan 1970"),
- static_cast(strlen("Not really a driver")),
+ static_cast(strlen_c("Not really a driver")),
const_cast("Not really a driver")
};
ON_CALL(*this, drmGetVersion(_))
diff --git a/tests/unit-tests/console/test_linux_virtual_terminal.cpp b/tests/unit-tests/console/test_linux_virtual_terminal.cpp
index 206c2ec6af7..4739f012e5c 100644
--- a/tests/unit-tests/console/test_linux_virtual_terminal.cpp
+++ b/tests/unit-tests/console/test_linux_virtual_terminal.cpp
@@ -16,9 +16,10 @@
#include "src/server/console/linux_virtual_terminal.h"
#include "src/server/report/null_report_factory.h"
-#include
#include
+#include
#include
+#include
#include
#include
@@ -791,7 +792,7 @@ std::string uevent_content_for_device(
{
std::stringstream content;
- if (strncmp(device_name, "/dev/", strlen("/dev/")) != 0)
+ if (strncmp(device_name, "/dev/", mir::strlen_c("/dev/")) != 0)
{
throw std::logic_error{"device_name is expected to be the fully-qualified /dev/foo path"};
}
@@ -799,7 +800,7 @@ std::string uevent_content_for_device(
content
<< "MAJOR=" << major << "\n"
<< "MINOR=" << minor << "\n"
- << "DEVNAME=" << device_name + strlen ("/dev/") << "\n";
+ << "DEVNAME=" << device_name + mir::strlen_c("/dev/") << "\n";
return content.str();
}
@@ -931,8 +932,8 @@ TEST_F(LinuxVirtualTerminalTest, throws_error_when_parsing_fails)
"MINOR=61\n"
"I_AINT_NO_DEVNAME=fb0";
- mir::AnonymousShmFile uevent{strlen(uevent_content)};
- ::memcpy(uevent.base_ptr(), uevent_content, strlen(uevent_content));
+ mir::AnonymousShmFile uevent{mir::strlen_c(uevent_content)};
+ ::memcpy(uevent.base_ptr(), uevent_content, mir::strlen_c(uevent_content));
EXPECT_CALL(*fops, open(StrEq(expected_filename), FlagsSet(O_RDONLY, O_CLOEXEC)))
.WillOnce(Return(uevent.fd()));
diff --git a/tests/unit-tests/console/test_minimal_console_services.cpp b/tests/unit-tests/console/test_minimal_console_services.cpp
index 52aae6511a4..bd7e7501351 100644
--- a/tests/unit-tests/console/test_minimal_console_services.cpp
+++ b/tests/unit-tests/console/test_minimal_console_services.cpp
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
@@ -42,7 +43,7 @@ std::string uevent_content_for_device(
{
std::stringstream content;
- if (strncmp(device_name, "/dev/", strlen("/dev/")) != 0)
+ if (strncmp(device_name, "/dev/", mir::strlen_c("/dev/")) != 0)
{
throw std::logic_error{"device_name is expected to be the fully-qualified /dev/foo path"};
}
@@ -50,7 +51,7 @@ std::string uevent_content_for_device(
content
<< "MAJOR=" << major << "\n"
<< "MINOR=" << minor << "\n"
- << "DEVNAME=" << device_name + strlen ("/dev/") << "\n";
+ << "DEVNAME=" << device_name + mir::strlen_c("/dev/") << "\n";
return content.str();
}
@@ -276,7 +277,7 @@ TEST_F(MinimalConsoleServicesTest, failure_to_open_sys_file_results_in_immediate
auto error_on_device_open = mtf::add_open_handler(
[](char const* path, int, std::optional) -> std::optional
{
- if (!strncmp("/sys", path, strlen("/sys")))
+ if (!strncmp("/sys", path, mir::strlen_c("/sys")))
{
errno = EINVAL;
return {-1};