Skip to content

Commit

Permalink
string-list: allow case-insensitive string list
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Jan 7, 2013
1 parent 7e0651a commit 8dd5afc
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
17 changes: 13 additions & 4 deletions string-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ static int get_entry_index(const struct string_list *list, const char *string,
int *exact_match)
{
int left = -1, right = list->nr;
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;

while (left + 1 < right) {
int middle = (left + right) / 2;
int compare = strcmp(string, list->items[middle].string);
int compare = cmp(string, list->items[middle].string);
if (compare < 0)
right = middle;
else if (compare > 0)
Expand Down Expand Up @@ -96,8 +97,9 @@ void string_list_remove_duplicates(struct string_list *list, int free_util)
{
if (list->nr > 1) {
int src, dst;
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;
for (src = dst = 1; src < list->nr; src++) {
if (!strcmp(list->items[dst - 1].string, list->items[src].string)) {
if (!cmp(list->items[dst - 1].string, list->items[src].string)) {
if (list->strdup_strings)
free(list->items[src].string);
if (free_util)
Expand Down Expand Up @@ -230,24 +232,31 @@ struct string_list_item *string_list_append(struct string_list *list,
list->strdup_strings ? xstrdup(string) : (char *)string);
}

/* Yuck */
static compare_strings_fn compare_for_qsort;

/* Only call this from inside sort_string_list! */
static int cmp_items(const void *a, const void *b)
{
const struct string_list_item *one = a;
const struct string_list_item *two = b;
return strcmp(one->string, two->string);
return compare_for_qsort(one->string, two->string);
}

void sort_string_list(struct string_list *list)
{
compare_for_qsort = list->cmp ? list->cmp : strcmp;
qsort(list->items, list->nr, sizeof(*list->items), cmp_items);
}

struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
const char *string)
{
int i;
compare_strings_fn cmp = list->cmp ? list->cmp : strcmp;

for (i = 0; i < list->nr; i++)
if (!strcmp(string, list->items[i].string))
if (!cmp(string, list->items[i].string))
return list->items + i;
return NULL;
}
Expand Down
4 changes: 4 additions & 0 deletions string-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ struct string_list_item {
char *string;
void *util;
};

typedef int (*compare_strings_fn)(const char *, const char *);

struct string_list {
struct string_list_item *items;
unsigned int nr, alloc;
unsigned int strdup_strings:1;
compare_strings_fn cmp; /* NULL uses strcmp() */
};

#define STRING_LIST_INIT_NODUP { NULL, 0, 0, 0 }
Expand Down

0 comments on commit 8dd5afc

Please sign in to comment.