Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-common / core / fe-modules.c
index e351dc7142f481b9054a6972be92d2db36ced374..3c3c979022885f07a2aa4d1cb302251cff30a600 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "module.h"
 #include "modules.h"
+#include "modules-load.h"
 #include "module-formats.h"
 #include "signals.h"
 #include "commands.h"
 
 #include "printtext.h"
 
-static void sig_module_error(void *number, const char *module,
-                            const char *data)
+#ifdef HAVE_GMODULE
+
+static void sig_module_error(void *number, const char *data,
+                            const char *rootmodule, const char *submodule)
 {
        switch (GPOINTER_TO_INT(number)) {
        case MODULE_ERROR_ALREADY_LOADED:
                printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-                           TXT_MODULE_ALREADY_LOADED, module);
+                           TXT_MODULE_ALREADY_LOADED, rootmodule, submodule);
                break;
        case MODULE_ERROR_LOAD:
                printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-                           TXT_MODULE_LOAD_ERROR, module, data);
+                           TXT_MODULE_LOAD_ERROR, rootmodule, submodule, data);
                break;
        case MODULE_ERROR_INVALID:
                printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
-                           TXT_MODULE_INVALID, module);
+                           TXT_MODULE_INVALID, rootmodule, submodule);
                break;
        }
 }
 
-static void sig_module_loaded(MODULE_REC *rec)
+static void sig_module_loaded(MODULE_REC *module, MODULE_FILE_REC *file)
 {
        printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                   TXT_MODULE_LOADED, rec->name);
+                   TXT_MODULE_LOADED, module->name, file->name);
 }
 
-static void sig_module_unloaded(MODULE_REC *rec)
+static void sig_module_unloaded(MODULE_REC *module, MODULE_FILE_REC *file)
 {
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                   TXT_MODULE_UNLOADED, rec->name);
+       if (file != NULL && file->gmodule != NULL) {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
+                           TXT_MODULE_UNLOADED, module->name, file->name);
+       }
+}
+
+static int module_list_sub(MODULE_REC *module, int mark_type,
+                          GString *submodules)
+{
+       GSList *tmp;
+        int all_dynamic, dynamic;
+
+       g_string_truncate(submodules, 0);
+
+        all_dynamic = -1;
+       for (tmp = module->files; tmp != NULL; tmp = tmp->next) {
+               MODULE_FILE_REC *file = tmp->data;
+
+               /* if there's dynamic and static modules mixed, we'll need
+                  to specify them separately */
+               if (!mark_type) {
+                       dynamic = file->gmodule != NULL;
+                       if (all_dynamic != -1 && all_dynamic != dynamic) {
+                               return module_list_sub(module, TRUE,
+                                                      submodules);
+                       }
+                       all_dynamic = dynamic;
+               }
+
+               if (submodules->len > 0)
+                       g_string_append_c(submodules, ' ');
+               g_string_append(submodules, file->name);
+               if (mark_type) {
+                       g_string_append(submodules, file->gmodule == NULL ?
+                                       " (static)" : " (dynamic)");
+               }
+       }
+
+        return all_dynamic;
 }
 
 static void cmd_load_list(void)
 {
        GSList *tmp;
+       GString *submodules;
+        const char *type;
+        int dynamic;
+
+        submodules = g_string_new(NULL);
 
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_MODULE_HEADER);
+       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_MODULE_HEADER);
        for (tmp = modules; tmp != NULL; tmp = tmp->next) {
                MODULE_REC *rec = tmp->data;
 
-               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                           TXT_MODULE_LINE, rec->name);
+                dynamic = module_list_sub(rec, FALSE, submodules);
+               type = dynamic == -1 ? "mixed" :
+                       dynamic ? "dynamic" : "static";
+
+               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                           TXT_MODULE_LINE, rec->name, type, submodules->str);
        }
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_MODULE_FOOTER);
+       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_MODULE_FOOTER);
+
+       g_string_free(submodules, TRUE);
 }
 
 static char **module_prefixes_get(void)
@@ -79,7 +130,7 @@ static char **module_prefixes_get(void)
         char **list, *name;
         int count;
 
-       list = g_new(char *, 2 + 2*g_slist_length(chat_protocols));
+       list = g_new(char *, 2 + 3*g_slist_length(chat_protocols));
        list[0] = "fe";
 
        count = 1;
@@ -91,6 +142,7 @@ static char **module_prefixes_get(void)
 
                list[count++] = name;
                 list[count++] = g_strconcat("fe_", name, NULL);
+                list[count++] = g_strconcat("fe_common_", name, NULL);
        }
        list[count] = NULL;
 
@@ -108,36 +160,67 @@ static void module_prefixes_free(char **list)
         g_free(list);
 }
 
-/* SYNTAX: LOAD <module> */
+/* SYNTAX: LOAD <module> [<submodule>] */
 static void cmd_load(const char *data)
 {
-#ifdef HAVE_GMODULE
+        char *rootmodule, *submodule;
        char **module_prefixes;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
-       if (*data == '\0')
+
+       if (!cmd_get_params(data, &free_arg, 2 , &rootmodule, &submodule))
+               return;
+
+       if (*rootmodule == '\0')
                cmd_load_list();
        else {
                module_prefixes = module_prefixes_get();
-               module_load(data, module_prefixes);
+               if (*submodule == '\0')
+                       module_load(rootmodule, module_prefixes);
+               else {
+                       module_load_sub(rootmodule, submodule,
+                                       module_prefixes);
+               }
                 module_prefixes_free(module_prefixes);
        }
-#else
-       printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
-                 "Dynamic modules loading not supported");
-#endif
+
+       cmd_params_free(free_arg);
 }
 
-/* SYNTAX: UNLOAD <module> */
+/* SYNTAX: UNLOAD <module> [<submodule>] */
 static void cmd_unload(const char *data)
 {
-       MODULE_REC *rec;
+       MODULE_REC *module;
+        MODULE_FILE_REC *file;
+        char *rootmodule, *submodule;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
-       if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
 
-       rec = module_find(data);
-       if (rec != NULL) module_unload(rec);
+       if (!cmd_get_params(data, &free_arg, 2 , &rootmodule, &submodule))
+               return;
+       if (*rootmodule == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+       module = module_find(rootmodule);
+       if (module != NULL) {
+               if (*submodule == '\0')
+                       module_unload(module);
+               else {
+                       file = module_file_find(module, submodule);
+                        if (file != NULL)
+                               module_file_unload(file);
+                       else
+                                module = NULL;
+               }
+       }
+
+       if (module == NULL) {
+               printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                            TXT_MODULE_NOT_LOADED, rootmodule, submodule);
+       }
+
+       cmd_params_free(free_arg);
 }
 
 void fe_modules_init(void)
@@ -159,3 +242,22 @@ void fe_modules_deinit(void)
        command_unbind("load", (SIGNAL_FUNC) cmd_load);
        command_unbind("unload", (SIGNAL_FUNC) cmd_unload);
 }
+
+#else /* !HAVE_GMODULE */
+
+static void cmd_load(const char *data)
+{
+       printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                 "Dynamic modules loading not supported");
+}
+
+void fe_modules_init(void)
+{
+       command_bind("load", NULL, (SIGNAL_FUNC) cmd_load);
+}
+
+void fe_modules_deinit(void)
+{
+       command_unbind("load", (SIGNAL_FUNC) cmd_load);
+}
+#endif