Merge branch 'sj/string-list'
Code and test clean-up around string-list API. * sj/string-list: u-string-list: move "remove duplicates" test to "u-string-list.c" u-string-list: move "filter string" test to "u-string-list.c" u-string-list: move "test_split_in_place" to "u-string-list.c" u-string-list: move "test_split" into "u-string-list.c" string-list: enable sign compare warnings check string-list: return index directly when inserting an existing element string-list: remove unused "insert_at" parameter from add_entry string-list: fix sign compare warnings for loop iterator
This commit is contained in:
1
Makefile
1
Makefile
@@ -1365,6 +1365,7 @@ CLAR_TEST_SUITES += u-prio-queue
|
||||
CLAR_TEST_SUITES += u-reftable-tree
|
||||
CLAR_TEST_SUITES += u-strbuf
|
||||
CLAR_TEST_SUITES += u-strcmp-offset
|
||||
CLAR_TEST_SUITES += u-string-list
|
||||
CLAR_TEST_SUITES += u-strvec
|
||||
CLAR_TEST_SUITES += u-trailer
|
||||
CLAR_TEST_SUITES += u-urlmatch-normalization
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define DISABLE_SIGN_COMPARE_WARNINGS
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "string-list.h"
|
||||
|
||||
@@ -17,19 +15,19 @@ void string_list_init_dup(struct string_list *list)
|
||||
|
||||
/* if there is no exact match, point to the index where the entry could be
|
||||
* inserted */
|
||||
static int get_entry_index(const struct string_list *list, const char *string,
|
||||
int *exact_match)
|
||||
static size_t get_entry_index(const struct string_list *list, const char *string,
|
||||
int *exact_match)
|
||||
{
|
||||
int left = -1, right = list->nr;
|
||||
size_t left = 0, right = list->nr;
|
||||
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
|
||||
|
||||
while (left + 1 < right) {
|
||||
int middle = left + (right - left) / 2;
|
||||
while (left < right) {
|
||||
size_t middle = left + (right - left) / 2;
|
||||
int compare = cmp(string, list->items[middle].string);
|
||||
if (compare < 0)
|
||||
right = middle;
|
||||
else if (compare > 0)
|
||||
left = middle;
|
||||
left = middle + 1;
|
||||
else {
|
||||
*exact_match = 1;
|
||||
return middle;
|
||||
@@ -40,14 +38,13 @@ static int get_entry_index(const struct string_list *list, const char *string,
|
||||
return right;
|
||||
}
|
||||
|
||||
/* returns -1-index if already exists */
|
||||
static int add_entry(int insert_at, struct string_list *list, const char *string)
|
||||
static size_t add_entry(struct string_list *list, const char *string)
|
||||
{
|
||||
int exact_match = 0;
|
||||
int index = insert_at != -1 ? insert_at : get_entry_index(list, string, &exact_match);
|
||||
size_t index = get_entry_index(list, string, &exact_match);
|
||||
|
||||
if (exact_match)
|
||||
return -1 - index;
|
||||
return index;
|
||||
|
||||
ALLOC_GROW(list->items, list->nr+1, list->alloc);
|
||||
if (index < list->nr)
|
||||
@@ -63,10 +60,7 @@ static int add_entry(int insert_at, struct string_list *list, const char *string
|
||||
|
||||
struct string_list_item *string_list_insert(struct string_list *list, const char *string)
|
||||
{
|
||||
int index = add_entry(-1, list, string);
|
||||
|
||||
if (index < 0)
|
||||
index = -1 - index;
|
||||
size_t index = add_entry(list, string);
|
||||
|
||||
return list->items + index;
|
||||
}
|
||||
@@ -116,9 +110,9 @@ struct string_list_item *string_list_lookup(struct string_list *list, const char
|
||||
void string_list_remove_duplicates(struct string_list *list, int free_util)
|
||||
{
|
||||
if (list->nr > 1) {
|
||||
int src, dst;
|
||||
size_t dst = 1;
|
||||
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
|
||||
for (src = dst = 1; src < list->nr; src++) {
|
||||
for (size_t src = 1; src < list->nr; src++) {
|
||||
if (!cmp(list->items[dst - 1].string, list->items[src].string)) {
|
||||
if (list->strdup_strings)
|
||||
free(list->items[src].string);
|
||||
@@ -134,8 +128,8 @@ void string_list_remove_duplicates(struct string_list *list, int free_util)
|
||||
int for_each_string_list(struct string_list *list,
|
||||
string_list_each_func_t fn, void *cb_data)
|
||||
{
|
||||
int i, ret = 0;
|
||||
for (i = 0; i < list->nr; i++)
|
||||
int ret = 0;
|
||||
for (size_t i = 0; i < list->nr; i++)
|
||||
if ((ret = fn(&list->items[i], cb_data)))
|
||||
break;
|
||||
return ret;
|
||||
@@ -144,8 +138,8 @@ int for_each_string_list(struct string_list *list,
|
||||
void filter_string_list(struct string_list *list, int free_util,
|
||||
string_list_each_func_t want, void *cb_data)
|
||||
{
|
||||
int src, dst = 0;
|
||||
for (src = 0; src < list->nr; src++) {
|
||||
size_t dst = 0;
|
||||
for (size_t src = 0; src < list->nr; src++) {
|
||||
if (want(&list->items[src], cb_data)) {
|
||||
list->items[dst++] = list->items[src];
|
||||
} else {
|
||||
@@ -171,13 +165,12 @@ void string_list_remove_empty_items(struct string_list *list, int free_util)
|
||||
void string_list_clear(struct string_list *list, int free_util)
|
||||
{
|
||||
if (list->items) {
|
||||
int i;
|
||||
if (list->strdup_strings) {
|
||||
for (i = 0; i < list->nr; i++)
|
||||
for (size_t i = 0; i < list->nr; i++)
|
||||
free(list->items[i].string);
|
||||
}
|
||||
if (free_util) {
|
||||
for (i = 0; i < list->nr; i++)
|
||||
for (size_t i = 0; i < list->nr; i++)
|
||||
free(list->items[i].util);
|
||||
}
|
||||
free(list->items);
|
||||
@@ -189,13 +182,12 @@ void string_list_clear(struct string_list *list, int free_util)
|
||||
void string_list_clear_func(struct string_list *list, string_list_clear_func_t clearfunc)
|
||||
{
|
||||
if (list->items) {
|
||||
int i;
|
||||
if (clearfunc) {
|
||||
for (i = 0; i < list->nr; i++)
|
||||
for (size_t i = 0; i < list->nr; i++)
|
||||
clearfunc(list->items[i].util, list->items[i].string);
|
||||
}
|
||||
if (list->strdup_strings) {
|
||||
for (i = 0; i < list->nr; i++)
|
||||
for (size_t i = 0; i < list->nr; i++)
|
||||
free(list->items[i].string);
|
||||
}
|
||||
free(list->items);
|
||||
|
||||
@@ -1,105 +1,9 @@
|
||||
#define DISABLE_SIGN_COMPARE_WARNINGS
|
||||
|
||||
#include "test-tool.h"
|
||||
#include "strbuf.h"
|
||||
#include "string-list.h"
|
||||
|
||||
/*
|
||||
* Parse an argument into a string list. arg should either be a
|
||||
* ':'-separated list of strings, or "-" to indicate an empty string
|
||||
* list (as opposed to "", which indicates a string list containing a
|
||||
* single empty string). list->strdup_strings must be set.
|
||||
*/
|
||||
static void parse_string_list(struct string_list *list, const char *arg)
|
||||
{
|
||||
if (!strcmp(arg, "-"))
|
||||
return;
|
||||
|
||||
(void)string_list_split(list, arg, ':', -1);
|
||||
}
|
||||
|
||||
static void write_list(const struct string_list *list)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list->nr; i++)
|
||||
printf("[%d]: \"%s\"\n", i, list->items[i].string);
|
||||
}
|
||||
|
||||
static void write_list_compact(const struct string_list *list)
|
||||
{
|
||||
int i;
|
||||
if (!list->nr)
|
||||
printf("-\n");
|
||||
else {
|
||||
printf("%s", list->items[0].string);
|
||||
for (i = 1; i < list->nr; i++)
|
||||
printf(":%s", list->items[i].string);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int prefix_cb(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
const char *prefix = (const char *)cb_data;
|
||||
return starts_with(item->string, prefix);
|
||||
}
|
||||
|
||||
int cmd__string_list(int argc, const char **argv)
|
||||
{
|
||||
if (argc == 5 && !strcmp(argv[1], "split")) {
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
int i;
|
||||
const char *s = argv[2];
|
||||
int delim = *argv[3];
|
||||
int maxsplit = atoi(argv[4]);
|
||||
|
||||
i = string_list_split(&list, s, delim, maxsplit);
|
||||
printf("%d\n", i);
|
||||
write_list(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 5 && !strcmp(argv[1], "split_in_place")) {
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
int i;
|
||||
char *s = xstrdup(argv[2]);
|
||||
const char *delim = argv[3];
|
||||
int maxsplit = atoi(argv[4]);
|
||||
|
||||
i = string_list_split_in_place(&list, s, delim, maxsplit);
|
||||
printf("%d\n", i);
|
||||
write_list(&list);
|
||||
string_list_clear(&list, 0);
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 4 && !strcmp(argv[1], "filter")) {
|
||||
/*
|
||||
* Retain only the items that have the specified prefix.
|
||||
* Arguments: list|- prefix
|
||||
*/
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
const char *prefix = argv[3];
|
||||
|
||||
parse_string_list(&list, argv[2]);
|
||||
filter_string_list(&list, 0, prefix_cb, (void *)prefix);
|
||||
write_list_compact(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) {
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
|
||||
parse_string_list(&list, argv[2]);
|
||||
string_list_remove_duplicates(&list, 0);
|
||||
write_list_compact(&list);
|
||||
string_list_clear(&list, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "sort")) {
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
@@ -11,6 +11,7 @@ clar_test_suites = [
|
||||
'unit-tests/u-reftable-tree.c',
|
||||
'unit-tests/u-strbuf.c',
|
||||
'unit-tests/u-strcmp-offset.c',
|
||||
'unit-tests/u-string-list.c',
|
||||
'unit-tests/u-strvec.c',
|
||||
'unit-tests/u-trailer.c',
|
||||
'unit-tests/u-urlmatch-normalization.c',
|
||||
@@ -123,7 +124,6 @@ integration_tests = [
|
||||
't0060-path-utils.sh',
|
||||
't0061-run-command.sh',
|
||||
't0062-revision-walking.sh',
|
||||
't0063-string-list.sh',
|
||||
't0066-dir-iterator.sh',
|
||||
't0067-parse_pathspec_file.sh',
|
||||
't0068-for-each-repo.sh',
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2012 Michael Haggerty
|
||||
#
|
||||
|
||||
test_description='Test string list functionality'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_split () {
|
||||
cat >expected &&
|
||||
test_expect_success "split $1 at $2, max $3" "
|
||||
test-tool string-list split '$1' '$2' '$3' >actual &&
|
||||
test_cmp expected actual &&
|
||||
test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
|
||||
test_cmp expected actual
|
||||
"
|
||||
}
|
||||
|
||||
test_split_in_place() {
|
||||
cat >expected &&
|
||||
test_expect_success "split (in place) $1 at $2, max $3" "
|
||||
test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
|
||||
test_cmp expected actual
|
||||
"
|
||||
}
|
||||
|
||||
test_split "foo:bar:baz" ":" "-1" <<EOF
|
||||
3
|
||||
[0]: "foo"
|
||||
[1]: "bar"
|
||||
[2]: "baz"
|
||||
EOF
|
||||
|
||||
test_split "foo:bar:baz" ":" "0" <<EOF
|
||||
1
|
||||
[0]: "foo:bar:baz"
|
||||
EOF
|
||||
|
||||
test_split "foo:bar:baz" ":" "1" <<EOF
|
||||
2
|
||||
[0]: "foo"
|
||||
[1]: "bar:baz"
|
||||
EOF
|
||||
|
||||
test_split "foo:bar:baz" ":" "2" <<EOF
|
||||
3
|
||||
[0]: "foo"
|
||||
[1]: "bar"
|
||||
[2]: "baz"
|
||||
EOF
|
||||
|
||||
test_split "foo:bar:" ":" "-1" <<EOF
|
||||
3
|
||||
[0]: "foo"
|
||||
[1]: "bar"
|
||||
[2]: ""
|
||||
EOF
|
||||
|
||||
test_split "" ":" "-1" <<EOF
|
||||
1
|
||||
[0]: ""
|
||||
EOF
|
||||
|
||||
test_split ":" ":" "-1" <<EOF
|
||||
2
|
||||
[0]: ""
|
||||
[1]: ""
|
||||
EOF
|
||||
|
||||
test_split_in_place "foo:;:bar:;:baz:;:" ":;" "-1" <<EOF
|
||||
10
|
||||
[0]: "foo"
|
||||
[1]: ""
|
||||
[2]: ""
|
||||
[3]: "bar"
|
||||
[4]: ""
|
||||
[5]: ""
|
||||
[6]: "baz"
|
||||
[7]: ""
|
||||
[8]: ""
|
||||
[9]: ""
|
||||
EOF
|
||||
|
||||
test_split_in_place "foo:;:bar:;:baz" ":;" "0" <<EOF
|
||||
1
|
||||
[0]: "foo:;:bar:;:baz"
|
||||
EOF
|
||||
|
||||
test_split_in_place "foo:;:bar:;:baz" ":;" "1" <<EOF
|
||||
2
|
||||
[0]: "foo"
|
||||
[1]: ";:bar:;:baz"
|
||||
EOF
|
||||
|
||||
test_split_in_place "foo:;:bar:;:baz" ":;" "2" <<EOF
|
||||
3
|
||||
[0]: "foo"
|
||||
[1]: ""
|
||||
[2]: ":bar:;:baz"
|
||||
EOF
|
||||
|
||||
test_split_in_place "foo:;:bar:;:" ":;" "-1" <<EOF
|
||||
7
|
||||
[0]: "foo"
|
||||
[1]: ""
|
||||
[2]: ""
|
||||
[3]: "bar"
|
||||
[4]: ""
|
||||
[5]: ""
|
||||
[6]: ""
|
||||
EOF
|
||||
|
||||
test_expect_success "test filter_string_list" '
|
||||
test "x-" = "x$(test-tool string-list filter - y)" &&
|
||||
test "x-" = "x$(test-tool string-list filter no y)" &&
|
||||
test yes = "$(test-tool string-list filter yes y)" &&
|
||||
test yes = "$(test-tool string-list filter no:yes y)" &&
|
||||
test yes = "$(test-tool string-list filter yes:no y)" &&
|
||||
test y1:y2 = "$(test-tool string-list filter y1:y2 y)" &&
|
||||
test y2:y1 = "$(test-tool string-list filter y2:y1 y)" &&
|
||||
test "x-" = "x$(test-tool string-list filter x1:x2 y)"
|
||||
'
|
||||
|
||||
test_expect_success "test remove_duplicates" '
|
||||
test "x-" = "x$(test-tool string-list remove_duplicates -)" &&
|
||||
test "x" = "x$(test-tool string-list remove_duplicates "")" &&
|
||||
test a = "$(test-tool string-list remove_duplicates a)" &&
|
||||
test a = "$(test-tool string-list remove_duplicates a:a)" &&
|
||||
test a = "$(test-tool string-list remove_duplicates a:a:a:a:a)" &&
|
||||
test a:b = "$(test-tool string-list remove_duplicates a:b)" &&
|
||||
test a:b = "$(test-tool string-list remove_duplicates a:a:b)" &&
|
||||
test a:b = "$(test-tool string-list remove_duplicates a:b:b)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:b:c)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:c)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:b:b:c)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:b:c:c)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:b:c:c)" &&
|
||||
test a:b:c = "$(test-tool string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
|
||||
'
|
||||
|
||||
test_done
|
||||
227
t/unit-tests/u-string-list.c
Normal file
227
t/unit-tests/u-string-list.c
Normal file
@@ -0,0 +1,227 @@
|
||||
#include "unit-test.h"
|
||||
#include "string-list.h"
|
||||
|
||||
static void t_vcreate_string_list_dup(struct string_list *list,
|
||||
int free_util, va_list ap)
|
||||
{
|
||||
const char *arg;
|
||||
|
||||
cl_assert(list->strdup_strings);
|
||||
|
||||
string_list_clear(list, free_util);
|
||||
while ((arg = va_arg(ap, const char *)))
|
||||
string_list_append(list, arg);
|
||||
}
|
||||
|
||||
static void t_create_string_list_dup(struct string_list *list, int free_util, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
cl_assert(list->strdup_strings);
|
||||
|
||||
string_list_clear(list, free_util);
|
||||
va_start(ap, free_util);
|
||||
t_vcreate_string_list_dup(list, free_util, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void t_string_list_clear(struct string_list *list, int free_util)
|
||||
{
|
||||
string_list_clear(list, free_util);
|
||||
cl_assert_equal_p(list->items, NULL);
|
||||
cl_assert_equal_i(list->nr, 0);
|
||||
cl_assert_equal_i(list->alloc, 0);
|
||||
}
|
||||
|
||||
static void t_string_list_equal(struct string_list *list,
|
||||
struct string_list *expected_strings)
|
||||
{
|
||||
cl_assert_equal_i(list->nr, expected_strings->nr);
|
||||
cl_assert(list->nr <= list->alloc);
|
||||
for (size_t i = 0; i < expected_strings->nr; i++)
|
||||
cl_assert_equal_s(list->items[i].string,
|
||||
expected_strings->items[i].string);
|
||||
}
|
||||
|
||||
static void t_string_list_split(const char *data, int delim, int maxsplit, ...)
|
||||
{
|
||||
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, maxsplit);
|
||||
t_vcreate_string_list_dup(&expected_strings, 0, ap);
|
||||
va_end(ap);
|
||||
|
||||
string_list_clear(&list, 0);
|
||||
len = string_list_split(&list, data, delim, maxsplit);
|
||||
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(void)
|
||||
{
|
||||
t_string_list_split("foo:bar:baz", ':', -1, "foo", "bar", "baz", NULL);
|
||||
t_string_list_split("foo:bar:baz", ':', 0, "foo:bar:baz", NULL);
|
||||
t_string_list_split("foo:bar:baz", ':', 1, "foo", "bar:baz", NULL);
|
||||
t_string_list_split("foo:bar:baz", ':', 2, "foo", "bar", "baz", NULL);
|
||||
t_string_list_split("foo:bar:", ':', -1, "foo", "bar", "", NULL);
|
||||
t_string_list_split("", ':', -1, "", NULL);
|
||||
t_string_list_split(":", ':', -1, "", "", NULL);
|
||||
}
|
||||
|
||||
static void t_string_list_split_in_place(const char *data, const char *delim,
|
||||
int maxsplit, ...)
|
||||
{
|
||||
struct string_list expected_strings = STRING_LIST_INIT_DUP;
|
||||
struct string_list list = STRING_LIST_INIT_NODUP;
|
||||
char *string = xstrdup(data);
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, maxsplit);
|
||||
t_vcreate_string_list_dup(&expected_strings, 0, ap);
|
||||
va_end(ap);
|
||||
|
||||
string_list_clear(&list, 0);
|
||||
len = string_list_split_in_place(&list, string, delim, maxsplit);
|
||||
cl_assert_equal_i(len, expected_strings.nr);
|
||||
t_string_list_equal(&list, &expected_strings);
|
||||
|
||||
free(string);
|
||||
string_list_clear(&expected_strings, 0);
|
||||
string_list_clear(&list, 0);
|
||||
}
|
||||
|
||||
void test_string_list__split_in_place(void)
|
||||
{
|
||||
t_string_list_split_in_place("foo:;:bar:;:baz:;:", ":;", -1,
|
||||
"foo", "", "", "bar", "", "", "baz", "", "", "", NULL);
|
||||
t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 0,
|
||||
"foo:;:bar:;:baz", NULL);
|
||||
t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 1,
|
||||
"foo", ";:bar:;:baz", NULL);
|
||||
t_string_list_split_in_place("foo:;:bar:;:baz", ":;", 2,
|
||||
"foo", "", ":bar:;:baz", NULL);
|
||||
t_string_list_split_in_place("foo:;:bar:;:", ":;", -1,
|
||||
"foo", "", "", "bar", "", "", "", NULL);
|
||||
}
|
||||
|
||||
static int prefix_cb(struct string_list_item *item, void *cb_data)
|
||||
{
|
||||
const char *prefix = (const char *)cb_data;
|
||||
return starts_with(item->string, prefix);
|
||||
}
|
||||
|
||||
static void t_string_list_filter(struct string_list *list, ...)
|
||||
{
|
||||
struct string_list expected_strings = STRING_LIST_INIT_DUP;
|
||||
const char *prefix = "y";
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, list);
|
||||
t_vcreate_string_list_dup(&expected_strings, 0, ap);
|
||||
va_end(ap);
|
||||
|
||||
filter_string_list(list, 0, prefix_cb, (void *)prefix);
|
||||
t_string_list_equal(list, &expected_strings);
|
||||
|
||||
string_list_clear(&expected_strings, 0);
|
||||
}
|
||||
|
||||
void test_string_list__filter(void)
|
||||
{
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
|
||||
t_create_string_list_dup(&list, 0, NULL);
|
||||
t_string_list_filter(&list, NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "no", NULL);
|
||||
t_string_list_filter(&list, NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "yes", NULL);
|
||||
t_string_list_filter(&list, "yes", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "no", "yes", NULL);
|
||||
t_string_list_filter(&list, "yes", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "yes", "no", NULL);
|
||||
t_string_list_filter(&list, "yes", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "y1", "y2", NULL);
|
||||
t_string_list_filter(&list, "y1", "y2", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "y2", "y1", NULL);
|
||||
t_string_list_filter(&list, "y2", "y1", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "x1", "x2", NULL);
|
||||
t_string_list_filter(&list, NULL);
|
||||
|
||||
t_string_list_clear(&list, 0);
|
||||
}
|
||||
|
||||
static void t_string_list_remove_duplicates(struct string_list *list, ...)
|
||||
{
|
||||
struct string_list expected_strings = STRING_LIST_INIT_DUP;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, list);
|
||||
t_vcreate_string_list_dup(&expected_strings, 0, ap);
|
||||
va_end(ap);
|
||||
|
||||
string_list_remove_duplicates(list, 0);
|
||||
t_string_list_equal(list, &expected_strings);
|
||||
|
||||
string_list_clear(&expected_strings, 0);
|
||||
}
|
||||
|
||||
void test_string_list__remove_duplicates(void)
|
||||
{
|
||||
struct string_list list = STRING_LIST_INIT_DUP;
|
||||
|
||||
t_create_string_list_dup(&list, 0, NULL);
|
||||
t_string_list_remove_duplicates(&list, NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "", NULL);
|
||||
t_string_list_remove_duplicates(&list, "", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", "a", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", "b", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "b", "b", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "b", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", "b", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "b", "b", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "b", "c", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", "b", "b", "c", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_create_string_list_dup(&list, 0, "a", "a", "a", "b", "b", "b",
|
||||
"c", "c", "c", NULL);
|
||||
t_string_list_remove_duplicates(&list, "a", "b", "c", NULL);
|
||||
|
||||
t_string_list_clear(&list, 0);
|
||||
}
|
||||
Reference in New Issue
Block a user