diff options
-rw-r--r-- | src/compgen.c | 41 | ||||
-rw-r--r-- | src/string_vec.c | 16 | ||||
-rw-r--r-- | src/string_vec.h | 2 |
3 files changed, 17 insertions, 42 deletions
diff --git a/src/compgen.c b/src/compgen.c index 9e9f422..8421cec 100644 --- a/src/compgen.c +++ b/src/compgen.c @@ -170,45 +170,24 @@ struct string_vec compgen() return programs; } +static int cmpscorep(const void *restrict a, const void *restrict b) +{ + struct scored_string *restrict str1 = (struct scored_string *)a; + struct scored_string *restrict str2 = (struct scored_string *)b; + return str2->history_score - str1->history_score; +} + void compgen_history_sort(struct string_vec *programs, struct history *history) { log_debug("Moving already known programs to the front.\n"); - /* - * Remove any programs in our history from the generated list, and - * store which ones we found in to_add. - * Removal is done without changing the count, as we're about to re-add - * them at the front. - */ - struct string_vec to_add = string_vec_create(); for (size_t i = 0; i < history->count; i++) { - char **res = string_vec_find(programs, history->buf[i].name); + struct scored_string *res = string_vec_find(programs, history->buf[i].name); if (res == NULL) { log_debug("History entry \"%s\" not found.\n", history->buf[i].name); continue; } - free(*res); - *res = NULL; - string_vec_add(&to_add, history->buf[i].name); - to_add.buf[to_add.count - 1].history_score = history->buf[i].run_count; + res->history_score = history->buf[i].run_count; } - /* Sort the vector to push the removed entries to the end. */ - string_vec_sort(programs); - - /* - * Move the results down by the number of items we want to add. There's - * guaranteed to be enough space to do this, as we just removed that - * many items. - */ - memmove( - &programs->buf[to_add.count], - programs->buf, - (programs->count - to_add.count) * sizeof(programs->buf[0])); - - /* Add our history to the front in order. */ - for (size_t i = 0; i < to_add.count; i++) { - programs->buf[i].string = xstrdup(to_add.buf[i].string); - programs->buf[i].history_score = to_add.buf[i].history_score; - } - string_vec_destroy(&to_add); + qsort(programs->buf, programs->count, sizeof(programs->buf[0]), cmpscorep); } diff --git a/src/string_vec.c b/src/string_vec.c index a30a570..4607727 100644 --- a/src/string_vec.c +++ b/src/string_vec.c @@ -11,23 +11,19 @@ static int cmpstringp(const void *restrict a, const void *restrict b) { - /* - * For qsort we receive pointers to the array elements (which are - * pointers to char), so convert and dereference them for comparison. - */ - const char *restrict str1 = *(const char **)a; - const char *restrict str2 = *(const char **)b; + struct scored_string *restrict str1 = (struct scored_string *)a; + struct scored_string *restrict str2 = (struct scored_string *)b; /* * Ensure any NULL strings are shoved to the end. */ - if (str1 == NULL) { + if (str1->string == NULL) { return 1; } - if (str2 == NULL) { + if (str2->string == NULL) { return -1; } - return strcmp(str1, str2); + return strcmp(str1->string, str2->string); } static int cmpscorep(const void *restrict a, const void *restrict b) @@ -109,7 +105,7 @@ void string_vec_uniq(struct string_vec *restrict vec) vec->count = count; } -char **string_vec_find(struct string_vec *restrict vec, const char * str) +struct scored_string *string_vec_find(struct string_vec *restrict vec, const char * str) { return bsearch(&str, vec->buf, vec->count, sizeof(vec->buf[0]), cmpstringp); } diff --git a/src/string_vec.h b/src/string_vec.h index f4e0bb9..f3e840c 100644 --- a/src/string_vec.h +++ b/src/string_vec.h @@ -32,7 +32,7 @@ void string_vec_sort(struct string_vec *restrict vec); void string_vec_uniq(struct string_vec *restrict vec); -char **string_vec_find(struct string_vec *restrict vec, const char *str); +struct scored_string *string_vec_find(struct string_vec *restrict vec, const char *str); [[nodiscard("memory leaked")]] struct string_vec string_vec_filter( |