diff --git a/include/asm/format.hpp b/include/asm/format.hpp index 7f9d793c..8a85c200 100644 --- a/include/asm/format.hpp +++ b/include/asm/format.hpp @@ -37,8 +37,8 @@ public: void useCharacter(int c); void finishCharacters(); - std::string formatString(std::string const &value) const; - std::string formatNumber(uint32_t value) const; + void appendString(std::string &str, std::string const &value) const; + void appendNumber(std::string &str, uint32_t value) const; }; #endif // RGBDS_FORMAT_SPEC_H diff --git a/src/asm/format.cpp b/src/asm/format.cpp index cc93a155..92ff1191 100644 --- a/src/asm/format.cpp +++ b/src/asm/format.cpp @@ -3,9 +3,7 @@ #include "asm/format.hpp" #include -#include #include -#include #include #include #include @@ -105,7 +103,7 @@ void FormatSpec::finishCharacters() { state = FORMAT_INVALID; } -std::string FormatSpec::formatString(std::string const &value) const { +void FormatSpec::appendString(std::string &str, std::string const &value) const { int useType = type; if (isEmpty()) { // No format was specified @@ -127,8 +125,7 @@ std::string FormatSpec::formatString(std::string const &value) const { size_t totalLen = width > valueLen ? width : valueLen; size_t padLen = totalLen - valueLen; - std::string str; - str.reserve(totalLen); + str.reserve(str.length() + totalLen); if (alignLeft) { str.append(value); str.append(padLen, ' '); @@ -141,11 +138,9 @@ std::string FormatSpec::formatString(std::string const &value) const { error("Formatted string value too long\n"); str.resize(MAXSTRLEN); } - - return str; } -std::string FormatSpec::formatNumber(uint32_t value) const { +void FormatSpec::appendNumber(std::string &str, uint32_t value) const { int useType = type; bool usePrefix = prefix; if (isEmpty()) { @@ -224,8 +219,7 @@ std::string FormatSpec::formatNumber(uint32_t value) const { size_t totalLen = width > numLen ? width : numLen; size_t padLen = totalLen - numLen; - std::string str; - str.reserve(totalLen); + str.reserve(str.length() + totalLen); if (alignLeft) { if (signChar) str += signChar; @@ -256,6 +250,4 @@ std::string FormatSpec::formatNumber(uint32_t value) const { error("Formatted numeric value too long\n"); str.resize(MAXSTRLEN); } - - return str; } diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index eb746cc1..18fd1c8f 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -1170,20 +1170,20 @@ static char const *readInterpolation(size_t depth) { // Don't return before `lexerState->disableInterpolation` is reset! lexerState->disableInterpolation = disableInterpolation; - static char buf[MAXSTRLEN + 1]; - Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf); if (!sym) { error("Interpolated symbol \"%s\" does not exist\n", fmtBuf.c_str()); } else if (sym->type == SYM_EQUS) { - std::string str = fmt.formatString(*sym->getEqus()); - memcpy(buf, str.c_str(), str.length() + 1); - return buf; + static std::string buf; + buf.clear(); + fmt.appendString(buf, *sym->getEqus()); + return buf.c_str(); } else if (sym->isNumeric()) { - std::string str = fmt.formatNumber(sym->getConstantValue()); - memcpy(buf, str.c_str(), str.length() + 1); - return buf; + static std::string buf; + buf.clear(); + fmt.appendNumber(buf, sym->getConstantValue()); + return buf.c_str(); } else { error("Only numerical and string symbols can be interpolated\n"); } diff --git a/src/asm/parser.y b/src/asm/parser.y index 8fe0dc1d..b3e5dda9 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -2696,11 +2696,11 @@ static std::string strfmt( // Will warn after formatting is done. str += '%'; } else if (auto *n = std::get_if(&args[argIndex]); n) { - str.append(fmt.formatNumber(*n)); + fmt.appendNumber(str, *n); } else { assert(std::holds_alternative(args[argIndex])); auto &s = std::get(args[argIndex]); - str.append(fmt.formatString(s)); + fmt.appendString(str, s); } argIndex++;