Mercurial > dovecot > core-2.2
changeset 22636:96e51a11c0aa
lib: Implement t_strsplit_tabescaped_inplace()
This is a more efficient version of t_strsplit_tabescaped(), which modifies
the input string instead of duplicating it.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 04 Nov 2017 01:39:38 +0200 |
parents | 82d8656bb3ad |
children | da955f909fdd |
files | src/lib/strescape.c src/lib/strescape.h |
diffstat | 2 files changed, 47 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/strescape.c Sat Nov 04 01:37:19 2017 +0200 +++ b/src/lib/strescape.c Sat Nov 04 01:39:38 2017 +0200 @@ -249,6 +249,50 @@ return str_tabunescape(t_strdup_noconst(str)); } +const char *const *t_strsplit_tabescaped_inplace(char *data) +{ + /* @UNSAFE */ + char **array; + unsigned int count, new_alloc_count, alloc_count; + + if (*data == '\0') + return t_new(const char *, 1); + + alloc_count = 32; + array = t_malloc(sizeof(char *) * alloc_count); + + array[0] = data; count = 1; + bool need_unescape = FALSE; + while ((data = strpbrk(data, "\t\001")) != NULL) { + /* separator or escape char found */ + if (*data == '\001') { + need_unescape = TRUE; + data++; + continue; + } + if (count+1 >= alloc_count) { + new_alloc_count = nearest_power(alloc_count+1); + array = p_realloc(unsafe_data_stack_pool, array, + sizeof(char *) * alloc_count, + sizeof(char *) * + new_alloc_count); + alloc_count = new_alloc_count; + } + *data++ = '\0'; + if (need_unescape) { + str_tabunescape(array[count-1]); + need_unescape = FALSE; + } + array[count++] = data; + } + if (need_unescape) + str_tabunescape(array[count-1]); + i_assert(count < alloc_count); + array[count] = NULL; + + return (const char *const *)array; +} + char **p_strsplit_tabescaped(pool_t pool, const char *str) { char **args;
--- a/src/lib/strescape.h Sat Nov 04 01:37:19 2017 +0200 +++ b/src/lib/strescape.h Sat Nov 04 01:39:38 2017 +0200 @@ -28,5 +28,8 @@ char **p_strsplit_tabescaped(pool_t pool, const char *str); const char *const *t_strsplit_tabescaped(const char *str); +/* Same as t_strsplit_tabescaped(), but the input string is modified and the + returned pointers inside the array point to the original string. */ +const char *const *t_strsplit_tabescaped_inplace(char *str); #endif