static mrb_value struct_members(mrb_state *mrb, mrb_value s) { mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s)); if (!mrb_array_p(s)) { mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { if (RSTRUCT_LEN(s) == 0) { /* probably uninitialized */ mrb_ary_resize(mrb, s, RARRAY_LEN(members)); } else { mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%S required %S given)", mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s))); } } return members; }
static mrb_value mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self) { struct RClass *klass = mrb_obj_class(mrb, self); int i, n; n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); } for (i = 0; i < argc; i++) { mrb_ary_set(mrb, self, i, argv[i]); } for (i = argc; i < n; i++) { mrb_ary_set(mrb, self, i, mrb_nil_value()); } return self; }
static mrb_value mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self) { struct RClass *klass = mrb_obj_class(mrb, self); int n; struct RStruct *st; mrb_struct_modify(self); n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); } st = RSTRUCT(self); st->ptr = (mrb_value *)mrb_calloc(mrb, sizeof(mrb_value), n); st->len = n; memcpy(st->ptr, argv, sizeof(mrb_value)*argc); return self; }
/* * call-seq: * obj.clone -> an_object * * Produces a shallow copy of <i>obj</i>---the instance variables of * <i>obj</i> are copied, but not the objects they reference. Copies * the frozen state of <i>obj</i>. See also the discussion * under <code>Object#dup</code>. * * class Klass * attr_accessor :str * end * s1 = Klass.new #=> #<Klass:0x401b3a38> * s1.str = "Hello" #=> "Hello" * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> * s2.str[1,4] = "i" #=> "i" * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" * * This method may have class-specific behavior. If so, that * behavior will be documented under the #+initialize_copy+ method of * the class. * * Some Class(True False Nil Symbol Fixnum Float) Object cannot clone. */ MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self) { struct RObject *p; mrb_value clone; if (mrb_immediate_p(self)) { mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); } if (mrb_type(self) == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); } p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); p->c = mrb_singleton_class_clone(mrb, self); clone = mrb_obj_value(p); init_copy(mrb, clone, self); return clone; }
/* :nodoc: */ mrb_value mrb_struct_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value s; mrb_get_args(mrb, "o", &s); if (mrb_obj_equal(mrb, copy, s)) return copy; //mrb_check_frozen(copy); if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) { mrb_raise(mrb, E_TYPE_ERROR, "struct size mismatch"); } memcpy(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), sizeof(mrb_value)*RSTRUCT_LEN(copy)); return copy; }
static mrb_value mrb_digest_init_copy(mrb_state *mrb, mrb_value copy) { struct mrb_md *m1, *m2; mrb_value src; mrb_get_args(mrb, "o", &src); if (mrb_obj_equal(mrb, copy, src)) return copy; if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } if (!DATA_PTR(copy)) { DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct mrb_md)); DATA_TYPE(copy) = &mrb_md_type; } m1 = DATA_PTR(src); m2 = DATA_PTR(copy); lib_md_init_copy(mrb, m2, m1); return copy; }
static mrb_value mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self) { struct RClass *klass = mrb_obj_class(mrb, self); long n; struct RStruct *st; mrb_struct_modify(self); n = num_members(mrb, klass); if (n < argc) { mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs"); } st = RSTRUCT(self); st->ptr = malloc(sizeof(mrb_value)*argc); st->len = n; memcpy(st->ptr, argv, sizeof(mrb_value)*argc); //if (n > argc) { // mrb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc); //} return self; }
static mrb_value mrb_time_minus(mrb_state *mrb, mrb_value self) { mrb_float f; mrb_value other; struct mrb_time *tm, *tm2; mrb_get_args(mrb, "o", &other); tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(mrb, f); } else { mrb_get_args(mrb, "f", &f); return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone); } }
/* * call-seq: * obj.clone -> an_object * * Produces a shallow copy of <i>obj</i>---the instance variables of * <i>obj</i> are copied, but not the objects they reference. Copies * the frozen state of <i>obj</i>. See also the discussion * under <code>Object#dup</code>. * * class Klass * attr_accessor :str * end * s1 = Klass.new #=> #<Klass:0x401b3a38> * s1.str = "Hello" #=> "Hello" * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> * s2.str[1,4] = "i" #=> "i" * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" * * This method may have class-specific behavior. If so, that * behavior will be documented under the #+initialize_copy+ method of * the class. * * Some Class(True False Nil Symbol Fixnum Float) Object cannot clone. */ MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self) { struct RObject *p; mrb_value clone; if (mrb_immediate_p(self)) { mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); } if (mrb_type(self) == MRB_TT_SCLASS) { mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); } p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); p->c = mrb_singleton_class_clone(mrb, self); mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); clone = mrb_obj_value(p); init_copy(mrb, clone, self); p->flags |= mrb_obj_ptr(self)->flags & MRB_FL_OBJ_IS_FROZEN; return clone; }
static mrb_value method_super_method(mrb_state *mrb, mrb_value self) { mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@recv")); mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass")); mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner")); mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name")); struct RClass *super, *rklass; struct RProc *proc; struct RObject *me; switch (mrb_type(klass)) { case MRB_TT_SCLASS: super = mrb_class_ptr(klass)->super->super; break; case MRB_TT_ICLASS: super = mrb_class_ptr(klass)->super; break; default: super = mrb_class_ptr(owner)->super; break; } proc = method_search_vm(mrb, &super, mrb_symbol(name)); if (!proc) return mrb_nil_value(); rklass = super; while (super->tt == MRB_TT_ICLASS) super = super->c; me = method_object_alloc(mrb, mrb_obj_class(mrb, self)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(super)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), recv); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), name); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), mrb_obj_value(proc)); mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), mrb_obj_value(rklass)); return mrb_obj_value(me); }
static mrb_value mrb_time_minus(mrb_state *mrb, mrb_value self) { mrb_float f; mrb_value other; struct mrb_time *tm, *tm2; mrb_get_args(mrb, "o", &other); tm = (struct mrb_time *)mrb_get_datatype(mrb, self, &mrb_time_type); if (!tm) return mrb_nil_value(); tm2 = (struct mrb_time *)mrb_get_datatype(mrb, other, &mrb_time_type); if (tm2) { f = (mrb_float)(tm->sec - tm2->sec) + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; return mrb_float_value(f); } else { mrb_get_args(mrb, "f", &f); return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, tm->usec, tm->timezone); } }
/* * call-seq: * LCD.new(font, x, y, width, height, color) # => LCD * * Creates LCD object. * * Parameters: * +font+ font size. * :small small font (6x8, default) * :medium medium font (8x16) * +x+ Window origin (left) X coordinate. (default: 0) * +y+ Window origin (top) Y coordinate. (default: 0) * +width+ Width of window. (default: LCD::WIDTH) * +height+ Height of window. (default: LCD::HEIGHT) * +color+ LCD foreground color. * :black black (default) * :white while * * Returns LCD object. */ static mrb_value mrb_lcd_init(mrb_state *mrb, mrb_value self) { struct RClass *lcd = mrb_obj_class(mrb, self); mrb_value fmap = mrb_const_get(mrb, mrb_obj_value(lcd), mrb_intern_lit(mrb, "FONT")); mrb_value cmap = mrb_const_get(mrb, mrb_obj_value(lcd), mrb_intern_lit(mrb, "COLOR")); mrb_sym font = mrb_intern_lit(mrb, "small"); mrb_sym col = mrb_intern_lit(mrb, "black"); mrb_value fontv; mrb_value colv; mrb_lcd_t *plcd; DATA_TYPE(self) = &mrb_lcd_type; plcd = (mrb_lcd_t*)mrb_malloc(mrb, sizeof(mrb_lcd_t)); DATA_PTR(self) = plcd; memset(plcd, 0, sizeof(mrb_lcd_t)); plcd->width = EV3_LCD_WIDTH; plcd->height = EV3_LCD_HEIGHT; mrb_get_args(mrb, "|niiiin", &font, &plcd->left, &plcd->top, &plcd->width, &plcd->height, &col); fontv = mrb_hash_get(mrb, fmap, mrb_symbol_value(font)); if (mrb_nil_p(fontv)) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid font size :%S", mrb_sym2str(mrb, font)); } plcd->font = mrb_fixnum(fontv); if (_font_size[plcd->font].w == 0) { /* initialize font size at 1st time */ ev3_font_get_size(plcd->font, &_font_size[plcd->font].w, &_font_size[plcd->font].h); } colv = mrb_hash_get(mrb, cmap, mrb_symbol_value(col)); if (mrb_nil_p(colv)) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid foreground color :%S", mrb_sym2str(mrb, col)); } plcd->color = mrb_fixnum(colv); return self; }
mrb_value mrb_range_eq(mrb_state *mrb, mrb_value range) { struct RRange *rr; struct RRange *ro; mrb_value obj; mrb_get_args(mrb, "o", &obj); if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */ return mrb_false_value(); } rr = mrb_range_ptr(range); ro = mrb_range_ptr(obj); if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) || !mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) || rr->excl != ro->excl) { return mrb_false_value(); } return mrb_true_value(); }
static mrb_value mrb_kernel_method(mrb_state *mrb, mrb_value self) { struct RClass *method = mrb_class_get(mrb, "Method"); struct RClass *owner; struct RProc *proc; mrb_value id; mrb_value me; mrb_value argv[5]; mrb_get_args(mrb, "o", &id); mrb_search_method_owner(mrb, mrb_class(mrb, self), self, id, &owner, &proc); argv[0] = mrb_obj_value(mrb_obj_class(mrb, self)); argv[1] = mrb_obj_value(owner); argv[2] = self; argv[3] = id; argv[4] = mrb_obj_value(proc); me = mrb_obj_new(mrb, method, 5, argv); return me; }
mrb_value mrb_matchdata_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value src; struct mrb_matchdata *mrb_md_copy, *mrb_md_src; int vecsize; mrb_get_args(mrb, "o", &src); if (mrb_obj_equal(mrb, copy, src)) return copy; if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } mrb_md_copy = (struct mrb_matchdata *)mrb_malloc(mrb, sizeof(*mrb_md_copy)); mrb_md_src = DATA_PTR(src); if (mrb_md_src->ovector == NULL) { mrb_md_copy->ovector = NULL; mrb_md_copy->length = -1; } else { vecsize = sizeof(int) * mrb_md_src->length * 3; mrb_md_copy->ovector = mrb_malloc(mrb, vecsize); memcpy(mrb_md_copy->ovector, mrb_md_src->ovector, vecsize); mrb_md_copy->length = mrb_md_src->length; } if (DATA_PTR(copy) != NULL) { mrb_matchdata_free(mrb, DATA_PTR(copy)); } DATA_PTR(copy) = mrb_md_copy; mrb_iv_set(mrb, copy, mrb_intern_lit(mrb, "@regexp"), mrb_iv_get(mrb, src, mrb_intern_lit(mrb, "@regexp"))); mrb_iv_set(mrb, copy, mrb_intern_lit(mrb, "@string"), mrb_iv_get(mrb, src, mrb_intern_lit(mrb, "@string"))); return copy; }
/* :nodoc: */ mrb_value mrb_struct_init_copy(mrb_state *mrb, mrb_value copy) { mrb_value s; mrb_int i, len; mrb_get_args(mrb, "o", &s); if (mrb_obj_equal(mrb, copy, s)) return copy; if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } if (!mrb_array_p(s)) { mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) { mrb_raise(mrb, E_TYPE_ERROR, "struct size mismatch"); } len = RSTRUCT_LEN(copy); for (i = 0; i < len; i++) { mrb_ary_set(mrb, copy, i, RSTRUCT_PTR(s)[i]); } return copy; }
mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) { if (mrb_obj_class(mrb, obj) == c) return TRUE; return FALSE; }
/* * call-seq: * obj.class -> class * * Returns the class of <i>obj</i>. This method must always be * called with an explicit receiver, as <code>class</code> is also a * reserved word in Ruby. * * 1.class #=> Fixnum * self.class #=> Object */ static mrb_value mrb_obj_class_m(mrb_state *mrb, mrb_value self) { return mrb_obj_value(mrb_obj_class(mrb, self)); }
static mrb_value mrb_struct_members_m(mrb_state *mrb, mrb_value obj) { return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj))); }
const char* mrb_obj_classname(mrb_state *mrb, mrb_value obj) { return mrb_class_name(mrb, mrb_obj_class(mrb, obj)); }
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; }