From b252869bb71e7746ef34fd868565f72ae346e796 Mon Sep 17 00:00:00 2001 From: Julian Eder Date: Tue, 9 Jun 2026 09:14:31 +0200 Subject: [PATCH] cores/WString: Add missing __FlashStringHelper implementations. The F() macro produces a const __FlashStringHelper* pointer. WString.h declared the corresponding constructor, assignment operator, copy helper, concat overload and StringSumHelper operator+, but WString.cpp was missing all five implementations, causing undefined-reference linker errors whenever a library (e.g. SimpleSerialShell) used F() with String operations. On XMC (non-AVR) pgmspace.h maps strcpy_P / strlen_P to plain strcpy / strlen, so the implementations are identical to the char* counterparts. Fixes #439 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Julian Eder --- cores/WString.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/cores/WString.cpp b/cores/WString.cpp index 7fb9b6bf..7c0c3fe4 100644 --- a/cores/WString.cpp +++ b/cores/WString.cpp @@ -45,6 +45,11 @@ String::String(const String &value) { *this = value; } +String::String(const __FlashStringHelper *pstr) { + init(); + *this = pstr; +} + String::String(char c) { init(); char buf[2]; @@ -159,6 +164,16 @@ String &String::copy(const char *cstr, unsigned int length) { return *this; } +String &String::copy(const __FlashStringHelper *pstr, unsigned int length) { + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + String &String::operator=(const String &rhs) { if (this == &rhs) { return *this; @@ -183,6 +198,16 @@ String &String::operator=(const char *cstr) { return *this; } +String &String::operator=(const __FlashStringHelper *pstr) { + if (pstr) { + copy(pstr, strlen_P((PGM_P)pstr)); + } else { + invalidate(); + } + + return *this; +} + /*********************************************/ /* concat */ /*********************************************/ @@ -261,6 +286,23 @@ unsigned char String::concat(double num) { return concat(string, strlen(string)); } +unsigned char String::concat(const __FlashStringHelper *pstr) { + if (!pstr) { + return 0; + } + unsigned int length = strlen_P((PGM_P)pstr); + if (length == 0) { + return 1; + } + unsigned int newlen = len + length; + if (!reserve(newlen)) { + return 0; + } + strcpy_P(buffer + len, (PGM_P)pstr); + len = newlen; + return 1; +} + /*********************************************/ /* Concatenate */ /*********************************************/ @@ -345,6 +387,14 @@ StringSumHelper &operator+(const StringSumHelper &lhs, double num) { return a; } +StringSumHelper &operator+(const StringSumHelper &lhs, const __FlashStringHelper *rhs) { + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) { + a.invalidate(); + } + return a; +} + /*********************************************/ /* Comparison */ /*********************************************/