From 985700c79dd80c6f4937e29774efe322a4505f9c Mon Sep 17 00:00:00 2001 From: Alexander Shaduri Date: Thu, 7 Mar 2024 14:38:44 +0400 Subject: [PATCH] Moved to C++23, making the code compatible with it (u8string / u8path incompatibilities). --- CMakeLists.txt | 2 +- data/cmake/FindFilesystem.cmake | 2 +- src/applib/app_builder_widget.h | 2 +- src/applib/command_executor_gui.cpp | 4 ++-- src/applib/smartctl_executor.cpp | 2 +- src/applib/storage_detector_win32.cpp | 2 +- src/applib/storage_device.cpp | 2 +- src/build_config/compiler_options.cmake | 4 ++-- src/gsc_add_device_window.cpp | 4 ++-- src/gsc_executor_log_window.cpp | 4 ++-- src/gsc_info_window.cpp | 2 +- src/gsc_init.cpp | 4 ++-- src/gsc_main_window.cpp | 6 +++--- src/gsc_main_window_iconview.h | 4 ++-- src/gsc_preferences_window.cpp | 4 ++-- src/gsc_text_window.h | 2 +- src/hz/fs.h | 20 ++++++++++++++++++++ src/hz/string_algo.h | 24 ++++++++++++++++++++++++ 18 files changed, 69 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 241ab11..b683279 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ ############################################################################### # License: BSD Zero Clause License file # Copyright: -# (C) 2021 Alexander Shaduri +# (C) 2021 - 2024 Alexander Shaduri ############################################################################### # 3.14 for proper object library support (wrt linking) diff --git a/data/cmake/FindFilesystem.cmake b/data/cmake/FindFilesystem.cmake index e925a9f..57c9868 100644 --- a/data/cmake/FindFilesystem.cmake +++ b/data/cmake/FindFilesystem.cmake @@ -129,7 +129,7 @@ cmake_push_check_state() set(CMAKE_REQUIRED_QUIET ${Filesystem_FIND_QUIETLY}) # All of our tests required C++17 or later -set(CMAKE_CXX_STANDARD 17) +#set(CMAKE_CXX_STANDARD 17) # Normalize and check the component list we were given set(want_components ${Filesystem_FIND_COMPONENTS}) diff --git a/src/applib/app_builder_widget.h b/src/applib/app_builder_widget.h index 228624a..433684f 100644 --- a/src/applib/app_builder_widget.h +++ b/src/applib/app_builder_widget.h @@ -140,7 +140,7 @@ std::shared_ptr AppBuilderWidget::creat auto ui_path = hz::data_file_find("ui", std::string(Child::ui_name) + ".glade"); try { - auto ui = Gtk::Builder::create_from_file(ui_path.u8string()); // may throw + auto ui = Gtk::Builder::create_from_file(hz::fs_path_to_string(ui_path)); // may throw Child* raw_obj = nullptr; ui->get_widget_derived({Child::ui_name.data(), Child::ui_name.size()}, raw_obj); // Calls Child's constructor diff --git a/src/applib/command_executor_gui.cpp b/src/applib/command_executor_gui.cpp index 55cb49c..56e59b0 100644 --- a/src/applib/command_executor_gui.cpp +++ b/src/applib/command_executor_gui.cpp @@ -18,7 +18,7 @@ Copyright: #include "hz/string_algo.h" #include "hz/fs_ns.h" #include "command_executor_gui.h" - +#include "hz/fs.h" @@ -134,7 +134,7 @@ void CommandExecutorGui::set_running_dialog_abort_mode(bool aborting) } else if (!aborting) { std::string msg = hz::string_replace_copy(get_running_msg(), "{command}", - hz::fs::u8path(this->get_command_name()).filename().u8string()); + hz::fs_path_to_string(hz::fs::u8path(this->get_command_name()).filename())); running_dialog_->set_message("\n " + msg + " "); // running_dialog_->set_response_sensitive(Gtk::RESPONSE_CANCEL, true); diff --git a/src/applib/smartctl_executor.cpp b/src/applib/smartctl_executor.cpp index c2528b4..5d76c28 100644 --- a/src/applib/smartctl_executor.cpp +++ b/src/applib/smartctl_executor.cpp @@ -115,7 +115,7 @@ std::string execute_smartctl(const std::string& device, const std::string& devic device_specific_options += " "; - smartctl_ex->set_command(Glib::shell_quote(smartctl_binary.u8string()), + smartctl_ex->set_command(Glib::shell_quote(hz::fs_path_to_string(smartctl_binary)), smartctl_def_options + device_specific_options + command_options + " " + Glib::shell_quote(device)); diff --git a/src/applib/storage_detector_win32.cpp b/src/applib/storage_detector_win32.cpp index 3fa8664..92fe8db 100644 --- a/src/applib/storage_detector_win32.cpp +++ b/src/applib/storage_detector_win32.cpp @@ -206,7 +206,7 @@ std::string get_scan_open_multiport_devices(std::vector& drive if (!smartctl_def_options.empty()) smartctl_def_options += " "; - smartctl_ex->set_command(Glib::shell_quote(smartctl_binary.u8string()), + smartctl_ex->set_command(Glib::shell_quote(hz::fs_path_to_string(smartctl_binary)), smartctl_def_options + "--scan-open"); if (!smartctl_ex->execute() || !smartctl_ex->get_error_msg().empty()) { diff --git a/src/applib/storage_device.cpp b/src/applib/storage_device.cpp index e9eec41..623563c 100644 --- a/src/applib/storage_device.cpp +++ b/src/applib/storage_device.cpp @@ -685,7 +685,7 @@ hz::fs::path StorageDevice::get_virtual_file() const std::string StorageDevice::get_virtual_filename() const { - return (is_virtual_ ? virtual_file_.filename().u8string() : std::string()); + return (is_virtual_ ? hz::fs_path_to_string(virtual_file_.filename()) : std::string()); } diff --git a/src/build_config/compiler_options.cmake b/src/build_config/compiler_options.cmake index 2e77fb4..2193398 100644 --- a/src/build_config/compiler_options.cmake +++ b/src/build_config/compiler_options.cmake @@ -1,7 +1,7 @@ ############################################################################### # License: BSD Zero Clause License file # Copyright: -# (C) 2021 Alexander Shaduri +# (C) 2021 - 2024 Alexander Shaduri ############################################################################### # This file is included from root CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/data/cmake/") # --- Set the default C++ standard -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) # C++17 filesystem (including experimental) diff --git a/src/gsc_add_device_window.cpp b/src/gsc_add_device_window.cpp index b7bd01d..d8efe41 100644 --- a/src/gsc_add_device_window.cpp +++ b/src/gsc_add_device_window.cpp @@ -180,7 +180,7 @@ void GscAddDeviceWindow::on_device_name_browse_button_clicked() &g_object_unref); if (path.is_absolute()) - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog.get()), path.u8string().c_str()); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog.get()), hz::fs_path_to_string(path).c_str()); result = gtk_native_dialog_run(GTK_NATIVE_DIALOG(dialog.get())); @@ -194,7 +194,7 @@ void GscAddDeviceWindow::on_device_name_browse_button_clicked() // Note: This works on absolute paths only (otherwise it's gtk warning). if (path.is_absolute()) - dialog.set_filename(path.u8string()); // change to its dir and select it if exists. + dialog.set_filename(hz::fs_path_to_string(path)); // change to its dir and select it if exists. // Show the dialog and wait for a user response result = dialog.run(); // the main cycle blocks here diff --git a/src/gsc_executor_log_window.cpp b/src/gsc_executor_log_window.cpp index 470718b..0d4a190 100644 --- a/src/gsc_executor_log_window.cpp +++ b/src/gsc_executor_log_window.cpp @@ -250,7 +250,7 @@ void GscExecutorLogWindow::on_window_save_current_button_clicked() hz::fs::path file; #if GTK_CHECK_VERSION(3, 20, 0) file = hz::fs::u8path(app_string_from_gchar(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog.get())))); - last_dir = file.parent_path().u8string(); + last_dir = hz::fs_path_to_string(file.parent_path()); #else file = hz::fs::u8path(dialog.get_filename()); // in fs encoding last_dir = dialog.get_current_folder(); // save for the future @@ -368,7 +368,7 @@ void GscExecutorLogWindow::on_window_save_all_button_clicked() hz::fs::path file; #if GTK_CHECK_VERSION(3, 20, 0) file = hz::fs::u8path(app_string_from_gchar(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog.get())))); - last_dir = file.parent_path().u8string(); + last_dir = hz::fs_path_to_string(file.parent_path()); #else file = hz::fs::u8path(dialog.get_filename()); // in fs encoding last_dir = dialog.get_current_folder(); // save for the future diff --git a/src/gsc_info_window.cpp b/src/gsc_info_window.cpp index 86a3019..60345df 100644 --- a/src/gsc_info_window.cpp +++ b/src/gsc_info_window.cpp @@ -771,7 +771,7 @@ void GscInfoWindow::on_save_info_button_clicked() hz::fs::path file; #if GTK_CHECK_VERSION(3, 20, 0) file = hz::fs::u8path(app_string_from_gchar(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog.get())))); - last_dir = file.parent_path().u8string(); + last_dir = hz::fs_path_to_string(file.parent_path()); #else file = hz::fs::u8path(dialog.get_filename()); // in fs encoding last_dir = dialog.get_current_folder(); // save for the future diff --git a/src/gsc_init.cpp b/src/gsc_init.cpp index 1d9521e..1566fa1 100644 --- a/src/gsc_init.cpp +++ b/src/gsc_init.cpp @@ -105,9 +105,9 @@ namespace { global_config_file = hz::fs::u8path(BuildEnv::package_sysconf_dir()) / "gsmartcontrol2.conf"; } - debug_out_dump("app", DBG_FUNC_MSG << "Global config file: \"" << global_config_file.u8string() << "\"\n"); + debug_out_dump("app", DBG_FUNC_MSG << "Global config file: \"" << hz::fs_path_to_string(global_config_file) << "\"\n"); debug_out_dump("app", - DBG_FUNC_MSG << "Local config file: \"" << get_home_config_file().u8string() << "\"\n"); + DBG_FUNC_MSG << "Local config file: \"" << hz::fs_path_to_string(get_home_config_file()) << "\"\n"); // load global first std::error_code ec; diff --git a/src/gsc_main_window.cpp b/src/gsc_main_window.cpp index edbeddc..2e6905b 100644 --- a/src/gsc_main_window.cpp +++ b/src/gsc_main_window.cpp @@ -84,7 +84,7 @@ GscMainWindow::GscMainWindow(BaseObjectType* gtkcobj, Glib::RefPtr bool show_output_button = true; do { - std::string smartctl_binary = get_smartctl_binary().u8string(); + std::string smartctl_binary = hz::fs_path_to_string(get_smartctl_binary()); // Don't use default options here - they are used when invoked // with a device option. @@ -1088,7 +1088,7 @@ void GscMainWindow::run_update_drivedb() if (smartctl_binary.is_absolute()) { update_binary_path = smartctl_binary.parent_path() / update_binary_path; } - std::string update_binary = Glib::shell_quote(update_binary_path.u8string()); + std::string update_binary = Glib::shell_quote(hz::fs_path_to_string(update_binary_path)); if constexpr(!BuildEnv::is_kernel_family_windows()) { // X11 update_binary = "xterm -hold -e " + update_binary; @@ -1356,7 +1356,7 @@ void GscMainWindow::show_load_virtual_file_chooser() files = dialog.get_filenames(); // in fs encoding #endif if (!files.empty()) { - last_dir = hz::fs::u8path(files.front()).parent_path().u8string(); + last_dir = hz::fs_path_to_string(hz::fs_path_from_string(files.front()).parent_path()); } rconfig::set_data("gui/drive_data_open_save_dir", last_dir); for (const auto& file : files) { diff --git a/src/gsc_main_window_iconview.h b/src/gsc_main_window_iconview.h index 90887f0..b37b2da 100644 --- a/src/gsc_main_window_iconview.h +++ b/src/gsc_main_window_iconview.h @@ -117,7 +117,7 @@ class GscMainWindowIconView : public Gtk::IconView { auto icon_file = hz::data_file_find("icons", "icon_hdd.png"); if (!icon_file.empty()) { try { - hd_icon = Gdk::Pixbuf::create_from_file(icon_file.u8string()); + hd_icon = Gdk::Pixbuf::create_from_file(hz::fs_path_to_string(icon_file)); } catch (...) { } // ignore exceptions } } @@ -132,7 +132,7 @@ class GscMainWindowIconView : public Gtk::IconView { auto icon_file = hz::data_file_find("icons", "icon_cddvd.png"); if (!icon_file.empty()) { try { - cddvd_icon = Gdk::Pixbuf::create_from_file(icon_file.u8string()); + cddvd_icon = Gdk::Pixbuf::create_from_file(hz::fs_path_to_string(icon_file)); } catch (...) { } // ignore exceptions } } diff --git a/src/gsc_preferences_window.cpp b/src/gsc_preferences_window.cpp index 8608670..f27db0a 100644 --- a/src/gsc_preferences_window.cpp +++ b/src/gsc_preferences_window.cpp @@ -536,7 +536,7 @@ void GscPreferencesWindow::on_smartctl_binary_browse_button_clicked() &g_object_unref); if (path.is_absolute()) - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog.get()), path.u8string().c_str()); + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog.get()), hz::fs_path_to_string(path).c_str()); if constexpr(BuildEnv::is_kernel_family_windows()) { gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog.get()), specific_filter->gobj()); @@ -560,7 +560,7 @@ void GscPreferencesWindow::on_smartctl_binary_browse_button_clicked() // Note: This works on absolute paths only (otherwise it's gtk warning). if (path.is_absolute()) - dialog.set_filename(path.u8string()); // change to its dir and select it if exists. + dialog.set_filename(hz::fs_path_to_string(path)); // change to its dir and select it if exists. // Show the dialog and wait for a user response result = dialog.run(); // the main cycle blocks here diff --git a/src/gsc_text_window.h b/src/gsc_text_window.h index dc82540..92cf5b0 100644 --- a/src/gsc_text_window.h +++ b/src/gsc_text_window.h @@ -214,7 +214,7 @@ class GscTextWindow : public AppBuilderWidget, Ins hz::fs::path file; #if GTK_CHECK_VERSION(3, 20, 0) file = hz::fs::u8path(app_string_from_gchar(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog.get())))); - last_dir = file.parent_path().u8string(); + last_dir = hz::fs_path_to_string(file.parent_path()); #else file = hz::fs::u8path(dialog.get_filename()); // in fs encoding last_dir = dialog.get_current_folder(); // save for the future diff --git a/src/hz/fs.h b/src/hz/fs.h index 0dc21fc..78660d6 100644 --- a/src/hz/fs.h +++ b/src/hz/fs.h @@ -41,6 +41,7 @@ Copyright: #include "fs_ns.h" #include "whereami.h" +#include "string_algo.h" /// \def HAVE_POSIX_OFF_T_FUNCS @@ -97,6 +98,25 @@ namespace hz { +/// Same as std::filesystem::path::u8string(), but returns std::string with UTF-8 data. +/// This is needed because since C++20, std::filesystem::path::u8string() returns std::u8string +/// instead of std::string, which is what is often desired for compatibility. +inline std::string fs_path_to_string(const fs::path& p) +{ + return u8string_to_string(p.u8string()); +} + + + +/// Same as std::filesystem::u8path(std::string), which is deprecated since C++20. +inline fs::path fs_path_from_string(std::string_view u8str) +{ + return fs::path(u8string_from_string(u8str)); +} + + + + /// Platform-dependent fopen(). Sets errno on error. inline std::FILE* fs_platform_fopen(const fs::path& file, const char* open_mode) { diff --git a/src/hz/string_algo.h b/src/hz/string_algo.h index f96413f..754d78d 100644 --- a/src/hz/string_algo.h +++ b/src/hz/string_algo.h @@ -22,6 +22,30 @@ namespace hz { +// --------------------------------------------- UTF8 + +/// Since C++20, std::filesystem::path::u8string() returns std::u8string instead of std::string. +/// This introduces incompatibility. We always assume that std::string contains utf-8 data, +/// So these conversion functions assume the same. + + +/// Convert std::u8string_view to UTF-8-containing std::string +inline std::string u8string_to_string(std::u8string_view u8str) +{ + return std::string(reinterpret_cast(u8str.data()), u8str.size()); +} + + +/// Convert UTF-8-containing std::string to std::u8string +inline std::u8string u8string_from_string(const std::string_view& str) +{ + return std::u8string(reinterpret_cast(str.data()), str.size()); +} + + + + + // --------------------------------------------- Split