source: style.c @ ecd4edf

release-1.10
Last change on this file since ecd4edf was 92ffd89, checked in by Jason Gross <jgross@mit.edu>, 11 years ago
Refactor perl calls through a single method I don't know the perl/C interface well enough to figure out the best way to standardize the many variants that we use to call perl code. Perhaps we should standardize the error messages, and put less knobs on the boilerplate macro.
  • Property mode set to 100644
File size: 2.5 KB
Line 
1#define OWL_PERL
2#include "owl.h"
3
4/* Assumes owenership of one existing ref on `obj`*/
5void owl_style_create_perl(owl_style *s, const char *name, SV *obj)
6{
7  s->name=g_strdup(name);
8  s->perlobj = obj;
9}
10
11int owl_style_matches_name(const owl_style *s, const char *name)
12{
13  if (!strcmp(s->name, name)) return(1);
14  return(0);
15}
16
17const char *owl_style_get_name(const owl_style *s)
18{
19  return(s->name);
20}
21
22const char *owl_style_get_description(const owl_style *s)
23{
24  SV *sv = NULL;
25  OWL_PERL_CALL(call_method("description", G_SCALAR|G_EVAL),
26                XPUSHs(s->perlobj);,
27                "Error in style_get_description: %s",
28                0,
29                false,
30                sv = SvREFCNT_inc(POPs);
31                );
32  if (sv) {
33    return SvPV_nolen(sv_2mortal(sv));
34  } else {
35    return "[error getting description]";
36  }
37}
38
39/* Use style 's' to format message 'm' into fmtext 'fm'.
40 * 'fm' should already be be initialzed
41 */
42void owl_style_get_formattext(const owl_style *s, owl_fmtext *fm, const owl_message *m)
43{
44  const char *body;
45  char *indent;
46  int curlen;
47  owl_fmtext with_tabs;
48
49  SV *sv = NULL;
50 
51  /* Call the perl object */
52  OWL_PERL_CALL(call_method("format_message", G_SCALAR|G_EVAL),
53                XPUSHs(s->perlobj);
54                XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));,
55                "Error in format_message: %s",
56                0,
57                false,
58                sv = SvREFCNT_inc(POPs);
59                );
60
61  if (sv) {
62    body = SvPV_nolen(sv);
63  } else {
64    body = "<unformatted message>";
65  }
66
67  /* indent and ensure ends with a newline */
68  indent = owl_text_indent(body, OWL_TAB, true);
69  curlen = strlen(indent);
70  if (curlen == 0 || indent[curlen-1] != '\n') {
71    char *tmp = indent;
72    indent = g_strconcat(tmp, "\n", NULL);
73    g_free(tmp);
74  }
75
76  owl_fmtext_init_null(&with_tabs);
77  /* fmtext_append.  This needs to change */
78  owl_fmtext_append_ztext(&with_tabs, indent);
79  /* Expand tabs, taking the indent into account. Otherwise, tabs from the
80   * style display incorrectly due to our own indent. */
81  owl_fmtext_expand_tabs(&with_tabs, fm, OWL_TAB_WIDTH - OWL_TAB);
82  owl_fmtext_cleanup(&with_tabs);
83
84  g_free(indent);
85  if(sv)
86    SvREFCNT_dec(sv);
87}
88
89int owl_style_validate(const owl_style *s) {
90  if (!s || !s->perlobj || !SvOK(s->perlobj)) {
91    return -1;
92  }
93  return 0;
94}
95
96void owl_style_cleanup(owl_style *s)
97{
98  if (s->name) g_free(s->name);
99  SvREFCNT_dec(s->perlobj);
100}
101
102void owl_style_delete(owl_style *s)
103{
104  owl_style_cleanup(s);
105  g_free(s);
106}
Note: See TracBrowser for help on using the repository browser.