about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG3
-rw-r--r--src/command/cmd_ac.c101
-rw-r--r--src/command/cmd_defs.c1
-rw-r--r--src/command/cmd_funcs.c24
-rw-r--r--src/omemo/omemo.c2
-rw-r--r--src/plugins/python_api.c2
-rw-r--r--src/tools/autocomplete.c35
-rw-r--r--src/tools/autocomplete.h1
-rw-r--r--src/ui/core.c4
-rw-r--r--src/ui/rosterwin.c1
-rw-r--r--src/ui/statusbar.c2
-rw-r--r--src/ui/window.c2
-rw-r--r--src/xmpp/roster_list.c9
13 files changed, 125 insertions, 62 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 9bc289f0..917e1b21 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,7 +35,8 @@ Unreleased
 - Iterate up to 100 logfiles (#519)
 - Fix rejoining of MUCs upon reconnect (#1120)
 - Add option to set all window related time formats (#632, #1120)
-- Fix several memory leaks (#1130)
+- Always check for directory changes with sendfile auto completion (#1154)
+- Fix several memory leaks (#1130, + plenty commits)
 - For details see https://github.com/profanity-im/profanity/milestone/17
 
 0.6.0 (2019-02-18)
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 1ce20862..5abee8be 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -1290,11 +1290,15 @@ cmd_ac_uninit(void)
     autocomplete_free(statusbar_show_ac);
 }
 
+static void
+_filepath_item_free(char **ptr) {
+    char *item = *ptr;
+    free(item);
+}
+
 char*
 cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean previous)
 {
-    static char* last_directory = NULL;
-
     unsigned int output_off = 0;
 
     char *result = NULL;
@@ -1322,11 +1326,13 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean
     // expand ~ to $HOME
     if (inpcp[0] == '~' && inpcp[1] == '/') {
         if (asprintf(&tmp, "%s/%sfoo", getenv("HOME"), inpcp+2) == -1) {
+            free(inpcp);
             return NULL;
         }
         output_off = strlen(getenv("HOME"))+1;
     } else {
         if (asprintf(&tmp, "%sfoo", inpcp) == -1) {
+            free(inpcp);
             return NULL;
         }
     }
@@ -1339,56 +1345,61 @@ cmd_ac_complete_filepath(const char *const input, char *const startstr, gboolean
     free(inpcp);
     free(inpcp2);
 
-    if (!last_directory || strcmp(last_directory, directory) != 0) {
-        free(last_directory);
-        last_directory = directory;
-        autocomplete_reset(filepath_ac);
-
-        struct dirent *dir;
-
-        DIR *d = opendir(directory);
-        if (d) {
-            while ((dir = readdir(d)) != NULL) {
-                if (strcmp(dir->d_name, ".") == 0) {
-                    continue;
-                } else if (strcmp(dir->d_name, "..") == 0) {
-                    continue;
-                } else if (*(dir->d_name) == '.' && *foofile != '.') {
-                    // only show hidden files on explicit request
-                    continue;
+    struct dirent *dir;
+    GArray *files = g_array_new(TRUE, FALSE, sizeof(char *));
+    g_array_set_clear_func(files, (GDestroyNotify)_filepath_item_free);
+
+    DIR *d = opendir(directory);
+    if (d) {
+        while ((dir = readdir(d)) != NULL) {
+            if (strcmp(dir->d_name, ".") == 0) {
+                continue;
+            } else if (strcmp(dir->d_name, "..") == 0) {
+                continue;
+            } else if (*(dir->d_name) == '.' && *foofile != '.') {
+                // only show hidden files on explicit request
+                continue;
+            }
+
+            char *acstring;
+            if (output_off) {
+                if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) {
+                    free(directory);
+                    free(foofile);
+                    return NULL;
                 }
-                char * acstring;
-                if (output_off) {
-                    if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                    if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                    free(tmp);
-                } else if (strcmp(directory, "/") == 0) {
-                    if (asprintf(&acstring, "/%s", dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
-                } else {
-                    if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) {
-                        free(foofile);
-                        return NULL;
-                    }
+                if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) {
+                    free(directory);
+                    free(foofile);
+                   return NULL;
+                }
+                free(tmp);
+            } else if (strcmp(directory, "/") == 0) {
+                if (asprintf(&acstring, "/%s", dir->d_name) == -1) {
+                    free(directory);
+                    free(foofile);
+                    return NULL;
+                }
+            } else {
+                if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) {
+                    free(directory);
+                    free(foofile);
+                    return NULL;
                 }
-                autocomplete_add(filepath_ac, acstring);
-                free(acstring);
             }
-            closedir(d);
+
+            char *acstring_cpy = strdup(acstring);
+            g_array_append_val(files, acstring_cpy);
+            free(acstring);
         }
-    } else {
-        free(directory);
+        closedir(d);
     }
+    free(directory);
     free(foofile);
 
+    autocomplete_update(filepath_ac, (char **)files->data);
+    g_array_free(files, TRUE);
+
     result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE, previous);
     if (result) {
         return result;
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 2dca64c0..efe2bad0 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2427,7 +2427,6 @@ _cmd_index(Command *cmd) {
     g_string_free(index_source, TRUE);
 
     GString *index = g_string_new("");
-    i = 0;
     for (i = 0; i < g_strv_length(tokens); i++) {
         index = g_string_append(index, tokens[i]);
         index = g_string_append(index, " ");
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index a6c0011f..b2893633 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -420,6 +420,7 @@ cmd_connect(ProfWin *window, const char *const command, gchar **args)
             } else {
                 cons_show("Error evaluating password, see logs for details.");
                 account_free(account);
+                free(user);
                 return TRUE;
             }
 
@@ -5406,6 +5407,10 @@ cmd_time(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_states(ProfWin *window, const char *const command, gchar **args)
 {
+    if (args[0] == NULL) {
+        return FALSE;
+    }
+
     _cmd_set_boolean_preference(args[0], command, "Sending chat states", PREF_STATES);
 
     // if disabled, disable outtype and gone
@@ -5439,6 +5444,10 @@ cmd_wintitle(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_outtype(ProfWin *window, const char *const command, gchar **args)
 {
+    if (args[0] == NULL) {
+        return FALSE;
+    }
+
     _cmd_set_boolean_preference(args[0], command, "Sending typing notifications", PREF_OUTTYPE);
 
     // if enabled, enable states
@@ -6612,6 +6621,10 @@ cmd_autoconnect(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_chlog(ProfWin *window, const char *const command, gchar **args)
 {
+    if (args[0] == NULL) {
+        return FALSE;
+    }
+
     _cmd_set_boolean_preference(args[0], command, "Chat logging", PREF_CHLOG);
 
     // if set to off, disable history
@@ -6633,6 +6646,10 @@ cmd_grlog(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_history(ProfWin *window, const char *const command, gchar **args)
 {
+    if (args[0] == NULL) {
+        return FALSE;
+    }
+
     _cmd_set_boolean_preference(args[0], command, "Chat history", PREF_HISTORY);
 
     // if set to on, set chlog
@@ -6646,6 +6663,10 @@ cmd_history(ProfWin *window, const char *const command, gchar **args)
 gboolean
 cmd_carbons(ProfWin *window, const char *const command, gchar **args)
 {
+    if (args[0] == NULL) {
+        return FALSE;
+    }
+
     _cmd_set_boolean_preference(args[0], command, "Message carbons preference", PREF_CARBONS);
 
     jabber_conn_status_t conn_status = connection_get_status();
@@ -6756,11 +6777,13 @@ cmd_plugins_sourcepath(ProfWin *window, const char *const command, gchar **args)
 
         if (!is_dir(path)) {
             cons_show("Plugins sourcepath must be a directory.");
+            free(path);
             return TRUE;
         }
 
         cons_show("Setting plugins sourcepath: %s", path);
         prefs_set_string(PREF_PLUGINS_SOURCEPATH, path);
+        free(path);
         return TRUE;
     }
 
@@ -6845,6 +6868,7 @@ cmd_plugins_install(ProfWin *window, const char *const command, gchar **args)
         return TRUE;
     }
 
+    free(path);
     cons_show("Argument must be a file or directory.");
     return TRUE;
 }
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index f82ad164..879a237a 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -389,7 +389,7 @@ omemo_start_sessions(void)
 {
     GSList *contacts = roster_get_contacts(ROSTER_ORD_NAME);
     if (contacts) {
-        GSList *curr = contacts;
+        GSList *curr;
         for (curr = contacts; curr != NULL; curr = g_slist_next(curr)){
             PContact contact = curr->data;
             const char *jid = p_contact_barejid(contact);
diff --git a/src/plugins/python_api.c b/src/plugins/python_api.c
index 99a96634..140b4abd 100644
--- a/src/plugins/python_api.c
+++ b/src/plugins/python_api.c
@@ -159,7 +159,6 @@ python_api_register_command(PyObject *self, PyObject *args)
 
         Py_ssize_t args_len = PyList_Size(arguments);
         char *c_arguments[args_len == 0 ? 0 : args_len+1][2];
-        i = 0;
         for (i = 0; i < args_len; i++) {
             PyObject *item = PyList_GetItem(arguments, i);
             Py_ssize_t len2 = PyList_Size(item);
@@ -180,7 +179,6 @@ python_api_register_command(PyObject *self, PyObject *args)
 
         len = PyList_Size(examples);
         char *c_examples[len == 0 ? 0 : len+1];
-        i = 0;
         for (i = 0; i < len; i++) {
             PyObject *item = PyList_GetItem(examples, i);
             char *c_item = python_str_or_unicode_to_string(item);
diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c
index 79312e53..03a30553 100644
--- a/src/tools/autocomplete.c
+++ b/src/tools/autocomplete.c
@@ -66,8 +66,10 @@ void
 autocomplete_clear(Autocomplete ac)
 {
     if (ac) {
-        g_list_free_full(ac->items, free);
-        ac->items = NULL;
+        if (ac->items) {
+            g_list_free_full(ac->items, free);
+            ac->items = NULL;
+        }
 
         autocomplete_reset(ac);
     }
@@ -102,6 +104,35 @@ autocomplete_length(Autocomplete ac)
 }
 
 void
+autocomplete_update(Autocomplete ac, char **items)
+{
+    gchar *last_found = NULL;
+    gchar *search_str = NULL;
+
+    if (ac->last_found) {
+        last_found = strdup(ac->last_found->data);
+    }
+
+    if (ac->search_str) {
+        search_str = strdup(ac->search_str);
+    }
+
+    autocomplete_clear(ac);
+    autocomplete_add_all(ac, items);
+
+    if (last_found) {
+        // NULL if last_found was removed on update.
+        ac->last_found = g_list_find_custom(ac->items, last_found, (GCompareFunc)strcmp);
+        free(last_found);
+    }
+
+    if (search_str) {
+        ac->search_str = strdup(search_str);
+        free(search_str);
+    }
+}
+
+void
 autocomplete_add(Autocomplete ac, const char *item)
 {
     if (ac) {
diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h
index 78bec44d..a8797369 100644
--- a/src/tools/autocomplete.h
+++ b/src/tools/autocomplete.h
@@ -51,6 +51,7 @@ void autocomplete_free(Autocomplete ac);
 
 void autocomplete_add(Autocomplete ac, const char *item);
 void autocomplete_add_all(Autocomplete ac, char **items);
+void autocomplete_update(Autocomplete ac, char **items);
 void autocomplete_remove(Autocomplete ac, const char *const item);
 void autocomplete_remove_all(Autocomplete ac, char **items);
 
diff --git a/src/ui/core.c b/src/ui/core.c
index c758ba47..3e083947 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -742,14 +742,12 @@ ui_print_system_msg_from_recipient(const char *const barejid, const char *messag
     ProfChatWin *chatwin = wins_get_chat(barejid);
     ProfWin *window = (ProfWin*)chatwin;
     if (window == NULL) {
-        int num = 0;
         window = wins_new_chat(barejid);
         if (window) {
             chatwin = (ProfChatWin*)window;
-            num = wins_get_num(window);
+            int num = wins_get_num(window);
             status_bar_active(num, WIN_CHAT, chatwin->barejid);
         } else {
-            num = 0;
             window = wins_get_console();
             status_bar_active(1, WIN_CONSOLE, "console");
         }
diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c
index 89575e0d..d7734174 100644
--- a/src/ui/rosterwin.c
+++ b/src/ui/rosterwin.c
@@ -335,7 +335,6 @@ _rosterwin_unsubscribed_item(ProfLayoutSplit *layout, ProfChatWin *chatwin)
     g_string_append(msg, name);
     if ((g_strcmp0(unreadpos, "after") == 0) && unread > 0) {
         g_string_append_printf(msg, " (%d)", unread);
-        unread = 0;
     }
     prefs_free_string(unreadpos);
 
diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c
index 9e1c9559..495b79ab 100644
--- a/src/ui/statusbar.c
+++ b/src/ui/statusbar.c
@@ -295,7 +295,7 @@ status_bar_draw(void)
         }
     }
 
-    pos = _status_bar_draw_extended_tabs(pos);
+    _status_bar_draw_extended_tabs(pos);
 
     wnoutrefresh(statusbar_win);
     inp_put_back();
diff --git a/src/ui/window.c b/src/ui/window.c
index 93e5801c..80074fc3 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1557,7 +1557,7 @@ _win_print_wrapped(WINDOW *win, const char *const message, size_t indent, int pa
             wordlen = utf8_display_len(word);
 
             int curx = getcurx(win);
-            int cury = getcury(win);
+            int cury;
             int maxx = getmaxx(win);
 
             // wrap required
diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c
index 88c3ec0f..dee7e362 100644
--- a/src/xmpp/roster_list.c
+++ b/src/xmpp/roster_list.c
@@ -232,10 +232,9 @@ void
 roster_change_name(PContact contact, const char *const new_name)
 {
     assert(roster != NULL);
-
     assert(contact != NULL);
 
-    const char *current_name = NULL;
+    char *current_name = NULL;
     const char *barejid = p_contact_barejid(contact);
 
     if (p_contact_name(contact)) {
@@ -244,6 +243,7 @@ roster_change_name(PContact contact, const char *const new_name)
 
     p_contact_set_name(contact, new_name);
     _replace_name(current_name, new_name, barejid);
+    free(current_name);
 }
 
 void
@@ -260,7 +260,7 @@ roster_remove(const char *const name, const char *const barejid)
     if (contact) {
         GList *resources = p_contact_get_available_resources(contact);
         while (resources) {
-            GString *fulljid = g_string_new(strdup(barejid));
+            GString *fulljid = g_string_new(barejid);
             g_string_append(fulljid, "/");
             g_string_append(fulljid, resources->data);
             autocomplete_remove(roster->fulljid_ac, fulljid->str);
@@ -304,13 +304,14 @@ roster_update(const char *const barejid, const char *const name, GSList *groups,
     p_contact_set_pending_out(contact, pending_out);
 
     const char * const new_name = name;
-    const char * current_name = NULL;
+    char * current_name = NULL;
     if (p_contact_name(contact)) {
         current_name = strdup(p_contact_name(contact));
     }
 
     p_contact_set_name(contact, new_name);
     _replace_name(current_name, new_name, barejid);
+    free(current_name);
 
     GSList *curr_new_group = groups;
     while (curr_new_group) {