From 73f8baf464426010f8bc752bdf6a1708c21d77ff Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Thu, 3 May 2018 17:29:10 +0200 Subject: [PATCH] Add method _parse_str for array. --- m-array.h | 32 ++++++++++++++++++++++++++++++++ tests/test-marray.c | 19 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/m-array.h b/m-array.h index 90bde100..630410f3 100644 --- a/m-array.h +++ b/m-array.h @@ -75,6 +75,7 @@ ,OPLIST(oplist) \ ,M_IF_METHOD(CMP, oplist)(SORT(M_C(name, _special_sort)),) \ ,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),) \ + ,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),) \ ,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),) \ ,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),) \ ,M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),) \ @@ -761,6 +762,37 @@ } \ , /* no OUT_STR */ ) \ \ + M_IF_METHOD(PARSE_STR, oplist)( \ + static inline bool \ + M_C(name, _parse_str)(array_t array, const char str[], const char**endp) \ + { \ + ARRAYI_CONTRACT(array); \ + assert (str != NULL); \ + M_C(name,_clean)(array); \ + bool success = false; \ + int c = *str++; \ + if (M_UNLIKELY (c != '[')) goto exit; \ + c = *str++; \ + if (M_UNLIKELY (c == ']')) { success = true; goto exit; } \ + if (M_UNLIKELY (c == 0)) goto exit; \ + str--; \ + type item; \ + M_GET_INIT oplist (item); \ + do { \ + bool b = M_GET_PARSE_STR oplist (item, str, &str); \ + do { c = *str++; } while (isspace(c)); \ + if (b == false || c == 0) { goto exit; } \ + M_C(name, _push_back)(array, item); \ + } while (c == M_GET_SEPARATOR oplist); \ + M_GET_CLEAR oplist (item); \ + ARRAYI_CONTRACT(array); \ + success = (c == ']'); \ + exit: \ + if (endp) *endp = str; \ + return success; \ + } \ + , /* no PARSE_STR */ ) \ + \ M_IF_METHOD(IN_STR, oplist)( \ static inline bool \ M_C(name, _in_str)(array_t array, FILE *file) \ diff --git a/tests/test-marray.c b/tests/test-marray.c index ec255b9b..64b05d3e 100644 --- a/tests/test-marray.c +++ b/tests/test-marray.c @@ -212,14 +212,33 @@ static void test_mpz(void) M_LET(str, STRING_OPLIST) { array_mpz_get_str(str, array1, false); assert (string_cmp_str (str, "[]") == 0); + const char *sp; + b = array_mpz_parse_str(array2, string_get_cstr(str), &sp); + assert(b); + assert(*sp == 0); + assert(array_mpz_equal_p(array1, array2)); + my_mpz_set_ui (z, 17); array_mpz_push_back (array1, z); array_mpz_get_str(str, array1, false); assert (string_cmp_str (str, "[17]") == 0); + b = array_mpz_parse_str(array2, string_get_cstr(str), &sp); + assert(b); + assert(*sp == 0); + assert(array_mpz_equal_p(array1, array2)); + my_mpz_set_ui (z, 42); array_mpz_push_back (array1, z); array_mpz_get_str(str, array1, true); assert (string_cmp_str (str, "[17][17,42]") == 0); + b = array_mpz_parse_str(array2, string_get_cstr(str), &sp); + assert(b); + assert(strcmp(sp, "[17,42]") == 0); + assert(!array_mpz_equal_p(array1, array2)); + b = array_mpz_parse_str(array2, sp, &sp); + assert(b); + assert(strcmp(sp, "") == 0); + assert(array_mpz_equal_p(array1, array2)); // NOTE: Not the same order than list... }