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_no0(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;
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
test_end();
}
+static void test_strsplit_tabescaped_inplace(void)
+{
+ const char *const *args;
+
+ test_begin("*_strsplit_tabescaped_inplace()");
+ for (unsigned int i = 0; i < N_ELEMENTS(strsplit_tests); i++) {
+ char *input = t_strdup_noconst(strsplit_tests[i].input);
+ args = t_strsplit_tabescaped_inplace(input);
+ for (unsigned int j = 0; strsplit_tests[i].output[j] != NULL; j++)
+ test_assert_idx(null_strcmp(strsplit_tests[i].output[j], args[j]) == 0, i);
+ }
+ test_end();
+}
+
void test_strescape(void)
{
strsplit_tests[0].input = t_strdup_printf("%s\t%s\t%s\t",
test_str_escape();
test_tabescape();
test_strsplit_tabescaped();
+ test_strsplit_tabescaped_inplace();
}