Skip to content

Commit 9d7d22e

Browse files
committed
string-list: optionally trim string pieces split by string_list_split*()
Teach the unified split_string() to take an optional "flags" word, and define the first flag STRING_LIST_SPLIT_TRIM to cause the split pieces to be trimmed before they are placed in the string list. Signed-off-by: Junio C Hamano <[email protected]>
1 parent c7922b3 commit 9d7d22e

File tree

3 files changed

+106
-5
lines changed

3 files changed

+106
-5
lines changed

string-list.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,18 @@ void unsorted_string_list_delete_item(struct string_list *list, int i, int free_
282282
*/
283283
static int append_one(struct string_list *list,
284284
const char *p, const char *end,
285-
int in_place)
285+
int in_place, unsigned flags)
286286
{
287287
if (!end)
288288
end = p + strlen(p);
289289

290+
if ((flags & STRING_LIST_SPLIT_TRIM)) {
291+
/* rtrim */
292+
for (; p < end; end--)
293+
if (!isspace(end[-1]))
294+
break;
295+
}
296+
290297
if (in_place) {
291298
*((char *)end) = '\0';
292299
string_list_append(list, p);
@@ -307,7 +314,7 @@ static int append_one(struct string_list *list,
307314
* returns "char *" pointer into that const string. Yucky but works ;-).
308315
*/
309316
static int split_string(struct string_list *list, const char *string, const char *delim,
310-
int maxsplit, int in_place)
317+
int maxsplit, int in_place, unsigned flags)
311318
{
312319
int count = 0;
313320
const char *p = string;
@@ -320,12 +327,18 @@ static int split_string(struct string_list *list, const char *string, const char
320327
for (;;) {
321328
char *end;
322329

330+
if (flags & STRING_LIST_SPLIT_TRIM) {
331+
/* ltrim */
332+
while (*p && isspace(*p))
333+
p++;
334+
}
335+
323336
if (0 <= maxsplit && maxsplit <= count)
324337
end = NULL;
325338
else
326339
end = strpbrk(p, delim);
327340

328-
count += append_one(list, p, end, in_place);
341+
count += append_one(list, p, end, in_place, flags);
329342

330343
if (!end)
331344
return count;
@@ -336,11 +349,23 @@ static int split_string(struct string_list *list, const char *string, const char
336349
int string_list_split(struct string_list *list, const char *string,
337350
const char *delim, int maxsplit)
338351
{
339-
return split_string(list, string, delim, maxsplit, 0);
352+
return split_string(list, string, delim, maxsplit, 0, 0);
340353
}
341354

342355
int string_list_split_in_place(struct string_list *list, char *string,
343356
const char *delim, int maxsplit)
344357
{
345-
return split_string(list, string, delim, maxsplit, 1);
358+
return split_string(list, string, delim, maxsplit, 1, 0);
359+
}
360+
361+
int string_list_split_f(struct string_list *list, const char *string,
362+
const char *delim, int maxsplit, unsigned flags)
363+
{
364+
return split_string(list, string, delim, maxsplit, 0, flags);
365+
}
366+
367+
int string_list_split_in_place_f(struct string_list *list, char *string,
368+
const char *delim, int maxsplit, unsigned flags)
369+
{
370+
return split_string(list, string, delim, maxsplit, 1, flags);
346371
}

string-list.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,4 +281,16 @@ int string_list_split(struct string_list *list, const char *string,
281281
*/
282282
int string_list_split_in_place(struct string_list *list, char *string,
283283
const char *delim, int maxsplit);
284+
285+
/* flag bits for split_f and split_in_place_f functions */
286+
enum {
287+
/* trim() resulting string piece before adding it to the list */
288+
STRING_LIST_SPLIT_TRIM = (1 << 0),
289+
};
290+
291+
int string_list_split_f(struct string_list *, const char *string,
292+
const char *delim, int maxsplit, unsigned flags);
293+
294+
int string_list_split_in_place_f(struct string_list *, char *string,
295+
const char *delim, int maxsplit, unsigned flags);
284296
#endif /* STRING_LIST_H */

t/unit-tests/u-string-list.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,70 @@ static void t_string_list_split(const char *data, const char *delim, int maxspli
6363
string_list_clear(&list, 0);
6464
}
6565

66+
static void t_string_list_split_f(const char *data, const char *delim,
67+
int maxsplit, unsigned flags, ...)
68+
{
69+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
70+
struct string_list list = STRING_LIST_INIT_DUP;
71+
va_list ap;
72+
int len;
73+
74+
va_start(ap, flags);
75+
t_vcreate_string_list_dup(&expected_strings, 0, ap);
76+
va_end(ap);
77+
78+
string_list_clear(&list, 0);
79+
len = string_list_split_f(&list, data, delim, maxsplit, flags);
80+
cl_assert_equal_i(len, expected_strings.nr);
81+
t_string_list_equal(&list, &expected_strings);
82+
83+
string_list_clear(&expected_strings, 0);
84+
string_list_clear(&list, 0);
85+
}
86+
87+
void test_string_list__split_f(void)
88+
{
89+
t_string_list_split_f("::foo:bar:baz:", ":", -1, 0,
90+
"", "", "foo", "bar", "baz", "", NULL);
91+
t_string_list_split_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
92+
"foo", "bar", "baz", NULL);
93+
t_string_list_split_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
94+
"a", "b c", NULL);
95+
}
96+
97+
static void t_string_list_split_in_place_f(const char *data_, const char *delim,
98+
int maxsplit, unsigned flags, ...)
99+
{
100+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
101+
struct string_list list = STRING_LIST_INIT_NODUP;
102+
char *data = xstrdup(data_);
103+
va_list ap;
104+
int len;
105+
106+
va_start(ap, flags);
107+
t_vcreate_string_list_dup(&expected_strings, 0, ap);
108+
va_end(ap);
109+
110+
string_list_clear(&list, 0);
111+
len = string_list_split_in_place_f(&list, data, delim, maxsplit, flags);
112+
cl_assert_equal_i(len, expected_strings.nr);
113+
t_string_list_equal(&list, &expected_strings);
114+
115+
free(data);
116+
string_list_clear(&expected_strings, 0);
117+
string_list_clear(&list, 0);
118+
}
119+
120+
void test_string_list__split_in_place_f(void)
121+
{
122+
t_string_list_split_in_place_f("::foo:bar:baz:", ":", -1, 0,
123+
"", "", "foo", "bar", "baz", "", NULL);
124+
t_string_list_split_in_place_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM,
125+
"foo", "bar", "baz", NULL);
126+
t_string_list_split_in_place_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM,
127+
"a", "b c", NULL);
128+
}
129+
66130
void test_string_list__split(void)
67131
{
68132
t_string_list_split("foo:bar:baz", ":", -1, "foo", "bar", "baz", NULL);

0 commit comments

Comments
 (0)