static mrb_value pcre_regexp_match(mrb_state *mrb, mrb_value self) { const char *str; char global_match[3]; mrb_value regexp; struct mrb_pcre_regexp *reg; int i; mrb_value mrb_i, mrb_match; size_t nmatch = 999; int match[999]; int regno; int ai; struct RClass* clazz; mrb_value c; mrb_value args[2]; mrb_get_args(mrb, "z", &str); regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); regno = pcre_exec(reg->re, NULL, str, strlen(str), 0, 0, match, nmatch); if (regno < 0) return mrb_nil_value(); mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), mrb_nil_value()); ai = mrb_gc_arena_save(mrb); clazz = mrb_class_get(mrb, "PcreMatchData"); c = mrb_obj_new(mrb, clazz, 0, NULL); mrb_iv_set(mrb, c,mrb_intern_lit(mrb, "@string"), mrb_str_new_cstr(mrb, str)); for (i = 0; i < regno; i++) { args[0] = mrb_fixnum_value(match[i * 2]); args[1] = mrb_fixnum_value(match[i * 2 + 1] - match[i * 2]); mrb_funcall_argv(mrb, c, mrb_intern_lit(mrb, "push"), sizeof(args)/sizeof(args[0]), &args[0]); if (i > 0 && i < 10) { sprintf(global_match, "$%i", i); mrb_i = mrb_fixnum_value(i); mrb_match = mrb_funcall_argv(mrb, c, mrb_intern_lit(mrb, "[]"), 1, &mrb_i); mrb_gv_set(mrb, mrb_intern_cstr(mrb, global_match), mrb_match); } mrb_gc_arena_restore(mrb, ai); } mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), c); return c; }
static mrb_value hs_regexp_match(mrb_state *mrb, mrb_value self) { const char *str; struct mrb_hs_regexp *reg; mrb_value m; regexp_info ri = { mrb }; mrb_get_args(mrb, "z", &str); Data_Get_Struct(mrb, self, &mrb_hs_regexp_type, reg); if (!reg->reg){ mrb_raise(mrb, E_ARGUMENT_ERROR, "HsRegexp is not initialized."); } ri.flag = reg->flag; if (hs_regexec(&ri, reg->reg, str)){ m = hs_regexp_get_match_data(mrb, self, str); }else{ m = mrb_nil_value(); } mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), INTERN("@last_match"), m); return m; }
/*! * Defines a class under the namespace of \a outer. * \param outer a class which contains the new class. * \param id name of the new class * \param super a class from which the new class will derive. * NULL means \c Object class. * \return the created class * \throw TypeError if the constant name \a name is already taken but * the constant is not a \c Class. * \throw NameError if the class is already defined but the class can not * be reopened because its superclass is not \a super. * \post top-level constant named \a name refers the returned class. * * \note if a class named \a name is already defined and its superclass is * \a super, the function just returns the defined class. */ struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) { struct RClass * c; mrb_sym id = mrb_intern(mrb, name); if (mrb_const_defined_at(mrb, outer, id)) { c = mrb_class_from_sym(mrb, outer, id); if (c->tt != MRB_TT_CLASS) { mrb_raise(mrb, E_TYPE_ERROR, "%s is not a class", mrb_sym2name(mrb, id)); } if (mrb_class_real(c->super) != super) { mrb_name_error(mrb, id, "%s is already defined", mrb_sym2name(mrb, id)); } return c; } if (!super) { mrb_warn("no super class for `%s::%s', Object assumed", mrb_obj_classname(mrb, mrb_obj_value(outer)), mrb_sym2name(mrb, id)); } c = mrb_class_new(mrb, super); setup_class(mrb, mrb_obj_value(outer), c, id); mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c)); return c; }
mrb_value mrb_class_superclass(mrb_state *mrb, mrb_value klass) { struct RClass *c; mrb_value superclass; c = mrb_class_ptr(klass); if (c->super) superclass = mrb_obj_value(mrb_class_real(c->super)); else superclass = mrb_nil_value(); return superclass; }
/*! * Defines a class under the namespace of \a outer. * \param outer a class which contains the new class. * \param id name of the new class * \param super a class from which the new class will derive. * NULL means \c Object class. * \return the created class * \throw TypeError if the constant name \a name is already taken but * the constant is not a \c Class. * \throw NameError if the class is already defined but the class can not * be reopened because its superclass is not \a super. * \post top-level constant named \a name refers the returned class. * * \note if a class named \a name is already defined and its superclass is * \a super, the function just returns the defined class. */ struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) { struct RClass * c; mrb_sym id = mrb_intern(mrb, name); if (mrb_const_defined_at(mrb, outer, id)) { c = class_from_sym(mrb, outer, id); if (mrb_class_real(c->super) != super) { mrb_name_error(mrb, id, "%S is already defined", name); } return c; } if (!super) { mrb_warn(mrb, "no super class for `%S::%S', Object assumed", outer, name); } c = mrb_class_new(mrb, super); setup_class(mrb, mrb_obj_value(outer), c, id); return c; }
struct RClass* mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) { struct RClass *c, *s; if (mrb_const_defined(mrb, outer, id)) { mrb_value v = mrb_const_get(mrb, outer, id); mrb_check_type(mrb, v, MRB_TT_CLASS); c = mrb_class_ptr(v); if (!mrb_nil_p(super)) { if (mrb_type(super) != MRB_TT_CLASS) { mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); } if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) { mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id)); } } return c; } if (!mrb_nil_p(super)) { if (mrb_type(super) != MRB_TT_CLASS) { mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); } s = mrb_class_ptr(super); } else { s = mrb->object_class; } c = mrb_class_new(mrb, s); setup_class(mrb, outer, c, id); mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c)); return c; }
struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj) { return mrb_class_real(mrb_class(mrb, obj)); }
mrb_value regexp_pcre_match(mrb_state *mrb, mrb_value self) { struct mrb_matchdata *mrb_md; int rc; int ccount, matchlen; int *match; struct RClass *c; mrb_value md, str; mrb_int i, pos; pcre_extra extra; struct mrb_regexp_pcre *reg; reg = (struct mrb_regexp_pcre *)mrb_get_datatype(mrb, self, &mrb_regexp_type); if (!reg) return mrb_nil_value(); pos = 0; mrb_get_args(mrb, "S|i", &str, &pos); // XXX: RSTRING_LEN(str) >= pos ... rc = pcre_fullinfo(reg->re, NULL, PCRE_INFO_CAPTURECOUNT, &ccount); if (rc < 0) { /* fullinfo error */ return mrb_nil_value(); } matchlen = ccount + 1; match = mrb_malloc(mrb, sizeof(int) * matchlen * 3); extra.flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION; extra.match_limit_recursion = 1000; rc = pcre_exec(reg->re, &extra, RSTRING_PTR(str), RSTRING_LEN(str), pos, 0, match, matchlen * 3); if (rc < 0) { mrb_free(mrb, match); return mrb_nil_value(); } /* XXX: need current scope */ mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), mrb_nil_value()); c = mrb_class_get(mrb, "MatchData"); md = mrb_funcall(mrb, mrb_obj_value(c), "new", 0); mrb_md = (struct mrb_matchdata *)mrb_get_datatype(mrb, md, &mrb_matchdata_type); mrb_md->ovector = match; mrb_md->length = matchlen; mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@regexp"), self); mrb_iv_set(mrb, md, mrb_intern_lit(mrb, "@string"), mrb_str_dup(mrb, str)); /* XXX: need current scope */ mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), md); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$~"), md); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$&"), mrb_funcall(mrb, md, "to_s", 0)); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$`"), mrb_funcall(mrb, md, "pre_match", 0)); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$'"), mrb_funcall(mrb, md, "post_match", 0)); for (i = 1; i < 10; i++) { char sym[8]; snprintf(sym, sizeof(sym), "$%d", i); mrb_gv_set(mrb, mrb_intern_cstr(mrb, sym), mrb_funcall(mrb, md, "[]", 1, mrb_fixnum_value(i))); } return md; }
/* * Class: org_jamruby_mruby_RClass * Method: n_classReal * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_org_jamruby_mruby_RClass_n_1classReal (JNIEnv *env, jclass, jlong c) { RClass * const cls = mrb_class_real(to_ptr<RClass>(c)); return to_jlong(cls); }