]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add t_split_key_value_eq()
authorMarco Bettini <marco.bettini@open-xchange.com>
Mon, 23 Jan 2023 09:38:51 +0000 (09:38 +0000)
committerMarco Bettini <marco.bettini@open-xchange.com>
Thu, 2 Feb 2023 14:13:02 +0000 (14:13 +0000)
src/lib/strfuncs.c
src/lib/strfuncs.h
src/lib/test-strfuncs.c

index 4a4e1d1f5995e16e5f3d10339d02e26c38d1ebbc..c1b6aeafc25b04f695788b9267ba3fa8c29ce517 100644 (file)
@@ -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)
 {
index a364c5ac9b00051d186802cbd656d2dddd82bcc8..160501323461226e6849137b6a1f80933c1f6ac3 100644 (file)
@@ -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)
index e38b583d1d19ec591ffe71a2a560da41d4d72eaa..fc59ae3acd3d22bf6a7c5b7a0b34123f5164ac73 100644 (file)
@@ -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();