mrb_value ruby_global_require(mrb_state* mrb, mrb_value self) { const char* filename_cstr = nullptr; mrb_get_args(mrb, "z", &filename_cstr); std::string filename(filename_cstr); auto engine = cocos2d::RubyEngine::getInstance(); std::string realfile = engine->findFile(filename); mrb_value loaded_path_arr = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$LOADED_FEATURES")); if (mrb_array_p(loaded_path_arr)) { mrb_int len = mrb_ary_len(mrb, loaded_path_arr); for (mrb_int i = 0; i < len; i++) { mrb_value path = mrb_ary_ref(mrb, loaded_path_arr, i); const char* path_cstr = mrb_str_to_cstr(mrb, path); if (realfile.compare(path_cstr) == 0) { return mrb_nil_value(); } } } if (! mrb_array_p(loaded_path_arr)) { loaded_path_arr = mrb_ary_new(mrb); mrb_value path = mrb_str_new_cstr(mrb, realfile.c_str()); mrb_ary_push(mrb, loaded_path_arr, path); mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$LOADED_FEATURES"), loaded_path_arr); } else { mrb_value path = mrb_str_new_cstr(mrb, realfile.c_str()); mrb_ary_push(mrb, loaded_path_arr, path); } engine->executeScriptFile(realfile.c_str()); return mrb_nil_value(); }
MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value v) { mrb_value a, recv_class; if (mrb_array_p(v)) { return v; } if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { return mrb_ary_new_from_values(mrb, 1, &v); } a = mrb_funcall(mrb, v, "to_a", 0); if (mrb_array_p(a)) { return a; } else if (mrb_nil_p(a)) { return mrb_ary_new_from_values(mrb, 1, &v); } else { recv_class = mrb_obj_value(mrb_obj_class(mrb, v)); mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)", recv_class, recv_class, mrb_obj_value(mrb_obj_class(mrb, a)) ); /* not reached */ return mrb_undef_value(); } }
static mrb_value mrb_sdl2_video_surface_fill_rects(mrb_state *mrb, mrb_value self) { uint32_t color; mrb_value rects; mrb_get_args(mrb, "io", &color, &rects); if (!mrb_array_p(rects)) { mrb_raise(mrb, E_TYPE_ERROR, "given 2nd argument is unexpected type (expected Array)."); } mrb_int const n = mrb_ary_len(mrb, rects); SDL_Surface *s = mrb_sdl2_video_surface_get_ptr(mrb, self); SDL_Rect r[n]; mrb_int i; for (i = 0; i < n; ++i) { SDL_Rect const * const ptr = mrb_sdl2_rect_get_ptr(mrb, mrb_ary_ref(mrb, rects, i)); if (NULL != ptr) { r[i] = *ptr; } else { r[i] = (SDL_Rect) { 0, 0, 0, 0 }; } } if (0 != SDL_FillRects(s, r, n, color)) { mruby_sdl2_raise_error(mrb); } return self; }
static mrb_value mrb_ary_eql(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_bool eql_p; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) { eql_p = 1; } else if (!mrb_array_p(ary2)) { eql_p = 0; } else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) { eql_p = 0; } else { mrb_int i; eql_p = 1; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { eql_p = 0; break; } } } return mrb_bool_value(eql_p); }
bool rubyval_to_std_vector_string(mrb_state* mrb, mrb_value arg, std::vector<std::string>* ret, const char* funcName) { if (! mrb_array_p(arg)) { return false; } mrb_int len = mrb_ary_len(mrb, arg); for (mrb_int i = 0; i < len; i++) { mrb_value v = mrb_ary_ref(mrb, arg, i); std::string str = ""; if (mrb_fixnum_p(v)) { mrb_int val = mrb_fixnum(v); char *cstr = nullptr; sprintf(cstr, "%d", val); str = std::string(cstr); } else if (mrb_float_p(v)) { mrb_float val = mrb_float(v); char *cstr = nullptr; sprintf(cstr, "%f", val); str = std::string(cstr); } ret->push_back(str); } return true; }
static mrb_value mrb_ary_equal(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_int i; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); if (mrb_special_const_p(ary2)) return mrb_false_value(); if (!mrb_array_p(ary2)) { if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) { return mrb_false_value(); } else { return mrb_bool_value(mrb_equal(mrb, ary2, ary1)); } } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { return mrb_false_value(); } } return mrb_true_value(); }
/* * call-seq: * ary <=> other_ary -> -1, 0, +1 or nil * * Comparison---Returns an integer (-1, 0, or +1) * if this array is less than, equal to, or greater than <i>other_ary</i>. * Each object in each array is compared (using <=>). If any value isn't * equal, then that inequality is the return value. If all the * values found are equal, then the return is based on a * comparison of the array lengths. Thus, two arrays are * ``equal'' according to <code>Array#<=></code> if and only if they have * the same length and the value of each element is equal to the * value of the corresponding element in the other array. * * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1 * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 * */ mrb_value mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; struct RArray *a1, *a2; mrb_value r; mrb_int i, len; mrb_get_args(mrb, "o", &ary2); if (!mrb_array_p(ary2)) return mrb_nil_value(); a1 = RARRAY(ary1); a2 = RARRAY(ary2); if (a1->len == a2->len && a1->ptr == a2->ptr) return mrb_fixnum_value(0); else { mrb_sym cmp = mrb_intern2(mrb, "<=>", 3); len = RARRAY_LEN(ary1); if (len > RARRAY_LEN(ary2)) { len = RARRAY_LEN(ary2); } for (i=0; i<len; i++) { mrb_value v = ary_elt(ary2, i); r = mrb_funcall_argv(mrb, ary_elt(ary1, i), cmp, 1, &v); if (mrb_type(r) != MRB_TT_FIXNUM || mrb_fixnum(r) != 0) return r; } } len = a1->len - a2->len; return mrb_fixnum_value((len == 0)? 0: (len > 0)? 1: -1); }
mrb_value mrb_mraa_i2c_write(mrb_state *mrb, mrb_value self){ mraa_i2c_context i2c; mrb_value mrv_wbuf; mrb_int length; mraa_result_t result; uint8_t *wbuf; mrb_int argc; Data_Get_Struct(mrb, self, &mrb_mraa_i2c_ctx_type, i2c); argc = mrb_get_args(mrb, "o|i", &mrv_wbuf, &length); result = MRAA_ERROR_INVALID_PARAMETER; if (mrb_array_p(mrv_wbuf)){ int i; if (argc == 1){ length = RARRAY_LEN(mrv_wbuf); } wbuf = (uint8_t *)mrb_malloc(mrb, sizeof(uint8_t) * length); memset(wbuf, 0, sizeof(uint8_t) * length); for (i = 0; i < length; i++){ wbuf[i] = mrb_fixnum(mrb_ary_ref(mrb, mrv_wbuf, i)); } result = mraa_i2c_write(i2c, wbuf, length); mrb_free(mrb, wbuf); } return mrb_fixnum_value(result); }
MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) { struct RArray *a = mrb_ary_ptr(ary); mrb_int tail, size; mrb_value *argv; mrb_int i, argc; ary_modify(mrb, a); /* len check */ if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len)); /* range check */ if (head < 0) { head += a->len; if (head < 0) { mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); } } if (a->len < len || a->len < head + len) { len = a->len - head; } tail = head + len; /* size check */ if (mrb_array_p(rpl)) { argc = RARRAY_LEN(rpl); argv = RARRAY_PTR(rpl); } else { argc = 1; argv = &rpl; } size = head + argc; if (tail < a->len) size += a->len - tail; if (size > a->aux.capa) ary_expand_capa(mrb, a, size); if (head > a->len) { ary_fill_with_nil(a->ptr + a->len, head - a->len); } else if (head < a->len) { value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail); } for (i = 0; i < argc; i++) { *(a->ptr + head + i) = *(argv + i); mrb_field_write_barrier_value(mrb, (struct RBasic*)a, argv[i]); } a->len = size; return ary; }
mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value v) { if (mrb_array_p(v)) { return v; } else { return mrb_ary_new_from_values(mrb, 1, &v); } }
static int num_members(mrb_state *mrb, struct RClass *klass) { mrb_value members; members = struct_ivar_get(mrb, mrb_obj_value(klass), mrb_intern(mrb, "__members__")); if (!mrb_array_p(members)) { mrb_raise(mrb, E_TYPE_ERROR, "broken members"); } return RARRAY_LEN(members); }
static void loading_files_delete(mrb_state *mrb, mrb_value filepath) { mrb_value loading_files = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$\"_")); if (!mrb_array_p(loading_files)) { return; } mrb_funcall(mrb, loading_files, "delete", 1, filepath); return; }
static mrb_value mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); if (!mrb_array_p(ary2)) { return mrb_nil_value(); } return ary2; }
MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value v) { if (mrb_array_p(v)) { return v; } if (mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { return mrb_funcall(mrb, v, "to_a", 0); } else { return mrb_ary_new_from_values(mrb, 1, &v); } }
mrb_value mrb_struct_s_members(mrb_state *mrb, mrb_value klass) { mrb_value members = struct_ivar_get(mrb, klass, mrb_intern_lit(mrb, "__members__")); if (mrb_nil_p(members)) { mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct"); } if (!mrb_array_p(members)) { mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct"); } return members; }
mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) { struct RArray *a = mrb_ary_ptr(ary); mrb_int tail, size; mrb_value *argv; mrb_int i, argc; ary_modify(mrb, a); /* range check */ if (head < 0) { head += a->len; if (head < 0) { mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); } } if (a->len < len || a->len < head + len) { len = a->len - head; } tail = head + len; /* size check */ if (mrb_array_p(rpl)) { argc = RARRAY_LEN(rpl); argv = RARRAY_PTR(rpl); } else { argc = 1; argv = &rpl; } size = head + argc; if (tail < a->len) size += a->len - tail; if (size > a->aux.capa) ary_expand_capa(mrb, a, size); if (head > a->len) { ary_fill_with_nil(a->ptr + a->len, (int)(head - a->len)); } else if (head < a->len) { memmove(a->ptr + head + argc, a->ptr + tail, sizeof(mrb_value)*(a->len - tail)); } for(i = 0; i < argc; i++) { *(a->ptr + head + i) = *(argv + i); } a->len = size; return ary; }
/* * call-seq: * Struct.new( [aString] [, aSym]+> ) -> StructClass * StructClass.new(arg, ...) -> obj * StructClass[arg, ...] -> obj * * Creates a new class, named by <i>aString</i>, containing accessor * methods for the given symbols. If the name <i>aString</i> is * omitted, an anonymous structure class will be created. Otherwise, * the name of this struct will appear as a constant in class * <code>Struct</code>, so it must be unique for all * <code>Struct</code>s in the system and should start with a capital * letter. Assigning a structure class to a constant effectively gives * the class the name of the constant. * * <code>Struct::new</code> returns a new <code>Class</code> object, * which can then be used to create specific instances of the new * structure. The number of actual parameters must be * less than or equal to the number of attributes defined for this * class; unset parameters default to <code>nil</code>. Passing too many * parameters will raise an <code>ArgumentError</code>. * * The remaining methods listed in this section (class and instance) * are defined for this generated class. * * # Create a structure with a name in Struct * Struct.new("Customer", :name, :address) #=> Struct::Customer * Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main"> * * # Create a structure named by its constant * Customer = Struct.new(:name, :address) #=> Customer * Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main"> */ static mrb_value mrb_struct_s_def(mrb_state *mrb, mrb_value klass) { mrb_value name, rest; mrb_value *pargv; int argcnt; mrb_int i; mrb_value b, st; mrb_sym id; mrb_value *argv; int argc; name = mrb_nil_value(); rest = mrb_nil_value(); mrb_get_args(mrb, "*&", &argv, &argc, &b); if (argc == 0) { /* special case to avoid crash */ rest = mrb_ary_new(mrb); } else { if (argc > 0) name = argv[0]; if (argc > 1) rest = argv[1]; if (mrb_array_p(rest)) { if (!mrb_nil_p(name) && mrb_symbol_p(name)) { /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ mrb_ary_unshift(mrb, rest, name); name = mrb_nil_value(); } } else { pargv = &argv[1]; argcnt = argc-1; if (!mrb_nil_p(name) && mrb_symbol_p(name)) { /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ name = mrb_nil_value(); pargv = &argv[0]; argcnt++; } rest = mrb_ary_new_from_values(mrb, argcnt, pargv); } for (i=0; i<RARRAY_LEN(rest); i++) { id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]); RARRAY_PTR(rest)[i] = mrb_symbol_value(id); } } st = make_struct(mrb, name, rest, struct_class(mrb)); if (!mrb_nil_p(b)) { mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(klass)); } return st; }
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)) { 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_ary_eq(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); if (!mrb_array_p(ary2)) { return mrb_false_value(); } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); return ary2; }
/* :nodoc: */ static 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; 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"); } mrb_ary_replace(mrb, copy, s); return copy; }
static mrb_value mrb_ary_eql(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_int i; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); if (!mrb_array_p(ary2)) return mrb_false_value(); if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { return mrb_false_value(); } } return mrb_true_value(); }
bool rubyval_to_array(mrb_state* mrb, mrb_value arg, __Array** outValue, const char* funcName) { if (! mrb_array_p(arg)) { return false; } mrb_int len = mrb_ary_len(mrb, arg); __Array* arr = __Array::createWithCapacity(len); for (mrb_int i = 0; i < len; i++) { mrb_value val = mrb_ary_ref(mrb, arg, i); Ref* ref = to_ref_value(mrb, val); arr->addObject(ref); } *outValue = arr; return true; }
bool rubyval_to_ccvaluevector(mrb_state* mrb, mrb_value arg, cocos2d::ValueVector* ret, const char* funcName) { if (! mrb_array_p(arg)) { return false; } mrb_int len = mrb_ary_len(mrb, arg); for (mrb_int i = 0; i < len; i++) { mrb_value v = mrb_ary_ref(mrb, arg, i); Value val; if (! rubyval_to_ccvalue(mrb, v, &val)) { return false; } ret->push_back(val); } return true; }
/* * call-seq: * Hash(arg) -> hash * * Converts <i>arg</i> to a <code>Hash</code> by calling * <i>arg</i><code>.to_hash</code>. Returns an empty <code>Hash</code> when * <i>arg</i> is <tt>nil</tt> or <tt>[]</tt>. * * Hash([]) #=> {} * Hash(nil) #=> {} * Hash(key: :value) #=> {:key => :value} * Hash([1, 2, 3]) #=> TypeError * */ static mrb_value mrb_f_hash(mrb_state *mrb, mrb_value self) { mrb_value arg, tmp; mrb_get_args(mrb, "o", &arg); if (mrb_nil_p(arg)) { return mrb_hash_new(mrb); } tmp = mrb_check_convert_type(mrb, arg, MRB_TT_HASH, "Hash", "to_hash"); if (mrb_nil_p(tmp)) { if (mrb_array_p(arg) && RARRAY_LEN(arg) == 0) { return mrb_hash_new(mrb); } mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Hash", mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, arg))); } return tmp; }
bool rubyval_to_carray_float(mrb_state* mrb, mrb_value arg, float** outValue, const char* funcName) { if (! mrb_array_p(arg)) { return false; } mrb_int len = mrb_ary_len(mrb, arg); float arr[len]; for (mrb_int i = 0; i < len; i++) { mrb_value val = mrb_ary_ref(mrb, arg, i); if (! mrb_float_p(val)) { return false; } arr[i] = mrb_float(val); } *outValue = arr; return true; }
static mrb_value inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) { mrb_int i; mrb_value s, arystr; char head[] = { '[' }; char sep[] = { ',', ' ' }; char tail[] = { ']' }; /* check recursive */ for(i=0; i<RARRAY_LEN(list); i++) { if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) { return mrb_str_new(mrb, "[...]", 5); } } mrb_ary_push(mrb, list, ary); arystr = mrb_str_buf_new(mrb, 64); mrb_str_buf_cat(mrb, arystr, head, sizeof(head)); for(i=0; i<RARRAY_LEN(ary); i++) { int ai = mrb_gc_arena_save(mrb); if (i > 0) { mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); } if (mrb_array_p(RARRAY_PTR(ary)[i])) { s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); } else { s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); } mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); mrb_gc_arena_restore(mrb, ai); } mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail)); mrb_ary_pop(mrb, list); return arystr; }
MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value v) { mrb_value a; if (mrb_array_p(v)) { return v; } if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { return mrb_ary_new_from_values(mrb, 1, &v); } a = mrb_funcall(mrb, v, "to_a", 0); if (mrb_nil_p(a)) { return mrb_ary_new_from_values(mrb, 1, &v); } mrb_ensure_array_type(mrb, a); return a; }
static mrb_value mrb_ary_equal(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; mrb_bool equal_p; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) { equal_p = 1; } else if (mrb_special_const_p(ary2)) { equal_p = 0; } else if (!mrb_array_p(ary2)) { if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) { equal_p = 0; } else { equal_p = mrb_equal(mrb, ary2, ary1); } } else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) { equal_p = 0; } else { mrb_int i; equal_p = 1; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { equal_p = 0; break; } } } return mrb_bool_value(equal_p); }
static mrb_value mrb_uv_key_set(mrb_state *mrb, mrb_value self) { uv_key_t *key; void *p; mrb_value new_val; mrb_value ary; mrb_get_args(mrb, "o", &new_val); if (mrb_type(new_val) < MRB_TT_HAS_BASIC) { mrb_raisef(mrb, E_TYPE_ERROR, "cannot store value without basic: %S", new_val); } key = (uv_key_t*)mrb_uv_get_ptr(mrb, self, &mrb_uv_key_type); p = uv_key_get(key); ary = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "values")); mrb_assert(mrb_array_p(ary)); if (p) { /* remove value */ int i, dst; for (i = 0, dst = 0; i < RARRAY_LEN(ary); ++i) { mrb_value v = RARRAY_PTR(ary)[i]; if (mrb_ptr(v) != p) { mrb_ary_ptr(ary)->ptr[dst++] = v; } } RARRAY_LEN(ary) = dst; } uv_key_set(key, mrb_ptr(new_val)); mrb_ary_push(mrb, ary, new_val); /* protect from GC */ return new_val; }
/* :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; }