diff --git a/cmdline/stress.c b/cmdline/stress.c index 9fc90065..b7d170d9 100644 --- a/cmdline/stress.c +++ b/cmdline/stress.c @@ -412,6 +412,29 @@ void stress_functions(dc_context_t* context) assert( strcmp(str, "")==0 ); free(str); + clist* list = dc_str_to_clist(NULL, " "); + assert( clist_count(list)==0 ); + clist_free_content(list); + clist_free(list); + + list = dc_str_to_clist("", " "); + assert( clist_count(list)==1 ); + clist_free_content(list); + clist_free(list); + + list = dc_str_to_clist(" ", " "); + assert( clist_count(list)==2 ); + clist_free_content(list); + clist_free(list); + + list = dc_str_to_clist("foo bar test", " "); + assert(clist_count(list)==3); + str = dc_str_from_clist(list, " "); + assert( strcmp(str, "foo bar test")==0 ); + clist_free_content(list); + clist_free(list); + free(str); + assert( strcmp("fresh=" DC_STRINGIFY(DC_STATE_IN_FRESH), "fresh=10")==0 ); /* these asserts check the values, the existance of the macros and also DC_STRINGIFY() */ assert( strcmp("noticed=" DC_STRINGIFY(DC_STATE_IN_NOTICED), "noticed=13")==0 ); assert( strcmp("seen=" DC_STRINGIFY(DC_STATE_IN_SEEN), "seen=16")==0 ); diff --git a/src/dc_tools.c b/src/dc_tools.c index 9170af14..55e0aa0a 100644 --- a/src/dc_tools.c +++ b/src/dc_tools.c @@ -552,6 +552,58 @@ char* dc_insert_breaks(const char* in, int break_every, const char* break_chars) } +// Join clist element to a string. +char* dc_str_from_clist(const clist* list, const char* delimiter) +{ + dc_strbuilder_t str; + dc_strbuilder_init(&str, 256); + + if (list) { + for (clistiter* cur = clist_begin(list); cur!=NULL ; cur=clist_next(cur)) { + const char* rfc724_mid = clist_content(cur); + if (rfc724_mid) { + if (str.buf[0] && delimiter) { + dc_strbuilder_cat(&str, delimiter); + } + dc_strbuilder_cat(&str, rfc724_mid); + } + } + } + + return str.buf; +} + + +// Split a string by a character. +// If the string is empty or NULL, an empty list is returned. +// The returned clist must be freed using clist_free_content()+clist_free() +// or given eg. to libetpan objects. +clist* dc_str_to_clist(const char* str, const char* delimiter) +{ + clist* list = clist_new(); + if (list==NULL) { + exit(54); + } + + if (str && delimiter && strlen(delimiter)>=1) { + const char* p1 = str; + while (1) { + const char* p2 = strstr(p1, delimiter); + if (p2==NULL) { + clist_append(list, (void*)strdup(p1)); + break; + } + else { + clist_append(list, (void*)strndup(p1, p2-p1)); + p1 = p2+strlen(delimiter); + } + } + } + + return list; +} + + /******************************************************************************* * clist tools ******************************************************************************/ diff --git a/src/dc_tools.h b/src/dc_tools.h index bd310750..6ffb2f88 100644 --- a/src/dc_tools.h +++ b/src/dc_tools.h @@ -42,6 +42,8 @@ void dc_truncate_n_unwrap_str (char*, int approx_characters, int do_unwrap) carray* dc_split_into_lines (const char* buf_terminated); /* split string into lines*/ void dc_free_splitted_lines (carray* lines); char* dc_insert_breaks (const char*, int break_every, const char* break_chars); /* insert a break every n characters, the return must be free()'d */ +char* dc_str_from_clist (const clist*, const char* delimiter); +clist* dc_str_to_clist (const char*, const char* delimiter); // from libetpan/src/data-types/base64.h (which cannot be included without adding libetpan/src/... to the include-search-paths, which would result in double-file-name-errors, so, for now, we use this hack) char* encode_base64 (const char * in, int len);