fzy
terminal fuzzy finder picker
git clone https://9o.is/git/fzy.git
commit 5e2ec08ea697399266018ae5671ced4bf8982507 parent 4168598a50f47d3e47e31dd84ffa765a219fac75 Author: John Hawthorn <john@freerunningtechnologies.com> Date: Wed, 17 Sep 2014 10:43:01 -0700 Use AoS instead of SoA; don't use qsort_r Fixes Bus Error on BSDs due to qsort_r not being the same qsort_r as linux. Diffstat:
| M | choices.c | | | 33 | +++++++++++++++------------------ |
| M | choices.h | | | 8 | ++++++-- |
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/choices.c b/choices.c @@ -1,4 +1,3 @@ -#define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> @@ -7,13 +6,13 @@ #define INITIAL_CAPACITY 1 -static int cmpchoice(size_t *idx1, size_t *idx2, double *choices_score) { - double score1 = choices_score[*idx1]; - double score2 = choices_score[*idx2]; +static int cmpchoice(const void *_idx1, const void *_idx2) { + const struct scored_position *a = _idx1; + const struct scored_position *b = _idx2; - if(score1 == score2) + if(a->score == b->score) return 0; - else if(score1 < score2) + else if(a->score < b->score) return 1; else return -1; @@ -21,10 +20,9 @@ static int cmpchoice(size_t *idx1, size_t *idx2, double *choices_score) { static void choices_resize(choices_t *c, int new_capacity){ c->strings = realloc(c->strings, new_capacity * sizeof(const char *)); - c->scores = realloc(c->scores, new_capacity * sizeof(double)); - c->sorted = realloc(c->sorted, new_capacity * sizeof(size_t)); + c->results = realloc(c->results, new_capacity * sizeof(struct scored_position)); - if(!c->strings || !c->scores || !c->sorted){ + if(!c->strings || !c->results){ fprintf(stderr, "Error: Can't allocate memory\n"); abort(); } @@ -37,16 +35,14 @@ static void choices_resize(choices_t *c, int new_capacity){ void choices_init(choices_t *c){ c->strings = NULL; - c->scores = NULL; - c->sorted = NULL; + c->results = NULL; c->capacity = c->size = 0; c->selection = c->available = 0; choices_resize(c, INITIAL_CAPACITY); } void choices_free(choices_t *c){ free(c->strings); - free(c->scores); - free(c->sorted); + free(c->results); }; void choices_add(choices_t *c, const char *choice){ @@ -66,23 +62,24 @@ void choices_search(choices_t *c, const char *search){ for(size_t i = 0; i < c->size; i++){ if(has_match(search, c->strings[i])){ - c->scores[i] = match(search, c->strings[i]); - c->sorted[c->available++] = i; + c->results[c->available].position = i; + c->results[c->available].score = match(search, c->strings[i]); + c->available++; } } - qsort_r(c->sorted, c->available, sizeof(size_t), (int (*)(const void *, const void *, void *))cmpchoice, c->scores); + qsort(c->results, c->available, sizeof(struct scored_position), cmpchoice); } const char *choices_get(choices_t *c, size_t n){ if(n < c->available){ - return c->strings[c->sorted[n]]; + return c->strings[c->results[n].position]; }else{ return NULL; } } double choices_getscore(choices_t *c, size_t n){ - return c->scores[c->sorted[n]];; + return c->results[n].score;; } void choices_prev(choices_t *c){ diff --git a/choices.h b/choices.h @@ -1,14 +1,18 @@ #ifndef CHOICES_H #define CHOICES_H CHOICES_H +struct scored_position { + size_t position; + double score; +}; + typedef struct { size_t capacity; size_t size; const char **strings; - double *scores; + struct scored_position *results; - size_t *sorted; size_t available; size_t selection; } choices_t;