Mercurial > pidgin
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 |