Created SILC Runtime Toolkit git repository Part I.
[runtime.git] / apps / irssi / src / core / signals.c
diff --git a/apps/irssi/src/core/signals.c b/apps/irssi/src/core/signals.c
deleted file mode 100644 (file)
index 3164245..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- signals.c : irssi
-
-    Copyright (C) 1999-2002 Timo Sirainen
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "module.h"
-#include "signals.h"
-#include "modules.h"
-
-typedef struct _SignalHook {
-       struct _SignalHook *next;
-
-        int priority;
-       const char *module;
-       SIGNAL_FUNC func;
-       void *user_data;
-} SignalHook;
-
-typedef struct {
-       int id; /* signal id */
-        int refcount;
-
-       int emitting; /* signal is being emitted */
-       int stop_emit; /* this signal was stopped */
-       int continue_emit; /* this signal emit was continued elsewhere */
-        int remove_count; /* hooks were removed from signal */
-
-        SignalHook *hooks;
-} Signal;
-
-void *signal_user_data;
-
-static GHashTable *signals;
-static Signal *current_emitted_signal;
-static SignalHook *current_emitted_hook;
-
-#define signal_ref(signal) ++(signal)->refcount
-#define signal_unref(signal) (signal_unref_full(signal, TRUE))
-
-static int signal_unref_full(Signal *rec, int remove)
-{
-        g_assert(rec->refcount > 0);
-
-       if (--rec->refcount != 0)
-               return TRUE;
-
-       /* remove whole signal from memory */
-       if (rec->hooks != NULL) {
-               g_error("signal_unref(%s) : BUG - hook list wasn't empty",
-                       signal_get_id_str(rec->id));
-       }
-
-       if (remove)
-               g_hash_table_remove(signals, GINT_TO_POINTER(rec->id));
-        g_free(rec);
-
-       return FALSE;
-}
-
-static void signal_hash_ref(void *key, Signal *rec)
-{
-       signal_ref(rec);
-}
-
-static int signal_hash_unref(void *key, Signal *rec)
-{
-       return !signal_unref_full(rec, FALSE);
-}
-
-void signal_add_full(const char *module, int priority,
-                    const char *signal, SIGNAL_FUNC func, void *user_data)
-{
-       signal_add_full_id(module, priority, signal_get_uniq_id(signal),
-                          func, user_data);
-}
-
-/* bind a signal */
-void signal_add_full_id(const char *module, int priority,
-                       int signal_id, SIGNAL_FUNC func, void *user_data)
-{
-       Signal *signal;
-        SignalHook *hook, **tmp;
-
-       g_return_if_fail(signal_id >= 0);
-       g_return_if_fail(func != NULL);
-
-       signal = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-       if (signal == NULL) {
-                /* new signal */
-               signal = g_new0(Signal, 1);
-               signal->id = signal_id;
-               g_hash_table_insert(signals, GINT_TO_POINTER(signal_id), signal);
-       }
-
-       hook = g_new0(SignalHook, 1);
-       hook->priority = priority;
-       hook->module = module;
-       hook->func = func;
-       hook->user_data = user_data;
-
-       /* insert signal to proper position in list */
-       for (tmp = &signal->hooks; ; tmp = &(*tmp)->next) {
-               if (*tmp == NULL) {
-                        /* last in list */
-                       *tmp = hook;
-                        break;
-               } else if (priority <= (*tmp)->priority) {
-                        /* insert before others with same priority */
-                       hook->next = *tmp;
-                       *tmp = hook;
-                        break;
-               }
-       }
-
-        signal_ref(signal);
-}
-
-static void signal_remove_hook(Signal *rec, SignalHook **hook_pos)
-{
-       SignalHook *hook;
-
-        hook = *hook_pos;
-        *hook_pos = hook->next;
-
-       g_free(hook);
-
-       signal_unref(rec);
-}
-
-/* Remove function from signal's emit list */
-static int signal_remove_func(Signal *rec, SIGNAL_FUNC func, void *user_data)
-{
-        SignalHook **hook;
-
-       for (hook = &rec->hooks; *hook != NULL; hook = &(*hook)->next) {
-               if ((*hook)->func == func && (*hook)->user_data == user_data) {
-                       if (rec->emitting) {
-                               /* mark it removed after emitting is done */
-                               (*hook)->func = NULL;
-                                rec->remove_count++;
-                       } else {
-                               /* remove the function from emit list */
-                               signal_remove_hook(rec, hook);
-                       }
-                       return TRUE;
-               }
-       }
-
-        return FALSE;
-}
-
-void signal_remove_id(int signal_id, SIGNAL_FUNC func, void *user_data)
-{
-       Signal *rec;
-
-       g_return_if_fail(signal_id >= 0);
-       g_return_if_fail(func != NULL);
-
-       rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-        if (rec != NULL)
-                signal_remove_func(rec, func, user_data);
-}
-
-/* unbind signal */
-void signal_remove_full(const char *signal, SIGNAL_FUNC func, void *user_data)
-{
-       g_return_if_fail(signal != NULL);
-
-       signal_remove_id(signal_get_uniq_id(signal), func, user_data);
-}
-
-static void signal_hooks_clean(Signal *rec)
-{
-       SignalHook **hook, **next;
-        int count;
-
-        count = rec->remove_count;
-        rec->remove_count = 0;
-
-       for (hook = &rec->hooks; *hook != NULL; hook = next) {
-               next = &(*hook)->next;
-
-               if ((*hook)->func == NULL) {
-                        next = hook;
-                       signal_remove_hook(rec, hook);
-
-                       if (--count == 0)
-                                break;
-               }
-       }
-}
-
-static int signal_emit_real(Signal *rec, int params, va_list va,
-                           SignalHook *first_hook)
-{
-       const void *arglist[SIGNAL_MAX_ARGUMENTS];
-       Signal *prev_emitted_signal;
-        SignalHook *hook, *prev_emitted_hook;
-       int i, stopped, stop_emit_count, continue_emit_count;
-
-       for (i = 0; i < SIGNAL_MAX_ARGUMENTS; i++)
-               arglist[i] = i >= params ? NULL : va_arg(va, const void *);
-
-       /* signal_stop_by_name("signal"); signal_emit("signal", ...);
-          fails if we compare rec->stop_emit against 0. */
-       stop_emit_count = rec->stop_emit;
-       continue_emit_count = rec->continue_emit;
-
-        signal_ref(rec);
-
-       stopped = FALSE;
-       rec->emitting++;
-
-       prev_emitted_signal = current_emitted_signal;
-       prev_emitted_hook = current_emitted_hook;
-       current_emitted_signal = rec;
-
-       for (hook = first_hook; hook != NULL; hook = hook->next) {
-               if (hook->func == NULL)
-                       continue; /* removed */
-
-               current_emitted_hook = hook;
-#if SIGNAL_MAX_ARGUMENTS != 6
-#  error SIGNAL_MAX_ARGUMENTS changed - update code
-#endif
-                signal_user_data = hook->user_data;
-               hook->func(arglist[0], arglist[1], arglist[2], arglist[3],
-                          arglist[4], arglist[5]);
-
-               if (rec->continue_emit != continue_emit_count)
-                       rec->continue_emit--;
-
-               if (rec->stop_emit != stop_emit_count) {
-                       stopped = TRUE;
-                       rec->stop_emit--;
-                       break;
-               }
-       }
-
-       current_emitted_signal = prev_emitted_signal;
-       current_emitted_hook = prev_emitted_hook;
-
-       rec->emitting--;
-       signal_user_data = NULL;
-
-       if (!rec->emitting) {
-               g_assert(rec->stop_emit == 0);
-               g_assert(rec->continue_emit == 0);
-
-                if (rec->remove_count > 0)
-                       signal_hooks_clean(rec);
-       }
-
-        signal_unref(rec);
-       return stopped;
-}
-
-int signal_emit(const char *signal, int params, ...)
-{
-       Signal *rec;
-       va_list va;
-       int signal_id;
-
-       g_return_val_if_fail(params >= 0 && params <= SIGNAL_MAX_ARGUMENTS, FALSE);
-
-       signal_id = signal_get_uniq_id(signal);
-
-       rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-       if (rec != NULL) {
-               va_start(va, params);
-               signal_emit_real(rec, params, va, rec->hooks);
-               va_end(va);
-       }
-
-       return rec != NULL;
-}
-
-int signal_emit_id(int signal_id, int params, ...)
-{
-       Signal *rec;
-       va_list va;
-
-       g_return_val_if_fail(signal_id >= 0, FALSE);
-       g_return_val_if_fail(params >= 0 && params <= SIGNAL_MAX_ARGUMENTS, FALSE);
-
-       rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-       if (rec != NULL) {
-               va_start(va, params);
-               signal_emit_real(rec, params, va, rec->hooks);
-               va_end(va);
-       }
-
-       return rec != NULL;
-}
-
-void signal_continue(int params, ...)
-{
-       Signal *rec;
-       va_list va;
-
-       rec = current_emitted_signal;
-       if (rec == NULL || rec->emitting <= rec->continue_emit)
-               g_warning("signal_continue() : no signals are being emitted currently");
-       else {
-               va_start(va, params);
-
-               /* stop the signal */
-               if (rec->emitting > rec->stop_emit)
-                       rec->stop_emit++;
-
-               /* re-emit */
-               rec->continue_emit++;
-               signal_emit_real(rec, params, va, current_emitted_hook->next);
-               va_end(va);
-       }
-}
-
-/* stop the current ongoing signal emission */
-void signal_stop(void)
-{
-       Signal *rec;
-
-       rec = current_emitted_signal;
-       if (rec == NULL)
-               g_warning("signal_stop() : no signals are being emitted currently");
-       else if (rec->emitting > rec->stop_emit)
-               rec->stop_emit++;
-}
-
-/* stop ongoing signal emission by signal name */
-void signal_stop_by_name(const char *signal)
-{
-       Signal *rec;
-       int signal_id;
-
-       signal_id = signal_get_uniq_id(signal);
-       rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-       if (rec == NULL)
-               g_warning("signal_stop_by_name() : unknown signal \"%s\"", signal);
-       else if (rec->emitting > rec->stop_emit)
-               rec->stop_emit++;
-}
-
-/* return the name of the signal that is currently being emitted */
-const char *signal_get_emitted(void)
-{
-       return signal_get_id_str(signal_get_emitted_id());
-}
-
-/* return the ID of the signal that is currently being emitted */
-int signal_get_emitted_id(void)
-{
-       Signal *rec;
-
-       rec = current_emitted_signal;
-        g_return_val_if_fail(rec != NULL, -1);
-       return rec->id;
-}
-
-/* return TRUE if specified signal was stopped */
-int signal_is_stopped(int signal_id)
-{
-       Signal *rec;
-
-       rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
-       g_return_val_if_fail(rec != NULL, FALSE);
-
-        return rec->emitting <= rec->stop_emit;
-}
-
-static void signal_remove_module(void *signal, Signal *rec,
-                                const char *module)
-{
-       SignalHook **hook, **next;
-
-       for (hook = &rec->hooks; *hook != NULL; hook = next) {
-               next = &(*hook)->next;
-
-               if (strcasecmp((*hook)->module, module) == 0) {
-                        next = hook;
-                       signal_remove_hook(rec, hook);
-               }
-       }
-}
-
-/* remove all signals that belong to `module' */
-void signals_remove_module(const char *module)
-{
-       g_return_if_fail(module != NULL);
-
-       g_hash_table_foreach(signals, (GHFunc) signal_hash_ref, NULL);
-       g_hash_table_foreach(signals, (GHFunc) signal_remove_module,
-                            (void *) module);
-       g_hash_table_foreach_remove(signals, (GHRFunc) signal_hash_unref, NULL);
-}
-
-void signals_init(void)
-{
-       signals = g_hash_table_new(NULL, NULL);
-}
-
-static void signal_free(void *key, Signal *rec)
-{
-       /* refcount-1 because we just referenced it ourself */
-       g_warning("signal_free(%s) : signal still has %d references:",
-                 signal_get_id_str(rec->id), rec->refcount-1);
-
-       while (rec->hooks != NULL) {
-               g_warning(" - module '%s' function %p",
-                         rec->hooks->module, rec->hooks->func);
-
-               signal_remove_hook(rec, &rec->hooks);
-       }
-}
-
-void signals_deinit(void)
-{
-       g_hash_table_foreach(signals, (GHFunc) signal_hash_ref, NULL);
-        g_hash_table_foreach(signals, (GHFunc) signal_free, NULL);
-       g_hash_table_foreach_remove(signals, (GHRFunc) signal_hash_unref, NULL);
-       g_hash_table_destroy(signals);
-
-       module_uniq_destroy("signals");
-}