Skip to content

Commit

Permalink
misc fixes
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/icu@3641 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
lrz committed Feb 27, 2010
1 parent d7a5d40 commit 41240b4
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 23 deletions.
1 change: 0 additions & 1 deletion encoding.h
Expand Up @@ -291,7 +291,6 @@ str_set_valid_encoding(rb_str_t *self, bool status)
}

VALUE mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2);
VALUE str_inspect(rb_str_t *str, bool dump);
VALUE rb_str_intern_fast(VALUE str);

// The following functions should always been prefered over anything else,
Expand Down
133 changes: 120 additions & 13 deletions re.cpp
Expand Up @@ -653,7 +653,41 @@ regexp_source(VALUE rcv, SEL sel)
static VALUE
regexp_inspect(VALUE rcv, SEL sel)
{
return regexp_source(rcv, 0);
VALUE str = rb_str_new2("/");
rb_str_concat(str, regexp_source(rcv, 0));
rb_str_cat2(str, "/");
// TODO: add options there.
return str;
}

/*
* call-seq:
* rxp.to_s => str
*
* Returns a string containing the regular expression and its options (using the
* <code>(?opts:source)</code> notation. This string can be fed back in to
* <code>Regexp::new</code> to a regular expression with the same semantics as
* the original. (However, <code>Regexp#==</code> may not return true when
* comparing the two, as the source of the regular expression itself may
* differ, as the example shows). <code>Regexp#inspect</code> produces a
* generally more readable version of <i>rxp</i>.
*
* r1 = /ab+c/ix #=> /ab+c/ix
* s1 = r1.to_s #=> "(?ix-m:ab+c)"
* r2 = Regexp.new(s1) #=> /(?ix-m:ab+c)/
* r1 == r2 #=> false
* r1.source #=> "ab+c"
* r2.source #=> "(?ix-m:ab+c)"
*/

static VALUE
regexp_to_s(VALUE rcv, SEL sel)
{
VALUE str = rb_str_new2("(?:");
// TODO: add options there.
rb_str_concat(str, regexp_source(rcv, 0));
rb_str_cat2(str, ")");
return str;
}

/*
Expand Down Expand Up @@ -709,6 +743,76 @@ regexp_options(VALUE rcv, SEL sel)
return INT2FIX(rb_reg_options(rcv));
}

static VALUE
match_getter(void)
{
VALUE match = rb_backref_get();
if (NIL_P(match)) {
return Qnil;
}
rb_match_busy(match);
return match;
}

static void
match_setter(VALUE val)
{
if (!NIL_P(val)) {
Check_Type(val, T_MATCH);
}
rb_backref_set(val);
}

static VALUE
last_match_getter(void)
{
return rb_reg_last_match(rb_backref_get());
}

static VALUE
prematch_getter(void)
{
return rb_reg_match_pre(rb_backref_get());
}

static VALUE
postmatch_getter(void)
{
return rb_reg_match_post(rb_backref_get());
}

static VALUE
last_paren_match_getter(void)
{
return rb_reg_match_last(rb_backref_get());
}

static VALUE
kcode_getter(void)
{
rb_warn("variable $KCODE is no longer effective");
return Qnil;
}

static void
kcode_setter(VALUE val, ID id)
{
rb_warn("variable $KCODE is no longer effective; ignored");
}

static VALUE
ignorecase_getter(void)
{
rb_warn("variable $= is no longer effective");
return Qfalse;
}

static void
ignorecase_setter(VALUE val, ID id)
{
rb_warn("variable $= is no longer effective; ignored");
}

/*
* Document-class: Regexp
*
Expand All @@ -726,17 +830,20 @@ Init_Regexp(void)
{
rb_eRegexpError = rb_define_class("RegexpError", rb_eStandardError);

#if 0
rb_define_virtual_variable("$~", match_getter, match_setter);
rb_define_virtual_variable("$&", last_match_getter, 0);
rb_define_virtual_variable("$`", prematch_getter, 0);
rb_define_virtual_variable("$'", postmatch_getter, 0);
rb_define_virtual_variable("$+", last_paren_match_getter, 0);

rb_define_virtual_variable("$=", ignorecase_getter, ignorecase_setter);
rb_define_virtual_variable("$KCODE", kcode_getter, kcode_setter);
rb_define_virtual_variable("$-K", kcode_getter, kcode_setter);
#endif
#define DEFINE_GVAR(name, getter, setter) \
rb_define_virtual_variable(name, (VALUE (*)(...))getter, \
(void (*)(...))setter)

DEFINE_GVAR("$~", match_getter, match_setter);
DEFINE_GVAR("$&", last_match_getter, 0);
DEFINE_GVAR("$`", prematch_getter, 0);
DEFINE_GVAR("$'", postmatch_getter, 0);
DEFINE_GVAR("$+", last_paren_match_getter, 0);
DEFINE_GVAR("$=", ignorecase_getter, ignorecase_setter);
DEFINE_GVAR("$KCODE", kcode_getter, kcode_setter);
DEFINE_GVAR("$-K", kcode_getter, kcode_setter);

#undef DEFINE_GVAR

rb_cRegexp = rb_define_class("Regexp", rb_cObject);
rb_objc_define_method(*(VALUE *)rb_cRegexp, "alloc",
Expand Down Expand Up @@ -766,7 +873,6 @@ Init_Regexp(void)
rb_objc_define_method(rb_cRegexp, "match", (void *)regexp_match2, -1);
rb_objc_define_method(rb_cRegexp, "~", (void *)regexp_match3, 0);
rb_objc_define_method(rb_cRegexp, "===", (void *)regexp_eqq, 1);
//rb_objc_define_method(rb_cRegexp, "to_s", rb_reg_to_s, 0);
rb_objc_define_method(rb_cRegexp, "source", (void *)regexp_source, 0);
rb_objc_define_method(rb_cRegexp, "casefold?", (void *)regexp_casefold, 0);
rb_objc_define_method(rb_cRegexp, "options", (void *)regexp_options, 0);
Expand All @@ -778,6 +884,7 @@ Init_Regexp(void)
rb_objc_define_method(rb_cRegexp, "named_captures",
rb_reg_named_captures, 0);
#endif
rb_objc_define_method(rb_cRegexp, "to_s", (void *)regexp_to_s, 0);
rb_objc_define_method(rb_cRegexp, "inspect", (void *)regexp_inspect, 0);

regexp_finalize_imp_super = rb_objc_install_method2((Class)rb_cRegexp,
Expand Down
2 changes: 1 addition & 1 deletion string.c
Expand Up @@ -2031,7 +2031,7 @@ inspect_append(VALUE result, UChar c, bool escape)
str_append_uchar(RSTR(result), c);
}

VALUE
static VALUE
str_inspect(rb_str_t *str, bool dump)
{
const bool uchars = str_is_stored_in_uchars(str);
Expand Down
46 changes: 38 additions & 8 deletions symbol.c
Expand Up @@ -22,14 +22,14 @@ static long last_id = 0;

typedef struct {
VALUE klass;
rb_str_t *str;
VALUE str;
ID id;
} rb_sym_t;

#define RSYM(obj) ((rb_sym_t *)(obj))

static rb_sym_t *
sym_alloc(rb_str_t *str, ID id)
sym_alloc(VALUE str, ID id)
{
rb_sym_t *sym = (rb_sym_t *)malloc(sizeof(rb_sym_t));
assert(rb_cSymbol != 0);
Expand Down Expand Up @@ -93,8 +93,7 @@ rb_intern_str(VALUE str)

id_register:
//printf("register %s hash %ld id %ld\n", RSTRING_PTR(str), name_hash, id);
assert(IS_RSTR(str));
sym = sym_alloc(RSTR(str), id);
sym = sym_alloc(str, id);
CFDictionarySetValue(sym_id, (const void *)name_hash, (const void *)id);
CFDictionarySetValue(id_str, (const void *)id, (const void *)sym);

Expand Down Expand Up @@ -122,7 +121,7 @@ rb_id2str(ID id)
id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
}

VALUE str = rb_str_dup((VALUE)RSYM(sym)->str);
VALUE str = rb_str_dup(RSYM(sym)->str);
rb_str_cat(str, "=", 1);
rb_intern_str(str);

Expand Down Expand Up @@ -171,7 +170,7 @@ rb_name2sym(const char *name)
VALUE
rb_sym_to_s(VALUE sym)
{
return rb_str_dup((VALUE)RSYM(sym)->str);
return rb_str_dup(RSYM(sym)->str);
}

const char *
Expand Down Expand Up @@ -223,7 +222,7 @@ Init_PreSymbol(void)
for (int i = 0; rb_op_tbl[i].token != 0; i++) {
ID id = rb_op_tbl[i].token;
VALUE str = rb_str_new2(rb_op_tbl[i].name);
rb_sym_t *sym = sym_alloc(RSTR(str), id);
rb_sym_t *sym = sym_alloc(str, id);
unsigned long name_hash = rb_str_hash(str);

//printf("pre-register %s hash %ld id %ld\n", RSTRING_PTR(str), name_hash, id);
Expand Down Expand Up @@ -257,11 +256,42 @@ rsym_equal(VALUE sym, SEL sel, VALUE other)
* :fred.inspect #=> ":fred"
*/

static bool
sym_should_be_escaped(VALUE sym)
{
UChar *chars = NULL;
long chars_len = 0;
bool need_free = false;
rb_str_get_uchars(RSYM(sym)->str, &chars, &chars_len, &need_free);

// TODO: this is really not enough, we should mimic 1.9's
// rb_enc_symname2_p() function.
bool escape = false;
for (long i = 0; i < chars_len; i++) {
if (!iswprint(chars[i])
|| iswspace(chars[i])) {
escape = true;
break;
}
}

if (need_free) {
free(chars);
}

return escape;
}

static VALUE
rsym_inspect(VALUE sym, SEL sel)
{
VALUE str = rb_str_new2(":");
rb_str_concat(str, str_inspect(RSYM(sym)->str, true));
if (sym_should_be_escaped(sym)) {
rb_str_concat(str, rb_str_inspect(RSYM(sym)->str));
}
else {
rb_str_concat(str, RSYM(sym)->str);
}
return str;
}

Expand Down

0 comments on commit 41240b4

Please sign in to comment.