errno.c: refactor `_sys_fail` to avoid `mrb_funcall`.

parent 9892742d
...@@ -18,29 +18,21 @@ static struct { ...@@ -18,29 +18,21 @@ static struct {
{0, 0}, {0, 0},
}; };
static mrb_value static void
mrb_sce_init(mrb_state *mrb, mrb_value self) mrb_sce_init(mrb_state *mrb, mrb_value self, mrb_value m, mrb_int n)
{ {
mrb_value m, str; mrb_value str;
mrb_int n; struct RClass *m_errno;
int argc, no_errno = 0; int no_errno = (n < 0);
char buf[20]; char buf[20];
argc = mrb_get_args(mrb, "o|i", &m, &n); m_errno = mrb_module_get_id(mrb, MRB_SYM(Errno));
if (argc == 1) {
if (mrb_fixnum_p(m)) {
n = mrb_fixnum(m);
m = mrb_nil_value();
} else {
no_errno = 1;
}
}
if (!no_errno) { if (!no_errno) {
int i; int i;
for (i=0; e2c[i].sym != 0; i++) { for (i=0; e2c[i].sym != 0; i++) {
if (e2c[i].eno == n) { if (e2c[i].eno == n) {
mrb_basic_ptr(self)->c = mrb_class_get_under_id(mrb, mrb_module_get_id(mrb, MRB_SYM(Errno)), e2c[i].sym); mrb_basic_ptr(self)->c = mrb_class_get_under_id(mrb, m_errno, e2c[i].sym);
str = mrb_str_new_cstr(mrb, strerror(n)); str = mrb_str_new_cstr(mrb, strerror(n));
break; break;
} }
...@@ -60,6 +52,24 @@ mrb_sce_init(mrb_state *mrb, mrb_value self) ...@@ -60,6 +52,24 @@ mrb_sce_init(mrb_state *mrb, mrb_value self)
mrb_str_append(mrb, str, m); mrb_str_append(mrb, str, m);
} }
mrb_iv_set(mrb, self, MRB_SYM(mesg), str); mrb_iv_set(mrb, self, MRB_SYM(mesg), str);
}
static mrb_value
mrb_sce_init_m(mrb_state *mrb, mrb_value self)
{
mrb_value m;
mrb_int n;
if (mrb_get_args(mrb, "o|i", &m, &n) == 1) {
if (mrb_fixnum_p(m)) {
n = mrb_fixnum(m);
m = mrb_nil_value();
}
else {
n = -1;
}
}
mrb_sce_init(mrb, self, m, n);
return self; return self;
} }
...@@ -88,27 +98,40 @@ mrb_sce_to_s(mrb_state *mrb, mrb_value self) ...@@ -88,27 +98,40 @@ mrb_sce_to_s(mrb_state *mrb, mrb_value self)
static mrb_value static mrb_value
mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls)
{ {
struct RClass *cl, *sce; struct RClass *sce;
mrb_value e, msg; mrb_value msg;
mrb_int no; mrb_int no = -1;
int argc; int argc;
char name[8]; char name[8];
mrb->c->ci->mid = 0; mrb->c->ci->mid = 0;
sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError)); sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError));
argc = mrb_get_args(mrb, "i|S", &no, &msg); argc = mrb_get_args(mrb, "i|S", &no, &msg);
struct RBasic* e = mrb_obj_alloc(mrb, MRB_TT_EXCEPTION, sce);
mrb_value exc = mrb_obj_value(e);
if (argc == 1) { if (argc == 1) {
e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 1, mrb_fixnum_value(no)); msg = mrb_nil_value();
} else {
e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 2, msg, mrb_fixnum_value(no));
} }
if (mrb_obj_class(mrb, e) == sce) { exc = mrb_obj_value(e);
snprintf(name, sizeof(name), "E%03ld", (long)no); mrb_sce_init(mrb, exc, msg, no);
cl = mrb_define_class_under(mrb, mrb_module_get_id(mrb, MRB_SYM(Errno)), name, sce); if (mrb_obj_class(mrb, exc) == sce && no > 0) {
mrb_define_const_id(mrb, cl, MRB_SYM(Errno), mrb_fixnum_value(no)); struct RClass *m_errno = mrb_module_get_id(mrb, MRB_SYM(Errno));
mrb_basic_ptr(e)->c = cl; struct RClass *cl;
snprintf(name, sizeof(name), "E%03d", (int)no);
mrb_sym esym = mrb_intern_cstr(mrb, name);
if (!mrb_const_defined_at(mrb, mrb_obj_value(m_errno), esym)) {
struct RClass *sce = mrb_class_get_id(mrb, MRB_SYM(SystemCallError));
cl = mrb_define_class_under_id(mrb, m_errno, esym, sce);
}
else {
cl = mrb_class_get_under_id(mrb, m_errno, esym);
}
e->c = cl;
} }
mrb_exc_raise(mrb, e); mrb_exc_raise(mrb, exc);
return mrb_nil_value(); /* NOTREACHED */ return mrb_nil_value(); /* NOTREACHED */
} }
...@@ -142,7 +165,7 @@ mrb_mruby_errno_gem_init(mrb_state *mrb) ...@@ -142,7 +165,7 @@ mrb_mruby_errno_gem_init(mrb_state *mrb)
mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1));
mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE()); mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE());
mrb_define_method(mrb, sce, "to_s", mrb_sce_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, sce, "to_s", mrb_sce_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, sce, "initialize", mrb_sce_init, MRB_ARGS_ARG(1, 1)); mrb_define_method(mrb, sce, "initialize", mrb_sce_init_m, MRB_ARGS_ARG(1, 1));
eno = mrb_define_module_id(mrb, MRB_SYM(Errno)); eno = mrb_define_module_id(mrb, MRB_SYM(Errno));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment