diff --git a/extras/tests/Helpers/progmem_emulation.hpp b/extras/tests/Helpers/progmem_emulation.hpp index ef309d10..f3c9246c 100644 --- a/extras/tests/Helpers/progmem_emulation.hpp +++ b/extras/tests/Helpers/progmem_emulation.hpp @@ -24,6 +24,11 @@ inline uint8_t pgm_read_byte(const void* p) { return *reinterpret_cast(convertFlashToPtr(p)); } -inline const void* pgm_read_ptr(const void* p) { - return *reinterpret_cast(convertFlashToPtr(p)); +inline void* pgm_read_ptr(const void* p) { + return *reinterpret_cast(convertFlashToPtr(p)); } + +#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, value) \ + static type const ARDUINOJSON_CONCAT2(name, _progmem)[] = value; \ + static type const* name = reinterpret_cast( \ + convertPtrToFlash(ARDUINOJSON_CONCAT2(name, _progmem))); diff --git a/extras/tests/MixedConfiguration/enable_progmem_1.cpp b/extras/tests/MixedConfiguration/enable_progmem_1.cpp index b862b419..a1d4249e 100644 --- a/extras/tests/MixedConfiguration/enable_progmem_1.cpp +++ b/extras/tests/MixedConfiguration/enable_progmem_1.cpp @@ -165,3 +165,22 @@ TEST_CASE("Reader") { REQUIRE(buffer[6] == 'g'); } } + +static void testStringification(DeserializationError error, + std::string expected) { + const __FlashStringHelper* s = error.f_str(); + CHECK(reinterpret_cast(convertFlashToPtr(s)) == expected); +} + +#define TEST_STRINGIFICATION(symbol) \ + testStringification(DeserializationError::symbol, #symbol) + +TEST_CASE("DeserializationError::f_str()") { + TEST_STRINGIFICATION(Ok); + TEST_STRINGIFICATION(EmptyInput); + TEST_STRINGIFICATION(IncompleteInput); + TEST_STRINGIFICATION(InvalidInput); + TEST_STRINGIFICATION(NoMemory); + TEST_STRINGIFICATION(NotSupported); + TEST_STRINGIFICATION(TooDeep); +} diff --git a/src/ArduinoJson/Deserialization/DeserializationError.hpp b/src/ArduinoJson/Deserialization/DeserializationError.hpp index f3f8a229..0c3c9423 100644 --- a/src/ArduinoJson/Deserialization/DeserializationError.hpp +++ b/src/ArduinoJson/Deserialization/DeserializationError.hpp @@ -86,18 +86,20 @@ class DeserializationError { return messages[_code]; } +#define ARDUINOJSON_EXPAND7(a, b, c, d, e, f, g) a, b, c, d, e, f, g + #if ARDUINOJSON_ENABLE_PROGMEM const __FlashStringHelper* f_str() const { - static const char s0[] PROGMEM = "Ok"; - static const char s1[] PROGMEM = "EmptyInput"; - static const char s2[] PROGMEM = "IncompleteInput"; - static const char s3[] PROGMEM = "InvalidInput"; - static const char s4[] PROGMEM = "NoMemory"; - static const char s5[] PROGMEM = "NotSupported"; - static const char s6[] PROGMEM = "TooDeep"; - static const char* const messages[] PROGMEM = {s0, s1, s2, s3, s4, s5, s6}; - ARDUINOJSON_ASSERT(static_cast(_code) < - sizeof(messages) / sizeof(messages[0])); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s0, "Ok"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s1, "EmptyInput"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s2, "IncompleteInput"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s3, "InvalidInput"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s4, "NoMemory"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s5, "NotSupported"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY(char, s6, "TooDeep"); + ARDUINOJSON_DEFINE_PROGMEM_ARRAY( + const char*, messages, + ARDUINOJSON_EXPAND7({s0, s1, s2, s3, s4, s5, s6})); return reinterpret_cast( pgm_read_ptr(messages + _code)); } diff --git a/src/ArduinoJson/Polyfills/pgmspace.hpp b/src/ArduinoJson/Polyfills/pgmspace.hpp index ffeffd18..8c1b5ac6 100644 --- a/src/ArduinoJson/Polyfills/pgmspace.hpp +++ b/src/ArduinoJson/Polyfills/pgmspace.hpp @@ -76,3 +76,13 @@ inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) { return dst; } #endif + +#ifndef ARDUINOJSON_DEFINE_PROGMEM_ARRAY +#ifdef PROGMEM +#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, value) \ + static type const name[] PROGMEM = value; +#else +#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, value) \ + static type const name[] = value; +#endif +#endif