From 6453d3e201d81e0fea44db66b10f38e3ba091ab3 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 20 Aug 2025 19:51:02 +0200 Subject: [PATCH 1/4] Use std::from_chars in MessageFormatParser --- components/misc/messageformatparser.cpp | 42 +++++++++++++++---------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/components/misc/messageformatparser.cpp b/components/misc/messageformatparser.cpp index a40dcccd52..f98544d380 100644 --- a/components/misc/messageformatparser.cpp +++ b/components/misc/messageformatparser.cpp @@ -1,12 +1,32 @@ #include "messageformatparser.hpp" +#include + +namespace +{ + int parseNumber(std::size_t& i, std::string_view m) + { + if (i < m.size() && m[i] >= '0' && m[i] <= '9') + { + size_t start = i++; + while (i < m.size() && m[i] >= '0' && m[i] <= '9') + ++i; + int parsed; + auto [ptr, ec] = std::from_chars(m.data() + start, m.data() + i, parsed); + if (ec == std::errc()) + return parsed; + } + return -1; + } +} + namespace Misc { - MessageFormatParser::~MessageFormatParser() {} + MessageFormatParser::~MessageFormatParser() = default; void MessageFormatParser::process(std::string_view m) { - for (unsigned int i = 0; i < m.size(); ++i) + for (std::size_t i = 0; i < m.size(); ++i) { if (m[i] == '%') { @@ -23,31 +43,19 @@ namespace Misc ++i; } - int width = 0; - bool widthSet = false; - while (i < m.size() && m[i] >= '0' && m[i] <= '9') - { - width = width * 10 + (m[i] - '0'); - widthSet = true; - ++i; - } + int width = parseNumber(i, m); if (i < m.size()) { int precision = -1; if (m[i] == '.') { - precision = 0; - while (++i < m.size() && m[i] >= '0' && m[i] <= '9') - { - precision = precision * 10 + (m[i] - '0'); - } + ++i; + precision = parseNumber(i, m); } if (i < m.size()) { - width = (widthSet) ? width : -1; - if (m[i] == 'S' || m[i] == 's') visitedPlaceholder(StringPlaceholder, pad, width, precision, FixedNotation); else if (m[i] == 'd' || m[i] == 'i') From 86605f353108e7419b89c60bb1d60b849232974a Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 21 Aug 2025 08:57:00 +0200 Subject: [PATCH 2/4] Make 0-width precision be 0 --- components/misc/messageformatparser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/misc/messageformatparser.cpp b/components/misc/messageformatparser.cpp index f98544d380..89dd58e1f0 100644 --- a/components/misc/messageformatparser.cpp +++ b/components/misc/messageformatparser.cpp @@ -4,7 +4,7 @@ namespace { - int parseNumber(std::size_t& i, std::string_view m) + int parseNumber(std::size_t& i, std::string_view m, int fallback) { if (i < m.size() && m[i] >= '0' && m[i] <= '9') { @@ -16,7 +16,7 @@ namespace if (ec == std::errc()) return parsed; } - return -1; + return fallback; } } @@ -43,7 +43,7 @@ namespace Misc ++i; } - int width = parseNumber(i, m); + int width = parseNumber(i, m, -1); if (i < m.size()) { @@ -51,7 +51,7 @@ namespace Misc if (m[i] == '.') { ++i; - precision = parseNumber(i, m); + precision = parseNumber(i, m, 0); } if (i < m.size()) From 59753d8b8e6635656211558a84141e986c3ed9d9 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 21 Aug 2025 09:42:02 +0200 Subject: [PATCH 3/4] Leave from_chars to figure out the length --- components/misc/messageformatparser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/misc/messageformatparser.cpp b/components/misc/messageformatparser.cpp index 89dd58e1f0..4b77a9da7a 100644 --- a/components/misc/messageformatparser.cpp +++ b/components/misc/messageformatparser.cpp @@ -8,11 +8,10 @@ namespace { if (i < m.size() && m[i] >= '0' && m[i] <= '9') { - size_t start = i++; - while (i < m.size() && m[i] >= '0' && m[i] <= '9') - ++i; + const char* start = m.data() + i; int parsed; - auto [ptr, ec] = std::from_chars(m.data() + start, m.data() + i, parsed); + auto [ptr, ec] = std::from_chars(start, m.data() + m.size(), parsed); + i += ptr - start; if (ec == std::errc()) return parsed; } From d66b86f2c9b9a063a8c7594985baa9707173a4c3 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 21 Aug 2025 22:00:00 +0200 Subject: [PATCH 4/4] Implement missing hex float format options --- components/interpreter/miscopcodes.hpp | 15 +++++++++++++-- components/misc/messageformatparser.cpp | 16 +++++++++++----- components/misc/messageformatparser.hpp | 10 ++++++---- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index 72cc1439d2..0b49b3c248 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -57,12 +57,12 @@ namespace Interpreter float value = mRuntime[0].mFloat; mRuntime.pop(); - if (notation == FixedNotation) + if (notation == Notation::Fixed) { out << std::fixed << value; mFormattedMessage += out.str(); } - else if (notation == ShortestNotation) + else if (notation == Notation::Shortest) { out << value; std::string standard = out.str(); @@ -75,6 +75,17 @@ namespace Interpreter mFormattedMessage += standard.length() < scientific.length() ? standard : scientific; } + // TODO switch to std::format so the precision argument applies to these two + else if (notation == Notation::HexLower) + { + out << std::hexfloat << value; + mFormattedMessage += out.str(); + } + else if (notation == Notation::HexUpper) + { + out << std::uppercase << std::hexfloat << value; + mFormattedMessage += out.str(); + } else { out << std::scientific << value; diff --git a/components/misc/messageformatparser.cpp b/components/misc/messageformatparser.cpp index 4b77a9da7a..649d0184d3 100644 --- a/components/misc/messageformatparser.cpp +++ b/components/misc/messageformatparser.cpp @@ -56,15 +56,21 @@ namespace Misc if (i < m.size()) { if (m[i] == 'S' || m[i] == 's') - visitedPlaceholder(StringPlaceholder, pad, width, precision, FixedNotation); + visitedPlaceholder(StringPlaceholder, pad, width, precision, Notation::Fixed); else if (m[i] == 'd' || m[i] == 'i') - visitedPlaceholder(IntegerPlaceholder, pad, width, precision, FixedNotation); + visitedPlaceholder(IntegerPlaceholder, pad, width, precision, Notation::Fixed); else if (m[i] == 'f' || m[i] == 'F') - visitedPlaceholder(FloatPlaceholder, pad, width, precision, FixedNotation); + visitedPlaceholder(FloatPlaceholder, pad, width, precision, Notation::Fixed); else if (m[i] == 'e' || m[i] == 'E') - visitedPlaceholder(FloatPlaceholder, pad, width, precision, ScientificNotation); + visitedPlaceholder(FloatPlaceholder, pad, width, precision, Notation::Scientific); else if (m[i] == 'g' || m[i] == 'G') - visitedPlaceholder(FloatPlaceholder, pad, width, precision, ShortestNotation); + visitedPlaceholder(FloatPlaceholder, pad, width, precision, Notation::Shortest); + else if (m[i] == 'a') + visitedPlaceholder(FloatPlaceholder, pad, width, precision, Notation::HexLower); + else if (m[i] == 'A') + visitedPlaceholder(FloatPlaceholder, pad, width, precision, Notation::HexUpper); + else + visitedCharacter(m[i]); } } } diff --git a/components/misc/messageformatparser.hpp b/components/misc/messageformatparser.hpp index dc7ce09884..eeef29234d 100644 --- a/components/misc/messageformatparser.hpp +++ b/components/misc/messageformatparser.hpp @@ -15,11 +15,13 @@ namespace Misc FloatPlaceholder }; - enum Notation + enum class Notation { - FixedNotation, - ScientificNotation, - ShortestNotation + Fixed, + Scientific, + Shortest, + HexUpper, + HexLower }; virtual void visitedPlaceholder(