3737#ifndef _COMMON_FUNC_H_
3838#define _COMMON_FUNC_H_
3939
40+
4041#ifdef __cplusplus
41- extern "C" {
42+ // namespace and templates must be outside the `extern "C"` declaration...
43+ namespace ADAFRUIT_DETAIL
44+ {
45+ template <typename T, size_t N>
46+ constexpr size_t arrcount_fails_if_not_array (T const (&)[N]) noexcept
47+ {
48+ return N;
49+ }
50+ }
51+ extern " C" {
52+ #define arrcount (arr ) ADAFRUIT_DETAIL::arrcount_fails_if_not_array(arr)
53+ #define ADA_STATIC_ASSERT (const_expr, message ) static_assert (const_expr, message)
54+ #elif __STDC_VERSION__ >= 201112L
55+ // Even C can have type-safety for equivalent of ARRAY_SIZE() macro, when using GCC (which this BSP does)
56+ #define __ADA_COMPATIBLE_TYPES (a,b ) __builtin_types_compatible_p(typeof (a), typeof (b)) // GCC extensions
57+ #define __ADA_BUILD_ERROR_IF_NONZERO (x ) (sizeof (struct { int :-!!(x)*0x1ee7 ;})) // if x is zero, reports "error: negative width in bit-field '<anonymous>'"
58+ #define __ADA_MUST_BE_ARRAY (x ) __ADA_BUILD_ERROR_IF_NONZERO(__ADA_COMPATIBLE_TYPES((x), &(*x)))
59+ #define ADA_STATIC_ASSERT (const_expr, message ) _Static_assert (const_expr, message)
60+ #define arrcount (_arr ) ( (sizeof (_arr) / sizeof ((_arr)[0 ])) + __ADA_MUST_BE_ARRAY(_arr) ) // compile-time error if not an array
61+ #else
62+ #error "C Compiler must support at least C11"
63+ #endif
64+
65+ #define ADA_STRING (x ) #x // /< stringify without expand
66+ #define ADA_XSTRING (x ) ADA_STRING(x) // /< expand then stringify
67+ #define ADA_STRCAT (a, b ) a##b // /< concat without expand
68+ #define ADA_XSTRCAT (a, b ) ADA_STRCAT(a, b) // /< expand then concat
69+
70+ #if defined __COUNTER__ && __COUNTER__ != __COUNTER__
71+ #define ADA_COUNTER __COUNTER__
72+ #else
73+ #define ADA_COUNTER __LINE__
4274#endif
4375
4476#define COMMENT_OUT (x )
4577
4678#define memclr (buffer, size ) memset(buffer, 0 , size)
4779#define varclr (_var ) memclr(_var, sizeof (*(_var)))
48- #define arrclr (_arr ) memclr(_arr, sizeof(_arr))
80+ #define arrclr (_arr ) memclr(_arr, sizeof (_arr[ 0 ]) * arrcount (_arr)) // adds type-safety
4981
50- #define arrcount (_arr ) ( sizeof(_arr) / sizeof(_arr[0]) )
5182
5283#define __swap32 (x ) __REV(x) // /< built-in function to swap Endian of 32-bit number
5384#define __swap16 (u16 ) ((uint16_t ) __REV16(u16 )) // /< built-in function to swap Endian of 16-bit number
117148const char * dbg_err_str (int32_t err_id); // TODO move to other place
118149
119150#if __cplusplus
120- #define PRINTF ::printf
151+ #define PRINTF ::printf
121152#else
122- #define PRINTF printf
153+ #define PRINTF printf
123154#endif
124155
125156
@@ -143,7 +174,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
143174
144175#define PRINT_LOCATION () PRINTF(" %s: %d:\n " , __PRETTY_FUNCTION__, __LINE__)
145176#define PRINT_MESS (x ) PRINTF(" %s: %d: %s \n " , __FUNCTION__, __LINE__, (char *)(x))
146- #define PRTNT_HEAP () if (CFG_DEBUG >= 3) PRINTF("\n%s: %d: Heap free: %d\n", __FUNCTION__, __LINE__, util_heap_get_free_size())
177+ #define PRINT_HEAP () if (CFG_DEBUG >= 3 ) PRINTF(" \n %s: %d: Heap free: %d\n " , __FUNCTION__, __LINE__, util_heap_get_free_size())
147178#define PRINT_STR (x ) PRINTF(" %s: %d: " #x " = %s\n " , __FUNCTION__, __LINE__, (char *)(x) )
148179#define PRINT_INT (x ) PRINTF(" %s: %d: " #x " = %ld\n " , __FUNCTION__, __LINE__, (uint32_t ) (x) )
149180#define PRINT_FLOAT (x ) PRINTF(" %s: %d: " #x " = %f\n " , __FUNCTION__, __LINE__, (float ) (x) )
@@ -182,7 +213,7 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
182213
183214#define PRINT_LOCATION ()
184215#define PRINT_MESS (x )
185- #define PRTNT_HEAP ()
216+ #define PRINT_HEAP ()
186217#define PRINT_STR (x )
187218#define PRINT_INT (x )
188219#define PRINT_HEX (x )
0 commit comments