Parcourir la source

Fixed compilation in IAR Embedded Workbench (issue #515)

Benoit Blanchon il y a 8 ans
Parent
commit
a2446f6c68

+ 4 - 1
CHANGELOG.md

@@ -5,12 +5,15 @@ HEAD
 ----
 
 * Fixed IntelliSense errors in Visual Micro (issue #483)
+* Fixed compilation in IAR Embedded Workbench (issue #515)
+* Added `ARDUINOJSON_DOUBLE_IS_64BITS`
+* Added `ARDUINOJSON_EMBEDDED_MODE`
 
 v5.10.0
 -------
 
 * Removed configurable number of decimal places (issues #288, #427 and #506)
-* Changed exponentation thresholds to `1e7` and `1e-5` (issues #288, #427 and #506)
+* Changed exponentiation thresholds to `1e7` and `1e-5` (issues #288, #427 and #506)
 * `JsonVariant::is<double>()` now returns `true` for integers
 * Fixed error `IsBaseOf is not a member of ArduinoJson::TypeTraits` (issue #495)
 * Fixed error `forming reference to reference` (issue #495)

+ 80 - 65
src/ArduinoJson/Configuration.hpp

@@ -7,30 +7,23 @@
 
 #pragma once
 
-// enable deprecated functions by default
-#ifndef ARDUINOJSON_ENABLE_DEPRECATED
-#define ARDUINOJSON_ENABLE_DEPRECATED 1
-#endif
-
-// control the exponentiation threshold for big numbers
-// CAUTION: cannot be more that 1e9 !!!!
-#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
-#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
+// Small or big machine?
+#ifndef ARDUINOJSON_EMBEDDED_MODE
+#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__)
+#define ARDUINOJSON_EMBEDDED_MODE 1
+#else
+#define ARDUINOJSON_EMBEDDED_MODE 0
 #endif
-
-// control the exponentiation threshold for small numbers
-#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
-#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
 #endif
 
-#ifdef ARDUINO  // assume this is an embedded platform
+#if ARDUINOJSON_EMBEDDED_MODE
 
-// store using float instead of double to reduce the memory usage (issue #134)
+// Store floats by default to reduce the memory usage (issue #134)
 #ifndef ARDUINOJSON_USE_DOUBLE
 #define ARDUINOJSON_USE_DOUBLE 0
 #endif
 
-// store using a long because it usually match the size of a float.
+// Store longs by default, because they usually match the size of a float.
 #ifndef ARDUINOJSON_USE_LONG_LONG
 #define ARDUINOJSON_USE_LONG_LONG 0
 #endif
@@ -38,57 +31,29 @@
 #define ARDUINOJSON_USE_INT64 0
 #endif
 
-// Arduino has its own implementation of String to replace std::string
-#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
-#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
-#endif
-
-#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
-#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
-#endif
-
-// On AVR archiecture, we can use PROGMEM
-#ifndef ARDUINOJSON_ENABLE_PROGMEM
-#ifdef PROGMEM
-#define ARDUINOJSON_ENABLE_PROGMEM 1
-#else
-#define ARDUINOJSON_ENABLE_PROGMEM 0
-#endif
-#endif
-
-// Arduino doesn't have std::string
+// Embedded systems usually don't have std::string
 #ifndef ARDUINOJSON_ENABLE_STD_STRING
 #define ARDUINOJSON_ENABLE_STD_STRING 0
 #endif
 
-// Arduino doesn't support STL stream
+// Embedded systems usually don't have std::stream
 #ifndef ARDUINOJSON_ENABLE_STD_STREAM
 #define ARDUINOJSON_ENABLE_STD_STREAM 0
 #endif
 
-#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
-#ifdef ARDUINO_ARCH_AVR
-// alignment isn't needed for 8-bit AVR
-#define ARDUINOJSON_ENABLE_ALIGNMENT 0
-#else
-// but must processor needs pointer to be align on word size
-#define ARDUINOJSON_ENABLE_ALIGNMENT 1
-#endif
-#endif
-
-// low value to prevent stack overflow
+// Limit nesting as the stack is likely to be small
 #ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
 #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
 #endif
 
-#else  // assume this is a computer
+#else  // ARDUINOJSON_EMBEDDED_MODE
 
-// on a computer we have plenty of memory so we can use doubles
+// On a computer we have plenty of memory so we can use doubles
 #ifndef ARDUINOJSON_USE_DOUBLE
 #define ARDUINOJSON_USE_DOUBLE 1
 #endif
 
-// use long long when available
+// Use long long when available
 #ifndef ARDUINOJSON_USE_LONG_LONG
 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
 #define ARDUINOJSON_USE_LONG_LONG 1
@@ -97,7 +62,7 @@
 #endif
 #endif
 
-// use _int64 on old versions of Visual Studio
+// Use _int64 on old versions of Visual Studio
 #ifndef ARDUINOJSON_USE_INT64
 #if defined(_MSC_VER) && _MSC_VER <= 1700
 #define ARDUINOJSON_USE_INT64 1
@@ -106,41 +71,91 @@
 #endif
 #endif
 
-// on a computer, we can use std::string
+// On a computer, we can use std::string
 #ifndef ARDUINOJSON_ENABLE_STD_STRING
 #define ARDUINOJSON_ENABLE_STD_STRING 1
 #endif
 
-// on a computer, there is no reason to beleive Arduino String is available
+// On a computer, we can assume std::stream
+#ifndef ARDUINOJSON_ENABLE_STD_STREAM
+#define ARDUINOJSON_ENABLE_STD_STREAM 1
+#endif
+
+// On a computer, the stack is large so we can increase nesting limit
+#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
+#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
+#endif
+
+#endif  // ARDUINOJSON_EMBEDDED_MODE
+
+#ifdef ARDUINO
+
+// Enable support for Arduino String
 #ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
-#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
+#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
 #endif
 
-// PROGMEM is only available on AVR architecture
-#ifndef ARDUINOJSON_ENABLE_PROGMEM
-#define ARDUINOJSON_ENABLE_PROGMEM 0
+// Enable support for Arduino Stream
+#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
+#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
 #endif
 
-// on a computer, we can assume that the STL is there
-#ifndef ARDUINOJSON_ENABLE_STD_STREAM
-#define ARDUINOJSON_ENABLE_STD_STREAM 1
+#else  // ARDUINO
+
+// Disable support for Arduino String
+#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
+#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
 #endif
 
-// on a computer, there is no reason to beleive Arduino Stream is available
+// Disable support for Arduino Stream
 #ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
 #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
 #endif
 
+#endif  // ARDUINO
+
+#ifndef ARDUINOJSON_ENABLE_PROGMEM
+#ifdef PROGMEM
+#define ARDUINOJSON_ENABLE_PROGMEM 1
+#else
+#define ARDUINOJSON_ENABLE_PROGMEM 0
+#endif
+#endif
+
 #ifndef ARDUINOJSON_ENABLE_ALIGNMENT
-// even if not required, most cpu's are faster with aligned pointers
+#ifdef ARDUINO_ARCH_AVR
+// alignment isn't needed for 8-bit AVR
+#define ARDUINOJSON_ENABLE_ALIGNMENT 0
+#else
+// but most processors need pointers to be align on word size
 #define ARDUINOJSON_ENABLE_ALIGNMENT 1
 #endif
+#endif
 
-// on a computer, we should have a lot of space on the stack
-#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
-#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
+// Enable deprecated functions by default
+#ifndef ARDUINOJSON_ENABLE_DEPRECATED
+#define ARDUINOJSON_ENABLE_DEPRECATED 1
 #endif
 
+// Control the exponentiation threshold for big numbers
+// CAUTION: cannot be more that 1e9 !!!!
+#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
+#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
+#endif
+
+// Control the exponentiation threshold for small numbers
+#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
+#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
+#endif
+
+// how many bits in a double
+#ifndef ARDUINOJSON_DOUBLE_IS_64BITS
+#if /*GCC*/ (defined(__SIZEOF_DOUBLE__) && __SIZEOF_DOUBLE__ < 8) || \
+    /*IAR*/ (defined(__DOUBLE__) && __DOUBLE__ < 64)
+#define ARDUINOJSON_DOUBLE_IS_64BITS 0
+#else
+#define ARDUINOJSON_DOUBLE_IS_64BITS 1  // by default support 64-bit
+#endif
 #endif
 
 #if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64

+ 12 - 2
src/ArduinoJson/Polyfills/attributes.hpp

@@ -7,11 +7,14 @@
 
 #pragma once
 
-#ifdef _MSC_VER
+#ifdef _MSC_VER  // Visual Studio
+
 #define FORCE_INLINE __forceinline
 #define NO_INLINE __declspec(noinline)
 #define DEPRECATED(msg) __declspec(deprecated(msg))
-#else
+
+#elif defined(__GNUC__)  // GCC or Clang
+
 #define FORCE_INLINE __attribute__((always_inline))
 #define NO_INLINE __attribute__((noinline))
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
@@ -19,4 +22,11 @@
 #else
 #define DEPRECATED(msg) __attribute__((deprecated))
 #endif
+
+#else  // Other compilers
+
+#define FORCE_INLINE
+#define NO_INLINE
+#define DEPRECATED(msg)
+
 #endif

+ 2 - 2
src/ArduinoJson/Polyfills/normalize.hpp

@@ -16,7 +16,7 @@ int16_t normalize(T& value) {
   int16_t powersOf10 = 0;
 
   if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
-#if !defined(__SIZEOF_DOUBLE__) || __SIZEOF_DOUBLE__ >= 8
+#if ARDUINOJSON_DOUBLE_IS_64BITS
     if (value >= 1e256) {
       value /= 1e256;
       powersOf10 = int16_t(powersOf10 + 256);
@@ -57,7 +57,7 @@ int16_t normalize(T& value) {
   }
 
   if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
-#if !defined(__SIZEOF_DOUBLE__) || __SIZEOF_DOUBLE__ >= 8
+#if ARDUINOJSON_DOUBLE_IS_64BITS
     if (value < 1e-255) {
       value *= 1e256;
       powersOf10 = int16_t(powersOf10 - 256);

+ 2 - 1
src/ArduinoJson/TypeTraits/FloatTraits.hpp

@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 #include <stdlib.h>  // for size_t
+#include "../Configuration.hpp"
 #include "../Polyfills/math.hpp"
 
 namespace ArduinoJson {
@@ -17,7 +18,7 @@ namespace TypeTraits {
 template <typename T, size_t = sizeof(T)>
 struct FloatTraits {};
 
-#if !defined(__SIZEOF_DOUBLE__) || __SIZEOF_DOUBLE__ >= 8
+#if ARDUINOJSON_DOUBLE_IS_64BITS
 template <typename T>
 struct FloatTraits<T, 8 /*64bits*/> {
   typedef int64_t mantissa_type;