static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr; ID id; long i, len; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); #if !WITH_OBJC rb_make_metaclass(nstr, RBASIC(klass)->klass); #endif rb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = rb_str_to_str(name); id = rb_to_id(name); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_under(klass, rb_id2name(id), klass); } rb_ivar_set(nstr, id_members, members); rb_objc_define_method(*(VALUE *)nstr, "alloc", struct_alloc, 0); rb_objc_define_method(*(VALUE *)nstr, "new", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "[]", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "members", rb_struct_s_members_m, 0); len = RARRAY_LEN(members); for (i=0; i< len; i++) { ID id = SYM2ID(RARRAY_AT(members, i)); if (rb_is_local_id(id) || rb_is_const_id(id)) { long j = i; /* Needed for block data reference. */ /* Struct attribute reader */ rb_objc_define_method(nstr, rb_id2name(id), pl_imp_implementationWithBlock(^(VALUE obj) { return RSTRUCT_PTR(obj)[j]; }), 0); /* Struct attribute writer */ rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)), pl_imp_implementationWithBlock(^(VALUE obj, VALUE val) { VALUE *ptr = RSTRUCT_PTR(obj); rb_struct_modify(obj); GC_WB(&ptr[i], val); return val; }), 1);
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr; ID id; long i, count; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); #if !WITH_OBJC rb_make_metaclass(nstr, RBASIC(klass)->klass); #endif rb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = rb_str_to_str(name); id = rb_to_id(name); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY_LEN(members))); rb_iv_set(nstr, "__members__", members); rb_objc_define_method(*(VALUE *)nstr, "alloc", struct_alloc, 0); rb_objc_define_method(*(VALUE *)nstr, "new", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "[]", rb_class_new_instance_imp, -1); rb_objc_define_method(*(VALUE *)nstr, "members", rb_struct_s_members_m, 0); for (i = 0, count = RARRAY_LEN(members); i < count; i++) { ID id = SYM2ID(RARRAY_AT(members, i)); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i < N_REF_FUNC) { rb_objc_define_method(nstr, rb_id2name(id), ref_func[i], 0); } else { rb_objc_define_method(nstr, rb_id2name(id), rb_struct_ref, 0); } rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)), rb_struct_set, 1); } } return nstr; }
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr, *ptr_members; ID id; long i, len; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); rb_make_metaclass(nstr, RBASIC(klass)->klass); rb_class_inherited(klass, nstr); } else { /* old style: should we warn? */ name = rb_str_to_str(name); id = rb_to_id(name); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name)); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", StringValuePtr(name)); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_id_under(klass, id, klass); } rb_ivar_set(nstr, id_members, members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i< len; i++) { ID id = SYM2ID(ptr_members[i]); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i < N_REF_FUNC) { rb_define_method_id(nstr, id, ref_func[i], 0); } else { rb_define_method_id(nstr, id, rb_struct_ref, 0); } rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1); } } return nstr; }
/* Foo = Numo::Struct.new { int8 :byte float64 :float, [2,2] dcomplex :compl } */ static VALUE nst_s_new(int argc, VALUE *argv, VALUE klass) { VALUE name=Qnil, rest, size; VALUE st, members; ID id; rb_scan_args(argc, argv, "0*", &rest); if (RARRAY_LEN(rest)>0) { name = RARRAY_AREF(rest,0); if (!NIL_P(name)) { VALUE tmp = rb_check_string_type(name); if (!NIL_P(tmp)) { rb_ary_shift(rest); } else { name = Qnil; } } } if (NIL_P(name)) { st = rb_define_class_id(name, klass); rb_funcall(klass, rb_intern("inherited"), 1, st); } else { char *cname = StringValuePtr(name); id = rb_intern(cname); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", cname); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", cname); rb_mod_remove_const(klass, ID2SYM(id)); } st = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(st, "__members__", rb_ary_new()); rb_iv_set(st, "__offset__", INT2FIX(0)); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } size = rb_iv_get(st, "__offset__"); members = rb_iv_get(st, "__members__"); //printf("size=%d\n",NUM2INT(size)); rb_define_const(st, CONTIGUOUS_STRIDE, size); rb_define_const(st, ELEMENT_BYTE_SIZE, size); rb_define_const(st, ELEMENT_BIT_SIZE, rb_funcall(size,'*',1,INT2FIX(8))); OBJ_FREEZE(members); rb_define_const(st, "DEFINITIONS", members); rb_define_singleton_method(st, "new", rb_class_new_instance, -1); //rb_define_singleton_method(st, "[]", rb_class_new_instance, -1); rb_define_method(st, "allocate", nst_allocate, 0); return st; }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { const char *name; int noex; if (!ex) { noex = NOEX_PUBLIC; } else { // TODO honor current scope ex noex = NOEX_PUBLIC; } if (!rb_is_local_id(id) && !rb_is_const_id(id)) { rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id)); } name = rb_id2name(id); if (!name) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } rb_vm_define_attr((Class)klass, name, read, write, noex); if (write) { rb_objc_define_kvo_setter(klass, id); } }
static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { VALUE nstr; ID id; long i; OBJ_FREEZE(members); if (NIL_P(name)) { nstr = rb_class_new(klass); rb_make_metaclass(nstr, RBASIC(klass)->klass); rb_class_inherited(klass, nstr); } else { char *cname = StringValuePtr(name); id = rb_intern(cname); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", cname); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", cname); rb_mod_remove_const(klass, ID2SYM(id)); } nstr = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len)); rb_iv_set(nstr, "__members__", members); rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); for (i=0; i< RARRAY(members)->len; i++) { ID id = SYM2ID(RARRAY(members)->ptr[i]); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i<10) { rb_define_method_id(nstr, id, ref_func[i], 0); } else { rb_define_method_id(nstr, id, rb_struct_ref, 0); } rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1); } } return nstr; }
void rbgobj_init_flags_class(VALUE klass) { GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass)); GString* source = g_string_new(NULL); guint i; for (i = 0; i < gclass->n_values; i++) { GFlagsValue* entry = &(gclass->values[i]); gchar* nick; gchar* p; gchar* replace_nick; replace_nick = rg_obj_constant_lookup(entry->value_nick); if (replace_nick){ nick = g_strdup(replace_nick); } else { nick = g_strdup(entry->value_nick); } for (p = nick; *p; p++) if (*p == '-' || *p == ' ') *p = '_'; else *p = tolower(*p); g_string_append_printf( source, "def %s%s?; self >= self.class.new(%d); end\n", g_ascii_isdigit(nick[0]) ? "_" : "", nick, entry->value); for (p = nick; *p; p++) *p = g_ascii_toupper(*p); #if 0 { ID id = rb_intern(nick); if (rb_is_const_id(id)) { rb_define_const(klass, nick, make_flags(entry->value, klass)); } } #else { rbgobj_define_const(klass, nick, make_flags(entry->value, klass)); } #endif g_free(nick); } rb_funcall(klass, id_module_eval, 3, rb_str_new2(source->str), rb_str_new2(__FILE__), INT2NUM(__LINE__)); g_string_free(source, TRUE); g_type_class_unref(gclass); }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { if (!rb_is_local_id(id) && !rb_is_const_id(id)) { rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id)); } const char *name = rb_id2name(id); if (name == NULL) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } rb_vm_define_attr((Class)klass, name, read, write); if (write) { rb_objc_define_kvo_setter(klass, id); } }
static VALUE inspect_struct(VALUE s, VALUE dummy, int recur) { VALUE cname = rb_class_name(rb_obj_class(s)); VALUE members, str = rb_str_new2("#<struct "); VALUE *ptr, *ptr_members; long i, len; char first = RSTRING_PTR(cname)[0]; if (recur || first != '#') { rb_str_append(str, cname); } if (recur) { return rb_str_cat2(str, ":...>"); } members = rb_struct_members(s); ptr_members = RARRAY_PTR(members); ptr = RSTRUCT_PTR(s); len = RSTRUCT_LEN(s); for (i=0; i<len; i++) { VALUE slot; ID id; if (i > 0) { rb_str_cat2(str, ", "); } else if (first != '#') { rb_str_cat2(str, " "); } slot = ptr_members[i]; id = SYM2ID(slot); if (rb_is_local_id(id) || rb_is_const_id(id)) { rb_str_append(str, rb_id2str(id)); } else { rb_str_append(str, rb_inspect(slot)); } rb_str_cat2(str, "="); rb_str_append(str, rb_inspect(ptr[i])); } rb_str_cat2(str, ">"); OBJ_INFECT(str, s); return str; }
static int fc_i(ID key, VALUE value, struct fc_result *res) { if (!rb_is_const_id(key)) return ST_CONTINUE; if (value == res->klass) { res->path = fc_path(res, key); return ST_STOP; } switch (TYPE(value)) { case T_MODULE: case T_CLASS: { CFDictionaryRef iv_dict = rb_class_ivar_dict(value); if (iv_dict == NULL) return ST_CONTINUE; else { struct fc_result arg; struct fc_result *list; list = res; while (list) { if (list->track == value) return ST_CONTINUE; list = list->prev; } arg.name = key; arg.path = 0; arg.klass = res->klass; arg.track = value; arg.prev = res; ivar_dict_foreach(iv_dict, fc_i, (VALUE)&arg); if (arg.path) { res->path = arg.path; return ST_STOP; } } break; } default: break; } return ST_CONTINUE; }
void rb_attr(VALUE klass, ID id, int read, int write, int ex) { const char *name; ID attriv; VALUE aname; int noex; if (!ex) { noex = NOEX_PUBLIC; } else { if (SCOPE_TEST(NOEX_PRIVATE)) { noex = NOEX_PRIVATE; rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ? "attribute accessor as module_function" : "private attribute?"); } else if (SCOPE_TEST(NOEX_PROTECTED)) { noex = NOEX_PROTECTED; } else { noex = NOEX_PUBLIC; } } if (!rb_is_local_id(id) && !rb_is_const_id(id)) { rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id)); } name = rb_id2name(id); if (!name) { rb_raise(rb_eArgError, "argument needs to be symbol or string"); } aname = rb_sprintf("@%s", name); rb_enc_copy(aname, rb_id2str(id)); attriv = rb_intern_str(aname); if (read) { rb_add_method(klass, id, NEW_IVAR(attriv), noex); } if (write) { rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex); } }
static int fc_i(ID key, rb_const_entry_t *ce, struct fc_result *res) { VALUE value = ce->value; if (!rb_is_const_id(key)) return ST_CONTINUE; if (value == res->klass) { res->path = fc_path(res, key); return ST_STOP; } switch (TYPE(value)) { case T_MODULE: case T_CLASS: if (!RCLASS_CONST_TBL(value)) return ST_CONTINUE; else { struct fc_result arg; struct fc_result *list; list = res; while (list) { if (list->track == value) return ST_CONTINUE; list = list->prev; } arg.name = key; arg.path = 0; arg.klass = res->klass; arg.track = value; arg.prev = res; st_foreach(RCLASS_CONST_TBL(value), fc_i, (st_data_t)&arg); if (arg.path) { res->path = arg.path; return ST_STOP; } } break; default: break; } return ST_CONTINUE; }
static VALUE inspect_struct(VALUE s, VALUE dummy, int recur) { const char *cname = rb_class2name(rb_obj_class(s)); VALUE str, members; long i; if (recur) { return rb_sprintf("#<struct %s:...>", cname); } members = rb_struct_members(s); if (cname[0] == '#') { str = rb_str_new2("#<struct "); } else { str = rb_sprintf("#<struct %s ", cname); } for (i=0; i<RSTRUCT_LEN(s); i++) { VALUE slot; ID id; if (i > 0) { rb_str_cat2(str, ", "); } slot = RARRAY_AT(members, i); id = SYM2ID(slot); if (rb_is_local_id(id) || rb_is_const_id(id)) { rb_str_buf_append(str, rb_id2str(id)); } else { rb_str_buf_append(str, rb_inspect(slot)); } rb_str_cat2(str, "="); rb_str_buf_append(str, rb_inspect(RSTRUCT_PTR(s)[i])); } rb_str_cat2(str, ">"); OBJ_INFECT(str, s); return str; }
static VALUE inspect_struct(VALUE s) { const char *cname = rb_class2name(rb_obj_class(s)); VALUE str, members; long i; members = rb_struct_members(s); str = rb_str_buf_new2("#<struct "); rb_str_cat2(str, cname); rb_str_cat2(str, " "); for (i=0; i<RSTRUCT(s)->len; i++) { VALUE slot; ID id; const char *p; if (i > 0) { rb_str_cat2(str, ", "); } slot = RARRAY(members)->ptr[i]; id = SYM2ID(slot); if (rb_is_local_id(id) || rb_is_const_id(id)) { p = rb_id2name(id); rb_str_cat2(str, p); } else { rb_str_append(str, rb_inspect(slot)); } rb_str_cat2(str, "="); rb_str_append(str, rb_inspect(RSTRUCT(s)->ptr[i])); } rb_str_cat2(str, ">"); OBJ_INFECT(str, s); return str; }
VALUE symbol_spec_rb_is_const_id(VALUE self, VALUE sym) { return rb_is_const_id(SYM2ID(sym)) ? Qtrue : Qfalse; }
static bool const_p(VALUE self, char* name) { return rb_obj_is_kind_of(self, rb_cModule) && rb_is_const_id(rb_intern(name)) && RTEST( rb_funcall(self, rb_intern("const_defined?"), 1, ID2SYM(rb_intern(name))) ); }