Permalink
Browse files

added Symbol#<=>, fixed some bugs in String#<=>

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/icu@3666 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 539b892 commit 3d2b558264eec25eb42d5cfd54a004c696e4b1be @lrz lrz committed Mar 2, 2010
Showing with 51 additions and 42 deletions.
  1. +33 −42 string.c
  2. +18 −0 symbol.c
View
@@ -843,53 +843,39 @@ str_compare(rb_str_t *self, rb_str_t *str)
return 0;
}
- if (self->length_in_bytes == 0) {
- if (str->length_in_bytes == 0) {
- // both strings are empty
- return 0;
- }
- else {
- // only self is empty
- goto bad_length;
- }
+ if (self->length_in_bytes == 0 && str->length_in_bytes == 0) {
+ // both strings are empty
+ return 0;
}
- else if (str->length_in_bytes == 0) {
- // only str is empty
- goto bad_length;
+
+ if (str_compatible_encoding(self, str) == NULL) {
+ // incompatible encodings
+ return -1;
}
- if (str_compatible_encoding(self, str) != NULL) {
- if (str_is_stored_in_uchars(self) == str_is_stored_in_uchars(str)) {
- if (self->length_in_bytes != str->length_in_bytes) {
- goto bad_length;
- }
- else {
- return memcmp(self->data.bytes, str->data.bytes,
- self->length_in_bytes);
- }
- }
- else { // one is in uchars and the other is in binary
- if (!str_try_making_data_uchars(self)
- || !str_try_making_data_uchars(str)) {
- // one is in uchars but the other one can't be converted in
- // uchars
- return -1;
- }
- if (self->length_in_bytes != str->length_in_bytes) {
- goto bad_length;
- }
- else {
- return memcmp(self->data.bytes, str->data.bytes,
- self->length_in_bytes);
- }
+ if (str_is_stored_in_uchars(self) != str_is_stored_in_uchars(str)) {
+ // one is in uchars and the other is in binary
+ if (!str_try_making_data_uchars(self)
+ || !str_try_making_data_uchars(str)) {
+ // one is in uchars but the other one can't be converted in
+ // uchars
+ return -1;
}
}
- else { // incompatible encodings
- return -1;
- }
-bad_length:
- return self->length_in_bytes > str->length_in_bytes ? 1 : -1;
+ const long min_len = self->length_in_bytes < str->length_in_bytes
+ ? self->length_in_bytes : str->length_in_bytes;
+
+ const int res = memcmp(self->data.bytes, str->data.bytes, min_len);
+
+ if (res == 0) {
+ if (self->length_in_bytes == str->length_in_bytes) {
+ return 0;
+ }
+ return self->length_in_bytes > str->length_in_bytes
+ ? 1 : -1;
+ }
+ return res > 1 ? 1 : -1;
}
static long
@@ -1931,7 +1917,6 @@ rstr_cmp(VALUE self, SEL sel, VALUE other)
* Two strings are equal if they have the same length and content.
*/
-
static VALUE
rstr_eql(VALUE self, SEL sel, VALUE other)
{
@@ -4216,3 +4201,9 @@ rb_str_update(VALUE str, long beg, long len, VALUE val)
abort(); // TODO
}
}
+
+int
+rb_str_cmp(VALUE str1, VALUE str2)
+{
+ return str_compare(str_need_string(str1), str_need_string(str2));
+}
View
@@ -234,6 +234,23 @@ Init_PreSymbol(void)
}
/*
+ * call-seq:
+ *
+ * str <=> other => -1, 0, +1 or nil
+ *
+ * Compares _sym_ with _other_ in string form.
+ */
+
+static VALUE
+rsym_cmp(VALUE sym, SEL sel, VALUE other)
+{
+ if (TYPE(other) != T_SYMBOL) {
+ return Qnil;
+ }
+ return INT2FIX(rb_str_cmp(RSYM(sym)->str, RSYM(other)->str));
+}
+
+/*
* call-seq:
* sym == obj => true or false
*
@@ -370,6 +387,7 @@ Init_Symbol(void)
rsym_all_symbols, 0);
rb_objc_define_method(rb_cSymbol, "==", rsym_equal, 1);
+ rb_objc_define_method(rb_cSymbol, "<=>", rsym_cmp, 1);
rb_objc_define_method(rb_cSymbol, "eql?", rsym_equal, 1);
//rb_objc_define_method(rb_cSymbol, "<=>", rsym_cmp, 1);
rb_objc_define_method(rb_cSymbol, "inspect", rsym_inspect, 0);

0 comments on commit 3d2b558

Please sign in to comment.