Update comments.
This commit is contained in:
1 parent
1882148a7c
commit
8e7eae5751
1 file changed
+62
-36
@@ -35,11 +35,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define M_CORE_VERSION_MAJOR 0
|
/* By default, always use stdio. Can be turned off in specific environement if needed
|
||||||
#define M_CORE_VERSION_MINOR 2
|
by defining M_USE_STDIO to 0 */
|
||||||
#define M_CORE_VERSION_PATCHLEVEL 3
|
|
||||||
|
|
||||||
/* By default, always use stdio. Can be turned off in specific environement if needed */
|
|
||||||
#ifndef M_USE_STDIO
|
#ifndef M_USE_STDIO
|
||||||
# define M_USE_STDIO 1
|
# define M_USE_STDIO 1
|
||||||
#endif
|
#endif
|
||||||
@@ -47,12 +44,19 @@
|
|||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
/************************ Compiler Macro ***********************/
|
/************************ Compiler Macro ***********************/
|
||||||
/***************************************************************/
|
/***************************************************************/
|
||||||
|
|
||||||
|
/* Define M*LIB version */
|
||||||
|
#define M_CORE_VERSION_MAJOR 0
|
||||||
|
#define M_CORE_VERSION_MINOR 2
|
||||||
|
#define M_CORE_VERSION_PATCHLEVEL 3
|
||||||
|
|
||||||
/* M_ASSUME is equivalent to assert, but gives hints to compiler
|
/* M_ASSUME is equivalent to assert, but gives hints to compiler
|
||||||
about how to optimize the code if NDEBUG is defined. */
|
about how to optimize the code if NDEBUG is defined.
|
||||||
|
Not sure if it is worth it however. */
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
# define M_ASSUME(x) assert(x)
|
# define M_ASSUME(x) assert(x)
|
||||||
#elif defined(__GNUC__) \
|
#elif defined(__GNUC__) \
|
||||||
@@ -76,9 +80,9 @@
|
|||||||
# define M_UNLIKELY(cond) (cond)
|
# define M_UNLIKELY(cond) (cond)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define the exclusion size so that 2 atomic variables can be in
|
/* Define the exclusion size so that 2 atomic variables are in
|
||||||
separate cache line. This prevents false sharing to occur within the
|
separate cache lines. This prevents false sharing to occur within the
|
||||||
CPU cache line. */
|
CPU. */
|
||||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||||
# define M_ALIGN_FOR_CACHELINE_EXCLUSION 128
|
# define M_ALIGN_FOR_CACHELINE_EXCLUSION 128
|
||||||
#else
|
#else
|
||||||
@@ -2185,6 +2189,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
|
|
||||||
/* Default oplist for C standard types (int & float).
|
/* Default oplist for C standard types (int & float).
|
||||||
Implement generic out_str/in_str/parse_str/get_str function if using C11.
|
Implement generic out_str/in_str/parse_str/get_str function if using C11.
|
||||||
|
Add FILE I/O if stdio.h has been included
|
||||||
*/
|
*/
|
||||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||||
|
|
||||||
@@ -2199,7 +2204,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
IN_SERIAL(M_IN_SERIAL_DEFAULT_ARG M_IPTR), OUT_SERIAL(M_OUT_SERIAL_DEFAULT_ARG), \
|
IN_SERIAL(M_IN_SERIAL_DEFAULT_ARG M_IPTR), OUT_SERIAL(M_OUT_SERIAL_DEFAULT_ARG), \
|
||||||
PARSE_STR(M_PARSE_DEFAULT_TYPE M_IPTR), M_GET_STR_METHOD_FOR_DEFAULT_TYPE)
|
PARSE_STR(M_PARSE_DEFAULT_TYPE M_IPTR), M_GET_STR_METHOD_FOR_DEFAULT_TYPE)
|
||||||
# else
|
# else
|
||||||
/* FILE support */
|
/* No FILE support */
|
||||||
# define M_DEFAULT_OPLIST \
|
# define M_DEFAULT_OPLIST \
|
||||||
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \
|
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \
|
||||||
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \
|
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), CMP(M_CMP_DEFAULT), \
|
||||||
@@ -2216,8 +2221,8 @@ m_core_hash (const void *str, size_t length)
|
|||||||
HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) )
|
HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default oplist for standard types for pointers.
|
/* Default oplist for standard types of pointers.
|
||||||
*/
|
*/
|
||||||
#define M_PTR_OPLIST \
|
#define M_PTR_OPLIST \
|
||||||
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \
|
(INIT(M_INIT_DEFAULT), INIT_SET(M_SET_DEFAULT), SET(M_SET_DEFAULT), \
|
||||||
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), \
|
CLEAR(M_NOTHING_DEFAULT), EQUAL(M_EQUAL_DEFAULT), \
|
||||||
@@ -2225,7 +2230,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
SWAP(M_SWAP_DEFAULT) )
|
SWAP(M_SWAP_DEFAULT) )
|
||||||
|
|
||||||
/* Default oplist for complex objects with "classic" names for methods.
|
/* Default oplist for complex objects with "classic" names for methods.
|
||||||
*/
|
*/
|
||||||
#define M_CLASSIC_OPLIST(name) ( \
|
#define M_CLASSIC_OPLIST(name) ( \
|
||||||
INIT(M_C(name, _init)), \
|
INIT(M_C(name, _init)), \
|
||||||
INIT_SET(M_C(name, _init_set)), \
|
INIT_SET(M_C(name, _init_set)), \
|
||||||
@@ -2233,7 +2238,10 @@ m_core_hash (const void *str, size_t length)
|
|||||||
CLEAR(M_C(name, _clear)), \
|
CLEAR(M_C(name, _clear)), \
|
||||||
TYPE(M_C(name, _t)) )
|
TYPE(M_C(name, _t)) )
|
||||||
|
|
||||||
/* OPLIST for 'const char *' (with NO memory allocation) */
|
/* OPLIST for 'const char *' string (with NO memory allocation).
|
||||||
|
TODO: M_CSTR_HASH is buggy as the alignment condition of the string
|
||||||
|
doesn't match the one of m_core_hash.
|
||||||
|
*/
|
||||||
#define M_CSTR_HASH(s) (m_core_hash((s), strlen(s)))
|
#define M_CSTR_HASH(s) (m_core_hash((s), strlen(s)))
|
||||||
#define M_CSTR_EQUAL(a,b) (strcmp((a),(b)) == 0)
|
#define M_CSTR_EQUAL(a,b) (strcmp((a),(b)) == 0)
|
||||||
#define M_CSTR_OUT_STR(file, str) fprintf(file, "%s", str)
|
#define M_CSTR_OUT_STR(file, str) fprintf(file, "%s", str)
|
||||||
@@ -2329,7 +2337,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Test if the argument is a valid oplist.
|
/* Test if the argument is a valid oplist.
|
||||||
NOTE: Imperfect test.
|
NOTE: Incomplete test.
|
||||||
*/
|
*/
|
||||||
#define M_OPLIST_P(a) \
|
#define M_OPLIST_P(a) \
|
||||||
M_AND(M_AND(M_PARENTHESIS_P(a), M_INV(M_PARENTHESIS_P (M_OPFLAT a))), \
|
M_AND(M_AND(M_PARENTHESIS_P(a), M_INV(M_PARENTHESIS_P (M_OPFLAT a))), \
|
||||||
@@ -2361,6 +2369,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
#define M_GLOBALI_OPLIST_OR_DEF_ELSE(a) M_GLOBALI_OPLIST_OR_DEF_ELSE2(a, M_C(M_OPL_, a)())
|
#define M_GLOBALI_OPLIST_OR_DEF_ELSE(a) M_GLOBALI_OPLIST_OR_DEF_ELSE2(a, M_C(M_OPL_, a)())
|
||||||
#define M_GLOBALI_OPLIST_OR_DEF_ELSE2(a, op) M_IF( M_OPLIST_P(op))(M_C(M_OPL_, a), M_GLOBALI_OPLIST_DEFAULT2)
|
#define M_GLOBALI_OPLIST_OR_DEF_ELSE2(a, op) M_IF( M_OPLIST_P(op))(M_C(M_OPL_, a), M_GLOBALI_OPLIST_DEFAULT2)
|
||||||
|
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
/******************** Syntax Enhancing **********************/
|
/******************** Syntax Enhancing **********************/
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
@@ -2447,12 +2456,15 @@ m_core_hash (const void *str, size_t length)
|
|||||||
#define M_LETI_SINGLE2_INIT(oplist, name, ...) \
|
#define M_LETI_SINGLE2_INIT(oplist, name, ...) \
|
||||||
M_IF_METHOD(INIT_WITH,oplist)(M_CALL_INIT_WITH(oplist, name, __VA_ARGS__), M_GET_INIT_SET oplist (name, __VA_ARGS__))
|
M_IF_METHOD(INIT_WITH,oplist)(M_CALL_INIT_WITH(oplist, name, __VA_ARGS__), M_GET_INIT_SET oplist (name, __VA_ARGS__))
|
||||||
|
|
||||||
|
|
||||||
/* Transform the va list by adding their number as the first argument of
|
/* Transform the va list by adding their number as the first argument of
|
||||||
the list.
|
the list.
|
||||||
Example: M_VA(a,b,c,d,e) ==> 5,a,b,c,d,e */
|
Example: M_VA(a,b,c,d,e) ==> 5,a,b,c,d,e */
|
||||||
#define M_VA(...) M_NARGS(__VA_ARGS__), __VA_ARGS__
|
#define M_VA(...) M_NARGS(__VA_ARGS__), __VA_ARGS__
|
||||||
|
|
||||||
/* Initialize the continaer 'dest' with oplist and fill in with the VA arguments */
|
|
||||||
|
/* Initialize the container 'dest' as per 'oplist'
|
||||||
|
and fill it with the given VA arguments */
|
||||||
#define M_INIT_VAI(oplist, dest, ...) \
|
#define M_INIT_VAI(oplist, dest, ...) \
|
||||||
(void)(M_GET_INIT oplist (dest) , \
|
(void)(M_GET_INIT oplist (dest) , \
|
||||||
M_MAP2_C(M_INIT_VAI_FUNC, (dest, M_GET_PUSH oplist) , __VA_ARGS__))
|
M_MAP2_C(M_INIT_VAI_FUNC, (dest, M_GET_PUSH oplist) , __VA_ARGS__))
|
||||||
@@ -2464,10 +2476,17 @@ m_core_hash (const void *str, size_t length)
|
|||||||
/********************* MEMORY handling **********************/
|
/********************* MEMORY handling **********************/
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
/* Note: For C build, we explicitly don't cast the return value of
|
/* Default MEMORY handling macros.
|
||||||
|
Can be overloaded by user code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define a C and C++ version for default memory allocators.
|
||||||
|
Note: For C build, we explicitly don't cast the return value of
|
||||||
malloc, realloc as it is safer (compilers shall warn in case
|
malloc, realloc as it is safer (compilers shall warn in case
|
||||||
of invalid implicit cast, whereas they won't if there is an
|
of invalid implicit cast, whereas they won't if there is an
|
||||||
explicit cast) */
|
explicit cast) */
|
||||||
|
|
||||||
|
/* Define allocators for object */
|
||||||
#ifndef M_MEMORY_ALLOC
|
#ifndef M_MEMORY_ALLOC
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
@@ -2479,6 +2498,7 @@ m_core_hash (const void *str, size_t length)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Define allocators for array */
|
||||||
#ifndef M_MEMORY_REALLOC
|
#ifndef M_MEMORY_REALLOC
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
@@ -2491,11 +2511,9 @@ m_core_hash (const void *str, size_t length)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Basic ERROR handling macros.
|
/* Basic ERROR handling macros.
|
||||||
// Note: Can be overloaded by used code to:
|
Note: Can be overloaded by user code to
|
||||||
// * throw an exception if needed.
|
*/
|
||||||
// * set a global error variable and return
|
|
||||||
// * abort
|
|
||||||
#ifndef M_MEMORY_FULL
|
#ifndef M_MEMORY_FULL
|
||||||
#define M_MEMORY_FULL(size) do { \
|
#define M_MEMORY_FULL(size) do { \
|
||||||
fprintf(stderr, "ERROR(M*LIB): Cannot allocate %zu bytes of memory at (%s:%s:%d).\n", \
|
fprintf(stderr, "ERROR(M*LIB): Cannot allocate %zu bytes of memory at (%s:%s:%d).\n", \
|
||||||
@@ -2518,6 +2536,8 @@ m_core_hash (const void *str, size_t length)
|
|||||||
/******************* Exponential Backoff ********************/
|
/******************* Exponential Backoff ********************/
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
|
/* Can be increased / decreased by user code if needed
|
||||||
|
to increase / decrease backoff of code */
|
||||||
#ifndef M_BACKOFF_MAX_COUNT
|
#ifndef M_BACKOFF_MAX_COUNT
|
||||||
#define M_BACKOFF_MAX_COUNT 6
|
#define M_BACKOFF_MAX_COUNT 6
|
||||||
#endif
|
#endif
|
||||||
@@ -2543,8 +2563,10 @@ m_backoff_reset(m_backoff_t backoff)
|
|||||||
static inline void
|
static inline void
|
||||||
m_backoff_wait(m_backoff_t backoff)
|
m_backoff_wait(m_backoff_t backoff)
|
||||||
{
|
{
|
||||||
|
/* x is qualified as volatile to avoid being optimized away
|
||||||
|
by the compiler in the active sleep loop */
|
||||||
volatile int x = 0;
|
volatile int x = 0;
|
||||||
/* Cheap but fast pseudo random */
|
/* Cheap but fast pseudo random. */
|
||||||
backoff->seed = backoff->seed * 34721 + 17449;
|
backoff->seed = backoff->seed * 34721 + 17449;
|
||||||
const unsigned int mask = (1U << backoff->count) -1;
|
const unsigned int mask = (1U << backoff->count) -1;
|
||||||
const unsigned int count = mask & (backoff->seed >> 8);
|
const unsigned int count = mask & (backoff->seed >> 8);
|
||||||
@@ -2568,7 +2590,7 @@ m_backoff_clear(m_backoff_t backoff)
|
|||||||
/********************** Serialization ***********************/
|
/********************** Serialization ***********************/
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
/* Return code:
|
/* Serialization Return code:
|
||||||
* - OK & done,
|
* - OK & done,
|
||||||
* - OK & continue parsing
|
* - OK & continue parsing
|
||||||
* - Fail parsing
|
* - Fail parsing
|
||||||
@@ -2614,40 +2636,40 @@ typedef struct m_serial_local_s {
|
|||||||
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
||||||
} m_serial_local_t[1];
|
} m_serial_local_t[1];
|
||||||
|
|
||||||
// Object to handle the generic serial read of an object.
|
/* Object to handle the generic serial read of an object. */
|
||||||
typedef struct m_serial_read_s {
|
typedef struct m_serial_read_s {
|
||||||
const struct m_serial_read_interface_s *interface;
|
const struct m_serial_read_interface_s *interface;
|
||||||
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
||||||
} m_serial_read_t[1];
|
} m_serial_read_t[1];
|
||||||
|
|
||||||
// Forward declaration of string_t.
|
/* Forward declaration of string_t defined in m-string.h */
|
||||||
struct string_s;
|
struct string_s;
|
||||||
|
|
||||||
// Interface exported by the serial read object.
|
/* Interface that has to be exported by the serial read object. */
|
||||||
typedef struct m_serial_read_interface_s {
|
typedef struct m_serial_read_interface_s {
|
||||||
m_serial_return_code_t (*read_boolean)(m_serial_read_t,bool *);
|
m_serial_return_code_t (*read_boolean)(m_serial_read_t,bool *);
|
||||||
m_serial_return_code_t (*read_integer)(m_serial_read_t, long long *, const size_t size_of_type);
|
m_serial_return_code_t (*read_integer)(m_serial_read_t, long long *, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*read_float)(m_serial_read_t, long double *, const size_t size_of_type);
|
m_serial_return_code_t (*read_float)(m_serial_read_t, long double *, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*read_string)(m_serial_read_t, struct string_s *);
|
m_serial_return_code_t (*read_string)(m_serial_read_t, struct string_s *);
|
||||||
m_serial_return_code_t (*read_array_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
m_serial_return_code_t (*read_array_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
||||||
m_serial_return_code_t (*read_array_next)(m_serial_local_t, m_serial_read_t); // Return M_SERIAL_OK_DONE when array is finished parsing.
|
m_serial_return_code_t (*read_array_next)(m_serial_local_t, m_serial_read_t);
|
||||||
m_serial_return_code_t (*read_map_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
m_serial_return_code_t (*read_map_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
||||||
m_serial_return_code_t (*read_map_value)(m_serial_local_t, m_serial_read_t);
|
m_serial_return_code_t (*read_map_value)(m_serial_local_t, m_serial_read_t);
|
||||||
m_serial_return_code_t (*read_map_next)(m_serial_local_t, m_serial_read_t); // Return M_SERIAL_OK_DONE when map is finished parsing.
|
m_serial_return_code_t (*read_map_next)(m_serial_local_t, m_serial_read_t);
|
||||||
m_serial_return_code_t (*read_tuple_start)(m_serial_local_t, m_serial_read_t);
|
m_serial_return_code_t (*read_tuple_start)(m_serial_local_t, m_serial_read_t);
|
||||||
m_serial_return_code_t (*read_tuple_id)(m_serial_local_t, m_serial_read_t, const char *const field_name [], const int max, int *); // Return M_SERIAL_OK_DONE when tuple is finished parsing.
|
m_serial_return_code_t (*read_tuple_id)(m_serial_local_t, m_serial_read_t, const char *const field_name [], const int max, int *);
|
||||||
m_serial_return_code_t (*read_variant_start)(m_serial_local_t, m_serial_read_t, const char *const field_name[], const int max, int*);
|
m_serial_return_code_t (*read_variant_start)(m_serial_local_t, m_serial_read_t, const char *const field_name[], const int max, int*);
|
||||||
m_serial_return_code_t (*read_variant_end)(m_serial_local_t, m_serial_read_t);
|
m_serial_return_code_t (*read_variant_end)(m_serial_local_t, m_serial_read_t);
|
||||||
} m_serial_read_interface_t;
|
} m_serial_read_interface_t;
|
||||||
|
|
||||||
|
|
||||||
// Object to handle the generic serial write of an object.
|
/* Object to handle the generic serial write of an object. */
|
||||||
typedef struct m_serial_write_s {
|
typedef struct m_serial_write_s {
|
||||||
const struct m_serial_write_interface_s *interface;
|
const struct m_serial_write_interface_s *interface;
|
||||||
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
||||||
} m_serial_write_t[1];
|
} m_serial_write_t[1];
|
||||||
|
|
||||||
// Interface exported by the serial write object.
|
/* Interface that has to be exported by the serial write object. */
|
||||||
typedef struct m_serial_write_interface_s {
|
typedef struct m_serial_write_interface_s {
|
||||||
m_serial_return_code_t (*write_boolean)(m_serial_write_t,const bool data);
|
m_serial_return_code_t (*write_boolean)(m_serial_write_t,const bool data);
|
||||||
m_serial_return_code_t (*write_integer)(m_serial_write_t,const long long data, const size_t size_of_type);
|
m_serial_return_code_t (*write_integer)(m_serial_write_t,const long long data, const size_t size_of_type);
|
||||||
@@ -2667,7 +2689,9 @@ typedef struct m_serial_write_interface_s {
|
|||||||
m_serial_return_code_t (*write_variant_end)(m_serial_local_t, m_serial_write_t);
|
m_serial_return_code_t (*write_variant_end)(m_serial_local_t, m_serial_write_t);
|
||||||
} m_serial_write_interface_t;
|
} m_serial_write_interface_t;
|
||||||
|
|
||||||
/* Convert a C default variale (bool, integer, float) to a Serialized data */
|
/* Convert a C default variale (bool, integer, float) to a Serialized data.
|
||||||
|
Supports only C11.
|
||||||
|
*/
|
||||||
#define M_OUT_SERIAL_DEFAULT_ARG(serial, x) \
|
#define M_OUT_SERIAL_DEFAULT_ARG(serial, x) \
|
||||||
_Generic(((void)0,(x)), \
|
_Generic(((void)0,(x)), \
|
||||||
bool: (serial)->interface->write_boolean(serial, M_AS_TYPE(bool, (x))), \
|
bool: (serial)->interface->write_boolean(serial, M_AS_TYPE(bool, (x))), \
|
||||||
@@ -2690,7 +2714,9 @@ typedef struct m_serial_write_interface_s {
|
|||||||
const void *: M_SERIAL_FAIL /* unsupported */, \
|
const void *: M_SERIAL_FAIL /* unsupported */, \
|
||||||
void *: M_SERIAL_FAIL /* unsupported */)
|
void *: M_SERIAL_FAIL /* unsupported */)
|
||||||
|
|
||||||
/* Convert a Serialized data to a C default variale (bool, integer, float) */
|
/* Convert a Serialized data to a C default variale (bool, integer, float)
|
||||||
|
Supports only C11.
|
||||||
|
*/
|
||||||
#define M_IN_SERIAL_DEFAULT_ARG(xptr, serial) \
|
#define M_IN_SERIAL_DEFAULT_ARG(xptr, serial) \
|
||||||
_Generic(((void)0,*(xptr)), \
|
_Generic(((void)0,*(xptr)), \
|
||||||
bool: (serial)->interface->read_boolean(serial, M_AS_TYPE(bool *, xptr)), \
|
bool: (serial)->interface->read_boolean(serial, M_AS_TYPE(bool *, xptr)), \
|
||||||
@@ -2713,7 +2739,8 @@ typedef struct m_serial_write_interface_s {
|
|||||||
const void *: M_SERIAL_FAIL /* unsupported */, \
|
const void *: M_SERIAL_FAIL /* unsupported */, \
|
||||||
void *: M_SERIAL_FAIL /* unsupported */)
|
void *: M_SERIAL_FAIL /* unsupported */)
|
||||||
|
|
||||||
/* Helper functions for M_IN_SERIAL_DEFAULT_ARG */
|
/* Helper functions for M_IN_SERIAL_DEFAULT_ARG
|
||||||
|
as we need to define a function per supported type in the generic expression */
|
||||||
#define M_IN_SERIAL_DEFAULT_TYPE_DEF(name, type, func, promoted_type) \
|
#define M_IN_SERIAL_DEFAULT_TYPE_DEF(name, type, func, promoted_type) \
|
||||||
static inline m_serial_return_code_t \
|
static inline m_serial_return_code_t \
|
||||||
name (m_serial_read_t serial, type *ptr) \
|
name (m_serial_read_t serial, type *ptr) \
|
||||||
@@ -2740,5 +2767,4 @@ M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_float, float, read_float, long dou
|
|||||||
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_double, double, read_float, long double)
|
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_double, double, read_float, long double)
|
||||||
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_ldouble, long double, read_float, long double)
|
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_ldouble, long double, read_float, long double)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in new issue
Block a user