source: perlglue.xs @ 6551eae

release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 6551eae was 6dc2d6b, checked in by Nelson Elhage <nelhage@mit.edu>, 12 years ago
save_excursion: Fix perl API error. We need to save a mark and SPAGAIN around call_* macros. The old behavior caused out-of-bounds stack dereferences and segfaults.
  • Property mode set to 100644
File size: 9.2 KB
Line 
1/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2#ifdef HAVE_LIBZEPHYR
3#include <zephyr/zephyr.h>
4#endif
5#include <EXTERN.h>
6
7#define OWL_PERL
8#include "owl.h"
9SV *owl_perlconfig_curmessage2hashref(void);
10
11#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
12
13        /*************************************************************
14         * NOTE
15         *************************************************************
16         * These functions, when they are intended to be user-visible,
17         * are documented in perl/lib/BarnOwl.pm. If you add functions
18         * to this file, add the appropriate documentation there!
19         *
20         * If the function is simple enough, we simply define its
21         * entire functionality here in XS. If, however, it needs
22         * complex argument processing or something, we define a
23         * simple version here that takes arguments in as flat a
24         * manner as possible, to simplify the XS code, put it in
25         * BarnOwl::Intenal::, and write a perl wrapper in BarnOwl.pm
26         * that munges the arguments as appropriate and calls the
27         * internal version.
28         */
29
30MODULE = BarnOwl                PACKAGE = BarnOwl
31
32char *
33command(cmd, ...)
34        char *cmd
35        PREINIT:
36                char *rv = NULL;
37                char **argv;
38                int i;
39        CODE:
40        {
41                if (items == 1) {
42                        rv = owl_function_command(cmd);
43                } else {
44                        argv = owl_malloc((items + 1) * sizeof *argv);
45                        argv[0] = cmd;
46                        for(i = 1; i < items; i++) {
47                                argv[i] = SvPV_nolen(ST(i));
48                        }
49                        rv = owl_function_command_argv(argv, items);
50                        owl_free(argv);
51                }
52                RETVAL = rv;
53        }
54        OUTPUT:
55                RETVAL
56        CLEANUP:
57                if (rv) owl_free(rv);
58
59SV *
60getcurmsg()
61        CODE:
62                RETVAL = owl_perlconfig_curmessage2hashref();
63        OUTPUT:
64                RETVAL
65
66int
67getnumcols()
68        CODE:
69                RETVAL = owl_global_get_cols(&g);
70        OUTPUT:
71                RETVAL
72               
73time_t
74getidletime()
75        CODE:
76                RETVAL = owl_global_get_idletime(&g);
77        OUTPUT:
78                RETVAL
79
80const char *
81zephyr_getrealm()
82        CODE:
83                RETVAL = owl_zephyr_get_realm();
84        OUTPUT:
85                RETVAL
86
87char *
88zephyr_getsender()
89        CODE:
90                RETVAL = owl_zephyr_get_sender();
91        OUTPUT:
92                RETVAL
93
94void
95zephyr_zwrite(cmd,msg)
96        char *cmd
97        char *msg
98        PREINIT:
99                int i;
100        CODE:
101                i = owl_zwrite_create_and_send_from_line(cmd, msg);
102
103char *
104ztext_stylestrip(ztext)
105        char *ztext
106        PREINIT:
107                char *rv = NULL;
108        CODE:
109                rv = owl_function_ztext_stylestrip(ztext);
110                RETVAL = rv;
111        OUTPUT:
112                RETVAL
113        CLEANUP:
114                if (rv) owl_free(rv);
115
116char *
117zephyr_smartstrip_user(in)
118        char *in
119        PREINIT:
120                char *rv = NULL;
121        CODE:
122        {
123                rv = owl_zephyr_smartstripped_user(in);
124                RETVAL = rv;
125        }
126        OUTPUT:
127                RETVAL
128        CLEANUP:
129                owl_free(rv);
130
131char *
132zephyr_getsubs()
133        PREINIT:
134                char *rv = NULL;
135        CODE:
136                rv = owl_zephyr_getsubs();
137                RETVAL = rv;
138    OUTPUT:
139                RETVAL
140    CLEANUP:
141                if (rv) owl_free(rv);
142
143void queue_message(msg) 
144        SV *msg
145        PREINIT:
146                owl_message *m;
147        CODE:
148        {
149                if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
150                        croak("Usage: BarnOwl::queue_message($message)");
151                }
152
153                m = owl_perlconfig_hashref2message(msg);
154
155                owl_global_messagequeue_addmsg(&g, m);
156        }
157
158void admin_message(header, body) 
159        char *header
160        char *body
161        CODE:
162        {
163                owl_function_adminmsg(header, body);           
164        }
165
166void start_question(line, callback)
167        char *line
168        SV *callback
169        PREINIT:
170        CODE:
171        {
172                if(!SV_IS_CODEREF(callback))
173                        croak("Callback must be a subref");
174
175                owl_function_start_question(line);
176
177                SvREFCNT_inc(callback);
178                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
179                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
180        }
181
182void start_password(line, callback)
183        char *line
184        SV *callback
185        PREINIT:
186        CODE:
187        {
188                if(!SV_IS_CODEREF(callback))
189                        croak("Callback must be a subref");
190
191                owl_function_start_password(line);
192
193                SvREFCNT_inc(callback);
194                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
195                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
196        }
197
198void start_edit_win(line, callback)
199        char *line
200        SV *callback
201        PREINIT:
202                owl_editwin * e;
203                char buff[1024];
204        CODE:
205        {
206                if(!SV_IS_CODEREF(callback))
207                        croak("Callback must be a subref");
208
209                e = owl_global_get_typwin(&g);
210                owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE,
211                                      owl_global_get_msg_history(&g));
212                owl_editwin_clear(e);
213                owl_editwin_set_dotsend(e);
214                snprintf(buff, 1023, "----> %s\n", line);
215                owl_editwin_set_locktext(e, buff);
216
217                owl_global_set_typwin_active(&g);
218
219                SvREFCNT_inc(callback);
220                owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
221                owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
222        }
223
224
225char * 
226get_data_dir ()
227        CODE:
228                RETVAL = owl_get_datadir();
229        OUTPUT:
230        RETVAL
231
232char * 
233get_config_dir ()
234        CODE:
235                RETVAL = owl_global_get_confdir(&g);
236        OUTPUT:
237        RETVAL 
238
239void
240popless_text(text) 
241        char *text
242        CODE:
243        {
244                owl_function_popless_text(text);
245        }
246
247void
248popless_ztext(text) 
249        char *text
250        CODE:
251        {
252                owl_fmtext fm;
253                owl_fmtext_init_null(&fm);
254                owl_fmtext_append_ztext(&fm, text);
255                owl_function_popless_fmtext(&fm);
256                owl_fmtext_free(&fm);
257        }
258
259void
260error(text) 
261        char *text
262        CODE:
263        {
264                owl_function_error("%s", text);
265        }
266
267void
268debug(text)
269        char *text
270        CODE:
271        {
272                owl_function_debugmsg("%s", text);
273        }
274
275void
276create_style(name, object)
277     char *name
278     SV  *object
279     PREINIT:
280                owl_style *s;
281     CODE:
282        {
283                s = owl_malloc(sizeof(owl_style));
284                owl_style_create_perl(s, name, object);
285                owl_global_add_style(&g, s);
286        }
287
288int
289getnumcolors()
290        CODE:
291                RETVAL = owl_function_get_color_count();
292        OUTPUT:
293                RETVAL
294
295void
296_remove_filter(filterName)
297        char *filterName
298        CODE:
299        {
300                /* Don't delete the current view, or the 'all' filter */
301                if (strcmp(filterName, owl_view_get_filtname(owl_global_get_current_view(&g)))
302                    && strcmp(filterName, "all")) {
303                        owl_global_remove_filter(&g,filterName);
304                }
305        }
306
307char *
308wordwrap(in, cols)
309        char *in
310        int cols
311        PREINIT:
312                char *rv = NULL;
313        CODE:
314                rv = owl_text_wordwrap(in, cols);
315                RETVAL = rv;   
316        OUTPUT:
317                RETVAL
318        CLEANUP:
319                if (rv) owl_free(rv);
320
321void
322add_dispatch(fd, cb)
323        int fd
324        SV * cb
325        CODE:
326        SvREFCNT_inc(cb);
327        owl_select_add_perl_dispatch(fd, cb);
328
329void
330remove_dispatch(fd)
331        int fd
332        CODE:
333        owl_select_remove_perl_dispatch(fd);
334
335MODULE = BarnOwl                PACKAGE = BarnOwl::Internal
336
337
338void
339new_command(name, func, summary, usage, description)
340        char *name
341        SV *func
342        char *summary
343        char *usage
344        char *description
345        PREINIT:
346                owl_cmd cmd;
347        CODE:
348        {
349                if(!SV_IS_CODEREF(func)) {
350                        croak("Command function must be a coderef!");
351                }
352                SvREFCNT_inc(func);
353                cmd.name = name;
354                cmd.cmd_perl = func;
355                cmd.summary = summary;
356                cmd.usage = usage;
357                cmd.description = description;
358                cmd.validctx = OWL_CTX_ANY;
359                cmd.cmd_aliased_to = NULL;
360                cmd.cmd_args_fn = NULL;
361                cmd.cmd_v_fn = NULL;
362                cmd.cmd_i_fn = NULL;
363                cmd.cmd_ctxargs_fn = NULL;
364                cmd.cmd_ctxv_fn = NULL;
365                cmd.cmd_ctxi_fn = NULL;
366                owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
367           }
368
369void
370new_variable_string(name, ival, summ, desc)
371        char * name
372        char * ival
373        char * summ
374        char * desc
375        CODE:
376        owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
377                                        name,
378                                        summ,
379                                        desc,
380                                        ival);
381
382void
383new_variable_int(name, ival, summ, desc)
384        char * name
385        int ival
386        char * summ
387        char * desc
388        CODE:
389        owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
390                                     name,
391                                     summ,
392                                     desc,
393                                     ival);
394
395void
396new_variable_bool(name, ival, summ, desc)
397        char * name
398        int ival
399        char * summ
400        char * desc
401        CODE:
402        owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
403                                      name,
404                                      summ,
405                                      desc,
406                                      ival);
407
408IV
409add_timer(after, interval, cb)
410        int after
411        int interval
412        SV *cb
413        PREINIT:
414                SV *ref;
415                owl_timer *t;
416        CODE:
417                ref = sv_rvweaken(newSVsv(cb));
418                t = owl_select_add_timer(after,
419                                         interval,
420                                         owl_perlconfig_perl_timer,
421                                         owl_perlconfig_perl_timer_destroy,
422                                         ref);
423        owl_function_debugmsg("Created timer %p", t);
424        RETVAL = (IV)t;
425        OUTPUT:
426                RETVAL
427
428void
429remove_timer(timer)
430        IV timer
431        PREINIT:
432                owl_timer *t;
433        CODE:
434                t = (owl_timer*)timer;
435                owl_function_debugmsg("Freeing timer %p", t);
436                                owl_select_remove_timer(t);
437
438MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
439
440int
441replace(count, string)
442        int count;
443        char *string;
444        CODE:
445                RETVAL = owl_editwin_replace(owl_global_get_typwin(&g), count, string);
446        OUTPUT:
447                RETVAL
448
449int
450point_move(delta)
451        int delta;
452        CODE:
453                RETVAL = owl_editwin_point_move(owl_global_get_typwin(&g), delta);
454        OUTPUT:
455                RETVAL
456
457int
458replace_region(string)
459        char *string;
460        CODE:
461                RETVAL = owl_editwin_replace_region(owl_global_get_typwin(&g), string);
462        OUTPUT:
463                RETVAL
464
465char *
466get_region()
467        PREINIT:
468                char *region;
469        CODE:
470                region = owl_editwin_get_region(owl_global_get_typwin(&g));
471                RETVAL = region;
472        OUTPUT:
473                RETVAL
474        CLEANUP:
475                owl_free(region);
476
477SV *
478save_excursion(sub)
479        SV *sub;
480        PROTOTYPE: &
481        PREINIT:
482                int count;
483                owl_editwin_excursion *x;
484        CODE:
485        {
486                x = owl_editwin_begin_excursion(owl_global_get_typwin(&g));
487                PUSHMARK(SP);
488                count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
489                SPAGAIN;
490                owl_editwin_end_excursion(owl_global_get_typwin(&g), x);
491
492                if(SvTRUE(ERRSV)) {
493                        croak(NULL);
494                }
495
496                if(count == 1)
497                        RETVAL = SvREFCNT_inc(POPs);
498                else
499                        XSRETURN_UNDEF;
500
501        }
502        OUTPUT:
503                RETVAL
504
505int
506current_column()
507        CODE:
508                RETVAL = owl_editwin_current_column(owl_global_get_typwin(&g));
509        OUTPUT:
510                RETVAL
511
512int
513point()
514        CODE:
515                RETVAL = owl_editwin_get_point(owl_global_get_typwin(&g));
516        OUTPUT:
517                RETVAL
518
519int
520mark()
521        CODE:
522                RETVAL = owl_editwin_get_mark(owl_global_get_typwin(&g));
523        OUTPUT:
524                RETVAL
Note: See TracBrowser for help on using the repository browser.