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, &copy_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 }