-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpostfix-mruby.c
130 lines (110 loc) · 3.36 KB
/
postfix-mruby.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* See https://github.com/tmtm/postfix-mruby
*
* Copyright (c) 2015 TOMITA Masahiro <[email protected]>
*/
#include <stdio.h>
#include "sys_defs.h"
#include "dict.h"
#include "mruby.h"
#include "mruby/compile.h"
#include "mruby/string.h"
#define DICT_TYPE_MRUBY "mruby"
typedef struct {
DICT dict;
mrb_state *mrb;
mrb_value obj;
} DICT_MRUBY;
static const char *dict_mruby_lookup(DICT *dict, const char *name)
{
mrb_value val, str;
mrb_state *mrb = ((DICT_MRUBY *)dict)->mrb;
mrb_value obj = ((DICT_MRUBY *)dict)->obj;
val = mrb_funcall(mrb, obj, "lookup", 1, mrb_str_new_cstr(mrb, name));
if (mrb->exc) {
mrb_value s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
msg_warn("dict_mruby_lookup: %s", mrb_string_value_cstr(mrb, &s));
dict->error = DICT_ERR_CONFIG;
return NULL;
}
str = mrb_funcall(mrb, val, "to_s", 0);
return mrb_string_value_cstr(mrb, &str);
}
static void dict_mruby_close(DICT *dict)
{
mrb_close(((DICT_MRUBY *)dict)->mrb);
dict_free(dict);
}
mrb_value log_verbose(mrb_state *mrb, mrb_value klass)
{
extern int msg_verbose;
return mrb_fixnum_value(msg_verbose);
}
mrb_value log_verbose_p(mrb_state *mrb, mrb_value klass)
{
extern int msg_verbose;
return msg_verbose ? mrb_true_value() : mrb_false_value();
}
mrb_value log_info(mrb_state *mrb, mrb_value klass)
{
mrb_value s;
mrb_get_args(mrb, "S", &s);
msg_info("%s", mrb_string_value_cstr(mrb, &s));
return mrb_nil_value();
}
mrb_value log_warn(mrb_state *mrb, mrb_value klass)
{
mrb_value s;
mrb_get_args(mrb, "S", &s);
msg_warn("%s", mrb_string_value_cstr(mrb, &s));
return mrb_nil_value();
}
mrb_value log_error(mrb_state *mrb, mrb_value klass)
{
mrb_value s;
mrb_get_args(mrb, "S", &s);
msg_error("%s", mrb_string_value_cstr(mrb, &s));
return mrb_nil_value();
}
mrb_value log_fatal(mrb_state *mrb, mrb_value klass)
{
mrb_value s;
mrb_get_args(mrb, "S", &s);
msg_fatal("%s", mrb_string_value_cstr(mrb, &s));
return mrb_nil_value();
}
void init_log_class(mrb_state *mrb)
{
struct RClass *log;
log = mrb_define_class(mrb, "Log", mrb->object_class);
mrb_define_class_method(mrb, log, "verbose", log_verbose, MRB_ARGS_NONE());
mrb_define_class_method(mrb, log, "verbose?", log_verbose_p, MRB_ARGS_NONE());
mrb_define_class_method(mrb, log, "info", log_info, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, log, "warn", log_warn, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, log, "error", log_error, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, log, "fatal", log_fatal, MRB_ARGS_REQ(1));
}
DICT *dict_mruby_open(const char *path, int open_flags, int dict_flags)
{
DICT_MRUBY *dict;
mrb_state *mrb;
mrb_value obj;
FILE *f;
if ((f = fopen(path, "r")) == NULL)
return dict_surrogate(DICT_TYPE_MRUBY, path, open_flags, dict_flags, "open file %s: %m", path);
mrb = mrb_open();
init_log_class(mrb);
obj = mrb_load_file(mrb, f);
fclose(f);
if (mrb->exc) {
mrb_value s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
return dict_surrogate(DICT_TYPE_MRUBY, path, open_flags, dict_flags, "load file %s: %s", path, mrb_string_value_cstr(mrb, &s));
}
dict = (DICT_MRUBY *)dict_alloc(DICT_TYPE_MRUBY, path, sizeof(DICT_MRUBY));
dict->dict.lookup = dict_mruby_lookup;
dict->dict.close = dict_mruby_close;
dict->dict.flags = dict_flags;
dict->mrb = mrb;
dict->obj = obj;
return (DICT *)dict;
}