Skip to content

Commit 8dd5afc

Browse files
committed
string-list: allow case-insensitive string list
Some string list needs to be searched case insensitively, and for that to work correctly, the string needs to be sorted case insensitively from the beginning. Allow a custom comparison function to be defined on a string list instance and use it throughout in place of strcmp(). Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7e0651a commit 8dd5afc

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

string-list.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ static int get_entry_index(const struct string_list *list, const char *string,
77
int *exact_match)
88
{
99
int left = -1, right = list->nr;
10+
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
1011

1112
while (left + 1 < right) {
1213
int middle = (left + right) / 2;
13-
int compare = strcmp(string, list->items[middle].string);
14+
int compare = cmp(string, list->items[middle].string);
1415
if (compare < 0)
1516
right = middle;
1617
else if (compare > 0)
@@ -96,8 +97,9 @@ void string_list_remove_duplicates(struct string_list *list, int free_util)
9697
{
9798
if (list->nr > 1) {
9899
int src, dst;
100+
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
99101
for (src = dst = 1; src < list->nr; src++) {
100-
if (!strcmp(list->items[dst - 1].string, list->items[src].string)) {
102+
if (!cmp(list->items[dst - 1].string, list->items[src].string)) {
101103
if (list->strdup_strings)
102104
free(list->items[src].string);
103105
if (free_util)
@@ -230,24 +232,31 @@ struct string_list_item *string_list_append(struct string_list *list,
230232
list->strdup_strings ? xstrdup(string) : (char *)string);
231233
}
232234

235+
/* Yuck */
236+
static compare_strings_fn compare_for_qsort;
237+
238+
/* Only call this from inside sort_string_list! */
233239
static int cmp_items(const void *a, const void *b)
234240
{
235241
const struct string_list_item *one = a;
236242
const struct string_list_item *two = b;
237-
return strcmp(one->string, two->string);
243+
return compare_for_qsort(one->string, two->string);
238244
}
239245

240246
void sort_string_list(struct string_list *list)
241247
{
248+
compare_for_qsort = list->cmp ? list->cmp : strcmp;
242249
qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
243250
}
244251

245252
struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
246253
const char *string)
247254
{
248255
int i;
256+
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
257+
249258
for (i = 0; i < list->nr; i++)
250-
if (!strcmp(string, list->items[i].string))
259+
if (!cmp(string, list->items[i].string))
251260
return list->items + i;
252261
return NULL;
253262
}

string-list.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ struct string_list_item {
55
char *string;
66
void *util;
77
};
8+
9+
typedef int (*compare_strings_fn)(const char *, const char *);
10+
811
struct string_list {
912
struct string_list_item *items;
1013
unsigned int nr, alloc;
1114
unsigned int strdup_strings:1;
15+
compare_strings_fn cmp; /* NULL uses strcmp() */
1216
};
1317

1418
#define STRING_LIST_INIT_NODUP { NULL, 0, 0, 0 }

0 commit comments

Comments
 (0)