*/
static int append_one(struct string_list *list,
const char *p, const char *end,
- int in_place)
+ int in_place, unsigned flags)
{
if (!end)
end = p + strlen(p);
+ if ((flags & STRING_LIST_SPLIT_TRIM)) {
+ /* rtrim */
+ for (; p < end; end--)
+ if (!isspace(end[-1]))
+ break;
+ }
+
if (in_place) {
*((char *)end) = '\0';
string_list_append(list, p);
* returns "char *" pointer into that const string. Yucky but works ;-).
*/
static int split_string(struct string_list *list, const char *string, const char *delim,
- int maxsplit, int in_place)
+ int maxsplit, int in_place, unsigned flags)
{
int count = 0;
const char *p = string;
for (;;) {
char *end;
+ if (flags & STRING_LIST_SPLIT_TRIM) {
+ /* ltrim */
+ while (*p && isspace(*p))
+ p++;
+ }
+
if (0 <= maxsplit && maxsplit <= count)
end = NULL;
else
end = strpbrk(p, delim);
- count += append_one(list, p, end, in_place);
+ count += append_one(list, p, end, in_place, flags);
if (!end)
return count;
int string_list_split(struct string_list *list, const char *string,
const char *delim, int maxsplit)
{
- return split_string(list, string, delim, maxsplit, 0);
+ return split_string(list, string, delim, maxsplit, 0, 0);
}
int string_list_split_in_place(struct string_list *list, char *string,
const char *delim, int maxsplit)
{
- return split_string(list, string, delim, maxsplit, 1);
+ return split_string(list, string, delim, maxsplit, 1, 0);
+}
+
+int string_list_split_f(struct string_list *list, const char *string,
+ const char *delim, int maxsplit, unsigned flags)
+{
+ return split_string(list, string, delim, maxsplit, 0, flags);
+}
+
+int string_list_split_in_place_f(struct string_list *list, char *string,
+ const char *delim, int maxsplit, unsigned flags)
+{
+ return split_string(list, string, delim, maxsplit, 1, flags);
}
*/
int string_list_split_in_place(struct string_list *list, char *string,
const char *delim, int maxsplit);
+
+/* Flag bits for split_f and split_in_place_f functions */
+enum {
+ /*
+ * trim whitespaces around resulting string piece before adding
+ * it to the list
+ */
+ STRING_LIST_SPLIT_TRIM = (1 << 0),
+};
+
+int string_list_split_f(struct string_list *, const char *string,
+ const char *delim, int maxsplit, unsigned flags);
+
+int string_list_split_in_place_f(struct string_list *, char *string,
+ const char *delim, int maxsplit, unsigned flags);
#endif /* STRING_LIST_H */
string_list_clear(&list, 0);
}
+static void t_string_list_split_f(const char *data, const char *delim,
+ int maxsplit, unsigned flags, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
+ va_list ap;
+ int len;
+
+ va_start(ap, flags);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_f(&list, data, delim, maxsplit, flags);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_f(void)
+{
+ t_string_list_split_f("::foo:bar:baz:", ":", -1, 0,
+ "", "", "foo", "bar", "baz", "", NULL);
+ t_string_list_split_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
+ "a", "b c", NULL);
+}
+
+static void t_string_list_split_in_place_f(const char *data_, const char *delim,
+ int maxsplit, unsigned flags, ...)
+{
+ struct string_list expected_strings = STRING_LIST_INIT_DUP;
+ struct string_list list = STRING_LIST_INIT_NODUP;
+ char *data = xstrdup(data_);
+ va_list ap;
+ int len;
+
+ va_start(ap, flags);
+ t_vcreate_string_list_dup(&expected_strings, 0, ap);
+ va_end(ap);
+
+ string_list_clear(&list, 0);
+ len = string_list_split_in_place_f(&list, data, delim, maxsplit, flags);
+ cl_assert_equal_i(len, expected_strings.nr);
+ t_string_list_equal(&list, &expected_strings);
+
+ free(data);
+ string_list_clear(&expected_strings, 0);
+ string_list_clear(&list, 0);
+}
+
+void test_string_list__split_in_place_f(void)
+{
+ t_string_list_split_in_place_f("::foo:bar:baz:", ":", -1, 0,
+ "", "", "foo", "bar", "baz", "", NULL);
+ t_string_list_split_in_place_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
+ "foo", "bar", "baz", NULL);
+ t_string_list_split_in_place_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
+ "a", "b c", NULL);
+}
+
void test_string_list__split(void)
{
t_string_list_split("foo:bar:baz", ":", -1, "foo", "bar", "baz", NULL);