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 a40dcccd52..649d0184d3 100644 --- a/components/misc/messageformatparser.cpp +++ b/components/misc/messageformatparser.cpp @@ -1,12 +1,31 @@ #include "messageformatparser.hpp" +#include + +namespace +{ + int parseNumber(std::size_t& i, std::string_view m, int fallback) + { + if (i < m.size() && m[i] >= '0' && m[i] <= '9') + { + const char* start = m.data() + i; + int parsed; + auto [ptr, ec] = std::from_chars(start, m.data() + m.size(), parsed); + i += ptr - start; + if (ec == std::errc()) + return parsed; + } + return fallback; + } +} + 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,41 +42,35 @@ 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, -1); 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, 0); } if (i < m.size()) { - width = (widthSet) ? width : -1; - 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(