New silcconfig library and server parser. Merged silc-newconfig-final.patch.
[runtime.git] / apps / irssi / src / perl / perl-sources.c
1 /*
2  perl-sources.c : irssi
3
4     Copyright (C) 1999-2001 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #define NEED_PERL_H
22 #include "module.h"
23 #include "signals.h"
24
25 #include "perl-core.h"
26 #include "perl-common.h"
27
28 typedef struct {
29         PERL_SCRIPT_REC *script;
30         int tag;
31         int refcount;
32
33         SV *func;
34         SV *data;
35 } PERL_SOURCE_REC;
36
37 static GSList *perl_sources;
38
39 static void perl_source_ref(PERL_SOURCE_REC *rec)
40 {
41         rec->refcount++;
42 }
43
44 static void perl_source_unref(PERL_SOURCE_REC *rec)
45 {
46         if (--rec->refcount != 0)
47                 return;
48
49         SvREFCNT_dec(rec->data);
50         SvREFCNT_dec(rec->func);
51         g_free(rec);
52 }
53
54 static void perl_source_destroy(PERL_SOURCE_REC *rec)
55 {
56         perl_sources = g_slist_remove(perl_sources, rec);
57
58         g_source_remove(rec->tag);
59         rec->tag = -1;
60
61         perl_source_unref(rec);
62 }
63
64 static int perl_source_event(PERL_SOURCE_REC *rec)
65 {
66         dSP;
67
68         ENTER;
69         SAVETMPS;
70
71         PUSHMARK(SP);
72         XPUSHs(sv_mortalcopy(rec->data));
73         PUTBACK;
74
75         perl_source_ref(rec);
76         perl_call_sv(rec->func, G_EVAL|G_DISCARD);
77         SPAGAIN;
78
79         if (SvTRUE(ERRSV)) {
80                 char *error = g_strdup(SvPV(ERRSV, PL_na));
81                 signal_emit("script error", 2, rec->script, error);
82                 g_free(error);
83         }
84         perl_source_unref(rec);
85
86         PUTBACK;
87         FREETMPS;
88         LEAVE;
89
90         return 1;
91 }
92
93 int perl_timeout_add(int msecs, SV *func, SV *data)
94 {
95         PERL_SCRIPT_REC *script;
96         PERL_SOURCE_REC *rec;
97         const char *pkg;
98
99         pkg = perl_get_package();
100         script = perl_script_find_package(pkg);
101         g_return_val_if_fail(script != NULL, -1);
102
103         rec = g_new0(PERL_SOURCE_REC, 1);
104         perl_source_ref(rec);
105
106         rec->script = script;
107         rec->func = perl_func_sv_inc(func, pkg);
108         rec->data = SvREFCNT_inc(data);
109         rec->tag = g_timeout_add(msecs, (GSourceFunc) perl_source_event, rec);
110
111         perl_sources = g_slist_append(perl_sources, rec);
112         return rec->tag;
113 }
114
115 int perl_input_add(int source, int condition, SV *func, SV *data)
116 {
117         PERL_SCRIPT_REC *script;
118         PERL_SOURCE_REC *rec;
119         GIOChannel *channel;
120         const char *pkg;
121
122         pkg = perl_get_package();
123         script = perl_script_find_package(pkg);
124         g_return_val_if_fail(script != NULL, -1);
125
126         rec = g_new0(PERL_SOURCE_REC, 1);
127         perl_source_ref(rec);
128
129         rec->script =script;
130         rec->func = perl_func_sv_inc(func, pkg);
131         rec->data = SvREFCNT_inc(data);
132
133         channel = g_io_channel_unix_new(source);
134         rec->tag = g_input_add(channel, condition,
135                                (GInputFunction) perl_source_event, rec);
136         g_io_channel_unref(channel);
137
138         perl_sources = g_slist_append(perl_sources, rec);
139         return rec->tag;
140 }
141
142 void perl_source_remove(int tag)
143 {
144         GSList *tmp;
145
146         for (tmp = perl_sources; tmp != NULL; tmp = tmp->next) {
147                 PERL_SOURCE_REC *rec = tmp->data;
148
149                 if (rec->tag == tag) {
150                         perl_source_destroy(rec);
151                         break;
152                 }
153         }
154 }
155
156 void perl_source_remove_script(PERL_SCRIPT_REC *script)
157 {
158         GSList *tmp, *next;
159
160         for (tmp = perl_sources; tmp != NULL; tmp = next) {
161                 PERL_SOURCE_REC *rec = tmp->data;
162
163                 next = tmp->next;
164                 if (rec->script == script)
165                         perl_source_destroy(rec);
166         }
167 }
168
169 void perl_sources_start(void)
170 {
171         perl_sources = NULL;
172 }
173
174 void perl_sources_stop(void)
175 {
176         /* timeouts and input waits */
177         while (perl_sources != NULL)
178                 perl_source_destroy(perl_sources->data);
179 }