diff --git a/global.c b/global.c index 04f7049..2dbee82 100644 --- a/global.c +++ b/global.c @@ -28,6 +28,84 @@ static volatile uint8_t user_input_used = 0; /**< how much data has been receive static volatile uint32_t sleep_duration = 0; /**< sleep duration count down (in SysTick interrupts) */ +uint8_t addu8_safe(uint8_t a, uint8_t b) +{ + if (a > UINT8_MAX - b) { + return UINT8_MAX; + } else { + return a + b; + } +} + +uint16_t addu16_safe(uint16_t a, uint16_t b) +{ + if (a > UINT16_MAX - b) { + return UINT16_MAX; + } else { + return a + b; + } +} + +uint32_t addu32_safe(uint32_t a, uint32_t b) +{ + if (a > UINT32_MAX - b) { + return UINT32_MAX; + } else { + return a + b; + } +} + +int8_t adds8_safe(int8_t a, int8_t b) +{ + if (b > 0) { + if (a > INT8_MAX - b) { + return INT8_MAX; + } else { + return a + b; + } + } else { + if (a < INT8_MIN + b) { + return INT8_MIN; + } else { + return a + b; + } + } +} + +int16_t adds16_safe(int16_t a, int16_t b) +{ + if (b > 0) { + if (a > INT16_MAX - b) { + return INT16_MAX; + } else { + return a + b; + } + } else { + if (a < INT16_MIN + b) { + return INT16_MIN; + } else { + return a + b; + } + } +} + +int32_t adds32_safe(int32_t a, int32_t b) +{ + if (b > 0) { + if (a > INT32_MAX - b) { + return INT32_MAX; + } else { + return a + b; + } + } else { + if (a < INT32_MIN + b) { + return INT32_MIN; + } else { + return a + b; + } + } +} + char* b2s(uint64_t binary, uint8_t rjust) { static char string[64 + 1] = {0}; // the string representation to return diff --git a/global.h b/global.h index 9bbca0e..1dd6bab 100644 --- a/global.h +++ b/global.h @@ -24,11 +24,48 @@ /** integer underflow/overflow safe uint32_t addition (result to min/max on underflow/overflow) */ #define ADDU32_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > UINT32_MAX - _b) ? UINT32_MAX : (_a + _b)) : ((_a < _b) ? 0 : (_a - _b)));} /** integer underflow/overflow safe int8_t addition (result to min/max on underflow/overflow) */ -#define ADDS8_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > INT8_MAX - _b) ? INT8_MAX : (_a + _b)) : ((_a < INT8_MAX + _b) ? INT8_MAX : (_a - _b)));} +#define ADDS8_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > INT8_MAX - _b) ? INT8_MAX : (_a + _b)) : ((_a < INT8_MAX + _b) ? INT8_MAX : (_a + _b)));} /** integer underflow/overflow safe int16_t addition (result to min/max on underflow/overflow) */ -#define ADDS16_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > INT16_MAX - _b) ? INT16_MAX : (_a + _b)) : ((_a < INT16_MIN + _b) ? INT16_MIN : (_a - _b)));} +#define ADDS16_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > INT16_MAX - _b) ? INT16_MAX : (_a + _b)) : ((_a < INT16_MIN + _b) ? INT16_MIN : (_a + _b)));} /** integer underflow/overflow safe int32_t addition (result to min/max on underflow/overflow) */ -#define ADDS32_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > UINT32_MAX - _b) ? UINT32_MAX : (_a + _b)) : ((_a < INT32_MIN + _b) ? INT32_MIN : (_a - _b)));} +#define ADDS32_SAFE(a,b) {__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); a = (_b > 0 ? ((_a > INT32_MAX - _b) ? INT32_MAX : (_a + _b)) : ((_a < INT32_MIN + _b) ? INT32_MIN : (_a + _b)));} + +/** unsigned 8-bit integer overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +uint8_t addu8_safe(uint8_t a, uint8_t b); +/** unsigned 16-bit integer overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +uint16_t addu16_safe(uint16_t a, uint16_t b); +/** unsigned 8-bit integer overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +uint32_t addu32_safe(uint32_t a, uint32_t b); +/** signed 8-bit integer underflow/overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +int8_t adds8_safe(int8_t a, int8_t b); +/** signed 16-bit integer underflow/overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +int16_t adds16_safe(int16_t a, int16_t b); +/** signed 32-bit integer underflow/overflow safe addition + * @param[in] a first part of addition + * @param[in] b second part of addition + * return result of addition, or type max on overflow + */ +int32_t adds32_safe(int32_t a, int32_t b); /** build year as number */ #define COMPUTE_BUILD_YEAR \