diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/api.c | 14 | ||||
-rw-r--r-- | src/plugins/api.h | 8 | ||||
-rw-r--r-- | src/plugins/c_api.c | 14 | ||||
-rw-r--r-- | src/plugins/callbacks.c | 125 | ||||
-rw-r--r-- | src/plugins/callbacks.h | 6 | ||||
-rw-r--r-- | src/plugins/python_api.c | 26 |
6 files changed, 152 insertions, 41 deletions
diff --git a/src/plugins/api.c b/src/plugins/api.c index ea134fe4..2a577296 100644 --- a/src/plugins/api.c +++ b/src/plugins/api.c @@ -107,18 +107,21 @@ api_cons_bad_cmd_usage(const char *const cmd) void api_register_command(const char *const plugin_name, const 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_exec)(PluginCommand *command, gchar **args)) + const char **synopsis, const char *description, const char *arguments[][2], const char **examples, + void *callback, void(*callback_exec)(PluginCommand *command, gchar **args), void(*callback_destroy)(void *callback)) { PluginCommand *command = malloc(sizeof(PluginCommand)); - command->command_name = command_name; + command->command_name = strdup(command_name); command->min_args = min_args; command->max_args = max_args; command->callback = callback; command->callback_exec = callback_exec; + command->callback_destroy = callback_destroy; CommandHelp *help = malloc(sizeof(CommandHelp)); + help->tags[0] = NULL; + int i = 0; for (i = 0; synopsis[i] != NULL; i++) { help->synopsis[i] = strdup(synopsis[i]); @@ -140,16 +143,17 @@ api_register_command(const char *const plugin_name, const char *command_name, in command->help = help; - callbacks_add_command(command); + callbacks_add_command(plugin_name, command); } void api_register_timed(const char *const plugin_name, void *callback, int interval_seconds, - void (*callback_exec)(PluginTimedFunction *timed_function)) + void (*callback_exec)(PluginTimedFunction *timed_function), void(*callback_destroy)(void *callback)) { PluginTimedFunction *timed_function = malloc(sizeof(PluginTimedFunction)); timed_function->callback = callback; timed_function->callback_exec = callback_exec; + timed_function->callback_destroy = callback_destroy; timed_function->interval_seconds = interval_seconds; timed_function->timer = g_timer_new(); diff --git a/src/plugins/api.h b/src/plugins/api.h index 571c6168..0b1aec32 100644 --- a/src/plugins/api.h +++ b/src/plugins/api.h @@ -52,9 +52,9 @@ char** api_get_current_occupants(void); void api_register_command(const char *const plugin_name, const 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 *callback, void(*callback_func)(PluginCommand *command, gchar **args), void(*callback_destroy)(void *callback)); void api_register_timed(const char *const plugin_name, void *callback, int interval_seconds, - void (*callback_func)(PluginTimedFunction *timed_function)); + void (*callback_func)(PluginTimedFunction *timed_function), void(*callback_destroy)(void *callback)); void api_completer_add(const char *const plugin_name, const char *key, char **items); void api_completer_remove(const char *key, char **items); @@ -70,8 +70,8 @@ void api_win_create( const char *const plugin_name, const char *tag, void *callback, - void(*destroy)(void *callback), - void(*callback_func)(PluginWindowCallback *window_callback, char *tag, char *line)); + void(*callback_func)(PluginWindowCallback *window_callback, char *tag, char *line), + void(*destroy)(void *callback)); int api_win_focus(const char *tag); int api_win_show(const char *tag, const char *line); int api_win_show_themed(const char *tag, const char *const group, const char *const key, const char *const def, const char *line); diff --git a/src/plugins/c_api.c b/src/plugins/c_api.c index 96673972..32719feb 100644 --- a/src/plugins/c_api.c +++ b/src/plugins/c_api.c @@ -90,7 +90,9 @@ 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(plugin_name, command_name, min_args, max_args, synopsis, - description, arguments, examples, wrapper, c_command_callback); + description, arguments, examples, wrapper, c_command_callback, free); + + free(plugin_name); } static void @@ -101,7 +103,9 @@ c_api_register_timed(const char *filename, void(*callback)(void), int interval_s TimedWrapper *wrapper = malloc(sizeof(TimedWrapper)); wrapper->func = callback; - api_register_timed(plugin_name, wrapper, interval_seconds, c_timed_callback); + api_register_timed(plugin_name, wrapper, interval_seconds, c_timed_callback, free); + + free(plugin_name); } static void @@ -111,6 +115,8 @@ c_api_completer_add(const char *filename, const char *key, char **items) log_debug("Autocomplete add %s for %s", key, plugin_name); api_completer_add(plugin_name, key, items); + + free(plugin_name); } static void @@ -205,7 +211,9 @@ c_api_win_create(const char *filename, char *tag, void(*callback)(char *tag, cha WindowWrapper *wrapper = malloc(sizeof(WindowWrapper)); wrapper->func = callback; - api_win_create(plugin_name, tag, wrapper, free, c_window_callback); + api_win_create(plugin_name, tag, wrapper, c_window_callback, free); + + free(plugin_name); } static int diff --git a/src/plugins/callbacks.c b/src/plugins/callbacks.c index 57a8c09d..2569962c 100644 --- a/src/plugins/callbacks.c +++ b/src/plugins/callbacks.c @@ -44,7 +44,7 @@ #include "ui/ui.h" -static GSList *p_commands = NULL; +static GHashTable *p_commands = NULL; static GSList *p_timed_functions = NULL; static GHashTable *p_window_callbacks = NULL; @@ -57,22 +57,88 @@ _free_window_callback(PluginWindowCallback *window_callback) free(window_callback); } +//typedef struct cmd_help_t { +// const gchar *tags[20]; +// const gchar *synopsis[50]; +// const gchar *desc; +// const gchar *args[128][2]; +// const gchar *examples[20]; +//} CommandHelp; + +static void +_free_command_help(CommandHelp *help) +{ + int i = 0; + while (help->tags[i] != NULL) { + free(help->tags[i++]); + } + + i = 0; + while (help->synopsis[i] != NULL) { + free(help->synopsis[i++]); + } + + free(help->desc); + + i = 0; + while (help->args[i] != NULL && help->args[i][0] != NULL) { + free(help->args[i][0]); + free(help->args[i][1]); + i++; + } + + i = 0; + while (help->examples[i] != NULL) { + free(help->examples[i++]); + } + + free(help); +} + +static void +_free_command(PluginCommand *command) +{ + if (command->callback_destroy) { + command->callback_destroy(command->callback); + } + free(command->command_name); + + _free_command_help(command->help); + free(command); +} + +static void +_free_command_hash(GHashTable *command_hash) +{ + g_hash_table_destroy(command_hash); +} + void callbacks_init(void) { + p_commands = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_free_command_hash); p_window_callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_free_window_callback); } +// TODO move to plugin destroy functions void callbacks_close(void) { + g_hash_table_destroy(p_commands); g_hash_table_destroy(p_window_callbacks); } void -callbacks_add_command(PluginCommand *command) +callbacks_add_command(const char *const plugin_name, PluginCommand *command) { - p_commands = g_slist_append(p_commands, command); + GHashTable *command_hash = g_hash_table_lookup(p_commands, plugin_name); + if (command_hash) { + g_hash_table_insert(command_hash, strdup(command->command_name), command); + } else { + command_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_free_command); + g_hash_table_insert(command_hash, strdup(command->command_name), command); + g_hash_table_insert(p_commands, strdup(plugin_name), command_hash); + } cmd_ac_add(command->command_name); cmd_ac_add_help(&command->command_name[1]); } @@ -104,25 +170,32 @@ plugins_run_command(const char * const input) { gchar **split = g_strsplit(input, " ", -1); - GSList *p_command = p_commands; - while (p_command) { - PluginCommand *command = p_command->data; - if (g_strcmp0(split[0], command->command_name) == 0) { + GList *command_hashes = g_hash_table_get_values(p_commands); + GList *curr_hash = command_hashes; + while (curr_hash) { + GHashTable *command_hash = curr_hash->data; + + PluginCommand *command = g_hash_table_lookup(command_hash, split[0]); + if (command) { gboolean result; gchar **args = parse_args_with_freetext(input, command->min_args, command->max_args, &result); if (result == FALSE) { ui_invalid_command_usage(command->command_name, NULL); g_strfreev(split); + g_list_free(command_hashes); return TRUE; } else { command->callback_exec(command, args); g_strfreev(split); g_strfreev(args); + g_list_free(command_hashes); return TRUE; } } - p_command = g_slist_next(p_command); + + curr_hash = g_list_next(curr_hash); } + g_strfreev(split); return FALSE; } @@ -130,16 +203,22 @@ plugins_run_command(const char * const input) CommandHelp* plugins_get_help(const char *const cmd) { - GSList *curr = p_commands; - while (curr) { - PluginCommand *command = curr->data; - if (g_strcmp0(cmd, command->command_name) == 0) { + GList *command_hashes = g_hash_table_get_values(p_commands); + GList *curr_hash = command_hashes; + while (curr_hash) { + GHashTable *command_hash = curr_hash->data; + + PluginCommand *command = g_hash_table_lookup(command_hash, cmd); + if (command) { + g_list_free(command_hashes); return command->help; } - curr = g_slist_next(curr); + curr_hash = g_list_next(curr_hash); } + g_list_free(command_hashes); + return NULL; } @@ -167,12 +246,22 @@ plugins_get_command_names(void) { GList *result = NULL; - GSList *curr = p_commands; - while (curr) { - PluginCommand *command = curr->data; - result = g_list_append(result, (char*)command->command_name); - curr = g_slist_next(curr); + GList *command_hashes = g_hash_table_get_values(p_commands); + GList *curr_hash = command_hashes; + while (curr_hash) { + GHashTable *command_hash = curr_hash->data; + GList *commands = g_hash_table_get_keys(command_hash); + GList *curr = commands; + while (curr) { + char *command = curr->data; + result = g_list_append(result, command); + curr = g_list_next(curr); + } + g_list_free(commands); + curr_hash = g_list_next(curr_hash); } + g_list_free(command_hashes); + return result; } diff --git a/src/plugins/callbacks.h b/src/plugins/callbacks.h index 0ef6de9f..fa78d2c6 100644 --- a/src/plugins/callbacks.h +++ b/src/plugins/callbacks.h @@ -40,17 +40,19 @@ #include "command/cmd_defs.h" typedef struct p_command { - const char *command_name; + char *command_name; int min_args; int max_args; CommandHelp *help; void *callback; void (*callback_exec)(struct p_command *command, gchar **args); + void (*callback_destroy)(void *callback); } PluginCommand; typedef struct p_timed_function { void *callback; void (*callback_exec)(struct p_timed_function *timed_function); + void (*callback_destroy)(void *callback); int interval_seconds; GTimer *timer; } PluginTimedFunction; @@ -64,7 +66,7 @@ typedef struct p_window_input_callback { void callbacks_init(void); void callbacks_close(void); -void callbacks_add_command(PluginCommand *command); +void callbacks_add_command(const char *const plugin, PluginCommand *command); 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/python_api.c b/src/plugins/python_api.c index 1a60a07c..82cf22eb 100644 --- a/src/plugins/python_api.c +++ b/src/plugins/python_api.c @@ -166,19 +166,18 @@ python_api_register_command(PyObject *self, PyObject *args) allow_python_threads(); api_register_command(plugin_name, command_name, min_args, max_args, c_synopsis, - description, c_arguments, c_examples, p_callback, python_command_callback); + description, c_arguments, c_examples, p_callback, python_command_callback, NULL); disable_python_threads(); } + free(plugin_name); + return Py_BuildValue(""); } static PyObject * python_api_register_timed(PyObject *self, PyObject *args) { - char *plugin_name = _python_plugin_name(); - log_debug("Register timed for %s", plugin_name); - PyObject *p_callback = NULL; int interval_seconds = 0; @@ -186,12 +185,17 @@ python_api_register_timed(PyObject *self, PyObject *args) return Py_BuildValue(""); } + char *plugin_name = _python_plugin_name(); + log_debug("Register timed for %s", plugin_name); + if (p_callback && PyCallable_Check(p_callback)) { allow_python_threads(); - api_register_timed(plugin_name, p_callback, interval_seconds, python_timed_callback); + api_register_timed(plugin_name, p_callback, interval_seconds, python_timed_callback, NULL); disable_python_threads(); } + free(plugin_name); + return Py_BuildValue(""); } @@ -223,6 +227,8 @@ python_api_completer_add(PyObject *self, PyObject *args) api_completer_add(plugin_name, key, c_items); disable_python_threads(); + free(plugin_name); + return Py_BuildValue(""); } @@ -456,19 +462,21 @@ python_api_win_create(PyObject *self, PyObject *args) char *tag = NULL; PyObject *p_callback = NULL; - char *plugin_name = _python_plugin_name(); - log_debug("Win create %s for %s", tag, plugin_name); - if (!PyArg_ParseTuple(args, "sO", &tag, &p_callback)) { return Py_BuildValue(""); } + char *plugin_name = _python_plugin_name(); + log_debug("Win create %s for %s", tag, plugin_name); + if (p_callback && PyCallable_Check(p_callback)) { allow_python_threads(); - api_win_create(plugin_name, tag, p_callback, NULL, python_window_callback); + api_win_create(plugin_name, tag, p_callback, python_window_callback, NULL); disable_python_threads(); } + free(plugin_name); + return Py_BuildValue(""); } |