Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.

Commit ab53eb3

Browse files
author
Gustavo Lima Chaves
committed
Change sol_util_str_split()'s behavior WRT max_split argument.
It will now actually try and perform that number of splits, still returning what remained to be splitten, if any, as a single last split chunk. Signed-off-by: Gustavo Lima Chaves <[email protected]>
1 parent dfe54e7 commit ab53eb3

File tree

3 files changed

+43
-17
lines changed

3 files changed

+43
-17
lines changed

src/shared/sol-util.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,19 @@ sol_util_strerror(int errnum, char *buf, size_t buflen)
276276
}
277277

278278
struct sol_vector
279-
sol_util_str_split(const struct sol_str_slice slice, const char *delim, size_t maxsplit)
279+
sol_util_str_split(const struct sol_str_slice slice,
280+
const char *delim,
281+
size_t maxsplit)
280282
{
281283
struct sol_vector v = SOL_VECTOR_INIT(struct sol_str_slice);
282-
ssize_t dlen, len;
283284
const char *str = slice.data;
285+
ssize_t dlen;
286+
size_t len;
284287

285288
if (!slice.len || !delim)
286289
return v;
287290

288-
maxsplit = (maxsplit) ? : slice.len;
291+
maxsplit = (maxsplit) ? : slice.len - 1;
289292
dlen = strlen(delim);
290293
len = slice.len;
291294

@@ -298,16 +301,20 @@ sol_util_str_split(const struct sol_str_slice slice, const char *delim, size_t m
298301
s->len = _len; \
299302
} while (0)
300303

301-
while (str && (v.len < maxsplit)) {
304+
while (str && (v.len < maxsplit + 1)) {
302305
struct sol_str_slice *s;
303306
char *token = memmem(str, len, delim, dlen);
304307
if (!token) {
305308
CREATE_SLICE(str, len);
306309
break;
307310
}
308311

312+
if (v.len == (uint16_t)maxsplit)
313+
CREATE_SLICE(str, len);
314+
else
315+
CREATE_SLICE(str, (size_t)(token - str));
316+
309317
len -= (token - str) + dlen;
310-
CREATE_SLICE(str, token - str);
311318
str = token + dlen;
312319
}
313320
#undef CREATE_SLICE

src/shared/sol-util.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,21 @@ align_power2(unsigned int u)
187187
return 1 << ((sizeof(u) * 8) - left_zeros);
188188
}
189189

190-
/* The given slice 'slice' will be splitted in sub-strings delimited by the 'delim'
191-
* This function returns an vector of struct sol_str_slice.
190+
/**
191+
* Return a list of the words in a given string slice, using a given
192+
* delimiter string. If @a maxsplit is given, at most that number of
193+
* splits are done (thus, the list will have at most @c maxsplit+1
194+
* elements). If @c maxsplit is zero, then there is no limit on the
195+
* number of splits (all possible splits are made).
196+
*
197+
* @param slice The string slice to divide in sub-strings (in array of
198+
* slices form)
199+
* @param delim The delimiter string to divide @a slice based on
200+
* @param maxsplit The maximum number of splits to make on @a slice.
201+
* If it's 0, than make as many splits as it can.
192202
*
193-
* NOTE: Different from strtoken, it cosiderer the full string in 'delim' and split
194-
* up to the number of elements specified in 'maxplit'. If 'maxplit' is zero all
195-
* elements found are returned.
203+
* @return A vector of string slices with the splitted words, on
204+
* success, or @c NULL, otherwise.
196205
*/
197206
struct sol_vector sol_util_str_split(const struct sol_str_slice slice, const char *delim, size_t maxsplit);
198207

src/test/test-str-split.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,42 +46,50 @@ test_str_to_slice(void)
4646
const struct sol_str_slice slice;
4747
const char *delim;
4848
const char *const *strings;
49-
unsigned int len;
49+
unsigned int max_split;
50+
unsigned int n_splits;
5051
} items[] = {
5152
{
52-
{ strlen("Using space -l :q"), "Using space -l :qdsdsdsdkjskdjksjdksjdksjdksjd" },
53+
{ strlen("Using space -l :q"), "Using space -l :q"
54+
"dsdsdsdkjskdjksjdksjdksjdksjd" },
5355
" ",
5456
(const char *const []){ "Using", "space", "-l", ":q" },
57+
0,
5558
4
5659
},
5760
{
5861
{ strlen("Using space -l :q"), "Using space -l :q" },
5962
" ",
60-
(const char *const []){ "Using", "space" },
63+
(const char *const []){ "Using", "space -l :q" },
64+
1,
6165
2
6266
},
6367
{
6468
{ strlen("Using{{brackets{ {{"), "Using{{brackets{ {{" },
6569
"{",
66-
(const char *const []){ "Using", NULL, "brackets", " ", NULL, NULL },
70+
(const char *const []){ "Using", "", "brackets", " ", "", "" },
71+
5,
6772
6
6873
},
6974
{
7075
{ strlen("Using comma test"), "Using comma test" },
7176
",",
7277
(const char *const []){ "Using comma test" },
78+
0,
7379
1
7480
},
7581
{
7682
{ strlen("Using42brackets42 test42"), "Using42brackets42 test42" },
7783
"42",
78-
(const char *const []){ "Using", "brackets", " test", NULL },
84+
(const char *const []){ "Using", "brackets", " test", "" },
85+
3,
7986
4
8087
},
8188
{
8289
{ strlen("Using42brackets42 test42"), "Using42brackets42 test42" },
8390
NULL,
8491
NULL,
92+
0,
8593
0
8694
},
8795
};
@@ -91,8 +99,10 @@ test_str_to_slice(void)
9199
struct sol_vector tokens;
92100
struct sol_str_slice *s;
93101

94-
tokens = sol_util_str_split(items[i].slice, items[i].delim, items[i].len);
95-
ASSERT_INT_EQ(tokens.len, items[i].len);
102+
tokens = sol_util_str_split(items[i].slice, items[i].delim,
103+
items[i].max_split);
104+
105+
ASSERT_INT_EQ(tokens.len, items[i].n_splits);
96106

97107
SOL_VECTOR_FOREACH_IDX (&tokens, s, j)
98108
ASSERT(!strncmp(s->data, items[i].strings[j], s->len));

0 commit comments

Comments
 (0)