static mrb_value inspect_hash(mrb_state *mrb, mrb_value hash, int recur) { mrb_value str, str2; khash_t(ht) *h = RHASH_TBL(hash); khiter_t k; if (recur) return mrb_str_new_lit(mrb, "{...}"); str = mrb_str_new_lit(mrb, "{"); if (h && kh_size(h) > 0) { for (k = kh_begin(h); k != kh_end(h); k++) { int ai; if (!kh_exist(h,k)) continue; ai = mrb_gc_arena_save(mrb); if (RSTRING_LEN(str) > 1) mrb_str_cat_lit(mrb, str, ", "); str2 = mrb_inspect(mrb, kh_key(h,k)); mrb_str_append(mrb, str, str2); mrb_str_cat_lit(mrb, str, "=>"); str2 = mrb_inspect(mrb, kh_value(h,k)); mrb_str_append(mrb, str, str2); mrb_gc_arena_restore(mrb, ai); } } mrb_str_cat_lit(mrb, str, "}"); return str; }
static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc) { mrb_value str, mesg, file, line; mesg = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "mesg", 4)); file = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "file", 4)); line = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "line", 4)); if (!mrb_nil_p(file) && !mrb_nil_p(line)) { str = file; mrb_str_cat(mrb, str, ":", 1); mrb_str_append(mrb, str, line); mrb_str_cat(mrb, str, ": ", 2); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { mrb_str_append(mrb, str, mesg); mrb_str_cat(mrb, str, " (", 2); } mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { mrb_str_cat(mrb, str, ")", 1); } } else { str = mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc)); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { mrb_str_cat(mrb, str, ": ", 2); mrb_str_append(mrb, str, mesg); } else { mrb_str_cat(mrb, str, ": ", 2); mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); } } return str; }
static mrb_value mrb_mod_to_s(mrb_state *mrb, mrb_value klass) { mrb_value str; if (mrb_type(klass) == MRB_TT_SCLASS) { mrb_value v = mrb_iv_get(mrb, klass, mrb_intern2(mrb, "__attached__", 12)); str = mrb_str_new(mrb, "#<Class:", 8); switch (mrb_type(v)) { case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: mrb_str_append(mrb, str, mrb_inspect(mrb, v)); break; default: mrb_str_append(mrb, str, mrb_any_to_s(mrb, v)); break; } mrb_str_cat(mrb, str, ">", 1); } else { struct RClass *c; mrb_value path; str = mrb_str_buf_new(mrb, 32); c = mrb_class_ptr(klass); path = mrb_class_path(mrb, c); if (mrb_nil_p(path)) { switch (mrb_type(klass)) { case MRB_TT_CLASS: mrb_str_cat(mrb, str, "#<Class:", 8); break; case MRB_TT_MODULE: mrb_str_cat(mrb, str, "#<Module:", 9); break; default: /* Shouldn't be happened? */ mrb_str_cat(mrb, str, "#<??????:", 9); break; } mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c)); mrb_str_cat(mrb, str, ">", 1); } else { str = path; } } return str; }
static mrb_value mrb_mod_to_s(mrb_state *mrb, mrb_value klass) { if (mrb_type(klass) == MRB_TT_SCLASS) { mrb_value s = mrb_str_new(mrb, "#<", 2); mrb_value v = mrb_iv_get(mrb, klass, mrb_intern(mrb, "__attached__")); mrb_str_cat2(mrb, s, "Class:"); switch (mrb_type(v)) { case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: mrb_str_append(mrb, s, mrb_inspect(mrb, v)); break; default: mrb_str_append(mrb, s, mrb_any_to_s(mrb, v)); break; } mrb_str_cat2(mrb, s, ">"); return s; } else { struct RClass *c = mrb_class_ptr(klass); const char *cn = mrb_class_name(mrb, c); if (!cn) { char buf[256]; int n = 0; switch (mrb_type(klass)) { case MRB_TT_CLASS: n = snprintf(buf, sizeof(buf), "#<Class:%p>", c); break; case MRB_TT_MODULE: n = snprintf(buf, sizeof(buf), "#<Module:%p>", c); break; default: break; } return mrb_str_dup(mrb, mrb_str_new(mrb, buf, n)); } else { return mrb_str_dup(mrb, mrb_str_new_cstr(mrb, cn)); } } }
static mrb_value inspect_struct(mrb_state *mrb, mrb_value s, int recur) { const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s)); mrb_value members, str = mrb_str_new_lit(mrb, "#<struct "); mrb_value *ptr, *ptr_members; mrb_int i, len; if (cn) { mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn)); } if (recur) { return mrb_str_cat_lit(mrb, str, ":...>"); } members = mrb_struct_members(mrb, s); ptr_members = RARRAY_PTR(members); ptr = RSTRUCT_PTR(s); len = RSTRUCT_LEN(s); for (i=0; i<len; i++) { mrb_value slot; mrb_sym id; if (i > 0) { mrb_str_cat_lit(mrb, str, ", "); } else if (cn) { mrb_str_cat_lit(mrb, str, " "); } slot = ptr_members[i]; id = mrb_symbol(slot); if (mrb_is_local_id(id) || mrb_is_const_id(id)) { const char *name; mrb_int len; name = mrb_sym2name_len(mrb, id, &len); mrb_str_append(mrb, str, mrb_str_new(mrb, name, len)); } else { mrb_str_append(mrb, str, mrb_inspect(mrb, slot)); } mrb_str_cat_lit(mrb, str, "="); mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i])); } mrb_str_cat_lit(mrb, str, ">"); return str; }
static mrb_value mrb_proc_inspect(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); mrb_value str = mrb_str_new_lit(mrb, "#<Proc:"); mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self))); if (!MRB_PROC_CFUNC_P(p)) { mrb_irep *irep = p->body.irep; mrb_str_cat_lit(mrb, str, "@"); if (irep->filename) { mrb_str_cat_cstr(mrb, str, irep->filename); } else { mrb_str_cat_lit(mrb, str, "-"); } mrb_str_cat_lit(mrb, str, ":"); if (irep->lines) { mrb_str_append(mrb, str, mrb_fixnum_value(*irep->lines)); } else { mrb_str_cat_lit(mrb, str, "-"); } } if (MRB_PROC_STRICT_P(p)) { mrb_str_cat_lit(mrb, str, " (lambda)"); } mrb_str_cat_lit(mrb, str, ">"); return str; }
static mrb_value mrb_proc_inspect(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); mrb_value str = mrb_str_new_lit(mrb, "#<Proc:"); mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self))); if (!MRB_PROC_CFUNC_P(p)) { mrb_irep *irep = p->body.irep; const char *filename; int32_t line; mrb_str_cat_lit(mrb, str, "@"); filename = mrb_debug_get_filename(irep, 0); mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); mrb_str_cat_lit(mrb, str, ":"); line = mrb_debug_get_line(irep, 0); if (line != -1) { mrb_str_append(mrb, str, mrb_fixnum_value(line)); } else { mrb_str_cat_lit(mrb, str, "-"); } } if (MRB_PROC_STRICT_P(p)) { mrb_str_cat_lit(mrb, str, " (lambda)"); } mrb_str_cat_lit(mrb, str, ">"); return str; }
static int inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) { mrb_value str = *(mrb_value*)p; const char *s; mrb_int len; mrb_value ins; char *sp = RSTRING_PTR(str); /* need not to show internal data */ if (sp[0] == '-') { /* first element */ sp[0] = '#'; mrb_str_cat_lit(mrb, str, " "); } else { mrb_str_cat_lit(mrb, str, ", "); } s = mrb_sym2name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat_lit(mrb, str, "="); if (mrb_type(v) == MRB_TT_OBJECT) { ins = mrb_any_to_s(mrb, v); } else { ins = mrb_inspect(mrb, v); } mrb_str_append(mrb, str, ins); return 0; }
static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc) { mrb_value str, klass; klass = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc)); exc = mrb_obj_as_string(mrb, exc); if (RSTRING_LEN(exc) == 0) { return klass; } str = mrb_str_new2(mrb, "#<"); mrb_str_append(mrb, str, klass); mrb_str_cat2(mrb, str, ": "); mrb_str_append(mrb, str, exc); mrb_str_cat2(mrb, str, ">"); return str; }
static mrb_value mrb_file_realpath(mrb_state *mrb, mrb_value klass) { mrb_value pathname, dir_string, s, result; int argc; char *cpath; argc = mrb_get_args(mrb, "S|S", &pathname, &dir_string); if (argc == 2) { s = mrb_str_dup(mrb, dir_string); s = mrb_str_append(mrb, s, mrb_str_new_cstr(mrb, FILE_SEPARATOR)); s = mrb_str_append(mrb, s, pathname); pathname = s; } cpath = mrb_str_to_cstr(mrb, pathname); result = mrb_str_buf_new(mrb, PATH_MAX); if (realpath(cpath, RSTRING_PTR(result)) == NULL) mrb_sys_fail(mrb, cpath); mrb_str_resize(mrb, result, strlen(RSTRING_PTR(result))); return result; }
static mrb_value range_to_s(mrb_state *mrb, mrb_value range) { mrb_value str, str2; struct RRange *r = mrb_range_ptr(range); str = mrb_obj_as_string(mrb, r->edges->beg); str2 = mrb_obj_as_string(mrb, r->edges->end); str = mrb_str_dup(mrb, str); mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); mrb_str_append(mrb, str, str2); return str; }
static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc) { mrb_value str; str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc)); exc = mrb_obj_as_string(mrb, exc); if (RSTRING_LEN(exc) > 0) { mrb_str_cat2(mrb, str, ": "); mrb_str_append(mrb, str, exc); } return str; }
static mrb_value inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur) { mrb_value str, str2; struct RRange *r = mrb_range_ptr(range); if (recur) { return mrb_str_new2(mrb, r->excl ? "(... ... ...)" : "(... .. ...)"); } str = mrb_inspect(mrb, r->edges->beg); str2 = mrb_inspect(mrb, r->edges->end); str = mrb_str_dup(mrb, str); mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); mrb_str_append(mrb, str, str2); return str; }
static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc) { mrb_value str, mesg, file, line; mrb_bool append_mesg; mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg")); file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file")); line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line")); append_mesg = !mrb_nil_p(mesg); if (append_mesg) { mesg = mrb_obj_as_string(mrb, mesg); append_mesg = RSTRING_LEN(mesg) > 0; } if (!mrb_nil_p(file) && !mrb_nil_p(line)) { str = mrb_str_dup(mrb, file); mrb_str_cat_lit(mrb, str, ":"); mrb_str_append(mrb, str, line); mrb_str_cat_lit(mrb, str, ": "); if (append_mesg) { mrb_str_cat_str(mrb, str, mesg); mrb_str_cat_lit(mrb, str, " ("); } mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); if (append_mesg) { mrb_str_cat_lit(mrb, str, ")"); } } else { const char *cname = mrb_obj_classname(mrb, exc); str = mrb_str_new_cstr(mrb, cname); mrb_str_cat_lit(mrb, str, ": "); if (append_mesg) { mrb_str_cat_str(mrb, str, mesg); } else { mrb_str_cat_cstr(mrb, str, cname); } } return str; }
static int inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) { mrb_value str = *(mrb_value*)p; const char *s; size_t len; /* need not to show internal data */ if (RSTRING_PTR(str)[0] == '-') { /* first element */ RSTRING_PTR(str)[0] = '#'; mrb_str_cat(mrb, str, " ", 1); } else { mrb_str_cat(mrb, str, ", ", 2); } s = mrb_sym2name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); mrb_str_cat(mrb, str, "=", 1); mrb_str_append(mrb, str, mrb_inspect(mrb, v)); return 0; }
static mrb_value inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur) { mrb_value str, str2; struct RRange *r = mrb_range_ptr(range); if (recur) { static const char s[2][14] = { "(... ... ...)", "(... .. ...)" }; static const int n[] = { 13, 12 }; int idx; idx = (r->excl) ? 0 : 1; return mrb_str_new(mrb, s[idx], n[idx]); } str = mrb_inspect(mrb, r->edges->beg); str2 = mrb_inspect(mrb, r->edges->end); str = mrb_str_dup(mrb, str); mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); mrb_str_append(mrb, str, str2); return str; }
static mrb_value mrb_sce_init(mrb_state *mrb, mrb_value self) { mrb_value c, e2c, m, str; mrb_int n; int argc, no_errno = 0; char buf[20]; argc = mrb_get_args(mrb, "o|i", &m, &n); if (argc == 1) { if (mrb_type(m) == MRB_TT_FIXNUM) { n = mrb_fixnum(m); m = mrb_nil_value(); } else { no_errno = 1; } } if (!no_errno) { e2c = mrb_const_get(mrb, mrb_obj_value(mrb_module_get(mrb, "Errno")), mrb_intern_lit(mrb, "Errno2class")); c = mrb_hash_fetch(mrb, e2c, mrb_fixnum_value(n), mrb_nil_value()); if (!mrb_nil_p(c)) { mrb_basic_ptr(self)->c = mrb_class_ptr(c); str = mrb_str_new_cstr(mrb, strerror(n)); } else { mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "errno"), mrb_fixnum_value(n)); str = mrb_str_new_cstr(mrb, "Unknown error: "); snprintf(buf, sizeof(buf), "%d", (int)n); mrb_str_cat2(mrb, str, buf); } } else { str = mrb_str_new_cstr(mrb, "unknown error"); } if (!mrb_nil_p(m)) { mrb_str_cat2(mrb, str, " - "); mrb_str_append(mrb, str, m); } mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str); return self; }
static mrb_value inspect_obj(mrb_state *mrb, mrb_value obj, mrb_value str, int recur) { if (recur) { mrb_str_cat2(mrb, str, " ..."); } else { khiter_t k; kh_iv_t *h = RCLASS_IV_TBL(obj); if (h) { for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)){ mrb_sym id = kh_key(h, k); mrb_value value = kh_value(h, k); /* need not to show internal data */ if (RSTRING_PTR(str)[0] == '-') { /* first element */ RSTRING_PTR(str)[0] = '#'; mrb_str_cat2(mrb, str, " "); } else { mrb_str_cat2(mrb, str, ", "); } mrb_str_cat2(mrb, str, mrb_sym2name(mrb, id)); mrb_str_cat2(mrb, str, "="); mrb_str_append(mrb, str, mrb_inspect(mrb, value)); } } } } mrb_str_cat2(mrb, str, ">"); RSTRING_PTR(str)[0] = '#'; return str; }
static mrb_value mrb_sce_errno(mrb_state *mrb, mrb_value self) { struct RClass *c; mrb_sym sym; c = mrb_class(mrb, self); sym = mrb_intern_lit(mrb, "Errno"); #if MRUBY_RELEASE_NO < 10000 if (mrb_const_defined_at(mrb, c, sym)) { #else if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) { #endif return mrb_const_get(mrb, mrb_obj_value(c), sym); } else { sym = mrb_intern_lit(mrb, "errno"); return mrb_attr_get(mrb, self, sym); } } static mrb_value mrb_sce_to_s(mrb_state *mrb, mrb_value self) { return mrb_attr_get(mrb, self, mrb_intern_lit(mrb, "mesg")); } static mrb_value mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) { struct RClass *cl, *sce; mrb_value e, msg; mrb_int no; int argc; char name[8]; sce = mrb_class_get(mrb, "SystemCallError"); argc = mrb_get_args(mrb, "i|S", &no, &msg); if (argc == 1) { e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 1, mrb_fixnum_value(no)); } else { e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 2, msg, mrb_fixnum_value(no)); } if (mrb_obj_class(mrb, e) == sce) { snprintf(name, sizeof(name), "E%03ld", (long)no); cl = mrb_define_class_under(mrb, mrb_module_get(mrb, "Errno"), name, sce); mrb_define_const(mrb, cl, "Errno", mrb_fixnum_value(no)); mrb_basic_ptr(e)->c = cl; } mrb_exc_raise(mrb, e); return mrb_nil_value(); /* NOTREACHED */ } static mrb_value mrb_exxx_init(mrb_state *mrb, mrb_value self) { mrb_value m, no, str; no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), mrb_intern_lit(mrb, "Errno")); str = mrb_str_new_cstr(mrb, strerror(mrb_fixnum(no))); m = mrb_nil_value(); mrb_get_args(mrb, "|S", &m); if (!mrb_nil_p(m)) { mrb_str_cat2(mrb, str, " - "); mrb_str_append(mrb, str, m); } mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str); return self; }