summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compgen.c41
-rw-r--r--src/string_vec.c16
-rw-r--r--src/string_vec.h2
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(