about summary refs log tree commit diff stats
path: root/src/plugins
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2016-06-29 23:35:57 +0100
committerJames Booth <boothj5@gmail.com>2016-06-29 23:35:57 +0100
commita01eb5d08e1b39d60a6f8fc26e5a87ceb92ec18f (patch)
treebe77126865e0cb26963859ad384a225e9c993c9e /src/plugins
parent61a09476c511c33abd9b6be3d5786fee1fa93b94 (diff)
downloadprofani-tty-a01eb5d08e1b39d60a6f8fc26e5a87ceb92ec18f.tar.gz
WIP - Unload plugin commands
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/api.c3
-rw-r--r--src/plugins/api.h2
-rw-r--r--src/plugins/c_api.c4
-rw-r--r--src/plugins/callbacks.c34
-rw-r--r--src/plugins/callbacks.h4
-rw-r--r--src/plugins/plugins.c27
-rw-r--r--src/plugins/plugins.h1
-rw-r--r--src/plugins/profapi.c2
-rw-r--r--src/plugins/profapi.h2
-rw-r--r--src/plugins/python_api.c4
-rw-r--r--src/plugins/python_plugins.c1
11 files changed, 75 insertions, 9 deletions
diff --git a/src/plugins/api.c b/src/plugins/api.c
index 326ec61d..90272684 100644
--- a/src/plugins/api.c
+++ b/src/plugins/api.c
@@ -106,11 +106,12 @@ api_cons_bad_cmd_usage(const char *const cmd)
 }
 
 void
-api_register_command(const char *command_name, int min_args, int max_args,
+api_register_command(char *plugin_name, char *command_name, int min_args, int max_args,
     const char **synopsis, const char *description, const char *arguments[][2], const char **examples, void *callback,
     void(*callback_func)(PluginCommand *command, gchar **args))
 {
     PluginCommand *command = malloc(sizeof(PluginCommand));
+    command->plugin_name = plugin_name;
     command->command_name = command_name;
     command->min_args = min_args;
     command->max_args = max_args;
diff --git a/src/plugins/api.h b/src/plugins/api.h
index a835cd8b..6bbcfa5c 100644
--- a/src/plugins/api.h
+++ b/src/plugins/api.h
@@ -50,7 +50,7 @@ gboolean api_current_win_is_console(void);
 char* api_get_current_nick(void);
 char** api_get_current_occupants(void);
 
-void api_register_command(const char *command_name, int min_args, int max_args,
+void api_register_command(char *plugin_name, char *command_name, int min_args, int max_args,
     const char **synopsis, const char *description, const char *arguments[][2], const char **examples,
     void *callback, void(*callback_func)(PluginCommand *command, gchar **args));
 void api_register_timed(void *callback, int interval_seconds,
diff --git a/src/plugins/c_api.c b/src/plugins/c_api.c
index b5624946..4e5900b9 100644
--- a/src/plugins/c_api.c
+++ b/src/plugins/c_api.c
@@ -80,7 +80,7 @@ c_api_cons_bad_cmd_usage(const char *const cmd)
 }
 
 static void
-c_api_register_command(const char *filename, const char *command_name, int min_args, int max_args,
+c_api_register_command(const char *filename, char *command_name, int min_args, int max_args,
     const char **synopsis, const char *description, const char *arguments[][2], const char **examples,
     void(*callback)(char **args))
 {
@@ -89,7 +89,7 @@ c_api_register_command(const char *filename, const char *command_name, int min_a
 
     CommandWrapper *wrapper = malloc(sizeof(CommandWrapper));
     wrapper->func = callback;
-    api_register_command(command_name, min_args, max_args, synopsis,
+    api_register_command(plugin_name, command_name, min_args, max_args, synopsis,
         description, arguments, examples, wrapper, c_command_callback);
 }
 
diff --git a/src/plugins/callbacks.c b/src/plugins/callbacks.c
index 2572f7a4..8960738f 100644
--- a/src/plugins/callbacks.c
+++ b/src/plugins/callbacks.c
@@ -78,6 +78,40 @@ callbacks_add_command(PluginCommand *command)
 }
 
 void
+_command_destroy(PluginCommand *command)
+{
+    free(command->command_name);
+    free(command->plugin_name);
+    command_help_free(command->help);
+    // TODO free callback
+}
+
+void
+callbacks_remove_commands(const char *const plugin_name)
+{
+    GSList *items_to_remove = NULL;
+    GSList *curr = p_commands;
+    while (curr) {
+        PluginCommand *command = curr->data;
+        if (g_strcmp0(command->plugin_name, plugin_name) == 0) {
+            cmd_ac_remove(command->command_name);
+            cmd_ac_remove_help(&command->command_name[1]);
+            items_to_remove = g_slist_append(items_to_remove, curr);
+        }
+        curr = g_slist_next(curr);
+    }
+
+    curr = items_to_remove;
+    while (curr) {
+        GSList *item = curr->data;
+        PluginCommand *command = item->data;
+        _command_destroy(command);
+        p_commands = g_slist_remove_link(p_commands, item);
+        curr = g_slist_next(curr);
+    }
+}
+
+void
 callbacks_add_timed(PluginTimedFunction *timed_function)
 {
     p_timed_functions = g_slist_append(p_timed_functions, timed_function);
diff --git a/src/plugins/callbacks.h b/src/plugins/callbacks.h
index 9b175d0a..a8253e21 100644
--- a/src/plugins/callbacks.h
+++ b/src/plugins/callbacks.h
@@ -40,7 +40,8 @@
 #include "command/cmd_defs.h"
 
 typedef struct p_command {
-    const char *command_name;
+    char *plugin_name;
+    char *command_name;
     int min_args;
     int max_args;
     CommandHelp *help;
@@ -65,6 +66,7 @@ void callbacks_init(void);
 void callbacks_close(void);
 
 void callbacks_add_command(PluginCommand *command);
+void callbacks_remove_commands(const char *const plugin_name);
 void callbacks_add_timed(PluginTimedFunction *timed_function);
 void callbacks_add_window_handler(const char *tag, PluginWindowCallback *window_callback);
 void * callbacks_get_window_handler(const char *tag);
diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c
index 5757a174..3395c77f 100644
--- a/src/plugins/plugins.c
+++ b/src/plugins/plugins.c
@@ -172,6 +172,33 @@ plugins_load(const char *const name)
     }
 }
 
+gboolean
+plugins_unload(const char *const name)
+{
+    GSList *found = g_slist_find_custom(plugins, name, (GCompareFunc)_find_by_name);
+    if (!found) {
+        log_info("Failed to unload plugin: %s, plugin not currently loaded", name);
+        return FALSE;
+    }
+
+    plugins = g_slist_remove_link(plugins, found);
+
+#ifdef HAVE_PYTHON
+    if (g_str_has_suffix(name, ".py")) {
+        python_plugin_destroy(found->data);
+    }
+#endif
+#ifdef HAVE_C
+    if (g_str_has_suffix(name, ".so")) {
+        c_plugin_destroy(found->data);
+    }
+#endif
+
+    g_slist_free(found);
+
+    return TRUE;
+}
+
 GSList *
 plugins_get_list(void)
 {
diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h
index b03248ab..19ac269d 100644
--- a/src/plugins/plugins.h
+++ b/src/plugins/plugins.h
@@ -105,6 +105,7 @@ void plugins_reset_autocomplete(void);
 void plugins_shutdown(void);
 
 gboolean plugins_load(const char *const name);
+gboolean plugins_unload(const char *const name);
 
 void plugins_on_start(void);
 void plugins_on_shutdown(void);
diff --git a/src/plugins/profapi.c b/src/plugins/profapi.c
index d80e2690..617fd9f0 100644
--- a/src/plugins/profapi.c
+++ b/src/plugins/profapi.c
@@ -42,7 +42,7 @@ int (*prof_cons_show)(const char * const message) = NULL;
 int (*prof_cons_show_themed)(const char *const group, const char *const item, const char *const def, const char *const message) = NULL;
 int (*prof_cons_bad_cmd_usage)(const char *const cmd) = NULL;
 
-void (*_prof_register_command)(const char *filename, const char *command_name, int min_args, int max_args,
+void (*_prof_register_command)(const char *filename, char *command_name, int min_args, int max_args,
     const char **synopsis, const char *description, const char *arguments[][2], const char **examples,
     void(*callback)(char **args)) = NULL;
 
diff --git a/src/plugins/profapi.h b/src/plugins/profapi.h
index 8c41b2f2..7f26c33f 100644
--- a/src/plugins/profapi.h
+++ b/src/plugins/profapi.h
@@ -46,7 +46,7 @@ int (*prof_cons_show)(const char * const message);
 int (*prof_cons_show_themed)(const char *const group, const char *const item, const char *const def, const char *const message);
 int (*prof_cons_bad_cmd_usage)(const char *const cmd);
 
-void (*_prof_register_command)(const char *filename, const char *command_name, int min_args, int max_args,
+void (*_prof_register_command)(const char *filename, char *command_name, int min_args, int max_args,
     const char **synopsis, const char *description, const char *arguments[][2], const char **examples,
     void(*callback)(char **args));
 
diff --git a/src/plugins/python_api.c b/src/plugins/python_api.c
index 87a2b4d2..356a2854 100644
--- a/src/plugins/python_api.c
+++ b/src/plugins/python_api.c
@@ -105,7 +105,7 @@ python_api_cons_bad_cmd_usage(PyObject *self, PyObject *args)
 static PyObject*
 python_api_register_command(PyObject *self, PyObject *args)
 {
-    const char *command_name = NULL;
+    char *command_name = NULL;
     int min_args = 0;
     int max_args = 0;
     PyObject *synopsis = NULL;
@@ -165,7 +165,7 @@ python_api_register_command(PyObject *self, PyObject *args)
         c_examples[len] = NULL;
 
         allow_python_threads();
-        api_register_command(command_name, min_args, max_args, c_synopsis,
+        api_register_command(plugin_name, command_name, min_args, max_args, c_synopsis,
             description, c_arguments, c_examples, p_callback, python_command_callback);
         disable_python_threads();
     }
diff --git a/src/plugins/python_plugins.c b/src/plugins/python_plugins.c
index 7861f484..8e8f72a7 100644
--- a/src/plugins/python_plugins.c
+++ b/src/plugins/python_plugins.c
@@ -888,6 +888,7 @@ python_check_error(void)
 void
 python_plugin_destroy(ProfPlugin *plugin)
 {
+    callbacks_remove_commands(plugin->name);
     disable_python_threads();
     free(plugin->name);
     Py_XDECREF(plugin->module);