From c1ccaee58fe576e4e8f232f7e20ebb912ffb2a1a Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 11 Mar 2021 22:08:04 +0100 Subject: [PATCH 1/3] Remove duplicate code in autocomplete_param* autocomplete_param_with_func and -autocomplete_param_with_ac had lots of duplicate code. --- src/tools/autocomplete.c | 61 ++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index bd766e52..67cc6cb0 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -298,53 +298,34 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } } -char* -autocomplete_param_with_func(const char* const input, char* command, autocomplete_func func, gboolean previous, void* context) -{ - GString* auto_msg = NULL; - char* result = NULL; - char command_cpy[strlen(command) + 2]; - sprintf(command_cpy, "%s ", command); - int len = strlen(command_cpy); - - if (strncmp(input, command_cpy, len) == 0) { - int inp_len = strlen(input); - char prefix[inp_len]; - for (int i = len; i < inp_len; i++) { - prefix[i - len] = input[i]; - } - prefix[inp_len - len] = '\0'; - - char* found = func(prefix, previous, context); - if (found) { - auto_msg = g_string_new(command_cpy); - g_string_append(auto_msg, found); - free(found); - result = auto_msg->str; - g_string_free(auto_msg, FALSE); - } - } - - return result; -} - -char* -autocomplete_param_with_ac(const char* const input, char* command, Autocomplete ac, gboolean quote, gboolean previous) +// autocomplete_func func is used -> autocomplete_param_with_func +// Autocomplete ac, gboolean quote are used -> autocomplete_param_with_ac +static char* +_autocomplete_param_common(const char* const input, char* command, autocomplete_func func, Autocomplete ac, gboolean quote, gboolean previous, void* context) { GString* auto_msg = NULL; char* result = NULL; char* command_cpy = malloc(strlen(command) + 2); sprintf(command_cpy, "%s ", command); int len = strlen(command_cpy); - int inp_len = strlen(input); + if (strncmp(input, command_cpy, len) == 0) { + int inp_len = strlen(input); char prefix[inp_len]; + char *found; + for (int i = len; i < inp_len; i++) { prefix[i - len] = input[i]; } + prefix[inp_len - len] = '\0'; - char* found = autocomplete_complete(ac, prefix, quote, previous); + if (func) { + found = func(prefix, previous, context); + } else { + found = autocomplete_complete(ac, prefix, quote, previous); + } + if (found) { auto_msg = g_string_new(command_cpy); g_string_append(auto_msg, found); @@ -358,6 +339,18 @@ autocomplete_param_with_ac(const char* const input, char* command, Autocomplete return result; } +char* +autocomplete_param_with_func(const char* const input, char* command, autocomplete_func func, gboolean previous, void* context) +{ + return _autocomplete_param_common(input, command, func, NULL, FALSE, previous, context); +} + +char* +autocomplete_param_with_ac(const char* const input, char* command, Autocomplete ac, gboolean quote, gboolean previous) +{ + return _autocomplete_param_common(input, command, NULL, ac, quote, previous, NULL); +} + char* autocomplete_param_no_with_func(const char* const input, char* command, int arg_number, autocomplete_func func, gboolean previous, void* context) { From e3133ed98f5e24edea088b95f121f2ee4e41d5e4 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 11 Mar 2021 22:13:06 +0100 Subject: [PATCH 2/3] autocomplete: Use asprintf don't calculate length twice Through asprintf() we can get rid of malloc() + sprintf(). Also we don't need to calculate the strlen() again since asprintf() returns the bytes printes. Only non UTF-8 characters. But that was true before already. --- src/tools/autocomplete.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index 67cc6cb0..f8d2de62 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -33,6 +33,7 @@ * */ +#define _GNU_SOURCE #include #include #include @@ -303,11 +304,15 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, static char* _autocomplete_param_common(const char* const input, char* command, autocomplete_func func, Autocomplete ac, gboolean quote, gboolean previous, void* context) { - GString* auto_msg = NULL; + GString* auto_msg; + char* command_cpy; char* result = NULL; - char* command_cpy = malloc(strlen(command) + 2); - sprintf(command_cpy, "%s ", command); - int len = strlen(command_cpy); + int len; + + len = asprintf(&command_cpy, "%s ", command); + if (len == -1) { + return NULL; + } if (strncmp(input, command_cpy, len) == 0) { int inp_len = strlen(input); From 638a50f8d1c2f1c2c88c6d88b35491f73e758fc8 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 11 Mar 2021 22:24:27 +0100 Subject: [PATCH 3/3] autocomplete: remove duplicate code in search functions _search_next and _search_prev where exactly the same except taking the nex/prev from the list. Use one function with a direction argument. --- src/tools/autocomplete.c | 70 +++++++++------------------------------- 1 file changed, 16 insertions(+), 54 deletions(-) diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index f8d2de62..07689907 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -44,6 +44,11 @@ #include "tools/parser.h" #include "ui/ui.h" +typedef enum { + PREVIOUS, + NEXT +} search_direction; + struct autocomplete_t { GList* items; @@ -51,8 +56,7 @@ struct autocomplete_t gchar* search_str; }; -static gchar* _search_next(Autocomplete ac, GList* curr, gboolean quote); -static gchar* _search_prev(Autocomplete ac, GList* curr, gboolean quote); +static gchar* _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction); Autocomplete autocomplete_new(void) @@ -258,7 +262,7 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } ac->search_str = strdup(search_str); - found = _search_next(ac, ac->items, quote); + found = _search(ac, ac->items, quote, NEXT); return found; @@ -266,13 +270,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } else { if (previous) { // search from here-1 to beginning - found = _search_prev(ac, g_list_previous(ac->last_found), quote); + found = _search(ac, g_list_previous(ac->last_found), quote, PREVIOUS); if (found) { return found; } } else { // search from here+1 to end - found = _search_next(ac, g_list_next(ac->last_found), quote); + found = _search(ac, g_list_next(ac->last_found), quote, NEXT); if (found) { return found; } @@ -280,13 +284,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, if (previous) { // search from end - found = _search_prev(ac, g_list_last(ac->items), quote); + found = _search(ac, g_list_last(ac->items), quote, PREVIOUS); if (found) { return found; } } else { // search from beginning - found = _search_next(ac, ac->items, quote); + found = _search(ac, ac->items, quote, NEXT); if (found) { return found; } @@ -409,7 +413,7 @@ autocomplete_remove_older_than_max_reverse(Autocomplete ac, int maxsize) } static gchar* -_search_next(Autocomplete ac, GList* curr, gboolean quote) +_search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction) { gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL); gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1); @@ -448,54 +452,12 @@ _search_next(Autocomplete ac, GList* curr, gboolean quote) } g_free(curr_lower); - curr = g_list_next(curr); - } - g_free(search_str_lower); - return NULL; -} - -static gchar* -_search_prev(Autocomplete ac, GList* curr, gboolean quote) -{ - gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL); - gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1); - g_free(search_str_ascii); - - while (curr) { - gchar* curr_ascii = g_str_to_ascii(curr->data, NULL); - gchar* curr_lower = g_ascii_strdown(curr_ascii, -1); - g_free(curr_ascii); - - // match found - if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { - - // set pointer to last found - ac->last_found = curr; - - // if contains space, quote before returning - if (quote && g_strrstr(curr->data, " ")) { - GString* quoted = g_string_new("\""); - g_string_append(quoted, curr->data); - g_string_append(quoted, "\""); - - gchar* result = quoted->str; - g_string_free(quoted, FALSE); - - g_free(search_str_lower); - g_free(curr_lower); - return result; - - // otherwise just return the string - } else { - g_free(search_str_lower); - g_free(curr_lower); - return strdup(curr->data); - } + if (direction == PREVIOUS) { + curr = g_list_previous(curr); + } else { + curr = g_list_next(curr); } - - g_free(curr_lower); - curr = g_list_previous(curr); } g_free(search_str_lower);