mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
src/error.c@0:158c61bb030f, 2015-03-25 (annotated)
- Committer:
- mzta
- Date:
- Wed Mar 25 17:36:16 2015 +0000
- Revision:
- 0:158c61bb030f
mirb_mbed initial commit;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzta | 0:158c61bb030f | 1 | /* |
mzta | 0:158c61bb030f | 2 | ** error.c - Exception class |
mzta | 0:158c61bb030f | 3 | ** |
mzta | 0:158c61bb030f | 4 | ** See Copyright Notice in mruby.h |
mzta | 0:158c61bb030f | 5 | */ |
mzta | 0:158c61bb030f | 6 | |
mzta | 0:158c61bb030f | 7 | #include <errno.h> |
mzta | 0:158c61bb030f | 8 | #include <stdarg.h> |
mzta | 0:158c61bb030f | 9 | #include <stdlib.h> |
mzta | 0:158c61bb030f | 10 | #include "mruby.h" |
mzta | 0:158c61bb030f | 11 | #include "mruby/array.h" |
mzta | 0:158c61bb030f | 12 | #include "mruby/irep.h" |
mzta | 0:158c61bb030f | 13 | #include "mruby/proc.h" |
mzta | 0:158c61bb030f | 14 | #include "mruby/string.h" |
mzta | 0:158c61bb030f | 15 | #include "mruby/variable.h" |
mzta | 0:158c61bb030f | 16 | #include "mruby/debug.h" |
mzta | 0:158c61bb030f | 17 | #include "mruby/error.h" |
mzta | 0:158c61bb030f | 18 | #include "mruby/class.h" |
mzta | 0:158c61bb030f | 19 | #include "mrb_throw.h" |
mzta | 0:158c61bb030f | 20 | |
mzta | 0:158c61bb030f | 21 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 22 | mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len) |
mzta | 0:158c61bb030f | 23 | { |
mzta | 0:158c61bb030f | 24 | mrb_value arg = mrb_str_new(mrb, ptr, len); |
mzta | 0:158c61bb030f | 25 | return mrb_obj_new(mrb, c, 1, &arg); |
mzta | 0:158c61bb030f | 26 | } |
mzta | 0:158c61bb030f | 27 | |
mzta | 0:158c61bb030f | 28 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 29 | mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str) |
mzta | 0:158c61bb030f | 30 | { |
mzta | 0:158c61bb030f | 31 | str = mrb_str_to_str(mrb, str); |
mzta | 0:158c61bb030f | 32 | return mrb_obj_new(mrb, c, 1, &str); |
mzta | 0:158c61bb030f | 33 | } |
mzta | 0:158c61bb030f | 34 | |
mzta | 0:158c61bb030f | 35 | /* |
mzta | 0:158c61bb030f | 36 | * call-seq: |
mzta | 0:158c61bb030f | 37 | * Exception.new(msg = nil) -> exception |
mzta | 0:158c61bb030f | 38 | * |
mzta | 0:158c61bb030f | 39 | * Construct a new Exception object, optionally passing in |
mzta | 0:158c61bb030f | 40 | * a message. |
mzta | 0:158c61bb030f | 41 | */ |
mzta | 0:158c61bb030f | 42 | |
mzta | 0:158c61bb030f | 43 | static mrb_value |
mzta | 0:158c61bb030f | 44 | exc_initialize(mrb_state *mrb, mrb_value exc) |
mzta | 0:158c61bb030f | 45 | { |
mzta | 0:158c61bb030f | 46 | mrb_value mesg; |
mzta | 0:158c61bb030f | 47 | |
mzta | 0:158c61bb030f | 48 | if (mrb_get_args(mrb, "|o", &mesg) == 1) { |
mzta | 0:158c61bb030f | 49 | mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg); |
mzta | 0:158c61bb030f | 50 | } |
mzta | 0:158c61bb030f | 51 | return exc; |
mzta | 0:158c61bb030f | 52 | } |
mzta | 0:158c61bb030f | 53 | |
mzta | 0:158c61bb030f | 54 | /* |
mzta | 0:158c61bb030f | 55 | * Document-method: exception |
mzta | 0:158c61bb030f | 56 | * |
mzta | 0:158c61bb030f | 57 | * call-seq: |
mzta | 0:158c61bb030f | 58 | * exc.exception(string) -> an_exception or exc |
mzta | 0:158c61bb030f | 59 | * |
mzta | 0:158c61bb030f | 60 | * With no argument, or if the argument is the same as the receiver, |
mzta | 0:158c61bb030f | 61 | * return the receiver. Otherwise, create a new |
mzta | 0:158c61bb030f | 62 | * exception object of the same class as the receiver, but with a |
mzta | 0:158c61bb030f | 63 | * message equal to <code>string.to_str</code>. |
mzta | 0:158c61bb030f | 64 | * |
mzta | 0:158c61bb030f | 65 | */ |
mzta | 0:158c61bb030f | 66 | |
mzta | 0:158c61bb030f | 67 | static mrb_value |
mzta | 0:158c61bb030f | 68 | exc_exception(mrb_state *mrb, mrb_value self) |
mzta | 0:158c61bb030f | 69 | { |
mzta | 0:158c61bb030f | 70 | mrb_value exc; |
mzta | 0:158c61bb030f | 71 | mrb_value a; |
mzta | 0:158c61bb030f | 72 | int argc; |
mzta | 0:158c61bb030f | 73 | |
mzta | 0:158c61bb030f | 74 | argc = mrb_get_args(mrb, "|o", &a); |
mzta | 0:158c61bb030f | 75 | if (argc == 0) return self; |
mzta | 0:158c61bb030f | 76 | if (mrb_obj_equal(mrb, self, a)) return self; |
mzta | 0:158c61bb030f | 77 | exc = mrb_obj_clone(mrb, self); |
mzta | 0:158c61bb030f | 78 | mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), a); |
mzta | 0:158c61bb030f | 79 | |
mzta | 0:158c61bb030f | 80 | return exc; |
mzta | 0:158c61bb030f | 81 | } |
mzta | 0:158c61bb030f | 82 | |
mzta | 0:158c61bb030f | 83 | /* |
mzta | 0:158c61bb030f | 84 | * call-seq: |
mzta | 0:158c61bb030f | 85 | * exception.to_s -> string |
mzta | 0:158c61bb030f | 86 | * |
mzta | 0:158c61bb030f | 87 | * Returns exception's message (or the name of the exception if |
mzta | 0:158c61bb030f | 88 | * no message is set). |
mzta | 0:158c61bb030f | 89 | */ |
mzta | 0:158c61bb030f | 90 | |
mzta | 0:158c61bb030f | 91 | static mrb_value |
mzta | 0:158c61bb030f | 92 | exc_to_s(mrb_state *mrb, mrb_value exc) |
mzta | 0:158c61bb030f | 93 | { |
mzta | 0:158c61bb030f | 94 | mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); |
mzta | 0:158c61bb030f | 95 | struct RObject *p; |
mzta | 0:158c61bb030f | 96 | |
mzta | 0:158c61bb030f | 97 | if (!mrb_string_p(mesg)) { |
mzta | 0:158c61bb030f | 98 | return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc)); |
mzta | 0:158c61bb030f | 99 | } |
mzta | 0:158c61bb030f | 100 | p = mrb_obj_ptr(mesg); |
mzta | 0:158c61bb030f | 101 | if (!p->c) { |
mzta | 0:158c61bb030f | 102 | p->c = mrb->string_class; |
mzta | 0:158c61bb030f | 103 | } |
mzta | 0:158c61bb030f | 104 | return mesg; |
mzta | 0:158c61bb030f | 105 | } |
mzta | 0:158c61bb030f | 106 | |
mzta | 0:158c61bb030f | 107 | /* |
mzta | 0:158c61bb030f | 108 | * call-seq: |
mzta | 0:158c61bb030f | 109 | * exception.message -> string |
mzta | 0:158c61bb030f | 110 | * |
mzta | 0:158c61bb030f | 111 | * Returns the result of invoking <code>exception.to_s</code>. |
mzta | 0:158c61bb030f | 112 | * Normally this returns the exception's message or name. By |
mzta | 0:158c61bb030f | 113 | * supplying a to_str method, exceptions are agreeing to |
mzta | 0:158c61bb030f | 114 | * be used where Strings are expected. |
mzta | 0:158c61bb030f | 115 | */ |
mzta | 0:158c61bb030f | 116 | |
mzta | 0:158c61bb030f | 117 | static mrb_value |
mzta | 0:158c61bb030f | 118 | exc_message(mrb_state *mrb, mrb_value exc) |
mzta | 0:158c61bb030f | 119 | { |
mzta | 0:158c61bb030f | 120 | return mrb_funcall(mrb, exc, "to_s", 0); |
mzta | 0:158c61bb030f | 121 | } |
mzta | 0:158c61bb030f | 122 | |
mzta | 0:158c61bb030f | 123 | /* |
mzta | 0:158c61bb030f | 124 | * call-seq: |
mzta | 0:158c61bb030f | 125 | * exception.inspect -> string |
mzta | 0:158c61bb030f | 126 | * |
mzta | 0:158c61bb030f | 127 | * Returns this exception's file name, line number, |
mzta | 0:158c61bb030f | 128 | * message and class name. |
mzta | 0:158c61bb030f | 129 | * If file name or line number is not set, |
mzta | 0:158c61bb030f | 130 | * returns message and class name. |
mzta | 0:158c61bb030f | 131 | */ |
mzta | 0:158c61bb030f | 132 | |
mzta | 0:158c61bb030f | 133 | static mrb_value |
mzta | 0:158c61bb030f | 134 | exc_inspect(mrb_state *mrb, mrb_value exc) |
mzta | 0:158c61bb030f | 135 | { |
mzta | 0:158c61bb030f | 136 | mrb_value str, mesg, file, line; |
mzta | 0:158c61bb030f | 137 | mrb_bool append_mesg; |
mzta | 0:158c61bb030f | 138 | |
mzta | 0:158c61bb030f | 139 | mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); |
mzta | 0:158c61bb030f | 140 | file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); |
mzta | 0:158c61bb030f | 141 | line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); |
mzta | 0:158c61bb030f | 142 | |
mzta | 0:158c61bb030f | 143 | append_mesg = !mrb_nil_p(mesg); |
mzta | 0:158c61bb030f | 144 | if (append_mesg) { |
mzta | 0:158c61bb030f | 145 | mesg = mrb_obj_as_string(mrb, mesg); |
mzta | 0:158c61bb030f | 146 | append_mesg = RSTRING_LEN(mesg) > 0; |
mzta | 0:158c61bb030f | 147 | } |
mzta | 0:158c61bb030f | 148 | |
mzta | 0:158c61bb030f | 149 | if (!mrb_nil_p(file) && !mrb_nil_p(line)) { |
mzta | 0:158c61bb030f | 150 | str = mrb_str_dup(mrb, file); |
mzta | 0:158c61bb030f | 151 | mrb_str_cat_lit(mrb, str, ":"); |
mzta | 0:158c61bb030f | 152 | mrb_str_append(mrb, str, line); |
mzta | 0:158c61bb030f | 153 | mrb_str_cat_lit(mrb, str, ": "); |
mzta | 0:158c61bb030f | 154 | if (append_mesg) { |
mzta | 0:158c61bb030f | 155 | mrb_str_append(mrb, str, mesg); |
mzta | 0:158c61bb030f | 156 | mrb_str_cat_lit(mrb, str, " ("); |
mzta | 0:158c61bb030f | 157 | } |
mzta | 0:158c61bb030f | 158 | mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); |
mzta | 0:158c61bb030f | 159 | if (append_mesg) { |
mzta | 0:158c61bb030f | 160 | mrb_str_cat_lit(mrb, str, ")"); |
mzta | 0:158c61bb030f | 161 | } |
mzta | 0:158c61bb030f | 162 | } |
mzta | 0:158c61bb030f | 163 | else { |
mzta | 0:158c61bb030f | 164 | const char *cname = mrb_obj_classname(mrb, exc); |
mzta | 0:158c61bb030f | 165 | str = mrb_str_new_cstr(mrb, cname); |
mzta | 0:158c61bb030f | 166 | mrb_str_cat_lit(mrb, str, ": "); |
mzta | 0:158c61bb030f | 167 | if (append_mesg) { |
mzta | 0:158c61bb030f | 168 | mrb_str_append(mrb, str, mesg); |
mzta | 0:158c61bb030f | 169 | } |
mzta | 0:158c61bb030f | 170 | else { |
mzta | 0:158c61bb030f | 171 | mrb_str_cat_cstr(mrb, str, cname); |
mzta | 0:158c61bb030f | 172 | } |
mzta | 0:158c61bb030f | 173 | } |
mzta | 0:158c61bb030f | 174 | return str; |
mzta | 0:158c61bb030f | 175 | } |
mzta | 0:158c61bb030f | 176 | |
mzta | 0:158c61bb030f | 177 | |
mzta | 0:158c61bb030f | 178 | static void |
mzta | 0:158c61bb030f | 179 | exc_debug_info(mrb_state *mrb, struct RObject *exc) |
mzta | 0:158c61bb030f | 180 | { |
mzta | 0:158c61bb030f | 181 | mrb_callinfo *ci = mrb->c->ci; |
mzta | 0:158c61bb030f | 182 | mrb_code *pc = ci->pc; |
mzta | 0:158c61bb030f | 183 | |
mzta | 0:158c61bb030f | 184 | mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase))); |
mzta | 0:158c61bb030f | 185 | while (ci >= mrb->c->cibase) { |
mzta | 0:158c61bb030f | 186 | mrb_code *err = ci->err; |
mzta | 0:158c61bb030f | 187 | |
mzta | 0:158c61bb030f | 188 | if (!err && pc) err = pc - 1; |
mzta | 0:158c61bb030f | 189 | if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { |
mzta | 0:158c61bb030f | 190 | mrb_irep *irep = ci->proc->body.irep; |
mzta | 0:158c61bb030f | 191 | |
mzta | 0:158c61bb030f | 192 | int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq)); |
mzta | 0:158c61bb030f | 193 | char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq)); |
mzta | 0:158c61bb030f | 194 | if (line != -1 && file) { |
mzta | 0:158c61bb030f | 195 | mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file)); |
mzta | 0:158c61bb030f | 196 | mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line)); |
mzta | 0:158c61bb030f | 197 | return; |
mzta | 0:158c61bb030f | 198 | } |
mzta | 0:158c61bb030f | 199 | } |
mzta | 0:158c61bb030f | 200 | pc = ci->pc; |
mzta | 0:158c61bb030f | 201 | ci--; |
mzta | 0:158c61bb030f | 202 | } |
mzta | 0:158c61bb030f | 203 | } |
mzta | 0:158c61bb030f | 204 | |
mzta | 0:158c61bb030f | 205 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 206 | mrb_exc_raise(mrb_state *mrb, mrb_value exc) |
mzta | 0:158c61bb030f | 207 | { |
mzta | 0:158c61bb030f | 208 | mrb->exc = mrb_obj_ptr(exc); |
mzta | 0:158c61bb030f | 209 | if (!mrb->out_of_memory) { |
mzta | 0:158c61bb030f | 210 | exc_debug_info(mrb, mrb->exc); |
mzta | 0:158c61bb030f | 211 | } |
mzta | 0:158c61bb030f | 212 | if (!mrb->jmp) { |
mzta | 0:158c61bb030f | 213 | mrb_p(mrb, exc); |
mzta | 0:158c61bb030f | 214 | abort(); |
mzta | 0:158c61bb030f | 215 | } |
mzta | 0:158c61bb030f | 216 | MRB_THROW(mrb->jmp); |
mzta | 0:158c61bb030f | 217 | } |
mzta | 0:158c61bb030f | 218 | |
mzta | 0:158c61bb030f | 219 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 220 | mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg) |
mzta | 0:158c61bb030f | 221 | { |
mzta | 0:158c61bb030f | 222 | mrb_value mesg; |
mzta | 0:158c61bb030f | 223 | mesg = mrb_str_new_cstr(mrb, msg); |
mzta | 0:158c61bb030f | 224 | mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg)); |
mzta | 0:158c61bb030f | 225 | } |
mzta | 0:158c61bb030f | 226 | |
mzta | 0:158c61bb030f | 227 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 228 | mrb_vformat(mrb_state *mrb, const char *format, va_list ap) |
mzta | 0:158c61bb030f | 229 | { |
mzta | 0:158c61bb030f | 230 | const char *p = format; |
mzta | 0:158c61bb030f | 231 | const char *b = p; |
mzta | 0:158c61bb030f | 232 | ptrdiff_t size; |
mzta | 0:158c61bb030f | 233 | mrb_value ary = mrb_ary_new_capa(mrb, 4); |
mzta | 0:158c61bb030f | 234 | |
mzta | 0:158c61bb030f | 235 | while (*p) { |
mzta | 0:158c61bb030f | 236 | const char c = *p++; |
mzta | 0:158c61bb030f | 237 | |
mzta | 0:158c61bb030f | 238 | if (c == '%') { |
mzta | 0:158c61bb030f | 239 | if (*p == 'S') { |
mzta | 0:158c61bb030f | 240 | size = p - b - 1; |
mzta | 0:158c61bb030f | 241 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); |
mzta | 0:158c61bb030f | 242 | mrb_ary_push(mrb, ary, va_arg(ap, mrb_value)); |
mzta | 0:158c61bb030f | 243 | b = p + 1; |
mzta | 0:158c61bb030f | 244 | } |
mzta | 0:158c61bb030f | 245 | } |
mzta | 0:158c61bb030f | 246 | else if (c == '\\') { |
mzta | 0:158c61bb030f | 247 | if (*p) { |
mzta | 0:158c61bb030f | 248 | size = p - b - 1; |
mzta | 0:158c61bb030f | 249 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); |
mzta | 0:158c61bb030f | 250 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1)); |
mzta | 0:158c61bb030f | 251 | b = ++p; |
mzta | 0:158c61bb030f | 252 | } |
mzta | 0:158c61bb030f | 253 | else { |
mzta | 0:158c61bb030f | 254 | break; |
mzta | 0:158c61bb030f | 255 | } |
mzta | 0:158c61bb030f | 256 | } |
mzta | 0:158c61bb030f | 257 | } |
mzta | 0:158c61bb030f | 258 | if (b == format) { |
mzta | 0:158c61bb030f | 259 | return mrb_str_new_cstr(mrb, format); |
mzta | 0:158c61bb030f | 260 | } |
mzta | 0:158c61bb030f | 261 | else { |
mzta | 0:158c61bb030f | 262 | size = p - b; |
mzta | 0:158c61bb030f | 263 | mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); |
mzta | 0:158c61bb030f | 264 | return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0)); |
mzta | 0:158c61bb030f | 265 | } |
mzta | 0:158c61bb030f | 266 | } |
mzta | 0:158c61bb030f | 267 | |
mzta | 0:158c61bb030f | 268 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 269 | mrb_format(mrb_state *mrb, const char *format, ...) |
mzta | 0:158c61bb030f | 270 | { |
mzta | 0:158c61bb030f | 271 | va_list ap; |
mzta | 0:158c61bb030f | 272 | mrb_value str; |
mzta | 0:158c61bb030f | 273 | |
mzta | 0:158c61bb030f | 274 | va_start(ap, format); |
mzta | 0:158c61bb030f | 275 | str = mrb_vformat(mrb, format, ap); |
mzta | 0:158c61bb030f | 276 | va_end(ap); |
mzta | 0:158c61bb030f | 277 | |
mzta | 0:158c61bb030f | 278 | return str; |
mzta | 0:158c61bb030f | 279 | } |
mzta | 0:158c61bb030f | 280 | |
mzta | 0:158c61bb030f | 281 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 282 | mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) |
mzta | 0:158c61bb030f | 283 | { |
mzta | 0:158c61bb030f | 284 | va_list args; |
mzta | 0:158c61bb030f | 285 | mrb_value mesg; |
mzta | 0:158c61bb030f | 286 | |
mzta | 0:158c61bb030f | 287 | va_start(args, fmt); |
mzta | 0:158c61bb030f | 288 | mesg = mrb_vformat(mrb, fmt, args); |
mzta | 0:158c61bb030f | 289 | va_end(args); |
mzta | 0:158c61bb030f | 290 | mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg)); |
mzta | 0:158c61bb030f | 291 | } |
mzta | 0:158c61bb030f | 292 | |
mzta | 0:158c61bb030f | 293 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 294 | mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...) |
mzta | 0:158c61bb030f | 295 | { |
mzta | 0:158c61bb030f | 296 | mrb_value exc; |
mzta | 0:158c61bb030f | 297 | mrb_value argv[2]; |
mzta | 0:158c61bb030f | 298 | va_list args; |
mzta | 0:158c61bb030f | 299 | |
mzta | 0:158c61bb030f | 300 | va_start(args, fmt); |
mzta | 0:158c61bb030f | 301 | argv[0] = mrb_vformat(mrb, fmt, args); |
mzta | 0:158c61bb030f | 302 | va_end(args); |
mzta | 0:158c61bb030f | 303 | |
mzta | 0:158c61bb030f | 304 | argv[1] = mrb_symbol_value(id); |
mzta | 0:158c61bb030f | 305 | exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv); |
mzta | 0:158c61bb030f | 306 | mrb_exc_raise(mrb, exc); |
mzta | 0:158c61bb030f | 307 | } |
mzta | 0:158c61bb030f | 308 | |
mzta | 0:158c61bb030f | 309 | MRB_API void |
mzta | 0:158c61bb030f | 310 | mrb_warn(mrb_state *mrb, const char *fmt, ...) |
mzta | 0:158c61bb030f | 311 | { |
mzta | 0:158c61bb030f | 312 | #ifdef ENABLE_STDIO |
mzta | 0:158c61bb030f | 313 | va_list ap; |
mzta | 0:158c61bb030f | 314 | mrb_value str; |
mzta | 0:158c61bb030f | 315 | |
mzta | 0:158c61bb030f | 316 | va_start(ap, fmt); |
mzta | 0:158c61bb030f | 317 | str = mrb_vformat(mrb, fmt, ap); |
mzta | 0:158c61bb030f | 318 | fputs("warning: ", stderr); |
mzta | 0:158c61bb030f | 319 | fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); |
mzta | 0:158c61bb030f | 320 | va_end(ap); |
mzta | 0:158c61bb030f | 321 | #endif |
mzta | 0:158c61bb030f | 322 | } |
mzta | 0:158c61bb030f | 323 | |
mzta | 0:158c61bb030f | 324 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 325 | mrb_bug(mrb_state *mrb, const char *fmt, ...) |
mzta | 0:158c61bb030f | 326 | { |
mzta | 0:158c61bb030f | 327 | #ifdef ENABLE_STDIO |
mzta | 0:158c61bb030f | 328 | va_list ap; |
mzta | 0:158c61bb030f | 329 | mrb_value str; |
mzta | 0:158c61bb030f | 330 | |
mzta | 0:158c61bb030f | 331 | va_start(ap, fmt); |
mzta | 0:158c61bb030f | 332 | str = mrb_vformat(mrb, fmt, ap); |
mzta | 0:158c61bb030f | 333 | fputs("bug: ", stderr); |
mzta | 0:158c61bb030f | 334 | fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr); |
mzta | 0:158c61bb030f | 335 | va_end(ap); |
mzta | 0:158c61bb030f | 336 | #endif |
mzta | 0:158c61bb030f | 337 | exit(EXIT_FAILURE); |
mzta | 0:158c61bb030f | 338 | } |
mzta | 0:158c61bb030f | 339 | |
mzta | 0:158c61bb030f | 340 | static void |
mzta | 0:158c61bb030f | 341 | set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt) |
mzta | 0:158c61bb030f | 342 | { |
mzta | 0:158c61bb030f | 343 | mrb_funcall(mrb, info, "set_backtrace", 1, bt); |
mzta | 0:158c61bb030f | 344 | } |
mzta | 0:158c61bb030f | 345 | |
mzta | 0:158c61bb030f | 346 | static mrb_value |
mzta | 0:158c61bb030f | 347 | make_exception(mrb_state *mrb, int argc, const mrb_value *argv, mrb_bool isstr) |
mzta | 0:158c61bb030f | 348 | { |
mzta | 0:158c61bb030f | 349 | mrb_value mesg; |
mzta | 0:158c61bb030f | 350 | int n; |
mzta | 0:158c61bb030f | 351 | |
mzta | 0:158c61bb030f | 352 | mesg = mrb_nil_value(); |
mzta | 0:158c61bb030f | 353 | switch (argc) { |
mzta | 0:158c61bb030f | 354 | case 0: |
mzta | 0:158c61bb030f | 355 | break; |
mzta | 0:158c61bb030f | 356 | case 1: |
mzta | 0:158c61bb030f | 357 | if (mrb_nil_p(argv[0])) |
mzta | 0:158c61bb030f | 358 | break; |
mzta | 0:158c61bb030f | 359 | if (isstr) { |
mzta | 0:158c61bb030f | 360 | mesg = mrb_check_string_type(mrb, argv[0]); |
mzta | 0:158c61bb030f | 361 | if (!mrb_nil_p(mesg)) { |
mzta | 0:158c61bb030f | 362 | mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg); |
mzta | 0:158c61bb030f | 363 | break; |
mzta | 0:158c61bb030f | 364 | } |
mzta | 0:158c61bb030f | 365 | } |
mzta | 0:158c61bb030f | 366 | n = 0; |
mzta | 0:158c61bb030f | 367 | goto exception_call; |
mzta | 0:158c61bb030f | 368 | |
mzta | 0:158c61bb030f | 369 | case 2: |
mzta | 0:158c61bb030f | 370 | case 3: |
mzta | 0:158c61bb030f | 371 | n = 1; |
mzta | 0:158c61bb030f | 372 | exception_call: |
mzta | 0:158c61bb030f | 373 | { |
mzta | 0:158c61bb030f | 374 | mrb_sym exc = mrb_intern_lit(mrb, "exception"); |
mzta | 0:158c61bb030f | 375 | if (mrb_respond_to(mrb, argv[0], exc)) { |
mzta | 0:158c61bb030f | 376 | mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); |
mzta | 0:158c61bb030f | 377 | } |
mzta | 0:158c61bb030f | 378 | else { |
mzta | 0:158c61bb030f | 379 | /* undef */ |
mzta | 0:158c61bb030f | 380 | mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); |
mzta | 0:158c61bb030f | 381 | } |
mzta | 0:158c61bb030f | 382 | } |
mzta | 0:158c61bb030f | 383 | |
mzta | 0:158c61bb030f | 384 | break; |
mzta | 0:158c61bb030f | 385 | default: |
mzta | 0:158c61bb030f | 386 | mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc)); |
mzta | 0:158c61bb030f | 387 | break; |
mzta | 0:158c61bb030f | 388 | } |
mzta | 0:158c61bb030f | 389 | if (argc > 0) { |
mzta | 0:158c61bb030f | 390 | if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) |
mzta | 0:158c61bb030f | 391 | mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); |
mzta | 0:158c61bb030f | 392 | if (argc > 2) |
mzta | 0:158c61bb030f | 393 | set_backtrace(mrb, mesg, argv[2]); |
mzta | 0:158c61bb030f | 394 | } |
mzta | 0:158c61bb030f | 395 | |
mzta | 0:158c61bb030f | 396 | return mesg; |
mzta | 0:158c61bb030f | 397 | } |
mzta | 0:158c61bb030f | 398 | |
mzta | 0:158c61bb030f | 399 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 400 | mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv) |
mzta | 0:158c61bb030f | 401 | { |
mzta | 0:158c61bb030f | 402 | return make_exception(mrb, argc, argv, TRUE); |
mzta | 0:158c61bb030f | 403 | } |
mzta | 0:158c61bb030f | 404 | |
mzta | 0:158c61bb030f | 405 | MRB_API void |
mzta | 0:158c61bb030f | 406 | mrb_sys_fail(mrb_state *mrb, const char *mesg) |
mzta | 0:158c61bb030f | 407 | { |
mzta | 0:158c61bb030f | 408 | struct RClass *sce; |
mzta | 0:158c61bb030f | 409 | mrb_int no; |
mzta | 0:158c61bb030f | 410 | |
mzta | 0:158c61bb030f | 411 | no = (mrb_int)errno; |
mzta | 0:158c61bb030f | 412 | if (mrb_class_defined(mrb, "SystemCallError")) { |
mzta | 0:158c61bb030f | 413 | sce = mrb_class_get(mrb, "SystemCallError"); |
mzta | 0:158c61bb030f | 414 | if (mesg != NULL) { |
mzta | 0:158c61bb030f | 415 | mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); |
mzta | 0:158c61bb030f | 416 | } |
mzta | 0:158c61bb030f | 417 | else { |
mzta | 0:158c61bb030f | 418 | mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); |
mzta | 0:158c61bb030f | 419 | } |
mzta | 0:158c61bb030f | 420 | } |
mzta | 0:158c61bb030f | 421 | else { |
mzta | 0:158c61bb030f | 422 | mrb_raise(mrb, E_RUNTIME_ERROR, mesg); |
mzta | 0:158c61bb030f | 423 | } |
mzta | 0:158c61bb030f | 424 | } |
mzta | 0:158c61bb030f | 425 | |
mzta | 0:158c61bb030f | 426 | MRB_API mrb_noreturn void |
mzta | 0:158c61bb030f | 427 | mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, char const* fmt, ...) |
mzta | 0:158c61bb030f | 428 | { |
mzta | 0:158c61bb030f | 429 | mrb_value exc; |
mzta | 0:158c61bb030f | 430 | va_list ap; |
mzta | 0:158c61bb030f | 431 | |
mzta | 0:158c61bb030f | 432 | va_start(ap, fmt); |
mzta | 0:158c61bb030f | 433 | exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3, |
mzta | 0:158c61bb030f | 434 | mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), |
mzta | 0:158c61bb030f | 435 | mrb_ary_new_from_values(mrb, argc, argv)); |
mzta | 0:158c61bb030f | 436 | va_end(ap); |
mzta | 0:158c61bb030f | 437 | mrb_exc_raise(mrb, exc); |
mzta | 0:158c61bb030f | 438 | } |
mzta | 0:158c61bb030f | 439 | |
mzta | 0:158c61bb030f | 440 | void |
mzta | 0:158c61bb030f | 441 | mrb_init_exception(mrb_state *mrb) |
mzta | 0:158c61bb030f | 442 | { |
mzta | 0:158c61bb030f | 443 | struct RClass *exception, *runtime_error, *script_error; |
mzta | 0:158c61bb030f | 444 | |
mzta | 0:158c61bb030f | 445 | mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */ |
mzta | 0:158c61bb030f | 446 | MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); |
mzta | 0:158c61bb030f | 447 | mrb_define_class_method(mrb, exception, "exception", mrb_instance_new, MRB_ARGS_ANY()); |
mzta | 0:158c61bb030f | 448 | mrb_define_method(mrb, exception, "exception", exc_exception, MRB_ARGS_ANY()); |
mzta | 0:158c61bb030f | 449 | mrb_define_method(mrb, exception, "initialize", exc_initialize, MRB_ARGS_ANY()); |
mzta | 0:158c61bb030f | 450 | mrb_define_method(mrb, exception, "to_s", exc_to_s, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 451 | mrb_define_method(mrb, exception, "message", exc_message, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 452 | mrb_define_method(mrb, exception, "inspect", exc_inspect, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 453 | mrb_define_method(mrb, exception, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE()); |
mzta | 0:158c61bb030f | 454 | |
mzta | 0:158c61bb030f | 455 | mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ |
mzta | 0:158c61bb030f | 456 | runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ |
mzta | 0:158c61bb030f | 457 | mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str(mrb, runtime_error, mrb_str_new_lit(mrb, "Out of memory"))); |
mzta | 0:158c61bb030f | 458 | script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ |
mzta | 0:158c61bb030f | 459 | mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ |
mzta | 0:158c61bb030f | 460 | mrb_define_class(mrb, "SystemStackError", exception); |
mzta | 0:158c61bb030f | 461 | } |
mzta | 0:158c61bb030f | 462 |