From d8981dbb49679dffb5bd0f3558ea0fda37615175 Mon Sep 17 00:00:00 2001 From: Robear Selwans Date: Tue, 17 May 2022 22:48:13 +0200 Subject: [PATCH] Added EV_TOSTR and EV_TOSTRLEN Signed-off-by: Robear Selwans --- ev_macros.h | 5 ++++ ev_types.h | 78 ++++++++++++++++++++++++++++++++++++---------------- tostr_test.c | 40 +++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 tostr_test.c diff --git a/ev_macros.h b/ev_macros.h index 5ac2696..73dabda 100644 --- a/ev_macros.h +++ b/ev_macros.h @@ -286,4 +286,9 @@ #define __EV_INTERNAL_FOREACH63_UDATA(OP, UDATA, a, ...) OP(UDATA, a) __EV_INTERNAL_FOREACH62_UDATA(OP, UDATA, __VA_ARGS__) #define __EV_INTERNAL_FOREACH64_UDATA(OP, UDATA, a, ...) OP(UDATA, a) __EV_INTERNAL_FOREACH63_UDATA(OP, UDATA, __VA_ARGS__) +/*! + * \brief Macro to get a the hex value of a 4-number as a character + */ +#define EV_TOHEX_CHAR(c) (("0123456789abcdef")[c]) + #endif // EV_HEADERS_MACROS_H diff --git a/ev_types.h b/ev_types.h index b119194..a94914e 100644 --- a/ev_types.h +++ b/ev_types.h @@ -10,6 +10,9 @@ typedef void(*ev_free_fn)(void *self); typedef u64(*ev_hash_fn)(void *self, u64 seed); typedef bool(*ev_equal_fn)(void *self, void *other); +typedef void(*ev_tostr_fn)(void *self, char *out); +typedef u32(*ev_tostrlen_fn)(); + typedef struct { EV_DEBUG(const char *name;) @@ -20,15 +23,19 @@ typedef struct { ev_free_fn free_fn; ev_hash_fn hash_fn; ev_equal_fn equal_fn; + ev_tostr_fn tostr_fn; + ev_tostrlen_fn tostrlen_fn; void *default_val; void *invalid_val; } EvTypeData; -#define COPY_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_COPY_FUNCTION_,T),_),name) -#define FREE_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_FREE_FUNCTION_,T),_),name) -#define HASH_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_HASH_FUNCTION_,T),_),name) -#define EQUAL_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_EQUAL_FUNCTION_,T),_),name) +#define COPY_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_COPY_FUNCTION_,T),_),name) +#define FREE_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_FREE_FUNCTION_,T),_),name) +#define HASH_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_HASH_FUNCTION_,T),_),name) +#define EQUAL_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_EQUAL_FUNCTION_,T),_),name) +#define TOSTR_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTR_FUNCTION_,T),_),name) +#define TOSTRLEN_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTRLEN_FUNCTION_,T),_),name) #define DEFINE_COPY_FUNCTION(T,name) void COPY_FUNCTION(T,name)(T *dst, T *src) #define DEFINE_DEFAULT_COPY_FUNCTION(T) \ @@ -47,10 +54,28 @@ typedef struct { #define DEFINE_DEFAULT_EQUAL_FUNCTION(T) \ DEFINE_EQUAL_FUNCTION(T,DEFAULT) { return memcmp(self, other, sizeof(T)); } -#define DECLARE_COPY_FUNCTION(T,name) DEFINE_COPY_FUNCTION(T,name); -#define DECLARE_FREE_FUNCTION(T,name) DEFINE_FREE_FUNCTION(T,name); -#define DECLARE_HASH_FUNCTION(T,name) DEFINE_HASH_FUNCTION(T,name); -#define DECLARE_EQUAL_FUNCTION(T,name) DEFINE_EQUAL_FUNCTION(T,name); +#define DEFINE_TOSTR_FUNCTION(T,name) void TOSTR_FUNCTION(T,name)(T *self, char* out) +#define DEFINE_DEFAULT_TOSTR_FUNCTION(T) \ + DEFINE_TOSTR_FUNCTION(T,DEFAULT) \ + { \ + for(int i = 0; i < sizeof(T); i++) \ + { \ + u8 byte = ((u8*)self)[i];\ + out[i*2] = EV_TOHEX_CHAR((u32)(byte >> 4) & 0xf); \ + out[i*2+1] = EV_TOHEX_CHAR((u32)byte & 0xf); \ + } \ + } + +#define DEFINE_TOSTRLEN_FUNCTION(T,name) u32 TOSTRLEN_FUNCTION(T,name)() +#define DEFINE_DEFAULT_TOSTRLEN_FUNCTION(T) \ + DEFINE_TOSTRLEN_FUNCTION(T,DEFAULT) { return sizeof(T) * 2; } + +#define DECLARE_COPY_FUNCTION(T,name) DEFINE_COPY_FUNCTION(T,name); +#define DECLARE_FREE_FUNCTION(T,name) DEFINE_FREE_FUNCTION(T,name); +#define DECLARE_HASH_FUNCTION(T,name) DEFINE_HASH_FUNCTION(T,name); +#define DECLARE_EQUAL_FUNCTION(T,name) DEFINE_EQUAL_FUNCTION(T,name); +#define DECLARE_TOSTR_FUNCTION(T,name) DEFINE_TOSTR_FUNCTION(T,name); +#define DECLARE_TOSTRLEN_FUNCTION(T,name) DEFINE_TOSTRLEN_FUNCTION(T,name); #define EV_OVERRIDE_VAR(T) EV_CAT(__ev_internal_override_var_,T) #define TypeData(T) EV_CAT(EV_TYPEDATA_,T) @@ -71,26 +96,33 @@ typedef struct { #define __EV_STRUCT_METHOD_DEF(T, ...) EV_CAT(__EV_,EV_CAT(EV_HEAD __VA_ARGS__,_FN))(T, EV_TAIL __VA_ARGS__) -#define COPY(...) (COPY , __VA_ARGS__) -#define FREE(...) (FREE , __VA_ARGS__) -#define HASH(...) (HASH , __VA_ARGS__) -#define EQUAL(...) (EQUAL , __VA_ARGS__) -#define DEFAULT(...) (DEFAULT, __VA_ARGS__) -#define INVALID(...) (INVALID, __VA_ARGS__) +#define COPY(...) (COPY , __VA_ARGS__) +#define FREE(...) (FREE , __VA_ARGS__) +#define HASH(...) (HASH , __VA_ARGS__) +#define EQUAL(...) (EQUAL , __VA_ARGS__) +#define TOSTR(...) (TOSTR , __VA_ARGS__) +#define TOSTRLEN(...) (TOSTRLEN , __VA_ARGS__) +#define DEFAULT(...) (DEFAULT , __VA_ARGS__) +#define INVALID(...) (INVALID , __VA_ARGS__) -#define __EV_COPY_FN(T,name) .copy_fn = (ev_copy_fn) COPY_FUNCTION(T,name), -#define __EV_FREE_FN(T,name) .free_fn = (ev_free_fn) FREE_FUNCTION(T,name), -#define __EV_HASH_FN(T,name) .hash_fn = (ev_hash_fn) HASH_FUNCTION(T,name), -#define __EV_EQUAL_FN(T,name) .equal_fn = (ev_equal_fn)EQUAL_FUNCTION(T,name), +#define __EV_COPY_FN(T,name) .copy_fn = (ev_copy_fn) COPY_FUNCTION(T,name), +#define __EV_FREE_FN(T,name) .free_fn = (ev_free_fn) FREE_FUNCTION(T,name), +#define __EV_HASH_FN(T,name) .hash_fn = (ev_hash_fn) HASH_FUNCTION(T,name), +#define __EV_EQUAL_FN(T,name) .equal_fn = (ev_equal_fn) EQUAL_FUNCTION(T,name), +#define __EV_TOSTR_FN(T,name) .tostr_fn = (ev_tostr_fn) TOSTR_FUNCTION(T,name), +#define __EV_TOSTRLEN_FN(T,name) .tostrlen_fn = (ev_tostrlen_fn) TOSTRLEN_FUNCTION(T,name), #define __EV_DEFAULT_FN(T, ...) .default_val = (void*)&(T){ __VA_ARGS__ }, #define __EV_INVALID_FN(T, ...) .invalid_val = (void*)&(T){ __VA_ARGS__ }, -#define METHOD_CHECK(...) __VA_ARGS__ EV_DEBUG(?__VA_ARGS__:assert(!EV_STR(__VA_ARGS__)"not defined")) +void nop() {} +#define METHOD_CHECK(T, ...) (__VA_ARGS__ EV_DEBUG(?__VA_ARGS__:(assert(!EV_STRINGIZE(__VA_ARGS__)"not defined"),(T)nop))) -#define EV_COPY(T) METHOD_CHECK(TypeData(T).copy_fn) -#define EV_FREE(T) METHOD_CHECK(TypeData(T).free_fn) -#define EV_HASH(T) METHOD_CHECK(TypeData(T).hash_fn) -#define EV_EQUAL(T) METHOD_CHECK(TypeData(T).equal_fn) +#define EV_COPY(T) METHOD_CHECK(ev_copy_fn, TypeData(T).copy_fn) +#define EV_FREE(T) METHOD_CHECK(ev_free_fn, TypeData(T).free_fn) +#define EV_HASH(T) METHOD_CHECK(ev_hash_fn, TypeData(T).hash_fn) +#define EV_EQUAL(T) METHOD_CHECK(ev_equal_fn, TypeData(T).equal_fn) +#define EV_TOSTR(T) METHOD_CHECK(ev_tostr_fn, TypeData(T).tostr_fn) +#define EV_TOSTRLEN(T) METHOD_CHECK(ev_tostrlen_fn, TypeData(T).tostrlen_fn) #define __EV_OVERRIDE_DEFAULT(T, ...) EV_OVERRIDE_VAR(T).__VA_ARGS__, #define __EV_DEFAULT_INTERNAL(T) (*(T*)TypeData(T).default_val) #define EV_DEFAULT(T, ...) EV_VA_OPT_ELSE(__VA_ARGS__) \ diff --git a/tostr_test.c b/tostr_test.c new file mode 100644 index 0000000..ca99034 --- /dev/null +++ b/tostr_test.c @@ -0,0 +1,40 @@ +#include +#include "ev_types.h" +#include "ev_numeric.h" + +typedef struct { + char *name; + int age; + char *desc; +} Person; + +DEFINE_TOSTR_FUNCTION(Person, PERSON_PRINT) +{ + sprintf(out, "%s:\n\tage: %d\n\tdesc: %s", self->name, self->age, self->desc); +} + +TYPEDATA_GEN(Person, + TOSTR(PERSON_PRINT), + DEFAULT( + .name = "sisyphus", + .age = 9999, + .desc = "One can only imagine him happy" + ), + INVALID( + .name = NULL, + .age = -1, + .desc = NULL + ) +); + +int main() +{ + puts(""); + char out[256] = {}; + + Person sisyphue = EV_DEFAULT(Person); + EV_TOSTR(Person)(&sisyphue, out); + + puts(out); + return 0; +}