Skip to content

Commit 35e17b2

Browse files
committed
Merge branch 'ac/string-list-sort-u-and-tests'
The string_list API gains a new helper, string_list_sort_u(), and new unit tests to extend coverage. * ac/string-list-sort-u-and-tests: string-list: add string_list_sort_u() that mimics "sort -u" u-string-list: add unit tests for string-list methods
2 parents 4f39292 + 2e711ac commit 35e17b2

9 files changed

Lines changed: 263 additions & 16 deletions

File tree

builtin/clone.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,8 +1136,7 @@ int cmd_clone(int argc,
11361136
int val;
11371137

11381138
/* remove duplicates */
1139-
string_list_sort(&option_recurse_submodules);
1140-
string_list_remove_duplicates(&option_recurse_submodules, 0);
1139+
string_list_sort_u(&option_recurse_submodules, 0);
11411140

11421141
/*
11431142
* NEEDSWORK: In a multi-working-tree world, this needs to be

builtin/fast-export.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
11181118
free(full_name);
11191119
}
11201120

1121-
string_list_sort(&extra_refs);
1122-
string_list_remove_duplicates(&extra_refs, 0);
1121+
string_list_sort_u(&extra_refs, 0);
11231122
}
11241123

11251124
static void handle_tags_and_duplicates(struct string_list *extras)

builtin/pack-objects.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3855,10 +3855,8 @@ static void read_packs_list_from_stdin(struct rev_info *revs)
38553855
strbuf_reset(&buf);
38563856
}
38573857

3858-
string_list_sort(&include_packs);
3859-
string_list_remove_duplicates(&include_packs, 0);
3860-
string_list_sort(&exclude_packs);
3861-
string_list_remove_duplicates(&exclude_packs, 0);
3858+
string_list_sort_u(&include_packs, 0);
3859+
string_list_sort_u(&exclude_packs, 0);
38623860

38633861
repo_for_each_pack(the_repository, p) {
38643862
const char *pack_name = pack_basename(p);

builtin/sparse-checkout.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,7 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
293293
string_list_append(&sl, pe->pattern);
294294
}
295295

296-
string_list_sort(&sl);
297-
string_list_remove_duplicates(&sl, 0);
296+
string_list_sort_u(&sl, 0);
298297

299298
fprintf(fp, "/*\n!/*/\n");
300299

@@ -317,8 +316,7 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
317316

318317
strbuf_release(&parent_pattern);
319318

320-
string_list_sort(&sl);
321-
string_list_remove_duplicates(&sl, 0);
319+
string_list_sort_u(&sl, 0);
322320

323321
for (i = 0; i < sl.nr; i++) {
324322
char *pattern = escaped_pattern(sl.items[i].string);

help.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,7 @@ void list_cmds_by_config(struct string_list *list)
420420
if (repo_config_get_string_tmp(the_repository, "completion.commands", &cmd_list))
421421
return;
422422

423-
string_list_sort(list);
424-
string_list_remove_duplicates(list, 0);
423+
string_list_sort_u(list, 0);
425424

426425
while (*cmd_list) {
427426
struct strbuf sb = STRBUF_INIT;

notes.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,7 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
921921
if (string_list_add_note_lines(&sort_uniq_list, new_oid))
922922
goto out;
923923
string_list_remove_empty_items(&sort_uniq_list, 0);
924-
string_list_sort(&sort_uniq_list);
925-
string_list_remove_duplicates(&sort_uniq_list, 0);
924+
string_list_sort_u(&sort_uniq_list, 0);
926925

927926
/* create a new blob object from sort_uniq_list */
928927
if (for_each_string_list(&sort_uniq_list,

string-list.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ void string_list_sort(struct string_list *list)
247247
QSORT_S(list->items, list->nr, cmp_items, &sort_ctx);
248248
}
249249

250+
void string_list_sort_u(struct string_list *list, int free_util)
251+
{
252+
string_list_sort(list);
253+
string_list_remove_duplicates(list, free_util);
254+
}
255+
250256
struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
251257
const char *string)
252258
{

string-list.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ struct string_list_item *string_list_append_nodup(struct string_list *list, char
239239
*/
240240
void string_list_sort(struct string_list *list);
241241

242+
/**
243+
* Sort the list and then remove duplicate entries. If free_util is true,
244+
* call free() on the util members of any items that have to be deleted.
245+
*/
246+
void string_list_sort_u(struct string_list *list, int free_util);
247+
242248
/**
243249
* Like `string_list_has_string()` but for unsorted lists. Linear in
244250
* size of the list.

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

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,138 @@ void test_string_list__filter(void)
243243
t_string_list_clear(&list, 0);
244244
}
245245

246+
static void t_string_list_has_string(
247+
struct string_list *list,
248+
const char *string,
249+
int expected)
250+
{
251+
int has_string = string_list_has_string(list, string);
252+
cl_assert_equal_i(has_string, expected);
253+
}
254+
255+
void test_string_list__has_string(void)
256+
{
257+
struct string_list list = STRING_LIST_INIT_DUP;
258+
259+
t_create_string_list_dup(&list, 0, NULL);
260+
t_string_list_has_string(&list, "", 0);
261+
262+
t_create_string_list_dup(&list, 0, "a", "b", "c", NULL);
263+
t_string_list_has_string(&list, "a", 1);
264+
t_string_list_has_string(&list, "b", 1);
265+
t_string_list_has_string(&list, "c", 1);
266+
t_string_list_has_string(&list, "d", 0);
267+
268+
t_string_list_clear(&list, 0);
269+
}
270+
271+
static void t_string_list_insert(struct string_list *expected_strings, ...)
272+
{
273+
struct string_list strings_to_insert = STRING_LIST_INIT_DUP;
274+
struct string_list list = STRING_LIST_INIT_DUP;
275+
va_list ap;
276+
277+
va_start(ap, expected_strings);
278+
t_vcreate_string_list_dup(&strings_to_insert, 0, ap);
279+
va_end(ap);
280+
281+
for (size_t i = 0; i < strings_to_insert.nr; i++)
282+
string_list_insert(&list, strings_to_insert.items[i].string);
283+
284+
t_string_list_equal(&list, expected_strings);
285+
286+
string_list_clear(&strings_to_insert, 0);
287+
string_list_clear(&list, 0);
288+
}
289+
290+
void test_string_list__insert(void)
291+
{
292+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
293+
294+
t_create_string_list_dup(&expected_strings, 0, NULL);
295+
t_string_list_insert(&expected_strings, NULL);
296+
297+
t_create_string_list_dup(&expected_strings, 0, "a", "b", NULL);
298+
t_string_list_insert(&expected_strings, "b", "a", "a", "b", NULL);
299+
300+
t_create_string_list_dup(&expected_strings, 0, "a", "b", "c", NULL);
301+
t_string_list_insert(&expected_strings, "c", "b", "a", "c", "b", NULL);
302+
303+
t_create_string_list_dup(&expected_strings, 0, "", "a", NULL);
304+
t_string_list_insert(&expected_strings, "a", "a", "a", "", NULL);
305+
306+
t_string_list_clear(&expected_strings, 0);
307+
}
308+
309+
static void t_string_list_sort(struct string_list *list, ...)
310+
{
311+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
312+
va_list ap;
313+
314+
va_start(ap, list);
315+
t_vcreate_string_list_dup(&expected_strings, 0, ap);
316+
va_end(ap);
317+
318+
string_list_sort(list);
319+
t_string_list_equal(list, &expected_strings);
320+
321+
string_list_clear(&expected_strings, 0);
322+
}
323+
324+
void test_string_list__sort(void)
325+
{
326+
struct string_list list = STRING_LIST_INIT_DUP;
327+
328+
t_create_string_list_dup(&list, 0, NULL);
329+
t_string_list_sort(&list, NULL);
330+
331+
t_create_string_list_dup(&list, 0, "b", "", "a", NULL);
332+
t_string_list_sort(&list, "", "a", "b", NULL);
333+
334+
t_create_string_list_dup(&list, 0, "c", "a", "b", "a", NULL);
335+
t_string_list_sort(&list, "a", "a", "b", "c", NULL);
336+
337+
t_string_list_clear(&list, 0);
338+
}
339+
340+
static void t_string_list_remove(
341+
struct string_list *expected_strings,
342+
struct string_list *list,
343+
char const *str)
344+
{
345+
string_list_remove(list, str, 0);
346+
t_string_list_equal(list, expected_strings);
347+
}
348+
349+
void test_string_list__remove(void)
350+
{
351+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
352+
struct string_list list = STRING_LIST_INIT_DUP;
353+
354+
t_create_string_list_dup(&expected_strings, 0, NULL);
355+
t_create_string_list_dup(&list, 0, NULL);
356+
t_string_list_remove(&expected_strings, &list, "");
357+
358+
t_create_string_list_dup(&expected_strings, 0, "a", NULL);
359+
t_create_string_list_dup(&list, 0, "a", "a", NULL);
360+
t_string_list_remove(&expected_strings, &list, "a");
361+
362+
t_create_string_list_dup(&expected_strings, 0, "a", "b", "b", NULL);
363+
t_create_string_list_dup(&list, 0, "a", "b", "b", "c", NULL);
364+
t_string_list_remove(&expected_strings, &list, "c");
365+
366+
t_create_string_list_dup(&expected_strings, 0, "a", "b", "d", NULL);
367+
t_create_string_list_dup(&list, 0, "a", "b", "c", "d", NULL);
368+
t_string_list_remove(&expected_strings, &list, "c");
369+
370+
t_create_string_list_dup(&expected_strings, 0, "a", "b", "c", "d", NULL);
371+
t_create_string_list_dup(&list, 0, "a", "b", "c", "d", NULL);
372+
t_string_list_remove(&expected_strings, &list, "e");
373+
374+
t_string_list_clear(&expected_strings, 0);
375+
t_string_list_clear(&list, 0);
376+
}
377+
246378
static void t_string_list_remove_duplicates(struct string_list *list, ...)
247379
{
248380
struct string_list expected_strings = STRING_LIST_INIT_DUP;
@@ -304,3 +436,114 @@ void test_string_list__remove_duplicates(void)
304436

305437
t_string_list_clear(&list, 0);
306438
}
439+
440+
static void t_string_list_sort_u(struct string_list *list, ...)
441+
{
442+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
443+
va_list ap;
444+
445+
va_start(ap, list);
446+
t_vcreate_string_list_dup(&expected_strings, 0, ap);
447+
va_end(ap);
448+
449+
string_list_sort_u(list, 0);
450+
t_string_list_equal(list, &expected_strings);
451+
452+
string_list_clear(&expected_strings, 0);
453+
}
454+
455+
void test_string_list__sort_u(void)
456+
{
457+
struct string_list list = STRING_LIST_INIT_DUP;
458+
459+
t_create_string_list_dup(&list, 0, NULL);
460+
t_string_list_sort_u(&list, NULL);
461+
462+
t_create_string_list_dup(&list, 0, "", "", "", "", NULL);
463+
t_string_list_sort_u(&list, "", NULL);
464+
465+
t_create_string_list_dup(&list, 0, "b", "a", "a", "", NULL);
466+
t_string_list_sort_u(&list, "", "a", "b", NULL);
467+
468+
t_create_string_list_dup(&list, 0, "b", "a", "a", "d", "c", "c", NULL);
469+
t_string_list_sort_u(&list, "a", "b", "c", "d", NULL);
470+
471+
t_string_list_clear(&list, 0);
472+
}
473+
474+
static void t_string_list_remove_empty_items(
475+
struct string_list *expected_strings,
476+
struct string_list *list)
477+
{
478+
string_list_remove_empty_items(list, 0);
479+
t_string_list_equal(list, expected_strings);
480+
}
481+
482+
void test_string_list__remove_empty_items(void)
483+
{
484+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
485+
struct string_list list = STRING_LIST_INIT_DUP;
486+
487+
t_create_string_list_dup(&expected_strings, 0, NULL);
488+
t_create_string_list_dup(&list, 0, "", "", "", NULL);
489+
t_string_list_remove_empty_items(&expected_strings, &list);
490+
491+
t_create_string_list_dup(&expected_strings, 0, "a", "b", NULL);
492+
t_create_string_list_dup(&list, 0, "a", "", "b", "", NULL);
493+
t_string_list_remove_empty_items(&expected_strings, &list);
494+
495+
t_string_list_clear(&expected_strings, 0);
496+
t_string_list_clear(&list, 0);
497+
}
498+
499+
static void t_string_list_unsorted_string_list_has_string(
500+
struct string_list *list,
501+
const char *str, int expected)
502+
{
503+
int has_string = unsorted_string_list_has_string(list, str);
504+
cl_assert_equal_i(has_string, expected);
505+
}
506+
507+
void test_string_list__unsorted_string_list_has_string(void)
508+
{
509+
struct string_list list = STRING_LIST_INIT_DUP;
510+
511+
t_create_string_list_dup(&list, 0, "b", "d", "a", NULL);
512+
t_string_list_unsorted_string_list_has_string(&list, "a", 1);
513+
t_string_list_unsorted_string_list_has_string(&list, "b", 1);
514+
t_string_list_unsorted_string_list_has_string(&list, "c", 0);
515+
t_string_list_unsorted_string_list_has_string(&list, "d", 1);
516+
517+
t_string_list_clear(&list, 0);
518+
}
519+
520+
static void t_string_list_unsorted_string_list_delete_item(
521+
struct string_list *expected_list,
522+
struct string_list *list,
523+
int i)
524+
{
525+
unsorted_string_list_delete_item(list, i, 0);
526+
527+
t_string_list_equal(list, expected_list);
528+
}
529+
530+
void test_string_list__unsorted_string_list_delete_item(void)
531+
{
532+
struct string_list expected_strings = STRING_LIST_INIT_DUP;
533+
struct string_list list = STRING_LIST_INIT_DUP;
534+
535+
t_create_string_list_dup(&expected_strings, 0, "a", "c", "b", NULL);
536+
t_create_string_list_dup(&list, 0, "a", "d", "b", "c", NULL);
537+
t_string_list_unsorted_string_list_delete_item(&expected_strings, &list, 1);
538+
539+
t_create_string_list_dup(&expected_strings, 0, NULL);
540+
t_create_string_list_dup(&list, 0, "", NULL);
541+
t_string_list_unsorted_string_list_delete_item(&expected_strings, &list, 0);
542+
543+
t_create_string_list_dup(&expected_strings, 0, "a", "d", "c", "b", NULL);
544+
t_create_string_list_dup(&list, 0, "a", "d", "c", "b", "d", NULL);
545+
t_string_list_unsorted_string_list_delete_item(&expected_strings, &list, 4);
546+
547+
t_string_list_clear(&expected_strings, 0);
548+
t_string_list_clear(&list, 0);
549+
}

0 commit comments

Comments
 (0)