comparison src/perl.c @ 4029:31480901bf29

[gaim-migrate @ 4233] "with the change to .60 and the new method of using perl_call argument parsing was broken. What essentially happened is that the previous method of pre-parsing was to generate a string in the for 'arg one','arg two','arg three' and execute the perl function via &perlfunc(args). This would make the perl function in essense parse the variables for us. With the introduction of perl_call, however, that argument list was being treated as one long, singular argument. perl_call asks for lists of pointers to character arrays that are NULL terminated, and it passes them into the function using an internal method. With this said, I changed the function execute_perl from requiring (char* function, char* args) to (char* function, char** args). It no longer takes a single argument and inserts it into the appropriate data type that is terminated with a NULL element, instead you now have to pass it a pre-NULL terminated array of character pointers to accomodate some functions wanting to give it more than one argument. I modified the functions that use execute_perl to use this method, and commented those lines, as well chopping the multiple argument section into buf[0] = looking sections for clarity. Finally, I inserted a heft comment above execute_perl to try and explain what I did, I hope it is understandable. " -- Eric Timme (var1ety) committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Sun, 01 Dec 2002 20:43:00 +0000
parents 9682c0e022c6
children 9438d2e96cb1
comparison
equal deleted inserted replaced
4028:ab831dca298a 4029:31480901bf29
180 180
181 /* 181 /*
182 2001/06/14: execute_perl replaced by Martin Persson <mep@passagen.se> 182 2001/06/14: execute_perl replaced by Martin Persson <mep@passagen.se>
183 previous use of perl_eval leaked memory, replaced with 183 previous use of perl_eval leaked memory, replaced with
184 a version that uses perl_call instead 184 a version that uses perl_call instead
185 30/11/2002: execute_perl modified by Eric Timme <timothy@voidnet.com>
186 args changed to char** so that we can have preparsed
187 arguments again, and many headaches ensued! This essentially
188 means we replaced one hacked method with a messier hacked
189 method out of perceived necessity. Formerly execute_perl
190 required a single char_ptr, and it would insert it into an
191 array of character pointers and NULL terminate the new array.
192 Now we have to pass in pre-terminated character pointer arrays
193 to accomodate functions that want to pass in multiple arguments.
194
195 Previously arguments were preparsed because an argument list
196 was constructed in the form 'arg one','arg two' and was
197 executed via a call like &funcname(arglist) (see .59.x), so
198 the arglist was magically pre-parsed because of the method.
199 With Martin Persson's change to perl_call we now need to
200 use a null terminated list of character pointers for arguments
201 if we wish them to be parsed. Lacking a better way to allow
202 for both single arguments and many I created a NULL terminated
203 array in every function that called execute_perl and passed
204 that list into the function. In the former version a single
205 character pointer was passed in, and was placed into an array
206 of character pointers with two elements, with a NULL element
207 tacked onto the back, but this method no longer seemed prudent.
208
209 Enhancements in the future might be to get rid of pre-declaring
210 the array sizes? I am not comfortable enough with this
211 subject to attempt it myself and hope it to stand the test
212 of time.
185 */ 213 */
186 214
187 static int 215 static int
188 execute_perl(char *function, char *args) 216 execute_perl(char *function, char **args)
189 { 217 {
190 char *perl_args[2] = { args, NULL }, buf[512]; 218 char buf[512];
191 int count, ret_value = 1; 219 int count, ret_value = 1;
192 SV *sv; 220 SV *sv;
193 221
194 dSP; 222 dSP;
195 ENTER; 223 ENTER;
196 SAVETMPS; 224 SAVETMPS;
197 PUSHMARK(sp); 225 PUSHMARK(sp);
198 count = perl_call_argv(function, G_EVAL | G_SCALAR, perl_args); 226 count = perl_call_argv(function, G_EVAL | G_SCALAR, args);
199 SPAGAIN; 227 SPAGAIN;
200 228
201 sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV)); 229 sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV));
202 if (SvTRUE(sv)) { 230 if (SvTRUE(sv)) {
203 g_snprintf(buf, 512, "Perl error: %s\n", SvPV(sv, count)); 231 g_snprintf(buf, 512, "Perl error: %s\n", SvPV(sv, count));
218 return ret_value; 246 return ret_value;
219 247
220 } 248 }
221 249
222 void perl_unload_file(struct gaim_plugin *plug) { 250 void perl_unload_file(struct gaim_plugin *plug) {
251 char *atmp[2] = { "", NULL }; /* see execute_perl --et */
223 struct perlscript *scp = NULL; 252 struct perlscript *scp = NULL;
224 struct _perl_timeout_handlers *thn; 253 struct _perl_timeout_handlers *thn;
225 struct _perl_event_handlers *ehn; 254 struct _perl_event_handlers *ehn;
226 255
227 GList *pl = perl_list; 256 GList *pl = perl_list;
230 while (pl) { 259 while (pl) {
231 scp = pl->data; 260 scp = pl->data;
232 if (scp->plug == plug) { 261 if (scp->plug == plug) {
233 perl_list = g_list_remove(perl_list, scp); 262 perl_list = g_list_remove(perl_list, scp);
234 if (scp->shutdowncallback[0]) 263 if (scp->shutdowncallback[0])
235 execute_perl(scp->shutdowncallback, ""); 264 execute_perl(scp->shutdowncallback, atmp);
236 perl_list = g_list_remove(perl_list, scp); 265 perl_list = g_list_remove(perl_list, scp);
237 g_free(scp->name); 266 g_free(scp->name);
238 g_free(scp->version); 267 g_free(scp->version);
239 g_free(scp->shutdowncallback); 268 g_free(scp->shutdowncallback);
240 g_free(scp); 269 g_free(scp);
272 save_prefs(); 301 save_prefs();
273 } 302 }
274 303
275 int perl_load_file(char *script_name) 304 int perl_load_file(char *script_name)
276 { 305 {
306 char *atmp[2] = { script_name, NULL }; /* see execute_perl --et */
277 struct gaim_plugin *plug; 307 struct gaim_plugin *plug;
278 GList *p = probed_plugins; 308 GList *p = probed_plugins;
279 GList *s; 309 GList *s;
280 struct perlscript *scp; 310 struct perlscript *scp;
281 int ret; 311 int ret;
295 } 325 }
296 326
297 plug->handle = plug->path; 327 plug->handle = plug->path;
298 plugins = g_list_append(plugins, plug); 328 plugins = g_list_append(plugins, plug);
299 329
300 ret = execute_perl("load_n_eval", script_name); 330 ret = execute_perl("load_n_eval", atmp);
301 331
302 s = perl_list; 332 s = perl_list;
303 while (s) { 333 while (s) {
304 scp = s->data; 334 scp = s->data;
305 335
411 441
412 } 442 }
413 443
414 void perl_end() 444 void perl_end()
415 { 445 {
446 char *atmp[2] = { "", NULL }; /* see execute_perl --et */
416 struct perlscript *scp; 447 struct perlscript *scp;
417 struct _perl_timeout_handlers *thn; 448 struct _perl_timeout_handlers *thn;
418 struct _perl_event_handlers *ehn; 449 struct _perl_event_handlers *ehn;
419 450
420 while (perl_list) { 451 while (perl_list) {
421 scp = perl_list->data; 452 scp = perl_list->data;
422 perl_list = g_list_remove(perl_list, scp); 453 perl_list = g_list_remove(perl_list, scp);
423 if (scp->shutdowncallback[0]) 454 if (scp->shutdowncallback[0])
424 execute_perl(scp->shutdowncallback, ""); 455 execute_perl(scp->shutdowncallback, atmp);
425 g_free(scp->name); 456 g_free(scp->name);
426 g_free(scp->version); 457 g_free(scp->version);
427 g_free(scp->shutdowncallback); 458 g_free(scp->shutdowncallback);
428 g_free(scp); 459 g_free(scp);
429 } 460 }
838 XSRETURN(0); 869 XSRETURN(0);
839 } 870 }
840 871
841 int perl_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5) 872 int perl_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5)
842 { 873 {
843 char *buf = NULL; 874 /* changing buf to an array of char pointers so we get @_ back in
875 * order; basically scrapping legacy code in favor of blocky
876 * unimaginative code. Additionally, assigned values one at a time
877 * for the sake of clarity. --Eric Timme (30 November 2002) */
878
879 char *buf[5] = { NULL, NULL, NULL, NULL, NULL };
880 /* 5 for max 4 arguments =\ Note, if you change the above,
881 * change the two loops at the bottom that free up memory */
882
844 GList *handler; 883 GList *handler;
845 struct _perl_event_handlers *data; 884 struct _perl_event_handlers *data;
846 SV *handler_return; 885 SV *handler_return;
886 int i=0; /* necessary counter variable? --et */
847 887
848 switch (event) { 888 switch (event) {
849 case event_signon: 889 case event_signon:
850 case event_signoff: 890 case event_signoff:
851 buf = g_strdup_printf("'%lu'", (unsigned long)arg1); 891 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
852 break; 892 break;
853 case event_away: 893 case event_away:
854 buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1, 894 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
895 buf[1] = g_strdup_printf("%s",
855 ((struct gaim_connection *)arg1)->away ? 896 ((struct gaim_connection *)arg1)->away ?
856 escape_quotes(((struct gaim_connection *)arg1)->away) : ""); 897 escape_quotes(((struct gaim_connection *)arg1)->away) : "");
857 break; 898 break;
858 case event_im_recv: 899 case event_im_recv:
859 { 900 {
860 char *tmp = *(char **)arg2 ? g_strdup(escape_quotes(*(char **)arg2)) : g_malloc0(1); 901 char *tmp = *(char **)arg2 ? g_strdup(escape_quotes(*(char **)arg2)) : g_malloc0(1);
861 buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp, 902 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
862 *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); 903 buf[1] = g_strdup_printf("%s", tmp);
904 buf[2] = g_strdup_printf("%s",
905 *(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
863 g_free(tmp); 906 g_free(tmp);
864 } 907 }
865 break; 908 break;
866 case event_im_send: 909 case event_im_send:
867 { 910 {
868 char *tmp = arg2 ? g_strdup(escape_quotes(arg2)) : g_malloc0(1); 911 char *tmp = arg2 ? g_strdup(escape_quotes(arg2)) : g_malloc0(1);
869 buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp, 912 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
913 buf[1] = g_strdup_printf("%s", tmp);
914 buf[2] = g_strdup_printf("%s",
870 *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); 915 *(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
871 g_free(tmp); 916 g_free(tmp);
872 } 917 }
873 break; 918 break;
874 case event_buddy_signon: 919 case event_buddy_signon:
876 case event_set_info: 921 case event_set_info:
877 case event_buddy_away: 922 case event_buddy_away:
878 case event_buddy_back: 923 case event_buddy_back:
879 case event_buddy_idle: 924 case event_buddy_idle:
880 case event_buddy_unidle: 925 case event_buddy_unidle:
881 buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1, escape_quotes(arg2)); 926 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
927 buf[1] = g_strdup_printf("%s", escape_quotes(arg2));
882 break; 928 break;
883 case event_chat_invited: 929 case event_chat_invited:
884 { 930 {
885 char *tmp2, *tmp3, *tmp4; 931 char *tmp2, *tmp3, *tmp4;
886 tmp2 = g_strdup(escape_quotes(arg2)); 932 tmp2 = g_strdup(escape_quotes(arg2));
887 tmp3 = g_strdup(escape_quotes(arg3)); 933 tmp3 = g_strdup(escape_quotes(arg3));
888 tmp4 = arg4 ? g_strdup(escape_quotes(arg4)) : g_malloc0(1); 934 tmp4 = arg4 ? g_strdup(escape_quotes(arg4)) : g_malloc0(1);
889 buf = g_strdup_printf("'%lu','%s','%s','%s'", (unsigned long)arg1, tmp2, tmp3, tmp4); 935 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
936 buf[1] = g_strdup_printf("%s", tmp2);
937 buf[2] = g_strdup_printf("%s", tmp3);
938 buf[3] = g_strdup_printf("%s", tmp4);
890 g_free(tmp2); 939 g_free(tmp2);
891 g_free(tmp3); 940 g_free(tmp3);
892 g_free(tmp4); 941 g_free(tmp4);
893 } 942 }
894 break; 943 break;
895 case event_chat_join: 944 case event_chat_join:
896 case event_chat_buddy_join: 945 case event_chat_buddy_join:
897 case event_chat_buddy_leave: 946 case event_chat_buddy_leave:
898 buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2, 947 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
899 escape_quotes(arg3)); 948 buf[1] = g_strdup_printf("%d", (int)arg2);
949 buf[2] = g_strdup_printf("%s", escape_quotes(arg3));
900 break; 950 break;
901 case event_chat_leave: 951 case event_chat_leave:
902 buf = g_strdup_printf("'%lu','%d'", (unsigned long)arg1, (int)arg2); 952 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
953 buf[1] = g_strdup_printf("%d", (int)arg2);
903 break; 954 break;
904 case event_chat_recv: 955 case event_chat_recv:
905 { 956 {
906 char *t3, *t4; 957 char *t3, *t4;
907 t3 = g_strdup(escape_quotes(*(char **)arg3)); 958 t3 = g_strdup(escape_quotes(*(char **)arg3));
908 t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1); 959 t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1);
909 buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4); 960 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
961 buf[1] = g_strdup_printf("%d", (int)arg2);
962 buf[2] = g_strdup_printf("%s", t3);
963 buf[3] = g_strdup_printf("%s", t4);
910 g_free(t3); 964 g_free(t3);
911 g_free(t4); 965 g_free(t4);
912 } 966 }
913 break; 967 break;
914 case event_chat_send_invite: 968 case event_chat_send_invite:
915 { 969 {
916 char *t3, *t4; 970 char *t3, *t4;
917 t3 = g_strdup(escape_quotes(arg3)); 971 t3 = g_strdup(escape_quotes(arg3));
918 t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1); 972 t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1);
919 buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4); 973 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
974 buf[1] = g_strdup_printf("%d", (int)arg2);
975 buf[2] = g_strdup_printf("%s", t3);
976 buf[3] = g_strdup_printf("%s", t4);
920 g_free(t3); 977 g_free(t3);
921 g_free(t4); 978 g_free(t4);
922 } 979 }
923 break; 980 break;
924 case event_chat_send: 981 case event_chat_send:
925 buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2, 982 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
983 buf[1] = g_strdup_printf("%d", (int)arg2);
984 buf[2] = g_strdup_printf("%s",
926 *(char **)arg3 ? escape_quotes(*(char **)arg3) : ""); 985 *(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
927 break; 986 break;
928 case event_warned: 987 case event_warned:
929 buf = g_strdup_printf("'%lu','%s','%d'", (unsigned long)arg1, 988 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
930 arg2 ? escape_quotes(arg2) : "", (int)arg3); 989 buf[1] = g_strdup_printf("%s", arg2 ? escape_quotes(arg2) : "");
990 buf[2] = g_strdup_printf("%d", (int)arg3);
931 break; 991 break;
932 case event_quit: 992 case event_quit:
933 case event_blist_update: 993 case event_blist_update:
934 buf = g_malloc0(1); 994 buf[0] = g_malloc0(1);
935 break; 995 break;
936 case event_new_conversation: 996 case event_new_conversation:
937 case event_del_conversation: 997 case event_del_conversation:
938 buf = g_strdup_printf("'%s'", escape_quotes(arg1)); 998 buf[0] = g_strdup_printf("%s", escape_quotes(arg1));
939 break; 999 break;
940 case event_im_displayed_sent: 1000 case event_im_displayed_sent:
941 { 1001 {
942 char *tmp2, *tmp3; 1002 char *tmp2, *tmp3;
943 tmp2 = g_strdup(escape_quotes(arg2)); 1003 tmp2 = g_strdup(escape_quotes(arg2));
944 tmp3 = *(char **)arg3 ? g_strdup(escape_quotes(*(char **)arg3)) : g_malloc0(1); 1004 tmp3 = *(char **)arg3 ? g_strdup(escape_quotes(*(char **)arg3)) : g_malloc0(1);
945 buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp2, tmp3); 1005 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
1006 buf[1] = g_strdup_printf("%s", tmp2);
1007 buf[2] = g_strdup_printf("%s", tmp3);
946 g_free(tmp2); 1008 g_free(tmp2);
947 g_free(tmp3); 1009 g_free(tmp3);
948 } 1010 }
949 break; 1011 break;
950 case event_im_displayed_rcvd: 1012 case event_im_displayed_rcvd:
951 { 1013 {
952 char *tmp2, *tmp3; 1014 char *tmp2, *tmp3;
953 tmp2 = g_strdup(escape_quotes(arg2)); 1015 tmp2 = g_strdup(escape_quotes(arg2));
954 tmp3 = arg3 ? g_strdup(escape_quotes(arg3)) : g_malloc0(1); 1016 tmp3 = arg3 ? g_strdup(escape_quotes(arg3)) : g_malloc0(1);
955 buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp2, tmp3); 1017 buf[0] = g_strdup_printf("%lu", (unsigned long)arg1);
1018 buf[1] = g_strdup_printf("%s", tmp2);
1019 buf[2] = g_strdup_printf("%s", tmp3);
956 g_free(tmp2); 1020 g_free(tmp2);
957 g_free(tmp3); 1021 g_free(tmp3);
958 } 1022 }
959 break; 1023 break;
960 case event_draw_menu: 1024 case event_draw_menu:
968 for (handler = perl_event_handlers; handler != NULL; handler = handler->next) { 1032 for (handler = perl_event_handlers; handler != NULL; handler = handler->next) {
969 data = handler->data; 1033 data = handler->data;
970 if (!strcmp(event_name(event), data->event_type)) { 1034 if (!strcmp(event_name(event), data->event_type)) {
971 handler_return = execute_perl(data->handler_name, buf); 1035 handler_return = execute_perl(data->handler_name, buf);
972 if (handler_return) { 1036 if (handler_return) {
973 if (buf) 1037 /* loop to try and free up memory from the
974 g_free(buf); 1038 * char pointer array? --et */
1039 for (i=0;i<5;i++)
1040 if (buf[i])
1041 g_free(buf[i]);
975 return handler_return; 1042 return handler_return;
976 } 1043 }
977 } 1044 }
978 } 1045 }
979 1046
980 if (buf) 1047 /* loop to try and free up memory from the
981 g_free(buf); 1048 * char pointer array? --et */
1049 for (i=0;i<5;i++)
1050 if (buf[i])
1051 g_free(buf[i]);
982 1052
983 return 0; 1053 return 0;
984 } 1054 }
985 1055
986 XS (XS_GAIM_add_event_handler) 1056 XS (XS_GAIM_add_event_handler)
1039 } 1109 }
1040 } 1110 }
1041 1111
1042 static int perl_timeout(gpointer data) 1112 static int perl_timeout(gpointer data)
1043 { 1113 {
1114 char *atmp[2] = { NULL, NULL }; /* see execute_perl --et */
1044 struct _perl_timeout_handlers *handler = data; 1115 struct _perl_timeout_handlers *handler = data;
1045 execute_perl(handler->handler_name, escape_quotes(handler->handler_args)); 1116
1117 atmp[0] = escape_quotes(handler->handler_args);
1118 execute_perl(handler->handler_name, atmp);
1119
1046 perl_timeout_handlers = g_list_remove(perl_timeout_handlers, handler); 1120 perl_timeout_handlers = g_list_remove(perl_timeout_handlers, handler);
1047 g_free(handler->handler_args); 1121 g_free(handler->handler_args);
1048 g_free(handler->handler_name); 1122 g_free(handler->handler_name);
1049 g_free(handler); 1123 g_free(handler);
1050 1124