Merge pull request #11492 from lat9nq/c-numeric-conversions
general: Remove uncaught usages of C++ string number conversions
This commit is contained in:
		| @@ -282,7 +282,7 @@ void Config::ReadValues() { | |||||||
|     std::stringstream ss(title_list); |     std::stringstream ss(title_list); | ||||||
|     std::string line; |     std::string line; | ||||||
|     while (std::getline(ss, line, '|')) { |     while (std::getline(ss, line, '|')) { | ||||||
|         const auto title_id = std::stoul(line, nullptr, 16); |         const auto title_id = std::strtoul(line.c_str(), nullptr, 16); | ||||||
|         const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); |         const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); | ||||||
|  |  | ||||||
|         std::stringstream inner_ss(disabled_list); |         std::stringstream inner_ss(disabled_list); | ||||||
|   | |||||||
| @@ -225,6 +225,16 @@ public: | |||||||
|      */ |      */ | ||||||
|     [[nodiscard]] virtual constexpr u32 EnumIndex() const = 0; |     [[nodiscard]] virtual constexpr u32 EnumIndex() const = 0; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @returns True if the underlying type is a floating point storage | ||||||
|  |      */ | ||||||
|  |     [[nodiscard]] virtual constexpr bool IsFloatingPoint() const = 0; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @returns True if the underlying type is an integer storage | ||||||
|  |      */ | ||||||
|  |     [[nodiscard]] virtual constexpr bool IsIntegral() const = 0; | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
|      * Switchable settings |      * Switchable settings | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| #include <string> | #include <string> | ||||||
| #include <typeindex> | #include <typeindex> | ||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
|  | #include <fmt/core.h> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/settings_common.h" | #include "common/settings_common.h" | ||||||
| #include "common/settings_enums.h" | #include "common/settings_enums.h" | ||||||
| @@ -115,8 +116,12 @@ protected: | |||||||
|         } else if constexpr (std::is_same_v<Type, AudioEngine>) { |         } else if constexpr (std::is_same_v<Type, AudioEngine>) { | ||||||
|             // Compatibility with old AudioEngine setting being a string |             // Compatibility with old AudioEngine setting being a string | ||||||
|             return CanonicalizeEnum(value_); |             return CanonicalizeEnum(value_); | ||||||
|  |         } else if constexpr (std::is_floating_point_v<Type>) { | ||||||
|  |             return fmt::format("{:f}", value_); | ||||||
|  |         } else if constexpr (std::is_enum_v<Type>) { | ||||||
|  |             return std::to_string(static_cast<u32>(value_)); | ||||||
|         } else { |         } else { | ||||||
|             return std::to_string(static_cast<u64>(value_)); |             return std::to_string(value_); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -180,13 +185,15 @@ public: | |||||||
|                 this->SetValue(static_cast<u32>(std::stoul(input))); |                 this->SetValue(static_cast<u32>(std::stoul(input))); | ||||||
|             } else if constexpr (std::is_same_v<Type, bool>) { |             } else if constexpr (std::is_same_v<Type, bool>) { | ||||||
|                 this->SetValue(input == "true"); |                 this->SetValue(input == "true"); | ||||||
|             } else if constexpr (std::is_same_v<Type, AudioEngine>) { |             } else if constexpr (std::is_same_v<Type, float>) { | ||||||
|                 this->SetValue(ToEnum<Type>(input)); |                 this->SetValue(std::stof(input)); | ||||||
|             } else { |             } else { | ||||||
|                 this->SetValue(static_cast<Type>(std::stoll(input))); |                 this->SetValue(static_cast<Type>(std::stoll(input))); | ||||||
|             } |             } | ||||||
|         } catch (std::invalid_argument&) { |         } catch (std::invalid_argument&) { | ||||||
|             this->SetValue(this->GetDefault()); |             this->SetValue(this->GetDefault()); | ||||||
|  |         } catch (std::out_of_range&) { | ||||||
|  |             this->SetValue(this->GetDefault()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -215,11 +222,27 @@ public: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [[nodiscard]] constexpr bool IsFloatingPoint() const final { | ||||||
|  |         return std::is_floating_point_v<Type>; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [[nodiscard]] constexpr bool IsIntegral() const final { | ||||||
|  |         return std::is_integral_v<Type>; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     [[nodiscard]] std::string MinVal() const override final { |     [[nodiscard]] std::string MinVal() const override final { | ||||||
|         return this->ToString(minimum); |         if constexpr (std::is_arithmetic_v<Type> && !ranged) { | ||||||
|  |             return this->ToString(std::numeric_limits<Type>::min()); | ||||||
|  |         } else { | ||||||
|  |             return this->ToString(minimum); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     [[nodiscard]] std::string MaxVal() const override final { |     [[nodiscard]] std::string MaxVal() const override final { | ||||||
|         return this->ToString(maximum); |         if constexpr (std::is_arithmetic_v<Type> && !ranged) { | ||||||
|  |             return this->ToString(std::numeric_limits<Type>::max()); | ||||||
|  |         } else { | ||||||
|  |             return this->ToString(maximum); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [[nodiscard]] constexpr bool Ranged() const override { |     [[nodiscard]] constexpr bool Ranged() const override { | ||||||
|   | |||||||
| @@ -724,14 +724,14 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 const auto index = std::stoul(out[0].substr(8, 2), nullptr, 16); |                 const auto index = std::strtoul(out[0].substr(8, 2).c_str(), nullptr, 16); | ||||||
|                 keyblobs[index] = Common::HexStringToArray<0x90>(out[1]); |                 keyblobs[index] = Common::HexStringToArray<0x90>(out[1]); | ||||||
|             } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) { |             } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) { | ||||||
|                 if (!ValidCryptoRevisionString(out[0], 18, 2)) { |                 if (!ValidCryptoRevisionString(out[0], 18, 2)) { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 const auto index = std::stoul(out[0].substr(18, 2), nullptr, 16); |                 const auto index = std::strtoul(out[0].substr(18, 2).c_str(), nullptr, 16); | ||||||
|                 encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]); |                 encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]); | ||||||
|             } else if (out[0].compare(0, 20, "eticket_extended_kek") == 0) { |             } else if (out[0].compare(0, 20, "eticket_extended_kek") == 0) { | ||||||
|                 eticket_extended_kek = Common::HexStringToArray<576>(out[1]); |                 eticket_extended_kek = Common::HexStringToArray<576>(out[1]); | ||||||
| @@ -750,7 +750,7 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||||||
|                     } |                     } | ||||||
|                     if (out[0].compare(0, kv.second.size(), kv.second) == 0) { |                     if (out[0].compare(0, kv.second.size(), kv.second) == 0) { | ||||||
|                         const auto index = |                         const auto index = | ||||||
|                             std::stoul(out[0].substr(kv.second.size(), 2), nullptr, 16); |                             std::strtoul(out[0].substr(kv.second.size(), 2).c_str(), nullptr, 16); | ||||||
|                         const auto sub = kv.first.second; |                         const auto sub = kv.first.second; | ||||||
|                         if (sub == 0) { |                         if (sub == 0) { | ||||||
|                             s128_keys[{kv.first.first, index, 0}] = |                             s128_keys[{kv.first.first, index, 0}] = | ||||||
| @@ -770,7 +770,7 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||||||
|                     const auto& match = kak_names[j]; |                     const auto& match = kak_names[j]; | ||||||
|                     if (out[0].compare(0, std::strlen(match), match) == 0) { |                     if (out[0].compare(0, std::strlen(match), match) == 0) { | ||||||
|                         const auto index = |                         const auto index = | ||||||
|                             std::stoul(out[0].substr(std::strlen(match), 2), nullptr, 16); |                             std::strtoul(out[0].substr(std::strlen(match), 2).c_str(), nullptr, 16); | ||||||
|                         s128_keys[{S128KeyType::KeyArea, index, j}] = |                         s128_keys[{S128KeyType::KeyArea, index, j}] = | ||||||
|                             Common::HexStringToArray<16>(out[1]); |                             Common::HexStringToArray<16>(out[1]); | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -165,7 +165,7 @@ static std::string EscapeStringSequences(std::string in) { | |||||||
| void IPSwitchCompiler::ParseFlag(const std::string& line) { | void IPSwitchCompiler::ParseFlag(const std::string& line) { | ||||||
|     if (StartsWith(line, "@flag offset_shift ")) { |     if (StartsWith(line, "@flag offset_shift ")) { | ||||||
|         // Offset Shift Flag |         // Offset Shift Flag | ||||||
|         offset_shift = std::stoll(line.substr(19), nullptr, 0); |         offset_shift = std::strtoll(line.substr(19).c_str(), nullptr, 0); | ||||||
|     } else if (StartsWith(line, "@little-endian")) { |     } else if (StartsWith(line, "@little-endian")) { | ||||||
|         // Set values to read as little endian |         // Set values to read as little endian | ||||||
|         is_little_endian = true; |         is_little_endian = true; | ||||||
| @@ -263,7 +263,7 @@ void IPSwitchCompiler::Parse() { | |||||||
|                 // 11 - 8 hex digit offset + space + minimum two digit overwrite val |                 // 11 - 8 hex digit offset + space + minimum two digit overwrite val | ||||||
|                 if (patch_line.length() < 11) |                 if (patch_line.length() < 11) | ||||||
|                     break; |                     break; | ||||||
|                 auto offset = std::stoul(patch_line.substr(0, 8), nullptr, 16); |                 auto offset = std::strtoul(patch_line.substr(0, 8).c_str(), nullptr, 16); | ||||||
|                 offset += static_cast<unsigned long>(offset_shift); |                 offset += static_cast<unsigned long>(offset_shift); | ||||||
|  |  | ||||||
|                 std::vector<u8> replace; |                 std::vector<u8> replace; | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const { | |||||||
|                 return {}; |                 return {}; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             const auto value = static_cast<u32>(std::stoul(hex, nullptr, 0x10)); |             const auto value = static_cast<u32>(std::strtoul(hex.c_str(), nullptr, 0x10)); | ||||||
|             out[*current_entry].definition.opcodes[out[*current_entry].definition.num_opcodes++] = |             out[*current_entry].definition.opcodes[out[*current_entry].definition.num_opcodes++] = | ||||||
|                 value; |                 value; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| #include "yuzu/configuration/configure_ui.h" | #include "yuzu/configuration/configure_ui.h" | ||||||
|  |  | ||||||
| #include <array> | #include <array> | ||||||
|  | #include <cstdlib> | ||||||
| #include <set> | #include <set> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <string> | #include <string> | ||||||
| @@ -94,11 +95,7 @@ static void PopulateResolutionComboBox(QComboBox* screenshot_height, QWidget* pa | |||||||
| } | } | ||||||
|  |  | ||||||
| static u32 ScreenshotDimensionToInt(const QString& height) { | static u32 ScreenshotDimensionToInt(const QString& height) { | ||||||
|     try { |     return std::strtoul(height.toUtf8(), nullptr, 0); | ||||||
|         return std::stoi(height.toStdString()); |  | ||||||
|     } catch (std::invalid_argument&) { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) | ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ static QString DefaultSuffix(QWidget* parent, Settings::BasicSetting& setting) { | |||||||
|         return tr("%", context.c_str()); |         return tr("%", context.c_str()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return QStringLiteral(""); |     return default_suffix; | ||||||
| } | } | ||||||
|  |  | ||||||
| QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) { | QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) { | ||||||
| @@ -71,7 +71,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* paren | |||||||
|  |  | ||||||
|     QStyle* style = parent->style(); |     QStyle* style = parent->style(); | ||||||
|     QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); |     QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); | ||||||
|     QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); |     QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(), parent); | ||||||
|     restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count)); |     restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count)); | ||||||
|     restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); |     restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | ||||||
|  |  | ||||||
| @@ -151,7 +151,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||||||
|         return -1; |         return -1; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     const u32 setting_value = std::stoi(setting.ToString()); |     const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); | ||||||
|     combobox->setCurrentIndex(find_index(setting_value)); |     combobox->setCurrentIndex(find_index(setting_value)); | ||||||
|  |  | ||||||
|     serializer = [this, enumeration]() { |     serializer = [this, enumeration]() { | ||||||
| @@ -160,7 +160,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     restore_func = [this, find_index]() { |     restore_func = [this, find_index]() { | ||||||
|         const u32 global_value = std::stoi(RelevantDefault(setting)); |         const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); | ||||||
|         combobox->setCurrentIndex(find_index(global_value)); |         combobox->setCurrentIndex(find_index(global_value)); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -209,7 +209,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     const u32 setting_value = std::stoi(setting.ToString()); |     const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); | ||||||
|     set_index(setting_value); |     set_index(setting_value); | ||||||
|  |  | ||||||
|     serializer = [get_selected]() { |     serializer = [get_selected]() { | ||||||
| @@ -218,7 +218,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     restore_func = [this, set_index]() { |     restore_func = [this, set_index]() { | ||||||
|         const u32 global_value = std::stoi(RelevantDefault(setting)); |         const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); | ||||||
|         set_index(global_value); |         set_index(global_value); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -255,6 +255,59 @@ QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer, | |||||||
|     return line_edit; |     return line_edit; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void CreateIntSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||||||
|  |                             QLabel* feedback, const QString& use_format, QSlider* slider, | ||||||
|  |                             std::function<std::string()>& serializer, | ||||||
|  |                             std::function<void()>& restore_func) { | ||||||
|  |     const int max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); | ||||||
|  |  | ||||||
|  |     const auto update_feedback = [=](int value) { | ||||||
|  |         int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | ||||||
|  |         feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||||||
|  |     update_feedback(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||||||
|  |  | ||||||
|  |     slider->setMinimum(std::strtol(setting.MinVal().c_str(), nullptr, 0)); | ||||||
|  |     slider->setMaximum(max_val); | ||||||
|  |     slider->setValue(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||||||
|  |  | ||||||
|  |     serializer = [slider]() { return std::to_string(slider->value()); }; | ||||||
|  |     restore_func = [slider, &setting]() { | ||||||
|  |         slider->setValue(std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void CreateFloatSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||||||
|  |                               QLabel* feedback, const QString& use_format, QSlider* slider, | ||||||
|  |                               std::function<std::string()>& serializer, | ||||||
|  |                               std::function<void()>& restore_func) { | ||||||
|  |     const float max_val = std::strtof(setting.MaxVal().c_str(), nullptr); | ||||||
|  |     const float min_val = std::strtof(setting.MinVal().c_str(), nullptr); | ||||||
|  |     const float use_multiplier = | ||||||
|  |         multiplier == default_multiplier ? default_float_multiplier : multiplier; | ||||||
|  |  | ||||||
|  |     const auto update_feedback = [=](float value) { | ||||||
|  |         int present = (reversed ? max_val - value : value) + 0.5f; | ||||||
|  |         feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||||||
|  |     update_feedback(std::strtof(setting.ToString().c_str(), nullptr)); | ||||||
|  |  | ||||||
|  |     slider->setMinimum(min_val * use_multiplier); | ||||||
|  |     slider->setMaximum(max_val * use_multiplier); | ||||||
|  |     slider->setValue(std::strtof(setting.ToString().c_str(), nullptr) * use_multiplier); | ||||||
|  |  | ||||||
|  |     serializer = [slider, use_multiplier]() { | ||||||
|  |         return std::to_string(slider->value() / use_multiplier); | ||||||
|  |     }; | ||||||
|  |     restore_func = [slider, &setting, use_multiplier]() { | ||||||
|  |         slider->setValue(std::strtof(RelevantDefault(setting).c_str(), nullptr) * use_multiplier); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
| QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, | QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, | ||||||
|                               std::function<std::string()>& serializer, |                               std::function<std::string()>& serializer, | ||||||
|                               std::function<void()>& restore_func, |                               std::function<void()>& restore_func, | ||||||
| @@ -278,27 +331,19 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi | |||||||
|  |  | ||||||
|     layout->setContentsMargins(0, 0, 0, 0); |     layout->setContentsMargins(0, 0, 0, 0); | ||||||
|  |  | ||||||
|     int max_val = std::stoi(setting.MaxVal()); |     QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; | ||||||
|  |  | ||||||
|     QString suffix = |  | ||||||
|         given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; |  | ||||||
|  |  | ||||||
|     const QString use_format = QStringLiteral("%1").append(suffix); |     const QString use_format = QStringLiteral("%1").append(suffix); | ||||||
|  |  | ||||||
|     QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { |     if (setting.IsIntegral()) { | ||||||
|         int present = (reversed ? max_val - value : value) * multiplier + 0.5f; |         CreateIntSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, | ||||||
|         feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); |                         restore_func); | ||||||
|     }); |     } else { | ||||||
|  |         CreateFloatSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, | ||||||
|     slider->setMinimum(std::stoi(setting.MinVal())); |                           restore_func); | ||||||
|     slider->setMaximum(max_val); |     } | ||||||
|     slider->setValue(std::stoi(setting.ToString())); |  | ||||||
|  |  | ||||||
|     slider->setInvertedAppearance(reversed); |     slider->setInvertedAppearance(reversed); | ||||||
|     slider->setInvertedControls(reversed); |  | ||||||
|  |  | ||||||
|     serializer = [this]() { return std::to_string(slider->value()); }; |  | ||||||
|     restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); }; |  | ||||||
|  |  | ||||||
|     if (!Settings::IsConfiguringGlobal()) { |     if (!Settings::IsConfiguringGlobal()) { | ||||||
|         QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); |         QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); | ||||||
| @@ -311,14 +356,11 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||||||
|                                std::function<std::string()>& serializer, |                                std::function<std::string()>& serializer, | ||||||
|                                std::function<void()>& restore_func, |                                std::function<void()>& restore_func, | ||||||
|                                const std::function<void()>& touch) { |                                const std::function<void()>& touch) { | ||||||
|     const int min_val = |     const auto min_val = std::strtol(setting.MinVal().c_str(), nullptr, 0); | ||||||
|         setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min(); |     const auto max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); | ||||||
|     const int max_val = |     const auto default_val = std::strtol(setting.ToString().c_str(), nullptr, 0); | ||||||
|         setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max(); |  | ||||||
|     const int default_val = std::stoi(setting.ToString()); |  | ||||||
|  |  | ||||||
|     QString suffix = |     QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; | ||||||
|         given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; |  | ||||||
|  |  | ||||||
|     spinbox = new QSpinBox(this); |     spinbox = new QSpinBox(this); | ||||||
|     spinbox->setRange(min_val, max_val); |     spinbox->setRange(min_val, max_val); | ||||||
| @@ -329,13 +371,13 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||||||
|     serializer = [this]() { return std::to_string(spinbox->value()); }; |     serializer = [this]() { return std::to_string(spinbox->value()); }; | ||||||
|  |  | ||||||
|     restore_func = [this]() { |     restore_func = [this]() { | ||||||
|         auto value{std::stol(RelevantDefault(setting))}; |         auto value{std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)}; | ||||||
|         spinbox->setValue(value); |         spinbox->setValue(value); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (!Settings::IsConfiguringGlobal()) { |     if (!Settings::IsConfiguringGlobal()) { | ||||||
|         QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { |         QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { | ||||||
|             if (spinbox->value() != std::stoi(setting.ToStringGlobal())) { |             if (spinbox->value() != std::strtol(setting.ToStringGlobal().c_str(), nullptr, 0)) { | ||||||
|                 touch(); |                 touch(); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| @@ -344,6 +386,42 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||||||
|     return spinbox; |     return spinbox; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | QWidget* Widget::CreateDoubleSpinBox(const QString& given_suffix, | ||||||
|  |                                      std::function<std::string()>& serializer, | ||||||
|  |                                      std::function<void()>& restore_func, | ||||||
|  |                                      const std::function<void()>& touch) { | ||||||
|  |     const auto min_val = std::strtod(setting.MinVal().c_str(), nullptr); | ||||||
|  |     const auto max_val = std::strtod(setting.MaxVal().c_str(), nullptr); | ||||||
|  |     const auto default_val = std::strtod(setting.ToString().c_str(), nullptr); | ||||||
|  |  | ||||||
|  |     QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; | ||||||
|  |  | ||||||
|  |     double_spinbox = new QDoubleSpinBox(this); | ||||||
|  |     double_spinbox->setRange(min_val, max_val); | ||||||
|  |     double_spinbox->setValue(default_val); | ||||||
|  |     double_spinbox->setSuffix(suffix); | ||||||
|  |     double_spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||||||
|  |  | ||||||
|  |     serializer = [this]() { return fmt::format("{:f}", double_spinbox->value()); }; | ||||||
|  |  | ||||||
|  |     restore_func = [this]() { | ||||||
|  |         auto value{std::strtod(RelevantDefault(setting).c_str(), nullptr)}; | ||||||
|  |         double_spinbox->setValue(value); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     if (!Settings::IsConfiguringGlobal()) { | ||||||
|  |         QObject::connect(double_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), | ||||||
|  |                          [this, touch]() { | ||||||
|  |                              if (double_spinbox->value() != | ||||||
|  |                                  std::strtod(setting.ToStringGlobal().c_str(), nullptr)) { | ||||||
|  |                                  touch(); | ||||||
|  |                              } | ||||||
|  |                          }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return double_spinbox; | ||||||
|  | } | ||||||
|  |  | ||||||
| QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | ||||||
|                                std::function<void()>& restore_func, |                                std::function<void()>& restore_func, | ||||||
|                                const std::function<void()>& touch) { |                                const std::function<void()>& touch) { | ||||||
| @@ -353,7 +431,8 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     auto to_hex = [=](const std::string& input) { |     auto to_hex = [=](const std::string& input) { | ||||||
|         return QString::fromStdString(fmt::format("{:08x}", std::stoul(input))); |         return QString::fromStdString( | ||||||
|  |             fmt::format("{:08x}", std::strtoul(input.c_str(), nullptr, 0))); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     QRegularExpressionValidator* regex = new QRegularExpressionValidator( |     QRegularExpressionValidator* regex = new QRegularExpressionValidator( | ||||||
| @@ -366,7 +445,7 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||||||
|     line_edit->setValidator(regex); |     line_edit->setValidator(regex); | ||||||
|  |  | ||||||
|     auto hex_to_dec = [this]() -> std::string { |     auto hex_to_dec = [this]() -> std::string { | ||||||
|         return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16)); |         return std::to_string(std::strtoul(line_edit->text().toStdString().c_str(), nullptr, 16)); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     serializer = [hex_to_dec]() { return hex_to_dec(); }; |     serializer = [hex_to_dec]() { return hex_to_dec(); }; | ||||||
| @@ -386,7 +465,8 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||||||
|                                     std::function<void()>& restore_func, |                                     std::function<void()>& restore_func, | ||||||
|                                     const std::function<void()>& touch) { |                                     const std::function<void()>& touch) { | ||||||
|     const long long current_time = QDateTime::currentSecsSinceEpoch(); |     const long long current_time = QDateTime::currentSecsSinceEpoch(); | ||||||
|     const s64 the_time = disabled ? current_time : std::stoll(setting.ToString()); |     const s64 the_time = | ||||||
|  |         disabled ? current_time : std::strtoll(setting.ToString().c_str(), nullptr, 0); | ||||||
|     const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); |     const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); | ||||||
|  |  | ||||||
|     date_time_edit = new QDateTimeEdit(this); |     date_time_edit = new QDateTimeEdit(this); | ||||||
| @@ -399,7 +479,7 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||||||
|     auto get_clear_val = [this, restrict, current_time]() { |     auto get_clear_val = [this, restrict, current_time]() { | ||||||
|         return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { |         return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { | ||||||
|             if (restrict && checkbox->checkState() == Qt::Checked) { |             if (restrict && checkbox->checkState() == Qt::Checked) { | ||||||
|                 return std::stoll(RelevantDefault(setting)); |                 return std::strtoll(RelevantDefault(setting).c_str(), nullptr, 0); | ||||||
|             } |             } | ||||||
|             return current_time; |             return current_time; | ||||||
|         }()); |         }()); | ||||||
| @@ -506,8 +586,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||||||
|         } else { |         } else { | ||||||
|             data_component = CreateCombobox(serializer, restore_func, touch); |             data_component = CreateCombobox(serializer, restore_func, touch); | ||||||
|         } |         } | ||||||
|     } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || |     } else if (setting.IsIntegral()) { | ||||||
|                type == typeid(s64) || type == typeid(u8)) { |  | ||||||
|         switch (request) { |         switch (request) { | ||||||
|         case RequestType::Slider: |         case RequestType::Slider: | ||||||
|         case RequestType::ReverseSlider: |         case RequestType::ReverseSlider: | ||||||
| @@ -534,6 +613,20 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||||||
|         default: |         default: | ||||||
|             UNIMPLEMENTED(); |             UNIMPLEMENTED(); | ||||||
|         } |         } | ||||||
|  |     } else if (setting.IsFloatingPoint()) { | ||||||
|  |         switch (request) { | ||||||
|  |         case RequestType::Default: | ||||||
|  |         case RequestType::SpinBox: | ||||||
|  |             data_component = CreateDoubleSpinBox(suffix, serializer, restore_func, touch); | ||||||
|  |             break; | ||||||
|  |         case RequestType::Slider: | ||||||
|  |         case RequestType::ReverseSlider: | ||||||
|  |             data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix, | ||||||
|  |                                           serializer, restore_func, touch); | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             UNIMPLEMENTED(); | ||||||
|  |         } | ||||||
|     } else if (type == typeid(std::string)) { |     } else if (type == typeid(std::string)) { | ||||||
|         switch (request) { |         switch (request) { | ||||||
|         case RequestType::Default: |         case RequestType::Default: | ||||||
| @@ -638,10 +731,10 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati | |||||||
|             return std::pair{translations.at(id).first, translations.at(id).second}; |             return std::pair{translations.at(id).first, translations.at(id).second}; | ||||||
|         } |         } | ||||||
|         LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); |         LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); | ||||||
|         return std::pair{QString::fromStdString(setting_label), QStringLiteral("")}; |         return std::pair{QString::fromStdString(setting_label), QStringLiteral()}; | ||||||
|     }(); |     }(); | ||||||
|  |  | ||||||
|     if (label == QStringLiteral("")) { |     if (label == QStringLiteral()) { | ||||||
|         LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...", |         LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...", | ||||||
|                   setting.GetLabel()); |                   setting.GetLabel()); | ||||||
|         return; |         return; | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ class QObject; | |||||||
| class QPushButton; | class QPushButton; | ||||||
| class QSlider; | class QSlider; | ||||||
| class QSpinBox; | class QSpinBox; | ||||||
|  | class QDoubleSpinBox; | ||||||
| class QRadioButton; | class QRadioButton; | ||||||
|  |  | ||||||
| namespace Settings { | namespace Settings { | ||||||
| @@ -43,6 +44,10 @@ enum class RequestType { | |||||||
|     MaxEnum, |     MaxEnum, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | constexpr float default_multiplier{1.f}; | ||||||
|  | constexpr float default_float_multiplier{100.f}; | ||||||
|  | static const QString default_suffix = QStringLiteral(); | ||||||
|  |  | ||||||
| class Widget : public QWidget { | class Widget : public QWidget { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
|  |  | ||||||
| @@ -66,8 +71,9 @@ public: | |||||||
|                     const ComboboxTranslationMap& combobox_translations, QWidget* parent, |                     const ComboboxTranslationMap& combobox_translations, QWidget* parent, | ||||||
|                     bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_, |                     bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_, | ||||||
|                     RequestType request = RequestType::Default, bool managed = true, |                     RequestType request = RequestType::Default, bool managed = true, | ||||||
|                     float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr, |                     float multiplier = default_multiplier, | ||||||
|                     const QString& suffix = QStringLiteral("")); |                     Settings::BasicSetting* other_setting = nullptr, | ||||||
|  |                     const QString& suffix = default_suffix); | ||||||
|     virtual ~Widget(); |     virtual ~Widget(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -89,6 +95,7 @@ public: | |||||||
|     QPushButton* restore_button{}; ///< Restore button for custom configurations |     QPushButton* restore_button{}; ///< Restore button for custom configurations | ||||||
|     QLineEdit* line_edit{};        ///< QLineEdit, used for LineEdit and HexEdit |     QLineEdit* line_edit{};        ///< QLineEdit, used for LineEdit and HexEdit | ||||||
|     QSpinBox* spinbox{}; |     QSpinBox* spinbox{}; | ||||||
|  |     QDoubleSpinBox* double_spinbox{}; | ||||||
|     QCheckBox* checkbox{}; |     QCheckBox* checkbox{}; | ||||||
|     QSlider* slider{}; |     QSlider* slider{}; | ||||||
|     QComboBox* combobox{}; |     QComboBox* combobox{}; | ||||||
| @@ -126,6 +133,9 @@ private: | |||||||
|                                 const std::function<void()>& touch); |                                 const std::function<void()>& touch); | ||||||
|     QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, |     QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, | ||||||
|                            std::function<void()>& restore_func, const std::function<void()>& touch); |                            std::function<void()>& restore_func, const std::function<void()>& touch); | ||||||
|  |     QWidget* CreateDoubleSpinBox(const QString& suffix, std::function<std::string()>& serializer, | ||||||
|  |                                  std::function<void()>& restore_func, | ||||||
|  |                                  const std::function<void()>& touch); | ||||||
|  |  | ||||||
|     QWidget* parent; |     QWidget* parent; | ||||||
|     const TranslationMap& translations; |     const TranslationMap& translations; | ||||||
| @@ -145,14 +155,15 @@ public: | |||||||
|     Widget* BuildWidget(Settings::BasicSetting* setting, |     Widget* BuildWidget(Settings::BasicSetting* setting, | ||||||
|                         std::vector<std::function<void(bool)>>& apply_funcs, |                         std::vector<std::function<void(bool)>>& apply_funcs, | ||||||
|                         RequestType request = RequestType::Default, bool managed = true, |                         RequestType request = RequestType::Default, bool managed = true, | ||||||
|                         float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr, |                         float multiplier = default_multiplier, | ||||||
|                         const QString& suffix = QStringLiteral("")) const; |                         Settings::BasicSetting* other_setting = nullptr, | ||||||
|  |                         const QString& suffix = default_suffix) const; | ||||||
|  |  | ||||||
|     Widget* BuildWidget(Settings::BasicSetting* setting, |     Widget* BuildWidget(Settings::BasicSetting* setting, | ||||||
|                         std::vector<std::function<void(bool)>>& apply_funcs, |                         std::vector<std::function<void(bool)>>& apply_funcs, | ||||||
|                         Settings::BasicSetting* other_setting, |                         Settings::BasicSetting* other_setting, | ||||||
|                         RequestType request = RequestType::Default, |                         RequestType request = RequestType::Default, | ||||||
|                         const QString& suffix = QStringLiteral("")) const; |                         const QString& suffix = default_suffix) const; | ||||||
|  |  | ||||||
|     const ComboboxTranslationMap& ComboboxTranslations() const; |     const ComboboxTranslationMap& ComboboxTranslations() const; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -259,7 +259,7 @@ void Config::ReadValues() { | |||||||
|     std::stringstream ss(title_list); |     std::stringstream ss(title_list); | ||||||
|     std::string line; |     std::string line; | ||||||
|     while (std::getline(ss, line, '|')) { |     while (std::getline(ss, line, '|')) { | ||||||
|         const auto title_id = std::stoul(line, nullptr, 16); |         const auto title_id = std::strtoul(line.c_str(), nullptr, 16); | ||||||
|         const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, ""); |         const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, ""); | ||||||
|  |  | ||||||
|         std::stringstream inner_ss(disabled_list); |         std::stringstream inner_ss(disabled_list); | ||||||
|   | |||||||
| @@ -264,8 +264,9 @@ int main(int argc, char** argv) { | |||||||
|                 nickname = match[1]; |                 nickname = match[1]; | ||||||
|                 password = match[2]; |                 password = match[2]; | ||||||
|                 address = match[3]; |                 address = match[3]; | ||||||
|                 if (!match[4].str().empty()) |                 if (!match[4].str().empty()) { | ||||||
|                     port = static_cast<u16>(std::stoi(match[4])); |                     port = static_cast<u16>(std::strtoul(match[4].str().c_str(), nullptr, 0)); | ||||||
|  |                 } | ||||||
|                 std::regex nickname_re("^[a-zA-Z0-9._\\- ]+$"); |                 std::regex nickname_re("^[a-zA-Z0-9._\\- ]+$"); | ||||||
|                 if (!std::regex_match(nickname, nickname_re)) { |                 if (!std::regex_match(nickname, nickname_re)) { | ||||||
|                     std::cout |                     std::cout | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user