From 47a49263aedc01410f830fdb57812bd2e3185b24 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 2 May 2018 19:36:51 +0200 Subject: [PATCH] Add function _parse_str for string. --- m-core.h | 2 +- m-string.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ tests/test-mstring.c | 10 ++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/m-core.h b/m-core.h index 99598b52..1d47a5a6 100644 --- a/m-core.h +++ b/m-core.h @@ -1483,8 +1483,8 @@ m_core_hash (const void *str, size_t length) #define M_POP_POP(a) ,a, #define M_REVERSE_REVERSE(a) ,a, #define M_GET_STR_GET_STR(a) ,a, +#define M_PARSE_STR_PARSE_STR(a) ,a, #define M_OUT_STR_OUT_STR(a) ,a, -#define M_SET_STR_SET_STR(a) ,a, #define M_IN_STR_IN_STR(a) ,a, #define M_SEPARATOR_SEPARATOR(a) ,a, #define M_EXT_ALGO_EXT_ALGO(a) ,a, diff --git a/m-string.h b/m-string.h index df4ed27a..8ea382da 100644 --- a/m-string.h +++ b/m-string.h @@ -890,6 +890,50 @@ string_in_str(string_t v, FILE *f) return c == '"'; } +static inline bool +string_parse_str(string_t v, const char **str) +{ + STRINGI_CONTRACT(v); + M_ASSUME (str != NULL); + int c = *((*str)++); + if (c != '"') return false; + string_clean(v); + c = *((*str)++); + while (c != '"' && c != 0) { + if (M_UNLIKELY (c == '\\')) { + c = *((*str)++); + switch (c) { + case 'n': + case 't': + case 'r': + case '\\': + case '\"': + // This string acts as a perfect hashmap which supposes an ASCII mapping + // and (c^(c>>5)) is the hash function + c = " \r \" \n\\\t"[(c^(c>>5))& 0x07]; + break; + default: + if (!(c >= '0' && c <= '7')) + return false; + int d1 = c - '0'; + c = *((*str)++); + if (!(c >= '0' && c <= '7')) + return false; + int d2 = c - '0'; + c = *((*str)++); + if (!(c >= '0' && c <= '7')) + return false; + int d3 = c - '0'; + c = (d1 << 6) + (d2 << 3) + d3; + break; + } + } + string_push_back (v, c); + c = *((*str)++); + } + return c == '"'; +} + /* UTF8 Handling */ typedef enum { STRINGI_UTF8_STARTING = 0, diff --git a/tests/test-mstring.c b/tests/test-mstring.c index 8e382761..2a7337a4 100644 --- a/tests/test-mstring.c +++ b/tests/test-mstring.c @@ -288,6 +288,16 @@ static void test0(void) string_get_str(s2, s1, true); assert (string_cmp_str (s2, "\"Hello world\"\"Hello \\\"world\\\"\"") == 0); + const char *sp = string_get_cstr(s2); + b = string_parse_str(s1, &sp); + assert (b == true); + assert (strcmp(sp, "\"Hello \\\"world\\\"\"") == 0); + assert (string_cmp_str(s1, "Hello world") == 0); + b = string_parse_str(s1, &sp); + assert (b == true); + assert (strcmp(sp, "") == 0); + assert (string_cmp_str(s1, "Hello \"world\"") == 0); + string_set_str(s1, "Hello \"world\""); FILE *f = fopen ("a-mstring.dat", "wt"); assert (f != NULL);