From e1147fb33d25a7331ebce55a6d208aaa86dad634 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Thu, 23 Aug 2018 19:58:02 +0200 Subject: [PATCH] Add support for IN_STR for default C types. --- m-core.h | 30 +++++++++++++++++++++++++----- tests/test-mlist.c | 7 ++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/m-core.h b/m-core.h index ec4a2e75..ddfdc31f 100644 --- a/m-core.h +++ b/m-core.h @@ -1269,12 +1269,32 @@ const void *: "%p", \ void *: "%p") +#define M_SCANF_FORMAT(x) \ + _Generic(((void)0,x), \ + char: "%c", \ + signed char: "%hhd", \ + unsigned char: "%hhu", \ + signed short: "%hd", \ + unsigned short: "%hu", \ + signed int: "%d", \ + unsigned int: "%u", \ + long int: "%ld", \ + unsigned long int: "%lu", \ + long long int: "%Ld", \ + unsigned long long int: "%Lu", \ + float: "%f", \ + double: "%lf", \ + long double: "%Lf") + /* Print a C variable if it is a standard type to stdout.*/ #define M_PRINT_ARG(x) printf(M_PRINTF_FORMAT(x), x) /* Print a C variable if it is a standard type to the given file 'f'.*/ #define M_FPRINT_ARG(f, x) fprintf(f, M_PRINTF_FORMAT(x), x) +/* Get a C variable if it is a standard type from the given file 'f'.*/ +#define M_FSCAN_ARG(xptr, f) (fscanf(f, M_SCANF_FORMAT(*xptr), xptr) == 1) + /* Transform a C variable into a string_t (needs m-string.h) */ #define M_GET_STRING_ARG(string, x, append) \ (append ? string_cat_printf : string_printf) (str, M_PRINTF_FORMAT(x), x) @@ -1760,7 +1780,7 @@ m_core_hash (const void *str, size_t length) #define M_GET_REVERSE(...) M_GET_METHOD(REVERSE, M_NO_DEFAULT, __VA_ARGS__) #define M_GET_GET_STR(...) M_GET_METHOD(GET_STR, M_NO_DEFAULT, __VA_ARGS__) #define M_GET_PARSE_STR(...) M_GET_METHOD(PARSE_STR, M_NO_DEFAULT, __VA_ARGS__) -#define M_GET_OUT_STR(...) M_GET_METHOD(OUT_STR, M_FPRINT_ARG, __VA_ARGS__) +#define M_GET_OUT_STR(...) M_GET_METHOD(OUT_STR, M_NO_DEFAULT, __VA_ARGS__) #define M_GET_IN_STR(...) M_GET_METHOD(IN_STR, M_NO_DEFAULT, __VA_ARGS__) #define M_GET_SEPARATOR(...) M_GET_METHOD(SEPARATOR, ',', __VA_ARGS__) #define M_GET_EXT_ALGO(...) M_GET_METHOD(EXT_ALGO, M_NO_EXT_ALGO, __VA_ARGS__) @@ -1826,22 +1846,22 @@ m_core_hash (const void *str, size_t length) HASH(M_HASH_A1_DEFAULT)) /* Default oplist for C standard types (int & float). - Implement a generic out_str function if using C11. + Implement generic out_str/in_str/parse_str/get_str function if using C11. */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define M_DEFAULT_OPLIST \ (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), \ INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \ - HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) , OUT_STR(M_FPRINT_ARG), \ + HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) , \ + IN_STR(M_FSCAN_ARG M_IPTR), OUT_STR(M_FPRINT_ARG), \ PARSE_STR(M_PARSE_DEFAULT_TYPE M_IPTR), M_GET_STR_METHOD_FOR_DEFAULT_TYPE) #else #define M_DEFAULT_OPLIST \ (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), \ INIT_MOVE(M_MOVE_DEFAULT), MOVE(M_MOVE_DEFAULT) , \ - HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) , \ - M_GET_STR_METHOD_FOR_DEFAULT_TYPE) + HASH(M_HASH_DEFAULT), SWAP(M_SWAP_DEFAULT) ) #endif #define M_CLASSIC_OPLIST(name) ( \ diff --git a/tests/test-mlist.c b/tests/test-mlist.c index 2756d217..b500d2de 100644 --- a/tests/test-mlist.c +++ b/tests/test-mlist.c @@ -597,7 +597,7 @@ LIST_DEF(list_int, int) static void test_out_default_oplist(void) { M_LET(str, string_t) - M_LET(list, list_int_t) { + M_LET(list, l2, list_int_t) { FILE *f = fopen ("a-mlist.dat", "wt"); if (!f) abort(); list_int_push_back(list, 2); @@ -612,6 +612,11 @@ static void test_out_default_oplist(void) fclose(f); list_int_get_str(str, list, false); assert (string_equal_str_p(str, "[3,2]")); + f = fopen("a-mlist.dat", "rt"); + if (!f) abort(); + assert (list_int_in_str(l2, f) == true); + assert (list_int_equal_p(l2, list)); + fclose(f); } } #else