Permalink
Browse files

misc fixes

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/icu@3641 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent d7a5d40 commit 41240b43147ee3454362159867df101894756b73 @lrz lrz committed Feb 27, 2010
Showing with 159 additions and 23 deletions.
  1. +0 −1 encoding.h
  2. +120 −13 re.cpp
  3. +1 −1 string.c
  4. +38 −8 symbol.c
View
@@ -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,
View
@@ -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;
}
/*
@@ -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
*
@@ -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",
@@ -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);
@@ -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,
View
@@ -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);
View
@@ -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);
@@ -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);
@@ -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);
@@ -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 *
@@ -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);
@@ -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;
}

0 comments on commit 41240b4

Please sign in to comment.