From 8af4bfd64d72fad78e1b89c4317764a5dbd4539e Mon Sep 17 00:00:00 2001 From: Marco Bettini Date: Mon, 23 Jan 2023 09:38:51 +0000 Subject: [PATCH] lib: Add t_split_key_value_eq() --- src/lib/strfuncs.c | 13 ++++++++++++ src/lib/strfuncs.h | 10 ++++++++++ src/lib/test-strfuncs.c | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/lib/strfuncs.c b/src/lib/strfuncs.c index 4a4e1d1f59..c1b6aeafc2 100644 --- a/src/lib/strfuncs.c +++ b/src/lib/strfuncs.c @@ -709,6 +709,19 @@ size_t i_memcspn(const void *data, size_t data_len, return ptr - start; } +bool t_split_key_value(const char *arg, char separator, + const char **key_r, const char **value_r) +{ + *value_r = arg == NULL ? NULL : strchr(arg, separator); + if (*value_r != NULL) { + *key_r = t_strdup_until(arg, (*value_r)++); + return TRUE; + } + *value_r = ""; + *key_r = arg; + return FALSE; +} + static char ** split_str_slow(pool_t pool, const char *data, const char *separators, bool spaces) { diff --git a/src/lib/strfuncs.h b/src/lib/strfuncs.h index a364c5ac9b..1605013234 100644 --- a/src/lib/strfuncs.h +++ b/src/lib/strfuncs.h @@ -151,6 +151,16 @@ static inline char *i_strchr_to_next(const char *str, char chr) return tmp == NULL ? NULL : tmp+1; } +/* Split only on the first separator encountered. + Returns TRUE if the separator was found. + Returns FALSE and *value_r = "" otherwise. */ +bool t_split_key_value(const char *arg, char separator, + const char **key_r, const char **value_r); +static inline bool +t_split_key_value_eq(const char *arg, const char **key_r, const char **value_r) { + return t_split_key_value(arg, '=', key_r, value_r); +} + /* separators is an array of separator characters, not a separator string. an empty data string results in an array containing only NULL. */ char **p_strsplit(pool_t pool, const char *data, const char *separators) diff --git a/src/lib/test-strfuncs.c b/src/lib/test-strfuncs.c index e38b583d1d..fc59ae3acd 100644 --- a/src/lib/test-strfuncs.c +++ b/src/lib/test-strfuncs.c @@ -104,6 +104,49 @@ static void test_p_strarray_dup(void) test_end(); } +static void test_t_split_key_value(void) +{ + const char *key, *value; + + struct { + const char *input; + bool found; + const char *key; + const char *value; + } tests[] = { + { NULL, FALSE, NULL, "" }, + { "", FALSE, "", "" }, + { "=", TRUE, "", ""}, + { "====", TRUE, "", "==="}, + + { "key", FALSE, "key", "" }, + { "key=", TRUE, "key", "" }, + { "key=value", TRUE, "key", "value" }, + { "key=value=", TRUE, "key", "value=" }, + { "key=v=w=x", TRUE, "key", "v=w=x" }, + { "key=v=w=x=", TRUE, "key", "v=w=x=" }, + + { "=value", TRUE, "", "value" }, + { "=v=w=x", TRUE, "", "v=w=x" }, + { "=v=w=x=", TRUE, "", "v=w=x=" }, + { "==v=w=x=", TRUE, "", "=v=w=x=" }, + }; + + test_begin("t_split_key_value"); + { + test_assert(t_split_key_value("k:v", ':', &key, &value)); + test_assert_strcmp("k", key); + test_assert_strcmp("v", value); + } + for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { + bool found = t_split_key_value_eq(tests[i].input, &key, &value); + test_assert_idx(tests[i].found == found, i); + test_assert_idx(null_strcmp(tests[i].key, key) == 0, i); + test_assert_idx(null_strcmp(tests[i].value, value) == 0, i); + } + test_end(); +} + static void test_t_strsplit(void) { struct { @@ -685,6 +728,7 @@ void test_strfuncs(void) test_p_strdup_empty(); test_p_strdup_until(); test_p_strarray_dup(); + test_t_split_key_value(); test_t_strsplit(); test_t_strsplit_spaces(); test_t_str_replace(); -- 2.47.3