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 <gitster@pobox.com>
Junio C Hamano committed
Jan 7, 2013 at 12:24 UTC
8dd5afc926acb9829ebf56e9b78826a5242cd638
2 files changed
+17
-4
string-list.c
+13
-4
@@ -7,10 +7,11 @@ static int get_entry_index(const struct string_list *list, const char *string,
7
int *exact_match)
8
{
9
int left = -1, right = list->nr;
10
+ compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
11
12
while (left + 1 < right) {
13
int middle = (left + right) / 2;
13
- int compare = strcmp(string, list->items[middle].string);
14
+ int compare = cmp(string, list->items[middle].string);
15
if (compare < 0)
16
right = middle;
17
else if (compare > 0)
@@ -96,8 +97,9 @@ void string_list_remove_duplicates(struct string_list *list, int free_util)
97
{
98
if (list->nr > 1) {
99
int src, dst;
100
+ compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
101
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)) {
103
if (list->strdup_strings)
104
free(list->items[src].string);
105
if (free_util)
@@ -230,15 +232,20 @@ struct string_list_item *string_list_append(struct string_list *list,
232
list->strdup_strings ? xstrdup(string) : (char *)string);
233
}
234
235
+/* Yuck */
236
+static compare_strings_fn compare_for_qsort;
237
+
238
+/* Only call this from inside sort_string_list! */
239
static int cmp_items(const void *a, const void *b)
240
{
241
const struct string_list_item *one = a;
242
const struct string_list_item *two = b;
237
- return strcmp(one->string, two->string);
243
+ return compare_for_qsort(one->string, two->string);
244
}
245
246
void sort_string_list(struct string_list *list)
247
{
248
+ compare_for_qsort = list->cmp ? list->cmp : strcmp;
249
qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
250
}
251
@@ -246,8 +253,10 @@ struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
253
const char *string)
254
{
255
int i;
256
+ compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
257
+
258
for (i = 0; i < list->nr; i++)
250
- if (!strcmp(string, list->items[i].string))
259
+ if (!cmp(string, list->items[i].string))
260
return list->items + i;
261
return NULL;
262
}
string-list.h
+4
@@ -5,10 +5,14 @@ struct string_list_item {
5
char *string;
6
void *util;
7
};
8
+
9
+typedef int (*compare_strings_fn)(const char *, const char *);
10
+
11
struct string_list {
12
struct string_list_item *items;
13
unsigned int nr, alloc;
14
unsigned int strdup_strings:1;
15
+ compare_strings_fn cmp; /* NULL uses strcmp() */
16
};
17
18
#define STRING_LIST_INIT_NODUP { NULL, 0, 0, 0 }