Revision
3652
Author
lsansonetti@apple.com
Date
2010-02-27 02:33:32 -0800 (Sat, 27 Feb 2010)

Log Message

added #chars and #each_char

Modified Paths

Diff

Modified: MacRuby/branches/icu/string.c (3651 => 3652)


--- MacRuby/branches/icu/string.c	2010-02-27 10:33:02 UTC (rev 3651)
+++ MacRuby/branches/icu/string.c	2010-02-27 10:33:32 UTC (rev 3652)
@@ -3369,6 +3369,57 @@
     return str;
 }
 
+/*
+ *  Document-method: chars
+ *  call-seq:
+ *     str.chars                   => anEnumerator
+ *     str.chars {|substr| block } => str
+ *  
+ *  Returns an enumerator that gives each character in the string.
+ *  If a block is given, it iterates over each character in the string.
+ *     
+ *     "foo".chars.to_a   #=> ["f","o","o"]
+ */
+
+/*
+ *  Document-method: each_char
+ *  call-seq:
+ *     str.each_char {|cstr| block }    => str
+ *  
+ *  Passes each character in <i>str</i> to the given block.
+ *     
+ *     "hello".each_char {|c| print c, ' ' }
+ *     
+ *  <em>produces:</em>
+ *     
+ *     h e l l o 
+ */
+
+static VALUE
+rstr_each_char(VALUE str, SEL sel)
+{
+    RETURN_ENUMERATOR(str, 0, 0);
+
+    UChar *chars = NULL;
+    long chars_len = 0;
+    bool need_free = false;
+    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+
+    for (long i = 0; i < chars_len; i++) {
+	VALUE charstr = rb_unicode_str_new(&chars[i], 1);
+	rb_yield(charstr);
+	ENSURE_AND_RETURN_IF_BROKEN(
+	    if (need_free) free(chars)
+	);
+    }
+
+    if (need_free) {
+	free(chars);
+    }
+
+    return str;
+}
+
 // NSString primitives.
 
 static void
@@ -3511,6 +3562,8 @@
     rb_objc_define_method(rb_cRubyString, "rstrip!", rstr_rstrip_bang, 0);
     rb_objc_define_method(rb_cRubyString, "lines", rstr_each_line, -1);
     rb_objc_define_method(rb_cRubyString, "each_line", rstr_each_line, -1);
+    rb_objc_define_method(rb_cRubyString, "chars", rstr_each_char, 0);
+    rb_objc_define_method(rb_cRubyString, "each_char", rstr_each_char, 0);
 
     // Added for MacRuby (debugging).
     rb_objc_define_method(rb_cRubyString, "__chars_count__",

Modified: MacRuby/branches/icu/vm.h (3651 => 3652)


--- MacRuby/branches/icu/vm.h	2010-02-27 10:33:02 UTC (rev 3651)
+++ MacRuby/branches/icu/vm.h	2010-02-27 10:33:32 UTC (rev 3652)
@@ -468,6 +468,16 @@
     } \
     while (0)
 
+#define ENSURE_AND_RETURN_IF_BROKEN(code) \
+    do { \
+        VALUE __v = rb_vm_pop_broken_value(); \
+        if (__v != Qundef) { \
+	    code; \
+            return __v; \
+        } \
+    } \
+    while (0)
+
 void rb_vm_finalize(void);
 
 void rb_vm_load_bridge_support(const char *path, const char *framework_path,