Mercurial > pidgin.yaz
comparison plugins/perl/perl-handlers.c @ 6920:13f78c350cd3
[gaim-migrate @ 7467]
Fixed problems with the wrong data being sent to signal callbacks in perl
plugins. The resulting code has more sanity checks, but is extremely ugly,
and is therefore rated R. Parents, don't let your children see
perl-common.c.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Wed, 24 Sep 2003 00:03:08 +0000 |
parents | 1aa771990188 |
children | 11d05ddf30a3 |
comparison
equal
deleted
inserted
replaced
6919:1aa771990188 | 6920:13f78c350cd3 |
---|---|
69 int i; | 69 int i; |
70 int count; | 70 int count; |
71 int value_count; | 71 int value_count; |
72 GaimValue *ret_value, **values; | 72 GaimValue *ret_value, **values; |
73 SV **sv_args; | 73 SV **sv_args; |
74 STRLEN na; | 74 void **copy_args; |
75 | 75 |
76 dSP; | 76 dSP; |
77 ENTER; | 77 ENTER; |
78 SAVETMPS; | 78 SAVETMPS; |
79 PUSHMARK(sp); | 79 PUSHMARK(sp); |
80 | 80 |
81 gaim_signal_get_values(handler->instance, handler->signal, | 81 gaim_signal_get_values(handler->instance, handler->signal, |
82 &ret_value, &value_count, &values); | 82 &ret_value, &value_count, &values); |
83 | 83 |
84 sv_args = g_new(SV *, value_count); | 84 sv_args = g_new(SV *, value_count); |
85 copy_args = g_new(void *, value_count); | |
85 | 86 |
86 for (i = 0; i < value_count; i++) | 87 for (i = 0; i < value_count; i++) |
87 { | 88 { |
88 SV *sv = gaim_perl_sv_from_vargs(values[i], args); | 89 sv_args[i] = gaim_perl_sv_from_vargs(values[i], &args, ©_args[i]); |
89 | 90 |
90 sv_args[i] = sv; | 91 XPUSHs(sv_args[i]); |
91 | |
92 XPUSHs(sv); | |
93 } | 92 } |
94 | 93 |
95 XPUSHs((SV *)handler->data); | 94 XPUSHs((SV *)handler->data); |
96 | 95 |
97 PUTBACK; | 96 PUTBACK; |
103 SPAGAIN; | 102 SPAGAIN; |
104 | 103 |
105 if (count != 1) | 104 if (count != 1) |
106 croak("Uh oh! call_sv returned %i != 1", i); | 105 croak("Uh oh! call_sv returned %i != 1", i); |
107 else | 106 else |
108 { | 107 ret_val = gaim_perl_data_from_sv(ret_value, POPs); |
109 SV *temp_ret_val = POPs; | |
110 | |
111 switch (gaim_value_get_type(ret_value)) | |
112 { | |
113 case GAIM_TYPE_BOOLEAN: | |
114 ret_val = (void *)SvIV(temp_ret_val); | |
115 break; | |
116 | |
117 case GAIM_TYPE_INT: | |
118 ret_val = (void *)SvIV(temp_ret_val); | |
119 break; | |
120 | |
121 case GAIM_TYPE_UINT: | |
122 ret_val = (void *)SvUV(temp_ret_val); | |
123 break; | |
124 | |
125 case GAIM_TYPE_LONG: | |
126 ret_val = (void *)SvIV(temp_ret_val); | |
127 break; | |
128 | |
129 case GAIM_TYPE_ULONG: | |
130 ret_val = (void *)SvUV(temp_ret_val); | |
131 break; | |
132 | |
133 case GAIM_TYPE_INT64: | |
134 ret_val = (void *)SvIV(temp_ret_val); | |
135 break; | |
136 | |
137 case GAIM_TYPE_UINT64: | |
138 ret_val = (void *)SvUV(temp_ret_val); | |
139 break; | |
140 | |
141 case GAIM_TYPE_STRING: | |
142 ret_val = (void *)SvPV(temp_ret_val, na); | |
143 break; | |
144 | |
145 case GAIM_TYPE_POINTER: | |
146 ret_val = (void *)SvIV(temp_ret_val); | |
147 break; | |
148 | |
149 case GAIM_TYPE_BOXED: | |
150 ret_val = (void *)SvIV(temp_ret_val); | |
151 break; | |
152 | |
153 default: | |
154 ret_val = NULL; | |
155 } | |
156 } | |
157 } | 108 } |
158 else | 109 else |
159 call_sv(handler->callback, G_SCALAR); | 110 call_sv(handler->callback, G_SCALAR); |
160 | 111 |
161 /* See if any parameters changed. */ | 112 /* See if any parameters changed. */ |
162 for (i = 0; i < value_count; i++) | 113 for (i = 0; i < value_count; i++) |
163 { | 114 { |
164 if (gaim_value_is_outgoing(values[i])) | 115 if (gaim_value_is_outgoing(values[i])) |
165 { | 116 { |
166 switch (gaim_value_get_type(values[i])) | 117 *((void **)copy_args[i]) = gaim_perl_data_from_sv(values[i], |
167 { | 118 sv_args[i]); |
168 case GAIM_TYPE_BOOLEAN: | |
169 *va_arg(args, gboolean *) = SvIV(sv_args[i]); | |
170 break; | |
171 | |
172 case GAIM_TYPE_INT: | |
173 *va_arg(args, int *) = SvIV(sv_args[i]); | |
174 break; | |
175 | |
176 case GAIM_TYPE_UINT: | |
177 *va_arg(args, unsigned int *) = SvUV(sv_args[i]); | |
178 break; | |
179 | |
180 case GAIM_TYPE_LONG: | |
181 *va_arg(args, long *) = SvIV(sv_args[i]); | |
182 break; | |
183 | |
184 case GAIM_TYPE_ULONG: | |
185 *va_arg(args, unsigned long *) = SvUV(sv_args[i]); | |
186 break; | |
187 | |
188 case GAIM_TYPE_INT64: | |
189 *va_arg(args, gint64 *) = SvIV(sv_args[i]); | |
190 break; | |
191 | |
192 case GAIM_TYPE_UINT64: | |
193 *va_arg(args, guint64 *) = SvUV(sv_args[i]); | |
194 break; | |
195 | |
196 case GAIM_TYPE_STRING: | |
197 /* XXX Memory leak! */ | |
198 *va_arg(args, char **) = SvPV(sv_args[i], na); | |
199 break; | |
200 | |
201 case GAIM_TYPE_POINTER: | |
202 /* XXX Possible memory leak! */ | |
203 *va_arg(args, void **) = (void *)SvIV(sv_args[i]); | |
204 break; | |
205 | |
206 case GAIM_TYPE_BOXED: | |
207 /* Uh.. I dunno. Try this? Likely won't work. Heh. */ | |
208 /* XXX Possible memory leak! */ | |
209 *va_arg(args, void **) = (void *)SvIV(sv_args[i]); | |
210 break; | |
211 | |
212 default: | |
213 return FALSE; | |
214 } | |
215 } | 119 } |
216 } | 120 } |
217 | 121 |
218 FREETMPS; | 122 FREETMPS; |
219 LEAVE; | 123 LEAVE; |
220 | 124 |
221 g_free(sv_args); | 125 g_free(sv_args); |
126 g_free(copy_args); | |
222 | 127 |
223 gaim_debug_misc("perl", "ret_val = %p\n", ret_val); | 128 gaim_debug_misc("perl", "ret_val = %p\n", ret_val); |
224 | 129 |
225 return ret_val; | 130 return ret_val; |
226 } | 131 } |