diff options
| -rw-r--r-- | Documentation/technical/api-string-list.txt | 9 | ||||
| -rw-r--r-- | string-list.c | 17 | ||||
| -rw-r--r-- | string-list.h | 7 | ||||
| -rwxr-xr-x | t/t0063-string-list.sh | 17 | ||||
| -rw-r--r-- | test-string-list.c | 10 | 
5 files changed, 60 insertions, 0 deletions
| diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt index 300b301093..0f8b7cee36 100644 --- a/Documentation/technical/api-string-list.txt +++ b/Documentation/technical/api-string-list.txt @@ -30,6 +30,9 @@ member (you need this if you add things later) and you should set the  . Can sort an unsorted list using `sort_string_list`. +. Can remove duplicate items from a sorted list using +  `string_list_remove_duplicates`. +  . Can remove individual items of an unsorted list using    `unsorted_string_list_delete_item`. @@ -108,6 +111,12 @@ write `string_list_insert(...)->util = ...;`.  	Look up a given string in the string_list, returning the containing  	string_list_item. If the string is not found, NULL is returned. +`string_list_remove_duplicates`:: + +	Remove all but the first of consecutive entries that have the +	same string value.  If free_util is true, call free() on the +	util members of any items that have to be deleted. +  * Functions for unsorted lists only  `string_list_append`:: diff --git a/string-list.c b/string-list.c index 179fde4210..decfa747fc 100644 --- a/string-list.c +++ b/string-list.c @@ -92,6 +92,23 @@ struct string_list_item *string_list_lookup(struct string_list *list, const char  	return list->items + i;  } +void string_list_remove_duplicates(struct string_list *list, int free_util) +{ +	if (list->nr > 1) { +		int src, dst; +		for (src = dst = 1; src < list->nr; src++) { +			if (!strcmp(list->items[dst - 1].string, list->items[src].string)) { +				if (list->strdup_strings) +					free(list->items[src].string); +				if (free_util) +					free(list->items[src].util); +			} else +				list->items[dst++] = list->items[src]; +		} +		list->nr = dst; +	} +} +  int for_each_string_list(struct string_list *list,  			 string_list_each_func_t fn, void *cb_data)  { diff --git a/string-list.h b/string-list.h index 7d18e622ec..3a6a6dc392 100644 --- a/string-list.h +++ b/string-list.h @@ -48,6 +48,13 @@ struct string_list_item *string_list_insert_at_index(struct string_list *list,  						     int insert_at, const char *string);  struct string_list_item *string_list_lookup(struct string_list *list, const char *string); +/* + * Remove all but the first of consecutive entries with the same + * string value.  If free_util is true, call free() on the util + * members of any items that have to be deleted. + */ +void string_list_remove_duplicates(struct string_list *sorted_list, int free_util); +  /* Use these functions only on unsorted lists: */ diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh index a5f05cd206..dbfc05ebdc 100755 --- a/t/t0063-string-list.sh +++ b/t/t0063-string-list.sh @@ -71,4 +71,21 @@ test_expect_success "test filter_string_list" '  	test "x-" = "x$(test-string-list filter x1:x2 y)"  ' +test_expect_success "test remove_duplicates" ' +	test "x-" = "x$(test-string-list remove_duplicates -)" && +	test "x" = "x$(test-string-list remove_duplicates "")" && +	test a = "$(test-string-list remove_duplicates a)" && +	test a = "$(test-string-list remove_duplicates a:a)" && +	test a = "$(test-string-list remove_duplicates a:a:a:a:a)" && +	test a:b = "$(test-string-list remove_duplicates a:b)" && +	test a:b = "$(test-string-list remove_duplicates a:a:b)" && +	test a:b = "$(test-string-list remove_duplicates a:b:b)" && +	test a:b:c = "$(test-string-list remove_duplicates a:b:c)" && +	test a:b:c = "$(test-string-list remove_duplicates a:a:b:c)" && +	test a:b:c = "$(test-string-list remove_duplicates a:b:b:c)" && +	test a:b:c = "$(test-string-list remove_duplicates a:b:c:c)" && +	test a:b:c = "$(test-string-list remove_duplicates a:a:b:b:c:c)" && +	test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)" +' +  test_done diff --git a/test-string-list.c b/test-string-list.c index 702276c1fc..2d6eda707e 100644 --- a/test-string-list.c +++ b/test-string-list.c @@ -87,6 +87,16 @@ int main(int argc, char **argv)  		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; +	} +  	fprintf(stderr, "%s: unknown function name: %s\n", argv[0],  		argv[1] ? argv[1] : "(there was none)");  	return 1; | 
