summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h1
-rw-r--r--src/class.c6
-rw-r--r--src/error.c16
-rw-r--r--src/state.c6
-rw-r--r--test/driver.c36
5 files changed, 49 insertions, 16 deletions
diff --git a/include/mruby.h b/include/mruby.h
index b112b081c..e058d409f 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -156,6 +156,7 @@ void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
struct RClass * mrb_module_new(mrb_state *mrb);
+int mrb_class_defined(mrb_state *mrb, const char *name);
struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
struct RClass * mrb_class_obj_get(mrb_state *mrb, const char *name);
diff --git a/src/class.c b/src/class.c
index 0ba702919..a00000375 100644
--- a/src/class.c
+++ b/src/class.c
@@ -203,6 +203,12 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
+int
+mrb_class_defined(mrb_state *mrb, const char *name)
+{
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, name));
+}
+
static struct RClass *
class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
diff --git a/src/error.c b/src/error.c
index 421321c3d..6bd891768 100644
--- a/src/error.c
+++ b/src/error.c
@@ -5,6 +5,7 @@
*/
#include "mruby.h"
+#include <errno.h>
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
@@ -401,7 +402,20 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
- mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ struct RClass *sce;
+ mrb_int no;
+
+ no = (mrb_int)errno;
+ if (mrb_class_defined(mrb, "SystemCallError")) {
+ sce = mrb_class_get(mrb, "SystemCallError");
+ if (mesg != NULL) {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
+ } else {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
+ }
+ } else {
+ mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ }
}
void
diff --git a/src/state.c b/src/state.c
index b6805a4a4..efb6d66b1 100644
--- a/src/state.c
+++ b/src/state.c
@@ -53,6 +53,7 @@ mrb_alloca(mrb_state *mrb, size_t size)
struct alloca_header *p;
p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
+ if (p == NULL) return NULL;
p->next = mrb->mems;
mrb->mems = p;
return (void*)p->buf;
@@ -61,9 +62,12 @@ mrb_alloca(mrb_state *mrb, size_t size)
static void
mrb_alloca_free(mrb_state *mrb)
{
- struct alloca_header *p = mrb->mems;
+ struct alloca_header *p;
struct alloca_header *tmp;
+ if (mrb == NULL) return NULL;
+ p = mrb->mems;
+
while (p) {
tmp = p;
p = p->next;
diff --git a/test/driver.c b/test/driver.c
index eda82a7f2..4a7a7b25e 100644
--- a/test/driver.c
+++ b/test/driver.c
@@ -36,13 +36,31 @@ check_error(mrb_state *mrb)
return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0;
}
+static int
+eval_test(mrb_state *mrb)
+{
+ mrb_value return_value;
+ const char *prog = "report()";
+
+ /* evaluate the test */
+ return_value = mrb_load_string(mrb, prog);
+ /* did an exception occur? */
+ if (mrb->exc) {
+ mrb_p(mrb, return_value);
+ mrb->exc = 0;
+ return EXIT_FAILURE;
+ }
+ else if (!check_error(mrb)) {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
int
main(int argc, char **argv)
{
mrb_state *mrb;
- mrb_value return_value;
- const char *prog = "report()";
- int ret = EXIT_SUCCESS;
+ int ret;
print_hint();
@@ -59,17 +77,7 @@ main(int argc, char **argv)
}
mrb_init_mrbtest(mrb);
- /* evaluate the test */
- return_value = mrb_load_string(mrb, prog);
- /* did an exception occur? */
- if (mrb->exc) {
- mrb_p(mrb, return_value);
- mrb->exc = 0;
- ret = EXIT_FAILURE;
- }
- else if (!check_error(mrb)) {
- ret = EXIT_FAILURE;
- }
+ ret = eval_test(mrb);
mrb_close(mrb);
return ret;